Browse Source

tip: eq2sp 补充部分轮廓计算

lvxianyun 3 years ago
parent
commit
ebfa80dc51

+ 88 - 0
src/main/java/com/persagy/proxy/adm/utils/GeoToolsUtil.java

@@ -1,7 +1,10 @@
 package com.persagy.proxy.adm.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.*;
 
@@ -16,6 +19,7 @@ import java.util.List;
  * @Date 2021/9/3 20:31
  * @Version V1.0
  **/
+@Slf4j
 public class GeoToolsUtil {
     /**
      * 创建点
@@ -71,6 +75,25 @@ public class GeoToolsUtil {
 
         return polygon;
    }
+    /**
+     * 创建面
+     * @param outLines
+     */
+    private static Polygon createPolygon(ArrayNode outLines){
+        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
+        List<Coordinate> objects = new ArrayList<>();
+        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);
+        }
+        //注意数据的闭合
+        Coordinate[] coordinates = objects.toArray(new Coordinate[0]);
+        LinearRing ring = geometryFactory.createLinearRing(coordinates);
+        return geometryFactory.createPolygon(ring, null);
+    }
 
     /**
      * 点面包含关系判断
@@ -113,4 +136,69 @@ public class GeoToolsUtil {
                 || toPolygon.contains(fromPolygon);
     }
 
+    /**
+     * 点面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param pointLocal 坐标点
+     * @param outLines 轮廓线
+     * @return
+     */
+    public static Boolean isPointInPoly(ObjectNode pointLocal, ArrayNode outLines) {
+        if (null==pointLocal || CollUtil.isEmpty(outLines)){
+            return false;
+        }
+        //创建点
+        Point point = createPoint(pointLocal);
+        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 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;
+    }
+
 }

+ 65 - 8
src/main/java/com/persagy/proxy/report/controller/AdmSpaceInfoController.java

@@ -1,15 +1,22 @@
 package com.persagy.proxy.report.controller;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.dmp.common.constant.ResponseCode;
+import com.persagy.dmp.common.helper.SpringHelper;
 import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
 import com.persagy.proxy.adm.request.AdmDCSQueryRequest;
 import com.persagy.proxy.adm.request.AdmQueryCriteria;
 import com.persagy.proxy.adm.request.AdmResponse;
 import com.persagy.proxy.adm.utils.AdmContextUtil;
+import com.persagy.proxy.adm.utils.GeoToolsUtil;
 import com.persagy.proxy.object.model.AdmEquipment;
 import com.persagy.proxy.object.model.AdmISpace;
+import com.persagy.proxy.object.model.AdmSpace;
 import com.persagy.proxy.object.model.AdmSystem;
 import com.persagy.proxy.object.service.*;
 import lombok.RequiredArgsConstructor;
