Browse Source

fix bug:调整关系计算的逻辑

lijie 3 years ago
parent
commit
378c63f936
18 changed files with 451 additions and 46 deletions
  1. 3 1
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/basic/constant/CalRuleTypeEnum.java
  2. 152 22
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/basic/utils/GeoToolsUtil.java
  3. 14 0
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/dao/RelationDefineMapper.java
  4. 11 0
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/service/IRelationDefineService.java
  5. 13 0
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/service/impl/RelationDefineServiceImpl.java
  6. 26 0
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/dao/ObjectDigitalMapper.java
  7. 2 1
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/domain/SpaceCalDTO.java
  8. 29 11
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/CoordinateCalculateServiceImpl.java
  9. 154 0
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/EqToSpCalculateServiceImpl.java
  10. 3 2
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/ShThroughShRelCalculateServiceImpl.java
  11. 3 2
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/SpaceConnectionRelCalculateServiceImpl.java
  12. 1 1
      dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/impl/RelationCalServiceImpl.java
  13. 1 1
      dmp-business/dmp-rwd/src/main/resources/db/init/data.sql
  14. 31 0
      dmp-business/dmp-rwd/src/main/resources/mapper/ObjectDigitalMapper.xml
  15. 2 2
      dmp-business/dmp-rwd/src/main/resources/mapper/ObjectRelationMapper.xml
  16. 2 1
      dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/define/entity/RelationDefine.java
  17. 2 1
      dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/digital/entity/ObjectDigital.java
  18. 2 1
      dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/digital/entity/ObjectRelation.java

+ 3 - 1
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/basic/constant/CalRuleTypeEnum.java

