|
@@ -1,27 +1,21 @@
|
|
|
package com.fdkankan.indoor.core.service.impl;
|
|
|
|
|
|
-import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.fdkankan.indoor.base.constant.MsgCode;
|
|
|
+import com.fdkankan.indoor.base.convert.DistanceUtil;
|
|
|
import com.fdkankan.indoor.base.exception.BaseRuntimeException;
|
|
|
import com.fdkankan.indoor.base.util.Result;
|
|
|
-import com.fdkankan.indoor.core.entity.PoiTypeEntity;
|
|
|
-import com.fdkankan.indoor.core.entity.dto.PoiHotDto;
|
|
|
-import com.fdkankan.indoor.core.entity.dto.PoiSearchDto;
|
|
|
-import com.fdkankan.indoor.core.entity.dto.PoiTypeDto;
|
|
|
+import com.fdkankan.indoor.core.entity.dto.*;
|
|
|
import com.fdkankan.indoor.core.entity.PoiEntity;
|
|
|
-import com.fdkankan.indoor.core.entity.dto.SecurityDto;
|
|
|
import com.fdkankan.indoor.core.mapper.PoiMapper;
|
|
|
+import com.fdkankan.indoor.core.service.DataSetService;
|
|
|
import com.fdkankan.indoor.core.service.PoiService;
|
|
|
import com.fdkankan.indoor.core.service.PoiTypeService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
-import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
-import org.springframework.data.mongodb.core.query.Query;
|
|
|
-import org.springframework.data.mongodb.core.query.Update;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
@@ -46,6 +40,10 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
|
|
|
@Autowired
|
|
|
PoiMapper entityMapper;
|
|
|
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ DataSetService dataSetService;
|
|
|
+
|
|
|
@Override
|
|
|
public void remove(String sceneCode) {
|
|
|
entityMapper.deleteById(sceneCode);
|
|
@@ -176,6 +174,13 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
|
|
|
log.info("设置图标:{}", dto.getIcon());
|
|
|
}
|
|
|
|
|
|
+ // 2021-09-17 前端不一定会添加这个参数,根据dataSet.id 去找siteModelId
|
|
|
+ if (dto.getSite_model_entity_id() == null) {
|
|
|
+ Integer datasetId = dto.getDataset_id();
|
|
|
+ Integer siteModelIdByDataSetId = dataSetService.getSiteModelIdByDataSetId(sceneCode, datasetId);
|
|
|
+ dto.setSite_model_entity_id(siteModelIdByDataSetId);
|
|
|
+ }
|
|
|
+
|
|
|
data.add(dto);
|
|
|
resIds.add(dto.getId());
|
|
|
}
|
|
@@ -187,7 +192,6 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
|
|
|
|
|
|
save(entity);
|
|
|
|
|
|
-// return Result.success(findDataBySceneCode(sceneCode));
|
|
|
return Result.success(changeById(sceneCode, resIds));
|
|
|
}
|
|
|
|
|
@@ -210,9 +214,105 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
+// @Override
|
|
|
+// public Result filter(String sceneCode, PoiQueryDto param) {
|
|
|
+// List<PoiHotDto> data = findDataBySceneCode(sceneCode);
|
|
|
+// if (isLogin()) {
|
|
|
+// return Result.success(data);
|
|
|
+// }
|
|
|
+// return Result.success(changeSecurityUnLoginList(data));
|
|
|
+// }
|
|
|
+
|
|
|
+ // 查询是有优先级的
|
|
|
@Override
|
|
|
- public Result filter(String sceneCode) {
|
|
|
+ public Result filter(String sceneCode, PoiQueryDto param) {
|
|
|
List<PoiHotDto> data = findDataBySceneCode(sceneCode);
|
|
|
+
|
|
|
+ // 返回dataset对应的热点
|
|
|
+ if (param.getDataset() != null) {
|
|
|
+ List<Integer> dataset = param.getDataset();
|
|
|
+ if (dataset.size() > 0) {
|
|
|
+ // 默认只有一个元素
|
|
|
+ Integer dataSetId = dataset.get(0);
|
|
|
+ data = data.stream().filter(p -> dataSetId.equals(p.getDataset_id())).collect(Collectors.toList());
|
|
|
+ return Result.success(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ List<Integer> siteModelIds = param.getSite_model_entity();
|
|
|
+ List<Integer> poiTypeIds = param.getPoi_type();
|
|
|
+
|
|
|
+ if (siteModelIds.size() == 0 || poiTypeIds.size() == 0) {
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+
|
|
|
+ data = data.stream().filter(p -> siteModelIds.contains(p.getSite_model_entity_id())).collect(Collectors.toList());
|
|
|
+ data = data.stream().filter(p -> poiTypeIds.contains(p.getPoi_type_id())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (data.size() == 0) {
|
|
|
+ log.warn("查询结果没有符合条件的数据");
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理 lat, lon
|
|
|
+ Double lat = param.getLat();
|
|
|
+ Double lon = param.getLon();
|
|
|
+ if (lat != null && lon != null) {
|
|
|
+ // 处理半径, radius:半径
|
|
|
+ Double radius = param.getRadius();
|
|
|
+ if (radius != null) {
|
|
|
+ data = calculate(param, data);
|
|
|
+ } else {
|
|
|
+ // 没有半径,算最近的距离, 返回值只有一条数据
|
|
|
+ data = calculateMin(param, data);
|
|
|
+ }
|
|
|
+ log.info("lat、lon-输出数量:{}", data.size());
|
|
|
+
|
|
|
+ if (data.size() == 0) {
|
|
|
+ log.warn("查询结果没有符合条件的数据");
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理lon_min、lon_max, lat_min、lat_max
|
|
|
+ Double latMax = param.getLat_max();
|
|
|
+ Double latMin = param.getLat_min();
|
|
|
+ Double lonMax = param.getLon_max();
|
|
|
+ Double lonMin = param.getLon_min();
|
|
|
+ if (latMax != null && latMin != null && lonMax != null && lonMin != null) {
|
|
|
+ data = data.stream().filter(jsonData ->
|
|
|
+ jsonData.getLocation()[0] >= lonMin && jsonData.getLocation()[0] <= lonMax
|
|
|
+ && jsonData.getLocation()[1] >= latMin && jsonData.getLocation()[1] <= latMax).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (data.size() == 0) {
|
|
|
+ log.warn("查询结果没有符合条件的数据");
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对应db 根据那个字段排序
|
|
|
+ String sortOrder = param.getSort_order();
|
|
|
+ sortOrder = sortOrder==null ? null :sortOrder.toLowerCase();
|
|
|
+ // 升序还是降序
|
|
|
+ String sortBy = param.getSort_by();
|
|
|
+ sortBy = sortBy==null ? null :sortBy.toLowerCase();
|
|
|
+
|
|
|
+
|
|
|
+ // 处理排序reversed()降序, 默认是升序, 对
|
|
|
+ if ("desc".equals(sortBy) && "importance".equals(sortOrder)) {
|
|
|
+ data = data.stream().sorted(Comparator.comparing(PoiHotDto::getImportance).reversed()).collect(Collectors.toList());
|
|
|
+ } else if ("asc".equals(sortBy) && "importance".equals(sortOrder)){
|
|
|
+ data = data.stream().sorted(Comparator.comparing(PoiHotDto::getImportance)).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (data.size() == 0) {
|
|
|
+ log.warn("查询结果没有符合条件的数据");
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+
|
|
|
if (isLogin()) {
|
|
|
return Result.success(data);
|
|
|
}
|
|
@@ -220,6 +320,109 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
|
|
|
}
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * 计算最小距离
|
|
|
+ * @param queryJsonData
|
|
|
+ * @return 获取最小值对象
|
|
|
+ */
|
|
|
+ private List<PoiHotDto> calculateMin(PoiQueryDto queryJsonData, List<PoiHotDto> jsonDataList) {
|
|
|
+ log.info("run calculeMin");
|
|
|
+ List<PoiHotDto> newJsonData = new ArrayList<>();
|
|
|
+
|
|
|
+ // 计算距离后的结果集
|
|
|
+ HashMap<Double, PoiHotDto> calResultMap = new HashMap<>();
|
|
|
+
|
|
|
+ Double[] coordinates1 = new Double[3];
|
|
|
+ coordinates1[0] = queryJsonData.getLon();
|
|
|
+ coordinates1[1] = queryJsonData.getLat();
|
|
|
+
|
|
|
+// Double z = queryJsonData.getZ();
|
|
|
+// z = z == null ? 0 : z;
|
|
|
+// coordinates1[2] = z;
|
|
|
+
|
|
|
+ int i = 1;
|
|
|
+ Double min = null;
|
|
|
+ for (PoiHotDto jsonData : jsonDataList) {
|
|
|
+
|
|
|
+
|
|
|
+ Double[] coordinates2 = new Double[3];
|
|
|
+ coordinates2[0] = jsonData.getLocation()[0];
|
|
|
+ coordinates2[1] = jsonData.getLocation()[1];
|
|
|
+ coordinates2[2] = jsonData.getLocation()[2];
|
|
|
+
|
|
|
+ Double distance = DistanceUtil.distance(coordinates1, coordinates2, "miles");
|
|
|
+// log.info("计算出的距离:{}", distance);
|
|
|
+ // 默认取第一值
|
|
|
+ if (i==1) {
|
|
|
+ min = distance;
|
|
|
+ calResultMap.put(min, jsonData);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (distance < min) {
|
|
|
+ min = distance;
|
|
|
+ calResultMap.put(min, jsonData);
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("循环次数:{}, 最小值:{}", i, min);
|
|
|
+ // 获取最小值
|
|
|
+ PoiHotDto minJson = calResultMap.get(min);
|
|
|
+ newJsonData.add(minJson);
|
|
|
+ return newJsonData;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<PoiHotDto> calculate(PoiQueryDto queryJsonData, List<PoiHotDto> jsonDataList) {
|
|
|
+
|
|
|
+ Double[] coordinates1 = new Double[3];
|
|
|
+ coordinates1[0] = queryJsonData.getLon();
|
|
|
+ coordinates1[1] = queryJsonData.getLat();
|
|
|
+
|
|
|
+// Double z = queryJsonData.getZ();
|
|
|
+// z = z == null ? 0 : z;
|
|
|
+// coordinates1[2] = z;
|
|
|
+
|
|
|
+ // 计算距离后的结果集
|
|
|
+ Map<Double, PoiHotDto> calResultMap = new HashMap<>();
|
|
|
+ for (PoiHotDto jsonData : jsonDataList) {
|
|
|
+
|
|
|
+
|
|
|
+ Double[] coordinates2 = new Double[3];
|
|
|
+ coordinates2[0] = jsonData.getLocation()[0];
|
|
|
+ coordinates2[1] = jsonData.getLocation()[1];
|
|
|
+ coordinates2[2] = jsonData.getLocation()[2];
|
|
|
+ //计算两点的距离
|
|
|
+ double distance = (double) DistanceUtil.distance(coordinates1, coordinates2, "miles");
|
|
|
+ log.info("计算出的距离:{}", distance);
|
|
|
+
|
|
|
+ if (queryJsonData.getRadius() > distance) {
|
|
|
+ // 缓存对象
|
|
|
+ calResultMap.put(distance, jsonData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从小到大排序, 冒泡排序
|
|
|
+ List<Double> list = new ArrayList<>();
|
|
|
+ calResultMap.forEach((k,v) -> {
|
|
|
+ list.add(k);
|
|
|
+ });
|
|
|
+ log.info("排序前: {}", list);
|
|
|
+ // 升序排列
|
|
|
+ List<Double> collect = list.stream().sorted().collect(Collectors.toList());
|
|
|
+ log.info("排序后: {}", collect);
|
|
|
+
|
|
|
+
|
|
|
+ // 通过key获取对象
|
|
|
+ List<PoiHotDto> result = new ArrayList<>();
|
|
|
+ collect.forEach(p -> {
|
|
|
+ result.add(calResultMap.get(p));
|
|
|
+ });
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
private PoiEntity findById(String sceneCode){
|
|
|
Optional<PoiEntity> optional = entityMapper.findById(sceneCode);
|