@@ -20,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.QueryParam;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -90,7 +99,7 @@ public class AdmSpaceInfoController {
 	 */
 	@PostMapping("/unspace-in-eq")
 	public AdmResponse unSpaceEq(@QueryParam("type") String type, @QueryParam("spaceId") String spaceId, @RequestBody AdmQueryCriteria request) {
-		return unSpaceEq(type, spaceId, request, "MechInArch");
+		return unSpaceEq(type, spaceId, request, "MechInArch", false);
 	}
 
 	/**
@@ -102,22 +111,22 @@ public class AdmSpaceInfoController {
 	 */
 	@PostMapping("/unspace-for-eq")
 	public AdmResponse unSpaceForEq(@QueryParam("type") String type, @QueryParam("spaceId") String spaceId, @RequestBody AdmQueryCriteria request) {
-		return unSpaceForEqPoint(type, spaceId, request);
+		return unSpaceEq(type, spaceId, request, "MechForArch",false);
 	}
 	/**
 	 * 空间内没有服务于当前空间的设备
 	 */
 	@PostMapping("/unspace-for-eq-point")
 	public AdmResponse unSpaceForEqPoint(@QueryParam("type") String type, @QueryParam("spaceId") String spaceId, @RequestBody AdmQueryCriteria request) {
-		return unSpaceEq(type, spaceId, request, "MechForArch");
+		return unSpaceEq(type, spaceId, request, "MechForArch",true);
 	}
 
 	/**
-	 * 空间内没有和空间关联的设备
+	 * 根据空间轮廓 计算设备的坐标是否在空间内
 	 */
 	@PostMapping("/unspace-fIn-eq-point")
 	public AdmResponse unSpaceInEqPoint(@QueryParam("type") String type, @QueryParam("spaceId") String spaceId, @RequestBody AdmQueryCriteria request) {
-		return unSpaceEq(type, spaceId, request, "MechInArch");
+		return unSpaceEq(type, spaceId, request, "MechInArch", true);
 	}
 
 	/**
@@ -184,14 +193,62 @@ public class AdmSpaceInfoController {
 		}
 	}*/
 
-	private AdmResponse unSpaceEq(String type, String spaceId, AdmQueryCriteria request, String graphCode) {
+	/**
+	 * 根据空间和设备的关系,查询设备
+	 * @param type
+	 * @param spaceId
+	 * @param request
+	 * @param graphCode
+	 * @param isCalPoint 是否需要 设备的点位在空间轮廓线内 默认 true
+	 * @return
+	 */
+	private AdmResponse unSpaceEq(String type, String spaceId, AdmQueryCriteria request, String graphCode, Boolean isCalPoint) {
 		if (StrUtil.isBlank(spaceId)) {
 			return AdmResponse.failure(ResponseCode.A0400.getDesc() + "空间id为空");
 		}
+		AdmResponse responseEq = null;
+		AdmResponse responseSpace = null;
+		if(isCalPoint){
+			AdmQueryCriteria queryCriteria = new AdmQueryCriteria();
+			queryCriteria.setName(AdmSpace.OBJ_TYPE);
+			queryCriteria.setFilters(request.getFilters());
+			queryCriteria.addFilters("id = '"+spaceId+"'");
+			queryCriteria.addFilters("classCode = '"+type+"'");
+			queryCriteria.setPageSize(1);
+			responseSpace = spaceService.query(queryCriteria);
+		}
+		request.addFilters("not bimLocation isnull");
 		request.setName(AdmEquipment.OBJ_TYPE);
 		// 设置关系条件
 		request.resetRelationCond(true, graphCode, "Eq2Sp", type, spaceId, false);
-		return equipmentService.query(request);
-	}
+		responseEq = equipmentService.query(request);
 
+		if(isCalPoint && CollUtil.isNotEmpty(responseEq.getContent()) && null != responseSpace && CollUtil.isNotEmpty(responseSpace.getContent())){
+			//根据空间轮廓和设备坐标过滤掉不在空间内的设备
+			List<AdmEquipment> equipmentList = (List<AdmEquipment>) responseEq.getContent();
+			List<AdmEquipment> equipmentListNew = new ArrayList<>(16);
+			AdmSpace admSpace = (AdmSpace) responseSpace.getContent().get(0);
+			ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
+			ArrayNode jsonNodes = admSpace.getOutline();
+			for(AdmEquipment equipment : equipmentList){
+				String[] location = equipment.getBimLocation().split(",");
+				ObjectNode bimLocation = objectMapper.createObjectNode()
+						.put("x", location[0])
+						.put("y", location[1]);
+				if(location.length > 2){
+					bimLocation.put("z", location[2]);
+				}
+				if(GeoToolsUtil.isPointInPoly(bimLocation, jsonNodes)){
+					equipmentListNew.add(equipment);
+				}else{
+					continue;
+				}
+			}
+			if(CollUtil.isNotEmpty(equipmentListNew)){
+				responseEq.setContent(equipmentListNew);
+				responseEq.setTotal(equipmentListNew.size()*1L);
+			}
+		}
+		return responseEq;
+	}
 }