@@ -26,7 +26,9 @@ public enum CalRuleTypeEnum {
     /** 计算规则种类,5-根据下级空间是否连通计算关系 */
     SH_THROUGH_SH("5","shThroughShRelCalculateServiceImpl"),
     /** 计算规则种类,6-根据门,窗,虚拟墙,元空间是否连通计算关系 */
-    SPACE_CONNECTION("6","spaceConnectionRelCalculateServiceImpl");
+    SPACE_CONNECTION("6","spaceConnectionRelCalculateServiceImpl"),
+    /** 计算规则种类,7-设备与空间关系计算 */
+    EQ_TO_SP("7","eqToSpCalculateServiceImpl");
 
     CalRuleTypeEnum(String index, String beanName) {
         this.index = index;

+ 152 - 22
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/basic/utils/GeoToolsUtil.java

@@ -1,7 +1,10 @@
 package com.persagy.dmp.rwd.basic.utils;
 
 import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.extern.slf4j.Slf4j;
 import org.geotools.geometry.jts.JTSFactoryFinder;
 import org.locationtech.jts.geom.*;
 
@@ -17,6 +20,7 @@ import java.util.List;
  * @Date 2021/9/3 20:31
  * @Version V1.0
  **/
+@Slf4j
 public class GeoToolsUtil {
     /**
      * 创建点
@@ -42,12 +46,12 @@ public class GeoToolsUtil {
      * 创建面
      * @param outLines
      */
-    private static Polygon createPolygon(List<LinkedHashMap<String,Object>> outLines){
+    private static Polygon createPolygon(ArrayNode outLines){
         GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
         List<Coordinate> objects = new ArrayList<>();
-        for (LinkedHashMap<String,Object> outLine : outLines) {
-            double x = Double.parseDouble(outLine.getOrDefault("X",0.0D).toString());
-            double y = Double.parseDouble(outLine.getOrDefault("Y",0.0D).toString());
+        for (JsonNode outLine : outLines) {
+            double x = outLine.has("X")?Double.parseDouble(outLine.get("X").asText()):0.0D;
+            double y = outLine.has("Y")?Double.parseDouble(outLine.get("Y").asText()):0.0D;
             double z = 0L;
             Coordinate coordinate = new Coordinate(x, y, z);
             objects.add(coordinate);
@@ -55,9 +59,7 @@ public class GeoToolsUtil {
         //注意数据的闭合
         Coordinate[] coordinates = objects.toArray(new Coordinate[0]);
         LinearRing ring = geometryFactory.createLinearRing(coordinates);
-        Polygon polygon = geometryFactory.createPolygon(ring, null);
-
-        return polygon;
+        return geometryFactory.createPolygon(ring, null);
    }
 
     /**
@@ -67,38 +69,166 @@ public class GeoToolsUtil {
      * @param outLines 轮廓线
      * @return
      */
-   public static Boolean isPointInPoly(ObjectNode pointLocal, List<LinkedHashMap<String,Object>> outLines) {
+   public static Boolean isPointInPoly(ObjectNode pointLocal, ArrayNode outLines) {
        if (null==pointLocal || CollUtil.isEmpty(outLines)){
            return false;
        }
        //创建点
        Point point = createPoint(pointLocal);
-       //创建面
-       Polygon polygon = createPolygon(outLines);
+       if (!outLines.get(0).isArray()){
+           return isPointInPoly(point,outLines);
+       }
+       for (JsonNode outLine : outLines) {
+           if (outLine.isArray() && outLine.get(0).isArray()){
+               ArrayNode subOutlines = (ArrayNode)outLine;
+               for (JsonNode subOutLine : subOutlines) {
+                   //创建面
+                   if (isPointInPoly(point,(ArrayNode) subOutLine)){
+                       return true;
+                   }
+               }
+               continue;
+           }
+           //创建面
+           if (isPointInPoly(point,(ArrayNode)outLine)){
+               return true;
+           }
+       }
        //判断点面包含关系
-       return polygon.contains(point);
+       return false;
    }
     /**
      * 点面包含关系判断
      * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param point 坐标点
+     * @param outLines 轮廓线
+     * @return
+     */
+    public static Boolean isPointInPoly(Point point, ArrayNode outLines) {
+        if (null==point || CollUtil.isEmpty(outLines)){
+            return false;
+        }
+        //创建面
+        try {
+            Polygon polygon = createPolygon(outLines);
+            // 判断点面包含关系
+            return polygon.contains(point);
+        }catch (IllegalArgumentException argumentE){
+            try {
+                // 将第一个加入最后一个结点尝试一下
+                outLines.add(outLines.get(0));
+                Polygon polygon = createPolygon(outLines);
+                // 判断点面包含关系
+                return polygon.contains(point);
+            }catch (Exception ignored){}
+        } catch (Exception e){
+            log.warn("解析失败"+outLines.toString(),e);
+        }
+        return false;
+    }
+    /**
+     * 面面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
      * @param fromOutLines: 轮廓坐标
      * @param toOutLines: 轮廓坐标
      * @return
      */
-   public static Boolean isPolyInPoly(List<LinkedHashMap<String,Object>> fromOutLines,
-                                       List<LinkedHashMap<String,Object>> toOutLines) {
+   public static Boolean isPolyInPoly(ArrayNode fromOutLines, ArrayNode toOutLines) {
        if (CollUtil.isEmpty(fromOutLines) || CollUtil.isEmpty(toOutLines)){
            return false;
        }
-       //创建点
-       Polygon fromPolygon = createPolygon(fromOutLines);
-       //创建面
-       Polygon toPolygon = createPolygon(toOutLines);
-       //判断面-面包含关系
-       return fromPolygon.contains(toPolygon)
-               || fromPolygon.equalsTopo(toPolygon)
-               || fromPolygon.overlaps(toPolygon)
-               || toPolygon.contains(fromPolygon);
+       if (!fromOutLines.get(0).isArray()){
+           return isPolyInPolyInternal(fromOutLines,toOutLines);
+       }
+       for (JsonNode outLine : fromOutLines) {
+           if (outLine.isArray() && outLine.get(0).isArray()){
+               ArrayNode subOutlines = (ArrayNode)outLine;
+               for (JsonNode subOutLine : subOutlines) {
+                   //创建面
+                   if (isPolyInPolyInternal((ArrayNode) subOutLine,toOutLines)){
+                       return true;
+                   }
+               }
+               continue;
+           }
+           //创建面
+           if (isPolyInPolyInternal((ArrayNode)outLine,toOutLines)){
+               return true;
+           }
+       }
+       return false;
    }
+    /***
+     * Description: 判断面与面是否有交集
+     * @param fromOutLines : 左边的轮廓坐标数组
+     * @param toOutLines : 右边的轮廓坐标数组
+     * @return : boolean
+     * @author : lijie
+     * @date :2021/11/24 16:22
+     * Update By lijie 2021/11/24 16:22
+     */
+    private static Boolean isPolyInPolyInternal(ArrayNode fromOutLines, ArrayNode toOutLines) {
+        for (JsonNode outLine : toOutLines) {
+            if (outLine.isArray() && outLine.get(0).isArray()){
+                ArrayNode subOutlines = (ArrayNode)outLine;
+                for (JsonNode subOutLine : subOutlines) {
+                    //创建面
+                    if (decidePolyInPoly(fromOutLines,(ArrayNode) subOutLine)){
+                        return true;
+                    }
+                }
+                continue;
+            }
+            //创建面
+            if (decidePolyInPoly(fromOutLines,(ArrayNode)outLine)){
+                return true;
+            }
+        }
+        //判断点面包含关系
+        return false;
+    }
+    /***
+     * Description: 判断面与面是否有交集
+     * @param fromOutLines : 左边的轮廓坐标数组
+     * @param toOutLines : 右边的轮廓坐标数组
+     * @return : boolean
+     * @author : lijie
+     * @date :2021/11/24 16:22
+     * Update By lijie 2021/11/24 16:22
+     */
+    private static boolean decidePolyInPoly(ArrayNode fromOutLines, ArrayNode toOutLines) {
+        //创建点
+        Polygon fromPolygon = null;
+        Polygon toPolygon = null;
+        try {
+            fromPolygon = createPolygon(fromOutLines);
+        }catch (IllegalArgumentException argumentE){
+            try {
+                // 将第一个加入最后一个结点尝试一下
+                fromOutLines.add(fromOutLines.get(0));
+                fromPolygon = createPolygon(fromOutLines);
+            }catch (Exception ignored){}
+        } catch (Exception e){
+            return false;
+        }
+        try {
+            toPolygon = createPolygon(toOutLines);
+        }catch (IllegalArgumentException argumentE){
+            try {
+                // 将第一个加入最后一个结点尝试一下
+                toOutLines.add(toOutLines.get(0));
+                toPolygon = createPolygon(toOutLines);
+            }catch (Exception ignored){}
+        } catch (Exception e){
+            return false;
+        }
+        if (null==fromPolygon || null==toPolygon){
+            return false;
+        }
+        return fromPolygon.contains(toPolygon)
+                || fromPolygon.equalsTopo(toPolygon)
+                || fromPolygon.overlaps(toPolygon)
+                || toPolygon.contains(fromPolygon);
+    }
 
 }

+ 14 - 0
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/dao/RelationDefineMapper.java

@@ -1,7 +1,12 @@
 package com.persagy.dmp.rwd.define.dao;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.persagy.dmp.define.entity.RelationDefine;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 关系定义 DAO
@@ -9,4 +14,13 @@ import com.persagy.dmp.define.entity.RelationDefine;
  * @date 2021-06-25
  */
 public interface RelationDefineMapper extends BaseMapper<RelationDefine> {
+    /***
+     * Description: 根据条件查询数据
+     * @param queryWrapper : 查询条件
+     * @return : java.util.List<com.persagy.dmp.define.entity.RelationDefine>
+     * @author : lijie
+     * @date :2021/11/23 17:24
+     * Update By lijie 2021/11/23 17:24
+     */
+    List<RelationDefine> queryListByCondition(@Param("ew") LambdaQueryWrapper<RelationDefine> queryWrapper);
 }

+ 11 - 0
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/service/IRelationDefineService.java

@@ -1,6 +1,8 @@
 package com.persagy.dmp.rwd.define.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.persagy.dmp.define.entity.DigitalEquipClassRel;
@@ -69,4 +71,13 @@ public interface IRelationDefineService extends IService<RelationDefine> {
      * Update By lijie 2021/9/14 21:21
      */
     Map<String, RelationDefine> queryRelMapByCodes(Set<String> graphCodes, Set<String> relCodes);
+    /***
+     * Description: 根据条件查询数据
+     * @param queryWrapper : 查询条件
+     * @return : java.util.List<com.persagy.dmp.define.entity.RelationDefine>
+     * @author : lijie
+     * @date :2021/11/23 17:24
+     * Update By lijie 2021/11/23 17:24
+     */
+    List<RelationDefine> queryListByCondition(LambdaQueryWrapper<RelationDefine> queryWrapper);
 }

+ 13 - 0
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/define/service/impl/RelationDefineServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.persagy.dmp.common.constant.ValidEnum;
@@ -91,4 +92,16 @@ public class RelationDefineServiceImpl  extends ServiceImpl<RelationDefineMapper
         return relationDefines.stream().collect(Collectors.toMap(relationDefine -> relationDefine.getGraphCode()
                 + StrUtil.UNDERLINE+relationDefine.getCode(),relationDefine -> relationDefine,(k1,k2)->k1));
     }
+    /***
+     * Description: 根据条件查询数据
+     * @param queryWrapper : 查询条件
+     * @return : java.util.List<com.persagy.dmp.define.entity.RelationDefine>
+     * @author : lijie
+     * @date :2021/11/23 17:24
+     * Update By lijie 2021/11/23 17:24
+     */
+    @Override
+    public List<RelationDefine> queryListByCondition(LambdaQueryWrapper<RelationDefine> queryWrapper) {
+        return this.queryByCondition(queryWrapper);
+    }
 }

+ 26 - 0
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/dao/ObjectDigitalMapper.java

@@ -182,4 +182,30 @@ public interface ObjectDigitalMapper extends BaseMapper<ObjectDigital> {
      * @return
      */
     List<String> queryObjectClassCode(@Param("param") RequestData requestData);
+    /***
+     * Description: 根据项目id和楼层id查询设备的bimLocation
+     * @param groupCode : 集团编码
+     * @param projectId : 项目id
+     * @param floorId : 楼层id
+     * @return : java.util.List<com.persagy.dmp.digital.entity.ObjectDigital>
+     * @author : lijie
+     * @date :2021/11/24 10:15
+     * Update By lijie 2021/11/24 10:15
+     */
+    List<ObjectDigital> queryEquipBimLocationsByProjectIdAndFloorId(@Param("groupCode") String groupCode,
+                                                                    @Param("projectId") String projectId,
+                                                                    @Param("floorId") String floorId);
+    /***
+     * Description: 根据项目id和楼层id查询空间的outLines
+     * @param groupCode : 集团编码
+     * @param projectId : 项目id
+     * @param floorId : 楼层id
+     * @return : java.util.List<com.persagy.dmp.digital.entity.ObjectDigital>
+     * @author : lijie
+     * @date :2021/11/24 10:15
+     * Update By lijie 2021/11/24 10:15
+     */
+    List<ObjectDigital> querySpacesByProjectIdAndFloorId(@Param("groupCode") String groupCode,
+                                                         @Param("projectId") String projectId,
+                                                         @Param("floorId") String floorId);
 }

+ 2 - 1
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/domain/SpaceCalDTO.java

@@ -1,5 +1,6 @@
 package com.persagy.dmp.rwd.digital.domain;
 
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import lombok.Data;
 
@@ -23,7 +24,7 @@ public class SpaceCalDTO {
     /** 对象的bim点坐标 */
     private ObjectNode bimLocation;
     /** 对象的outline平面坐标 */
-    private List<LinkedHashMap<String,Object>> outLines;
+    private ArrayNode outLines;
     /** 对象id */
     private String id;
     /** 模型文件id */

+ 29 - 11
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/CoordinateCalculateServiceImpl.java

@@ -15,6 +15,7 @@ import com.persagy.dmp.define.entity.RelationDefine;
 import com.persagy.dmp.digital.entity.ObjectDigital;
 import com.persagy.dmp.digital.entity.ObjectRelation;
 import com.persagy.dmp.rwd.basic.constant.BusinessErrorRwdCode;
+import com.persagy.dmp.rwd.basic.constant.DigitalObjectType;
 import com.persagy.dmp.rwd.basic.utils.DigitalCommonUtils;
 import com.persagy.dmp.rwd.basic.utils.GeoToolsUtil;
 import com.persagy.dmp.rwd.digital.dao.ObjectDigitalMapper;
@@ -28,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /***
  * Description: 根据坐标计算关系的策略类
@@ -149,7 +151,12 @@ public class CoordinateCalculateServiceImpl implements CalculateService {
                 objectRelation.setRelCode(calculatingDTO.getRelCode());
                 objectRelation.setObjFrom(fromObjectDigital.getId());
                 objectRelation.setObjTo(toObjectDigital.getId());
-                objectRelation.setRelValue(calculatingDTO.getRelValue());
+                if (DigitalObjectType.SPACE.getIndex().equals(fromObjectDigital.getObjType())){
+                    objectRelation.setRelValue(fromObjectDigital.getClassCode());
+                }
+                if (DigitalObjectType.SPACE.getIndex().equals(toObjectDigital.getObjType())){
+                    objectRelation.setRelValue(toObjectDigital.getClassCode());
+                }
                 objectRelation.setCreateApp(calculatingDTO.getAppId());
                 objectRelation.setUpdateApp(calculatingDTO.getAppId());
                 objectRelation.setCreator(calculatingDTO.getAccountId());
@@ -162,7 +169,11 @@ public class CoordinateCalculateServiceImpl implements CalculateService {
             return;
         }
         // 删除关系
-        deleteRelDataByCondition(calculatingDTO,fromIds,toIds);
+        deleteRelDataByCondition(calculatingDTO,fromIds,toIds,
+                resultList.stream().map(ObjectRelation::getObjFrom).collect(Collectors.toSet()),
+                resultList.stream().map(ObjectRelation::getObjTo).collect(Collectors.toSet()),
+                resultList.stream().filter(objectRelation -> StrUtil.isNotBlank(objectRelation.getRelValue()))
+                        .map(ObjectRelation::getRelValue).collect(Collectors.toSet()));
         // 新增关系
         objectRelationService.saveBatch(resultList);
     }
@@ -176,14 +187,24 @@ public class CoordinateCalculateServiceImpl implements CalculateService {
      * @date :2021/9/11 16:13
      * Update By lijie 2021/9/11 16:13
      */
-    private void deleteRelDataByCondition(CalculatingDTO calculatingDTO, Set<String> fromIds, Set<String> toIds) {
-        fromIds.addAll(toIds);
-        QueryWrapper<ObjectRelation> queryWrapper = ObjectDigitalCriteriaHelper.createCommonQueryWrapper(fromIds,calculatingDTO);
+    private void deleteRelDataByCondition(CalculatingDTO calculatingDTO, Set<String> fromIds,
+                                          Set<String> toIds,Set<String> relFromIds,Set<String> relToIds,
+                                          Set<String> relValues) {
+        QueryWrapper<ObjectRelation> queryWrapper = ObjectDigitalCriteriaHelper.createCommonQueryWrapper(CollUtil.newHashSet(),calculatingDTO);
         queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.GRAPH_CODE_HUM),calculatingDTO.getGraphCode());
         queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.REL_CODE_HUM),calculatingDTO.getRelCode());
-        if (StrUtil.isNotBlank(calculatingDTO.getRelValue())){
-            queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.REL_VALUE_HUM),calculatingDTO.getRelValue());
+        if (CollUtil.isNotEmpty(relValues)){
+            queryWrapper.in(StrUtil.toUnderlineCase(ObjectRelation.REL_VALUE_HUM),relValues);
         }
+        queryWrapper.and(CollUtil.isNotEmpty(fromIds)
+                || CollUtil.isNotEmpty(toIds)
+                || CollUtil.isNotEmpty(relFromIds)
+                || CollUtil.isNotEmpty(relToIds),wrapper->{
+            wrapper.or(CollUtil.isNotEmpty(fromIds),subWapper->subWapper.in(ObjectRelation.PROP_ID,fromIds));
+            wrapper.or(CollUtil.isNotEmpty(toIds),subWapper->subWapper.in(ObjectRelation.PROP_ID,toIds));
+            wrapper.or(CollUtil.isNotEmpty(relFromIds),subWapper->subWapper.in(ObjectRelation.OBJ_FROM,relFromIds));
+            wrapper.or(CollUtil.isNotEmpty(relToIds),subWapper->subWapper.in(ObjectRelation.OBJ_TO,relToIds));
+        });
         objectRelationService.remove(queryWrapper);
     }
 
@@ -206,10 +227,7 @@ public class CoordinateCalculateServiceImpl implements CalculateService {
         queryWrapper.select(ObjectDigital.PROP_ID,
                 StrUtil.toUnderlineCase(CommonConstant.QUERY_GROUPCODE),
                 StrUtil.toUnderlineCase(CommonConstant.QUERY_PROJECTID),
-                StrUtil.format("JSON_UNQUOTE(JSON_EXTRACT(JSON_UNQUOTE(JSON_EXTRACT(infos,'$.{}'))," +
-                        "IF(JSON_DEPTH(JSON_UNQUOTE(JSON_EXTRACT(infos,'$.{}')))=3,'$[*]'," +
-                        "IF(JSON_DEPTH(JSON_UNQUOTE(JSON_EXTRACT(infos,'$.{}')))=4,'$[0][*]','$[0][0][*]')))) AS outLines",
-                        toInfoCode,toInfoCode,toInfoCode),
+                StrUtil.format("JSON_UNQUOTE(JSON_EXTRACT(infos,'$.{}')) AS outLines", toInfoCode),
                 ObjectDigital.CLASS_CODE,ObjectDigital.OBJ_TYPE);
         return objectDigitalMapper.queryToData(toIds,objType,toInfoCode,calculatingDTO);
     }

+ 154 - 0
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/EqToSpCalculateServiceImpl.java

@@ -0,0 +1,154 @@
+package com.persagy.dmp.rwd.digital.service.calstrategy;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.dmp.basic.dto.CoordinateCalInfo;
+import com.persagy.dmp.basic.dto.RelationCalRuleDTO;
+import com.persagy.dmp.common.constant.CommonConstant;
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.dmp.define.entity.RelationDefine;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.dmp.rwd.basic.constant.BusinessErrorRwdCode;
+import com.persagy.dmp.rwd.basic.constant.DigitalObjectType;
+import com.persagy.dmp.rwd.basic.utils.DigitalCommonUtils;
+import com.persagy.dmp.rwd.basic.utils.GeoToolsUtil;
+import com.persagy.dmp.rwd.digital.dao.ObjectDigitalMapper;
+import com.persagy.dmp.rwd.digital.domain.CalculatingDTO;
+import com.persagy.dmp.rwd.digital.service.CalculateService;
+import com.persagy.dmp.rwd.digital.service.IObjectDigitalService;
+import com.persagy.dmp.rwd.digital.service.IObjectRelationService;
+import com.persagy.dmp.rwd.digital.utils.ObjectDigitalCriteriaHelper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/***
+ * Description: 根据坐标计算关系的策略类
+ * @author : lijie
+ * @date :2021/9/8 17:02
+ * Update By lijie 2021/9/8 17:02
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class EqToSpCalculateServiceImpl implements CalculateService {
+
+    private final IObjectDigitalService objectDigitalService;
+    private final ObjectDigitalMapper objectDigitalMapper;
+    private final IObjectRelationService objectRelationService;
+
+    /***
+     * Description: 根据坐标计算关系
+     * @param calRule : 计算规则
+     * @param calculatingDTO : 参数
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/8 17:14
+     * Update By lijie 2021/9/8 17:14
+     */
+    @Override
+    public void calculateRelation(RelationCalRuleDTO calRule, CalculatingDTO calculatingDTO) {
+        // 1.先根据项目id查询项目下的所有项目
+        List<ObjectDigital> floors = queryFloorsByProjectId(calculatingDTO.getGroupCode(),calculatingDTO.getProjectId());
+        if (CollUtil.isEmpty(floors)){
+            return;
+        }
+        // 2.根据各个楼层分别进行关系计算
+        for (ObjectDigital floor : floors) {
+            // 2.1 根据项目id和楼层id查询设备列表
+            List<ObjectDigital> equipments = objectDigitalMapper
+                    .queryEquipBimLocationsByProjectIdAndFloorId(calculatingDTO.getGroupCode(),
+                            calculatingDTO.getProjectId(),floor.getId());
+            if (CollUtil.isEmpty(equipments)){
+                continue;
+            }
+            List<ObjectDigital> spaces =objectDigitalMapper.querySpacesByProjectIdAndFloorId(calculatingDTO.getGroupCode(),
+                    calculatingDTO.getProjectId(),floor.getId());
+            if (CollUtil.isEmpty(spaces)){
+                continue;
+            }
+            List<ObjectRelation> insertRels = new ArrayList<>();
+            for (ObjectDigital equipment : equipments) {
+                for (ObjectDigital space : spaces) {
+                    if (GeoToolsUtil.isPointInPoly(equipment.getBimLocation(),space.getOutLines())){
+                        ObjectRelation objectRelation = new ObjectRelation();
+                        objectRelation.setGroupCode(calculatingDTO.getGroupCode());
+                        objectRelation.setProjectId(calculatingDTO.getProjectId());
+                        objectRelation.setGraphId(DigitalCommonUtils.getDefaultGraphIdByGraphCode(calculatingDTO.getGraphCode()));
+                        objectRelation.setGraphCode(calculatingDTO.getGraphCode());
+                        objectRelation.setRelCode(calculatingDTO.getRelCode());
+                        objectRelation.setObjFrom(equipment.getId());
+                        objectRelation.setObjTo(space.getId());
+                        objectRelation.setRelValue(space.getClassCode());
+                        objectRelation.setCreateApp(calculatingDTO.getAppId());
+                        objectRelation.setUpdateApp(calculatingDTO.getAppId());
+                        objectRelation.setCreator(calculatingDTO.getAccountId());
+                        objectRelation.setModifier(calculatingDTO.getAccountId());
+                        objectRelation.setValid(1);
+                        insertRels.add(objectRelation);
+                    }
+                }
+            }
+            if (CollUtil.isNotEmpty(insertRels)){
+                deleteRelDataByCondition(calculatingDTO,insertRels.stream().map(ObjectRelation::getObjFrom).collect(Collectors.toSet()),
+                        insertRels.stream().map(ObjectRelation::getObjTo).collect(Collectors.toSet()));
+                objectRelationService.saveBatch(insertRels,insertRels.size());
+            }
+        }
+
+    }
+    /***
+     * Description: 根据集团编码和项目id查询项目下的楼层
+     * @param groupCode : 集团编码
+     * @param projectId : 项目id
+     * @return : java.util.List<com.persagy.dmp.digital.entity.ObjectDigital>
+     * @author : lijie
+     * @date :2021/11/24 10:06
+     * Update By lijie 2021/11/24 10:06
+     */
+    private List<ObjectDigital> queryFloorsByProjectId(String groupCode, String projectId) {
+        if (StrUtil.isBlank(projectId)){
+            return new ArrayList<>();
+        }
+        LambdaQueryWrapper<ObjectDigital> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ObjectDigital::getValid,Boolean.TRUE);
+        queryWrapper.eq(ObjectDigital::getGroupCode,groupCode);
+        queryWrapper.eq(ObjectDigital::getProjectId,projectId);
+        queryWrapper.eq(ObjectDigital::getObjType, DigitalObjectType.FLOOR.getIndex());
+        return objectDigitalService.list(queryWrapper);
+    }
+
+    /***
+     * Description: 根据请求参数和id集合删除关系
+     * @param calculatingDTO : 请求参数
+     * @param fromIds : 来源id集合
+     * @param toIds : 去向id集合
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/11 16:13
+     * Update By lijie 2021/9/11 16:13
+     */
+    private void deleteRelDataByCondition(CalculatingDTO calculatingDTO, Set<String> fromIds, Set<String> toIds) {
+        QueryWrapper<ObjectRelation> queryWrapper = ObjectDigitalCriteriaHelper
+                .createCommonQueryWrapper(CollUtil.newHashSet(),calculatingDTO);
+        queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.GRAPH_CODE_HUM),calculatingDTO.getGraphCode());
+        queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.REL_CODE_HUM),calculatingDTO.getRelCode());
+        if (StrUtil.isNotBlank(calculatingDTO.getRelValue())){
+            queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.REL_VALUE_HUM),calculatingDTO.getRelValue());
+        }
+        queryWrapper.and(CollUtil.isNotEmpty(fromIds) || CollUtil.isNotEmpty(toIds),wrapper->{
+            wrapper.or(CollUtil.isNotEmpty(fromIds),subWapper->subWapper.in(ObjectRelation.OBJ_FROM,fromIds));
+            wrapper.or(CollUtil.isNotEmpty(toIds),subWapper->subWapper.in(ObjectRelation.OBJ_TO,toIds));
+        });
+        objectRelationService.remove(queryWrapper);
+    }
+}

