فهرست منبع

孤立线检查加入线gis包含点gis判断

欧阳劲驰 1 ماه پیش
والد
کامیت
ff61202486

+ 5 - 1
src/main/java/com/shkpr/service/alambizplugin/components/GisSurveySystemChecker.java

@@ -151,6 +151,10 @@ public class GisSurveySystemChecker {
 
             //查询经纬度类型定义
             List<TypeDefine> typeDefines = typeDefineService.findLatLng();
+            //孤立点定义
+            GisSurveySystemCheckDefine isolatedPointsDefine = systemCheckDefines.stream().
+                    filter(it -> Objects.equals(GisSurveySystemCheckKeys.ISOLATED_POINTS, it.getKey()))
+                    .findFirst().orElse(null);
             //重复点定义
             GisSurveySystemCheckDefine duplicatePointsDefine = systemCheckDefines.stream().
                     filter(it -> Objects.equals(GisSurveySystemCheckKeys.DUPLICATE_POINTS, it.getKey()))
@@ -168,7 +172,7 @@ public class GisSurveySystemChecker {
             //孤立点检查
             if (points != null && lines != null) {
                 if (params.getStartSubitemKeys().contains(GisSurveySystemCheckKeys.ISOLATED_POINTS)) {
-                    isolatedPointsFuture = isolatedPointsFinder.findIsolatedPoints(points, lines, systemCheckId);
+                    isolatedPointsFuture = isolatedPointsFinder.findIsolatedPoints(points, lines, isolatedPointsDefine,systemCheckId);
                     subtask.put(GisSurveySystemCheckKeys.ISOLATED_POINTS, isolatedPointsFuture);
                 }
             }

+ 83 - 19
src/main/java/com/shkpr/service/alambizplugin/components/checker/IsolatedPointsFinder.java

@@ -7,28 +7,32 @@ import com.shkpr.service.alambizplugin.commtools.BeanUtil;
 import com.shkpr.service.alambizplugin.components.AsyncResultManager;
 import com.shkpr.service.alambizplugin.constants.GisSurveySystemCheckKeys;
 import com.shkpr.service.alambizplugin.constants.GisSurveySystemCheckResultHead;
+import com.shkpr.service.alambizplugin.constants.GisSurveyTemplateDefine;
 import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
 import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyLine;
 import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyPoint;
+import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckDefine;
+import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckDeviation;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckElement;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckId;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckResultDetail;
 import com.shkpr.service.alambizplugin.exception.UncheckedInterruptedException;
-import org.apache.commons.lang3.StringUtils;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.util.NumberUtil;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
 import org.springframework.stereotype.Component;
 import org.springframework.util.concurrent.ListenableFuture;
 
 import java.nio.file.Path;
+import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 寻找孤立点
@@ -54,12 +58,25 @@ public class IsolatedPointsFinder {
      *
      * @param points        点集合
      * @param lines         线集合
+     * @param define        系统检查定义
      * @param systemCheckId 系统检查id
      * @return 孤立点集合
      */
     @Async
     public ListenableFuture<GisSurveySystemCheckResultDetail> findIsolatedPoints(List<GisSurveyLayerApplyPoint> points
-            , List<GisSurveyLayerApplyLine> lines, GisSurveySystemCheckId systemCheckId) throws InterruptedException {
+            , List<GisSurveyLayerApplyLine> lines, GisSurveySystemCheckDefine define, GisSurveySystemCheckId systemCheckId) throws InterruptedException {
+        //偏差集合
+        List<GisSurveySystemCheckDeviation> deviations = define != null ? define.getDeviation() : Collections.emptyList();
+        //经纬度公差
+        double lngTolerance = deviations.stream()
+                .filter(deviation -> Objects.equals(GisSurveyTemplateDefine.LNG, deviation.getProperty()))
+                .map(GisSurveySystemCheckDeviation::getTolerance)
+                .findFirst().orElse(0d);
+        double latTolerance = deviations.stream()
+                .filter(deviation -> Objects.equals(GisSurveyTemplateDefine.LAT, deviation.getProperty()))
+                .map(GisSurveySystemCheckDeviation::getTolerance)
+                .findFirst().orElse(0d);
+
         LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始执行寻找孤立点========>");
         long begin = System.currentTimeMillis();
 
@@ -81,19 +98,24 @@ public class IsolatedPointsFinder {
             if (lines.isEmpty()) return new AsyncResult<>(createResult(Collections.emptyList(), systemCheckId, begin));
             //点为空,则无孤立点
             if (points.isEmpty()) return new AsyncResult<>(createResult(Collections.emptyList(), systemCheckId, begin));
-            //计算预期最大容量,避免频繁扩容
-            int expectedMaxSize = (int) (((long) lines.size() << 1) / .75f + 1);
-            //联通点code
-            Set<String> connectedPoints = new HashSet<>(expectedMaxSize);
-            //遍历所有线,标记参与的点
-            for (GisSurveyLayerApplyLine line : lines) {
-                //响应中断
-                if (Thread.interrupted()) throw new InterruptedException();
-                //上下游节点判空
-                if (StringUtils.isBlank(line.getUpNode()) || StringUtils.isBlank(line.getDownNode())) continue;
-                connectedPoints.add(line.getUpNode());
-                connectedPoints.add(line.getDownNode());
-            }
+            //联通点线关系
+            Map<String, List<GisSurveyLayerApplyLine>> connectedPoints = lines.parallelStream()
+                    //响应中断
+                    .peek(it -> {
+                        if (Thread.currentThread().isInterrupted())
+                            throw new UncheckedInterruptedException(new InterruptedException());
+                    })
+                    //上下节点分组
+                    .flatMap(line -> Stream.of(
+                            new AbstractMap.SimpleEntry<>(line.getUpNode(), line),
+                            new AbstractMap.SimpleEntry<>(line.getDownNode(), line)
+                    ))
+                    //过滤空,并合并
+                    .filter(it -> Objects.nonNull(it.getKey()) && Objects.nonNull(it.getValue()))
+                    .collect(Collectors.groupingBy(
+                            AbstractMap.SimpleEntry::getKey,
+                            Collectors.mapping(Map.Entry::getValue, Collectors.toList())
+                    ));
             //使用并行流找出孤立点
             List<GisSurveySystemCheckElement> elements = points.parallelStream()
                     //响应中断
@@ -101,10 +123,18 @@ public class IsolatedPointsFinder {
                         if (Thread.currentThread().isInterrupted())
                             throw new UncheckedInterruptedException(new InterruptedException());
                     })
+                    //排除空点
+                    .filter(point -> Objects.nonNull(point) && Objects.nonNull(point.getCode()))
+                    //过滤连通点
+                    .filter(point -> {
+                        //判断是否和线连通
+                        if (!connectedPoints.containsKey(point.getCode())) return true;
+                        //遍历连通的线,判断是否有包含关系
+                        return connectedPoints.get(point.getCode()).stream()
+                                .noneMatch(line -> calcContain(line, point, lngTolerance, latTolerance));
+                    })
                     //转为返回元素
                     .map(point -> BeanUtil.copy(point, GisSurveySystemCheckElement.class))
-                    //过滤连通点
-                    .filter(element -> Objects.nonNull(element) && !connectedPoints.contains(element.getCode()))
                     .collect(Collectors.toList());
             return new AsyncResult<>(createResult(elements, systemCheckId, begin));
         } catch (UncheckedInterruptedException e) {
@@ -113,6 +143,40 @@ public class IsolatedPointsFinder {
     }
 
     /**
+     * 计算包含
+     *
+     * @param line         线
+     * @param point        点
+     * @param lngTolerance 经度公差
+     * @param latTolerance 纬度公差
+     * @return 包含关系
+     */
+    private Boolean calcContain(GisSurveyLayerApplyLine line, GisSurveyLayerApplyPoint point, double lngTolerance, double latTolerance) {
+        //上节点判断
+        if (Objects.equals(point.getCode(), line.getUpNode())) {
+            //线坐标
+            Coordinate lineCcoordinate = line.getGis().getCoordinateN(0);
+            //点坐标
+            Coordinate pointCoordinate = point.getGis().getCoordinate();
+            //比较x和y
+            return NumberUtil.equalsWithTolerance(lineCcoordinate.x, pointCoordinate.x, lngTolerance) &&
+                    NumberUtil.equalsWithTolerance(lineCcoordinate.y, pointCoordinate.y, latTolerance);
+
+        }
+        //下节点判断
+        if (Objects.equals(point.getCode(), line.getDownNode())) {
+            //线坐标
+            Coordinate lineCcoordinate = line.getGis().getCoordinateN(line.getGis().getCoordinates().length - 1);
+            //点坐标
+            Coordinate pointCoordinate = point.getGis().getCoordinate();
+            //比较x和y
+            return NumberUtil.equalsWithTolerance(lineCcoordinate.x, pointCoordinate.x, lngTolerance) &&
+                    NumberUtil.equalsWithTolerance(lineCcoordinate.y, pointCoordinate.y, latTolerance);
+        }
+        return false;
+    }
+
+    /**
      * 创建结果
      *
      * @param data          数据