|
@@ -0,0 +1,440 @@
|
|
|
+package com.fdkankan.indoor.core.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.fdkankan.indoor.base.util.ConvertUtils;
|
|
|
+import com.fdkankan.indoor.base.util.GisUtils;
|
|
|
+import com.fdkankan.indoor.base.util.JsonUtil;
|
|
|
+import com.fdkankan.indoor.base.util.Result;
|
|
|
+import com.fdkankan.indoor.core.dto.SiteModelSearchDto;
|
|
|
+import com.fdkankan.indoor.core.entity.siteModel.Polygon;
|
|
|
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel;
|
|
|
+import com.fdkankan.indoor.core.entity.siteModel.SiteModel2;
|
|
|
+import com.fdkankan.indoor.core.service.SiteModel2Service;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
+import org.springframework.data.mongodb.core.query.Query;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.awt.geom.Point2D;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author Admin
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@AllArgsConstructor
|
|
|
+public class SiteModel2ServiceImpl implements SiteModel2Service {
|
|
|
+
|
|
|
+ private final MongoTemplate mongoTemplate;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SiteModel within(Double[] location, String type) {
|
|
|
+ List<SiteModel> models = new ArrayList<>();
|
|
|
+
|
|
|
+ SiteModel siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
|
|
|
+
|
|
|
+ models.add(copyModelNotContainChildren(siteModel));
|
|
|
+ if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
|
|
|
+ organizeModels(siteModel, models);
|
|
|
+ }
|
|
|
+ models = models.stream().filter(mod -> filterModels(mod, location, type)).collect(Collectors.toList());
|
|
|
+
|
|
|
+ Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
|
|
|
+ log.info("pointParam: {}", pointParam);
|
|
|
+ SiteModel siteModel1 = models.stream().filter(sm -> getSm(sm, pointParam)).findAny()
|
|
|
+ .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
|
|
|
+ return siteModel1;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SiteModel withinType(String code, Double[] location, String type) {
|
|
|
+ log.info("code: {}", code);
|
|
|
+ log.info("location: {}", location);
|
|
|
+ log.info("code: {}", type);
|
|
|
+
|
|
|
+ // 总对象
|
|
|
+ List<SiteModel> models = new ArrayList<>();
|
|
|
+ SiteModel siteModel = null;
|
|
|
+ if ("test1".equals(code)) {
|
|
|
+ siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model");
|
|
|
+ } else {
|
|
|
+ siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model_2");
|
|
|
+ }
|
|
|
+
|
|
|
+ // copy实体对象
|
|
|
+ SiteModel newSiteModel = copyModelNotContainChildren(siteModel);
|
|
|
+ // 做为父节点的低一条
|
|
|
+ models.add(newSiteModel);
|
|
|
+ if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
|
|
|
+ organizeModels2(siteModel, models);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 按type封装成对象数组
|
|
|
+ List<SiteModel> resultList = new ArrayList<>();
|
|
|
+ SiteModel result = null;
|
|
|
+
|
|
|
+ Point2D.Double pointParam = new Point2D.Double(location[0], location[1]);
|
|
|
+ log.info("pointParam: {}", pointParam);
|
|
|
+ if ("BUILDING".equals(type)) {
|
|
|
+ resultList = models.stream().filter(data -> "BUILDING".equals(data.getType())).collect(Collectors.toList());
|
|
|
+ result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
|
|
|
+ .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
|
|
|
+ } else if ("FLOOR".equals(type)) {
|
|
|
+ resultList = models.stream().filter(data -> "FLOOR".equals(data.getType())).collect(Collectors.toList());
|
|
|
+ log.info("resultList.size: {}", resultList.size());
|
|
|
+
|
|
|
+ result = resultList.stream().filter(sm -> getSmByFloor(sm, pointParam)).findAny().orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
|
|
|
+ } else if ("ROOM".equals(type)) {
|
|
|
+ resultList = models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
|
|
|
+ result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
|
|
|
+ .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
|
|
|
+ // type为空,返回全部数据
|
|
|
+ } else {
|
|
|
+ resultList = models.stream().filter(data -> "ROOM".equals(data.getType())).collect(Collectors.toList());
|
|
|
+ result = resultList.stream().filter(sm -> getSm(sm, pointParam)).findAny()
|
|
|
+ .orElseThrow(() -> new RuntimeException("没有找到符合多边形的点"));
|
|
|
+
|
|
|
+ List<SiteModel> roomChildren = new ArrayList<>();
|
|
|
+ roomChildren.add(result);
|
|
|
+ siteModel.setChildren(roomChildren);
|
|
|
+ result = siteModel;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("result: {}", result);
|
|
|
+
|
|
|
+ return result;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SiteModel findById(Long id, String code) {
|
|
|
+ SiteModel siteModel= null;
|
|
|
+ if ("test1".equals(code)) {
|
|
|
+ siteModel = mongoTemplate.findById(id, SiteModel.class);
|
|
|
+ } else {
|
|
|
+ SiteModel2 siteMode2 = mongoTemplate.findById(id, SiteModel2.class);
|
|
|
+ siteModel = new SiteModel();
|
|
|
+ BeanUtils.copyProperties(siteMode2, siteModel);
|
|
|
+ }
|
|
|
+ return siteModel;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result getData(JSONObject param, String code) {
|
|
|
+ String type = param.getString("type");
|
|
|
+ if (!"BUILDING".equals(type)) {
|
|
|
+ throw new RuntimeException("非BUILDING类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ SiteModel siteModel= null;
|
|
|
+ if ("test1".equals(code)) {
|
|
|
+ siteModel = mongoTemplate.findOne(new Query(), SiteModel.class);
|
|
|
+ } else {
|
|
|
+ SiteModel2 siteMode2 = mongoTemplate.findOne(new Query(), SiteModel2.class);
|
|
|
+ siteModel = new SiteModel();
|
|
|
+ BeanUtils.copyProperties(siteMode2, siteModel);
|
|
|
+ }
|
|
|
+ if (siteModel != null) {
|
|
|
+ siteModel.setChildren(new ArrayList<>());
|
|
|
+ return Result.success(siteModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result search(String sceneCode, SiteModelSearchDto searchDto) {
|
|
|
+ SiteModel siteModel = getSceneCode(sceneCode);
|
|
|
+ List<SiteModel> loopModel = getLoopModel(siteModel);
|
|
|
+ String searchKey = searchDto.getQuery();
|
|
|
+ Integer size = searchDto.getSize();
|
|
|
+ size = size==null?10: size;
|
|
|
+ List<SiteModel> collect = loopModel.stream().filter(p -> getContent(p, searchKey)).limit(size).collect(Collectors.toList());
|
|
|
+ log.info("返回collect数量: {}", collect.size());
|
|
|
+
|
|
|
+ // 映射实体名称
|
|
|
+ List<Object> result = ormSiteModel(collect);
|
|
|
+
|
|
|
+ return Result.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result latest(String sceneCode, Double[] location, Double radius) {
|
|
|
+ SiteModel siteModel = getSceneCode(sceneCode);
|
|
|
+
|
|
|
+ // 递归为对象
|
|
|
+ List<SiteModel> loopModel = getLoopModel(siteModel);
|
|
|
+
|
|
|
+ // 获取点在多边形的集合
|
|
|
+ List<SiteModel> result = loopModel.stream().filter(p -> pointIsArea(location, p)).collect(Collectors.toList());
|
|
|
+
|
|
|
+ log.info("没有父级的数量:{}", result.size());
|
|
|
+ // 将父级有parenId的对象添加到result
|
|
|
+ addSiteMode(loopModel, result);
|
|
|
+ log.info("添加父级后的数量:{}", result.size());
|
|
|
+
|
|
|
+
|
|
|
+ return Result.success(loopModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将父节点添加到结果集
|
|
|
+ * @param loopModel
|
|
|
+ * @param result
|
|
|
+ */
|
|
|
+ private void addSiteMode(List<SiteModel> loopModel, List<SiteModel> result) {
|
|
|
+ Set<SiteModel> parentSiteModel = getParentSiteModel(loopModel, result);
|
|
|
+ for (SiteModel siteModel : parentSiteModel) {
|
|
|
+ result.add(siteModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取父节点
|
|
|
+ * @param loopModel
|
|
|
+ * @param result
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Set<SiteModel> getParentSiteModel(List<SiteModel> loopModel, List<SiteModel> result){
|
|
|
+ Set<SiteModel> parent = new HashSet<>();
|
|
|
+ for (SiteModel siteModel : loopModel) {
|
|
|
+ for (SiteModel model : result) {
|
|
|
+ if (model.getParentId() == siteModel.getId()) {
|
|
|
+ parent.add(siteModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return parent;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 输入点是否在多边形内
|
|
|
+ * @param point
|
|
|
+ * @param param
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean pointIsArea(Double[] point, SiteModel param){
|
|
|
+ // 获取多边行点
|
|
|
+ Polygon polygon = param.getPolygon();
|
|
|
+ if (polygon == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ List<List<List<Double>>> coordinates = polygon.getCoordinates();
|
|
|
+ if (CollectionUtils.isEmpty(coordinates)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ List<List<Double>> lists = coordinates.get(0);
|
|
|
+ if (CollectionUtils.isEmpty(lists)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ Point2D.Double pointDouble = new Point2D.Double();
|
|
|
+ pointDouble.setLocation(point[0], point[1]);
|
|
|
+
|
|
|
+
|
|
|
+ List<Point2D.Double> allPoints = lists.stream()
|
|
|
+ .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
|
|
|
+
|
|
|
+ Boolean inArea = GisUtils.rayCasting(allPoints, pointDouble);
|
|
|
+ log.info("是否在多边型内: {}", inArea);
|
|
|
+
|
|
|
+ return inArea;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 前端需要, 映射实体
|
|
|
+ private List<Object> ormSiteModel(List<SiteModel> collect){
|
|
|
+ List<Object> list = new ArrayList<>();
|
|
|
+ for (SiteModel siteModel : collect) {
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("id", siteModel.getId());
|
|
|
+ jsonObject.put("title", siteModel.getName());
|
|
|
+ jsonObject.put("matching_title", siteModel.getName());
|
|
|
+ jsonObject.put("matching_description", null);
|
|
|
+ list.add(jsonObject);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 模糊匹配
|
|
|
+ private Boolean getContent(SiteModel p, String searchKey){
|
|
|
+ String name = p.getName();
|
|
|
+ log.info("name: {}, 配备结果:{}", name, name.contains(searchKey));
|
|
|
+ return name.contains(searchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据场景码获取对象
|
|
|
+ * @param sceneCode
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private SiteModel getSceneCode(String sceneCode){
|
|
|
+ SiteModel siteModel;
|
|
|
+
|
|
|
+ if ("test1".equals(sceneCode)) {
|
|
|
+ siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model");
|
|
|
+ } else {
|
|
|
+ siteModel = mongoTemplate.findOne(new Query(), SiteModel.class, "site_model_2");
|
|
|
+ }
|
|
|
+ return siteModel;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private boolean filterModels(SiteModel mod, Double[] location, String type) {
|
|
|
+ if (!StringUtils.isEmpty(type)) {
|
|
|
+ if (mod.getPolygon() == null || !type.equals(mod.getPolygon().getType())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (location != null && location.length == 3) {
|
|
|
+ if (mod.getZ_max() == null || mod.getZ_min() == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (mod.getZ_max() >= location[2] && mod.getZ_min() <= location[2]) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 判断的坐标在那个空间位置
|
|
|
+ private boolean getSm(SiteModel model, Point2D.Double pointParam) {
|
|
|
+ if (CollectionUtils.isEmpty(model.getPolygon().getCoordinates())
|
|
|
+ || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0))
|
|
|
+ || CollectionUtils.isEmpty(model.getPolygon().getCoordinates().get(0).get(0))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
|
|
|
+ .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
|
|
|
+ if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * type=FLOOR 时,polygon=null
|
|
|
+ * @param model
|
|
|
+ * @param pointParam
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean getSmByFloor(SiteModel model, Point2D.Double pointParam) {
|
|
|
+ Polygon polygon = model.getPolygon();
|
|
|
+ if (polygon == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Point2D.Double> allPoints = model.getPolygon().getCoordinates().get(0).stream()
|
|
|
+ .map(points -> new Point2D.Double(points.get(0), points.get(1))).collect(Collectors.toList());
|
|
|
+ if (JsonUtil.IsPtInPoly(pointParam, allPoints)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 复制数据的作用?
|
|
|
+ private SiteModel copyModelNotContainChildren(SiteModel siteModel) {
|
|
|
+ SiteModel newSiteModel = new SiteModel();
|
|
|
+ BeanUtils.copyProperties(siteModel, newSiteModel);
|
|
|
+ newSiteModel.setChildren(null);
|
|
|
+ return newSiteModel;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 递归的作用是?
|
|
|
+ private void organizeModels(SiteModel siteModel, List<SiteModel> models) {
|
|
|
+ List<SiteModel> children = siteModel.getChildren();
|
|
|
+ children = ConvertUtils.convertList(children, SiteModel.class);
|
|
|
+// copyList(children)
|
|
|
+ log.info("children.size: {}", children.size());
|
|
|
+ for (SiteModel child : children) {
|
|
|
+ models.add(copyModelNotContainChildren(child));
|
|
|
+ if (!CollectionUtils.isEmpty(child.getChildren())) {
|
|
|
+ organizeModels(child, models);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("models.size: {}", models.size());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<SiteModel> copyList(List<SiteModel2> list){
|
|
|
+ List<SiteModel> objects = new ArrayList<>();
|
|
|
+ for (SiteModel2 data : list) {
|
|
|
+ SiteModel entity = new SiteModel();
|
|
|
+ BeanUtils.copyProperties(data, entity);
|
|
|
+ objects.add(entity);
|
|
|
+ }
|
|
|
+ return objects;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 2021-07-14
|
|
|
+ * 获取原来的对象test1 一共是17条
|
|
|
+ * @param siteModel
|
|
|
+ * @param models 数量回保存到原来的数据
|
|
|
+ */
|
|
|
+ private void organizeModels2(SiteModel siteModel, List<SiteModel> models) {
|
|
|
+ for (SiteModel child : siteModel.getChildren()) {
|
|
|
+ models.add(copyModelNotContainChildren(child));
|
|
|
+ if (!CollectionUtils.isEmpty(child.getChildren())) {
|
|
|
+ organizeModels2(child, models);
|
|
|
+ }
|
|
|
+ }
|
|
|
+// log.info("models.size: {}", models.size());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void organizeModels3(SiteModel siteModel, List<SiteModel> models) {
|
|
|
+ for (SiteModel child : siteModel.getChildren()) {
|
|
|
+ Integer id = siteModel.getId();
|
|
|
+ child.setParentId(id);
|
|
|
+ models.add(copyModelNotContainChildren(child));
|
|
|
+ if (!CollectionUtils.isEmpty(child.getChildren())) {
|
|
|
+ organizeModels3(child, models);
|
|
|
+ }
|
|
|
+ }
|
|
|
+// log.info("models.size: {}", models.size());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 2021-07-16
|
|
|
+ * 递归出每一个对象
|
|
|
+ * @param siteModel
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<SiteModel> getLoopModel(SiteModel siteModel){
|
|
|
+ List<SiteModel> models = new ArrayList<>();
|
|
|
+ // copy实体对象
|
|
|
+ SiteModel newSiteModel = copyModelNotContainChildren(siteModel);
|
|
|
+ // 做为父节点的低一条
|
|
|
+ models.add(newSiteModel);
|
|
|
+ if (!CollectionUtils.isEmpty(siteModel.getChildren())) {
|
|
|
+// organizeModels2(siteModel, models);
|
|
|
+ organizeModels3(siteModel, models);
|
|
|
+ }
|
|
|
+ log.info("models.size: {}", models.size());
|
|
|
+ return models;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|