+ 3 - 2
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/ShThroughShRelCalculateServiceImpl.java

@@ -3,6 +3,7 @@ package com.persagy.dmp.rwd.digital.service.calstrategy;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.persagy.dmp.basic.dto.RelationCalRuleDTO;
 import com.persagy.dmp.digital.entity.ObjectDigital;
 import com.persagy.dmp.digital.entity.ObjectRelation;
@@ -54,7 +55,7 @@ public class ShThroughShRelCalculateServiceImpl implements CalculateService {
         }
         // 2.根据空间坐标计算有相交的竖井即存在连通关系
         // 2.1 获得{空间id:空间坐标}的映射
-        Map<String, List<LinkedHashMap<String, Object>>> spaceMap = objectRelations.stream()
+        Map<String, ArrayNode> spaceMap = objectRelations.stream()
                 .collect(Collectors.toMap(ObjectRelation::getObjTo, ObjectRelation::getOutLines, (k1, k2) -> k1));
         // 2.2 获得{竖井id:[空间id,空间id]}的映射
         Map<String, Set<String>> shaftSpaceIdMap = new HashMap<>();
@@ -117,7 +118,7 @@ public class ShThroughShRelCalculateServiceImpl implements CalculateService {
      * Update By lijie 2021/10/11 14:13
      */
     private Boolean isVerticallyOverlap(Set<String> spaceIds, Set<String> otherSpaceIds,
-                                        Map<String, List<LinkedHashMap<String, Object>>> spaceMap) {
+                                        Map<String, ArrayNode> spaceMap) {
         for (String spaceId : spaceIds) {
             for (String otherSpaceId : otherSpaceIds) {
                 if (GeoToolsUtil.isPolyInPoly(spaceMap.get(spaceId),spaceMap.get(otherSpaceId))){

+ 3 - 2
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/calstrategy/SpaceConnectionRelCalculateServiceImpl.java

@@ -7,6 +7,7 @@ import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.dmp.basic.dto.RelationCalRuleDTO;
 import com.persagy.dmp.basic.dto.SpaceConnectionCalDTO;
@@ -130,7 +131,7 @@ public class SpaceConnectionRelCalculateServiceImpl implements CalculateService
             List<SpaceCalDTO> subIspaces = ispaceMap.get(spaceCal.getFloorModelId());
             List<String> relIds = new ArrayList<>();
             for (SpaceCalDTO subIspace : subIspaces) {
-                List<LinkedHashMap<String, Object>> outLines = subIspace.getOutLines();
+                ArrayNode outLines = subIspace.getOutLines();
                 for (SpaceCalDTO space : spaces) {
                     if (GeoToolsUtil.isPolyInPoly(space.getOutLines(),outLines)){
                         relIds.add(space.getSpaceId());
@@ -226,7 +227,7 @@ public class SpaceConnectionRelCalculateServiceImpl implements CalculateService
                 List<String> relIds = new ArrayList<>();
                 // 2.1.3 通过门打开后的坐标点与空间关联性获得连通的空间数组
                 for (SpaceCalDTO space : spaces) {
-                    List<LinkedHashMap<String, Object>> outLines = space.getOutLines();
+                    ArrayNode outLines = space.getOutLines();
                     for (OpenPointDTO openPoint : openPoints) {
                         ObjectNode pointNode = objectMapper
                                 .createObjectNode()

+ 1 - 1
dmp-business/dmp-rwd/src/main/java/com/persagy/dmp/rwd/digital/service/impl/RelationCalServiceImpl.java

@@ -229,7 +229,7 @@ public class RelationCalServiceImpl implements RelationCalService {
         //queryWrapper.eq(RelationDefine::getGraphCode,requestData.getGraphCode());
         //queryWrapper.eq(RelationDefine::getCode,requestData.getRelCode());
         queryWrapper.eq(BaseEntity::getValid,true);
-        List<RelationDefine> relationDefines = relationDefineService.queryByCondition(queryWrapper);
+        List<RelationDefine> relationDefines = relationDefineService.queryListByCondition(queryWrapper);
         if (CollUtil.isEmpty(relationDefines)){
             throw new BusinessException(BusinessErrorRwdCode.A7309.getCode(),BusinessErrorRwdCode.A7309.getDesc());
         }

File diff suppressed because it is too large
+ 1 - 1
dmp-business/dmp-rwd/src/main/resources/db/init/data.sql


+ 31 - 0
dmp-business/dmp-rwd/src/main/resources/mapper/ObjectDigitalMapper.xml

@@ -712,6 +712,37 @@
             AND dto.obj_type = #{param.objType}
         </if>
     </select>
+    <select id="queryEquipBimLocationsByProjectIdAndFloorId" resultMap="BaseResultMap">
+        SELECT dto.id AS id,JSON_OBJECT('X',
+            JSON_EXTRACT(JSON_UNQUOTE(CONCAT('[',SUBSTRING(JSON_EXTRACT(infos, '$.bimLocation') FROM 2 FOR LENGTH(JSON_EXTRACT(infos, '$.bimLocation'))-2),']')),'$[0]'),
+            'Y',
+            JSON_EXTRACT(JSON_UNQUOTE(CONCAT('[',SUBSTRING(JSON_EXTRACT(infos, '$.bimLocation') FROM 2 FOR LENGTH(JSON_EXTRACT(infos, '$.bimLocation'))-2),']')),'$[1]'),
+            'Z',JSON_EXTRACT(JSON_UNQUOTE(CONCAT('[',SUBSTRING(JSON_EXTRACT(infos, '$.bimLocation') FROM 2 FOR LENGTH(JSON_EXTRACT(infos, '$.bimLocation'))-2),']')),'$[2]'))
+            AS bimLocation FROM dt_relation AS dtr
+            INNER JOIN dt_object AS dto ON (dto.id=dtr.obj_from)
+        WHERE dtr.graph_code='MechInArch'
+          AND dtr.rel_code='Eq2Fl'
+          AND dtr.group_code=#{groupCode}
+          AND dtr.project_id=#{projectId}
+          AND dtr.obj_to=#{floorId}
+          AND dtr.valid=TRUE
+          AND dto.valid=TRUE
+          AND JSON_UNQUOTE(JSON_EXTRACT(dto.infos, '$.bimLocation')) IS NOT NULL
+    </select>
+    <select id="querySpacesByProjectIdAndFloorId" resultMap="BaseResultMap">
+        SELECT dto.id AS id,
+               JSON_UNQUOTE(JSON_EXTRACT(infos,'$.outline' )) AS outLines,
+               dto.class_code AS class_code FROM dt_relation AS dtr
+        INNER JOIN dt_object AS dto ON (dto.id=dtr.obj_to)
+        WHERE dtr.graph_code='ArchSubset'
+          AND dtr.rel_code='Fl2Sp'
+          AND dtr.group_code=#{groupCode}
+          AND dtr.project_id=#{projectId}
+          AND dtr.obj_from=#{floorId}
+          AND dtr.valid=TRUE
+          AND dto.valid=TRUE
+          AND JSON_UNQUOTE(JSON_EXTRACT(dto.infos, '$.outline')) IS NOT NULL
+    </select>
 
 
 </mapper>

+ 2 - 2
dmp-business/dmp-rwd/src/main/resources/mapper/ObjectRelationMapper.xml

@@ -83,7 +83,7 @@
             CONCAT('Gt',#{param.graphCode},'001'),
             #{param.graphCode},
             #{param.relCode},
-            NULL,
+            #{param.relValue},
             dtr.obj_from,
             dtr.obj_to,
             #{param.appId},
@@ -96,7 +96,7 @@
         FROM
         (
         <if test="null!=param.chain and param.chain.size()>0">
-            SELECT
+            SELECT DISTINCT
             dtr0.obj_from AS obj_from,
             dtr${param.chain.size()-1}.obj_to AS obj_to,
             dtr0.group_code AS group_code,

+ 2 - 1
dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/define/entity/RelationDefine.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import com.persagy.dmp.basic.dto.RelationCalRuleDTO;
 import com.persagy.dmp.basic.dto.RelationCalDTO;
 import com.persagy.dmp.common.model.entity.AuditableEntity;
+import com.persagy.dmp.typehandler.RelationCalTypeHandler;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.hibernate.validator.constraints.Length;
@@ -46,7 +47,7 @@ public class RelationDefine extends AuditableEntity {
     /** 备注 */
     private String remark;
     /** 计算关系之前需要计算的关系 */
-    @TableField(value = "before_cal_rel",typeHandler = JacksonTypeHandler.class)
+    @TableField(value = "before_cal_rel",typeHandler = RelationCalTypeHandler.class)
     private List<RelationCalDTO> beforeCalRels;
     /** 计算器,就是计算规则 */
     @TableField(value = "cal_rule",typeHandler = JacksonTypeHandler.class)

+ 2 - 1
dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/digital/entity/ObjectDigital.java

@@ -3,6 +3,7 @@ package com.persagy.dmp.digital.entity;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.dmp.common.model.entity.AuditableEntity;
 import lombok.AllArgsConstructor;
@@ -112,7 +113,7 @@ public class ObjectDigital extends AuditableEntity {
     private ObjectNode bimLocation;
     /** 对象的outline平面坐标 */
     @TableField(exist = false,typeHandler = JacksonTypeHandler.class,value = "outLines")
-    private List<LinkedHashMap<String,Object>> outLines;
+    private ArrayNode outLines;
     /** 该对象的对象分类所拥有的classCode集合 */
     @TableField(exist = false,typeHandler = JacksonTypeHandler.class,value = "objTypeClassCodes")
     private Set<String> objTypeClassCodes;

+ 2 - 1
dmp-comp/dmp-digital-starter/src/main/java/com/persagy/dmp/digital/entity/ObjectRelation.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.persagy.dmp.common.model.entity.AuditableEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -62,7 +63,7 @@ public class ObjectRelation extends AuditableEntity {
     private String updateApp;
     /** 对象的outline平面坐标 */
     @TableField(exist = false,typeHandler = JacksonTypeHandler.class,value = "outLines")
-    private List<LinkedHashMap<String,Object>> outLines;
+    private ArrayNode outLines;
     /** 统计数 */
     @TableField(exist = false)
     private Integer count;