Explorar o código

回滚:线对象改为多线对象,第三方导入加入gis写入处理

欧阳劲驰 hai 8 horas
pai
achega
b169699fd7

+ 2 - 104
src/main/java/com/shkpr/service/alambizplugin/commtools/GeomUtil.java

@@ -11,10 +11,7 @@ import org.geotools.referencing.CRS;
 import org.geotools.referencing.GeodeticCalculator;
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Envelope;
-import org.locationtech.jts.geom.Geometry;
 import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LineString;
-import org.locationtech.jts.geom.MultiLineString;
 import org.locationtech.jts.geom.Polygon;
 import org.locationtech.jts.util.GeometricShapeFactory;
 import org.locationtech.jts.util.NumberUtil;
@@ -78,7 +75,7 @@ public class GeomUtil {
         //上节点判断
         if (Objects.equals(point.getCode(), line.getUpNode())) {
             //线坐标
-            Coordinate lineCcoordinate = line.getGis().getCoordinates()[0];
+            Coordinate lineCcoordinate = line.getGis().getCoordinateN(0);
             //点坐标
             Coordinate pointCoordinate = point.getGis().getCoordinate();
             //比较x和y
@@ -89,7 +86,7 @@ public class GeomUtil {
         //下节点判断
         if (Objects.equals(point.getCode(), line.getDownNode())) {
             //线坐标
-            Coordinate lineCcoordinate = line.getGis().getCoordinates()[line.getGis().getCoordinates().length - 1];
+            Coordinate lineCcoordinate = line.getGis().getCoordinateN(line.getGis().getCoordinates().length - 1);
             //点坐标
             Coordinate pointCoordinate = point.getGis().getCoordinate();
             //比较x和y
@@ -119,105 +116,6 @@ public class GeomUtil {
     }
 
     /**
-     * 转数组
-     *
-     * @param coordinate 坐标
-     * @return 坐标数组
-     */
-    public static double[] toArray(Coordinate coordinate) {
-        return new double[]{coordinate.getX(), coordinate.getY()};
-    }
-
-    /**
-     * 转数组
-     *
-     * @param lineString 线
-     * @return 坐标数组
-     */
-    public static double[][] toArray(LineString lineString) {
-        //获取geom的坐标
-        Coordinate[] coords = lineString.getCoordinates();
-        if (coords == null || coords.length == 0) return new double[0][2];
-        //构建坐标数组
-        double[][] result = new double[coords.length][2];
-        //存入坐标
-        for (int j = 0; j < coords.length; j++) {
-            result[j][0] = coords[j].getX();
-            result[j][1] = coords[j].getY();
-        }
-        return result;
-    }
-
-    /**
-     * 转数组
-     *
-     * @param multiLineString 线集合
-     * @return 坐标数组
-     */
-    public static double[][][] toArray(MultiLineString multiLineString) {
-        //geom长度
-        int geomLength = multiLineString.getNumGeometries();
-        //结果
-        double[][][] result = new double[geomLength][][];
-        //遍历geom
-        for (int i = 0; i < geomLength; i++) {
-            //获取geom
-            Geometry geom = multiLineString.getGeometryN(i);
-            if (geom instanceof LineString) result[i] = toArray((LineString) geom);
-            else result[i] = new double[0][];
-        }
-        return result;
-    }
-
-    /**
-     * 从数组转换
-     *
-     * @param array 数组
-     * @return 坐标
-     */
-    public static Coordinate ofArray(double[] array) {
-        if (array == null || array.length < 2) return null;
-        return new Coordinate(array[0], array[1]);
-    }
-
-    /**
-     * 从数组转换
-     *
-     * @param array 数组
-     * @return 线
-     */
-    public static LineString ofArray(double[][] array) {
-        if (array == null || array.length == 0) return geometryFactory.createLineString();
-        //遍历数组并构建坐标集合
-        Coordinate[] coordinates = new Coordinate[array.length];
-        for (int j = 0; j < array.length; j++) {
-            //坐标判断
-            if (array[j].length < 2) throw new IllegalArgumentException("坐标点必须包含 [x, y]");
-            //转坐标
-            coordinates[j] = ofArray(array[j]);
-        }
-        return geometryFactory.createLineString(coordinates);
-    }
-
-    /**
-     * 从数组转换
-     *
-     * @param array 数组
-     * @return 多线
-     */
-    public static MultiLineString ofArray(double[][][] array) {
-        if (array == null || array.length == 0) return geometryFactory.createMultiLineString();
-        //遍历数组并构建线集合
-        LineString[] lineStrings = new LineString[array.length];
-        for (int i = 0; i < array.length; i++) {
-            //转线
-            lineStrings[i] = ofArray(array[i]);
-        }
-        return geometryFactory.createMultiLineString(lineStrings);
-    }
-
-
-    /**
      * 创建圆
      *
      * @param centre  圆心

+ 15 - 36
src/main/java/com/shkpr/service/alambizplugin/components/GisSurveyThirdImporter.java

@@ -39,8 +39,6 @@ import org.apache.commons.lang3.math.NumberUtils;
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Geometry;
 import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LineString;
-import org.locationtech.jts.geom.MultiLineString;
 import org.locationtech.jts.geom.PrecisionModel;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
@@ -429,8 +427,8 @@ public class GisSurveyThirdImporter {
 
         //采集元素象集合
         List<GisSurveyLayerApplyThirdCopy> result = new ArrayList<>();
-        //点映射,用于线写入上下游节点
-        Map<String, GisSurveyLayerApplyThirdCopy> pointMapping = new HashMap<>();
+        //点映射,用于线写入上下游节点
+        Map<String, String> pointNoMapping = new HashMap<>();
         //格式化点
         for (Map<String, String> point : points) {
             //获取模版
@@ -438,25 +436,19 @@ public class GisSurveyThirdImporter {
             //解码点对象
             GisSurveyLayerApplyThirdCopy layerApply = decodePointToLayerApply(point, layerTemplate, params);
             //存入点号
-            pointMapping.put(layerApply.getNo(), layerApply);
+            pointNoMapping.put(layerApply.getNo(), layerApply.getCode());
 
             result.add(layerApply);
         }
-        //清除点缓存
-        points.clear();
-
         //格式化线
         for (Map<String, String> line : lines) {
             //获取模版
             GisMetadataLayerTemplate layerTemplate = lineTemplateMap.get(line.get(GisSurveyExcelDefine.FILE.LINE_LAYER));
             //解码对象
-            GisSurveyLayerApplyThirdCopy layerApply = decodeLineToLayerApply(line, layerTemplate, params, pointMapping);
+            GisSurveyLayerApplyThirdCopy layerApply = decodeLineToLayerApply(line, layerTemplate, params, pointNoMapping);
 
             result.add(layerApply);
         }
-        //清除点映射和线缓存
-        pointMapping.clear();
-        lines.clear();
 
         long end = System.currentTimeMillis();
         LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
@@ -556,14 +548,13 @@ public class GisSurveyThirdImporter {
     /**
      * 解码线数据到采集元素对象
      *
-     * @param line          线数据
-     * @param layerTemplate 图层模版
-     * @param params        导入参数
-     * @param pointMapping  点号映射
+     * @param line           线数据
+     * @param layerTemplate  图层模版
+     * @param params         导入参数
+     * @param pointNoMapping 点号映射
      * @return 采集元素拷贝对象
      */
-    private GisSurveyLayerApplyThirdCopy decodeLineToLayerApply(Map<String, String> line, GisMetadataLayerTemplate layerTemplate
-            , GisSurveyThirdImportParams params, Map<String, GisSurveyLayerApplyThirdCopy> pointMapping) {
+    private GisSurveyLayerApplyThirdCopy decodeLineToLayerApply(Map<String, String> line, GisMetadataLayerTemplate layerTemplate, GisSurveyThirdImportParams params, Map<String, String> pointNoMapping) {
         GisSurveyLayerApplyThirdCopy layerApply = new GisSurveyLayerApplyThirdCopy();
         //必填项
         layerApply.setJobId(params.getJobId());
@@ -573,26 +564,14 @@ public class GisSurveyThirdImporter {
         //默认值
         layerApply.setApply(GisSurveyExcelDefine.DEFAULT_VALUE.APPLY);
         layerApply.setSource(GisSurveyExcelDefine.DEFAULT_VALUE.SOURCE);
-        //上游节点
+        //上游节点
         String upNoStr = ThirdImportTemplateUtils.getValue(line, layerTemplate, GisSurveyExcelDefine.TEMPLATE.UP_NO);
-        GisSurveyLayerApplyThirdCopy upNo = StringUtils.isNotBlank(upNoStr) ? pointMapping.get(upNoStr) : null;
-        if (upNo != null) layerApply.setUpNode(upNo.getCode());
-        //下游节点
+        if (StringUtils.isNotBlank(upNoStr)) {
+            layerApply.setUpNode(pointNoMapping.get(upNoStr));
+        }
         String downNoStr = ThirdImportTemplateUtils.getValue(line, layerTemplate, GisSurveyExcelDefine.TEMPLATE.DOWN_NO);
-        GisSurveyLayerApplyThirdCopy downNo = StringUtils.isNotBlank(downNoStr) ? pointMapping.get(downNoStr) : null;
-        if (downNo != null) layerApply.setDownNode(downNo.getCode());
-        //gis
-        if (upNo != null && downNo != null && upNo.getGis() != null && downNo.getGis() != null) {
-            //上下游坐标
-            Coordinate upCoordinate = upNo.getGis().getCoordinate();
-            Coordinate downCoordinate = downNo.getGis().getCoordinate();
-            //创建线
-            LineString lineString = upCoordinate != null && downCoordinate != null ?
-                    geometryFactory.createLineString(new Coordinate[]{upCoordinate, downCoordinate}) : null;
-            //创建多线
-            MultiLineString multiLineString = new MultiLineString(new LineString[]{lineString}, geometryFactory);
-            //设置gis
-            if (lineString != null) layerApply.setGis(multiLineString);
+        if (StringUtils.isNotBlank(downNoStr)) {
+            layerApply.setDownNode(pointNoMapping.get(downNoStr));
         }
         //遍历属性模版
         List<GisSurveyPropertyValueThirdCopy> propertyValueList = new ArrayList<>();

+ 2 - 2
src/main/java/com/shkpr/service/alambizplugin/components/checker/CrossLinesFinder.java

@@ -11,7 +11,7 @@ import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyLine;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckElement;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckId;
 import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckResultDetail;
-import org.locationtech.jts.geom.MultiLineString;
+import org.locationtech.jts.geom.LineString;
 import org.locationtech.jts.index.strtree.STRtree;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
@@ -70,7 +70,7 @@ public class CrossLinesFinder {
         //元素存入索引
         for (GisSurveyLayerApplyLine layerApplyLine : lines) {
             if (layerApplyLine.getGis() == null) continue;
-            MultiLineString line = layerApplyLine.getGis();
+            LineString line = layerApplyLine.getGis();
             tree.insert(line.getEnvelopeInternal(), layerApplyLine);
         }
         tree.build();

+ 10 - 10
src/main/java/com/shkpr/service/alambizplugin/components/checker/OverlapLinesFinder.java

@@ -15,7 +15,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.locationtech.jts.algorithm.Orientation;
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.LineSegment;
-import org.locationtech.jts.geom.MultiLineString;
+import org.locationtech.jts.geom.LineString;
 import org.locationtech.jts.index.strtree.STRtree;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
@@ -77,7 +77,7 @@ public class OverlapLinesFinder {
         //元素存入索引
         for (GisSurveyLayerApplyLine layerApplyLine : lines) {
             if (layerApplyLine.getGis() == null) continue;
-            MultiLineString line = layerApplyLine.getGis();
+            LineString line = layerApplyLine.getGis();
             tree.insert(line.getEnvelopeInternal(), layerApplyLine);
         }
         tree.build();
@@ -154,10 +154,10 @@ public class OverlapLinesFinder {
      */
     public boolean calcFullOverlap(GisSurveyLayerApplyLine line1, GisSurveyLayerApplyLine line2) {
         //取出四个点
-        Coordinate a = line1.getGis().getCoordinates()[0];
-        Coordinate b = line1.getGis().getCoordinates()[1];
-        Coordinate c = line2.getGis().getCoordinates()[0];
-        Coordinate d = line2.getGis().getCoordinates()[1];
+        Coordinate a = line1.getGis().getCoordinateN(0);
+        Coordinate b = line1.getGis().getCoordinateN(1);
+        Coordinate c = line2.getGis().getCoordinateN(0);
+        Coordinate d = line2.getGis().getCoordinateN(1);
         if (a == null || b == null || c == null || d == null) return false;
         return (a.equals2D(c) && b.equals2D(d)) || (a.equals2D(d) && b.equals2D(c));
     }
@@ -171,10 +171,10 @@ public class OverlapLinesFinder {
      */
     public boolean calcPartialOverlap(GisSurveyLayerApplyLine line1, GisSurveyLayerApplyLine line2) {
         //取出四个点
-        Coordinate a = line1.getGis().getCoordinates()[0];
-        Coordinate b = line1.getGis().getCoordinates()[1];
-        Coordinate c = line2.getGis().getCoordinates()[0];
-        Coordinate d = line2.getGis().getCoordinates()[1];
+        Coordinate a = line1.getGis().getCoordinateN(0);
+        Coordinate b = line1.getGis().getCoordinateN(1);
+        Coordinate c = line2.getGis().getCoordinateN(0);
+        Coordinate d = line2.getGis().getCoordinateN(1);
         //点数量判断
         if (a == null || b == null || c == null || d == null) return false;
         //检查C和D是否在AB的直线上(叉积为0,则方向一致)

+ 107 - 0
src/main/java/com/shkpr/service/alambizplugin/dbdao/pgtype/GeomLineStringTypeHandlePg.java

@@ -0,0 +1,107 @@
+package com.shkpr.service.alambizplugin.dbdao.pgtype;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.PrecisionModel;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 地理线段类型处理器
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+@MappedTypes({LineString.class})
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
+    private static final GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4490);
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 解析
+     *
+     * @param lineStr 值
+     * @return 线段
+     * @throws SQLException sql异常
+     */
+    public static LineString parseLineString(String lineStr) throws SQLException {
+        //非空校验
+        if (lineStr == null || lineStr.isEmpty()) return null;
+        try {
+            //序列化
+            double[][] coordinates = objectMapper.readValue(lineStr, double[][].class);
+            //判断格式
+            if (coordinates.length == 2 && coordinates[0].length == 2 && coordinates[1].length == 2) {
+                //获取值
+                double x0 = coordinates[0][0];
+                double y0 = coordinates[0][1];
+                double x1 = coordinates[1][0];
+                double y1 = coordinates[1][1];
+                //构建线
+                return factory.createLineString(new Coordinate[]{new Coordinate(x0, y0), new Coordinate(x1, y1)});
+            }
+        } catch (IOException e) {
+            throw new SQLException("线段格式无效: " + lineStr);
+        }
+        throw new SQLException("线段格式无效: " + lineStr);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, LineString lineString, JdbcType jdbcType)
+            throws SQLException {
+        //将 LineString 序列化为 [[x1,y1],[x2,y2]] 字符串
+        if (lineString != null && lineString.getCoordinates() != null && lineString.getCoordinates().length == 2) {
+            Coordinate p0 = lineString.getCoordinateN(0);
+            Coordinate p1 = lineString.getCoordinateN(1);
+            String value = String.format("[[%s,%s],[%s,%s]]",
+                    BigDecimal.valueOf(p0.x).toPlainString(),
+                    BigDecimal.valueOf(p0.y).toPlainString(),
+                    BigDecimal.valueOf(p1.x).toPlainString(),
+                    BigDecimal.valueOf(p1.y).toPlainString()
+            );
+            ps.setString(i, value);
+        } else {
+            //处理空值
+            ps.setNull(i, JdbcType.VARCHAR.TYPE_CODE);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public LineString getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return rs.wasNull() ? null : parseLineString(rs.getString(columnName));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public LineString getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.wasNull() ? null : parseLineString(rs.getString(columnIndex));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public LineString getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.wasNull() ? null : parseLineString(cs.getString(columnIndex));
+    }
+}

+ 0 - 109
src/main/java/com/shkpr/service/alambizplugin/dbdao/pgtype/GeomMultiLineStringTypeHandlePg.java

@@ -1,109 +0,0 @@
-package com.shkpr.service.alambizplugin.dbdao.pgtype;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.shkpr.service.alambizplugin.commtools.GeomUtil;
-import org.apache.ibatis.type.BaseTypeHandler;
-import org.apache.ibatis.type.JdbcType;
-import org.apache.ibatis.type.MappedJdbcTypes;
-import org.apache.ibatis.type.MappedTypes;
-import org.locationtech.jts.geom.MultiLineString;
-
-import java.io.IOException;
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * 地理多线类型处理器
- *
- * @author 欧阳劲驰
- * @since 1.0.0
- */
-@MappedTypes({MultiLineString.class})
-@MappedJdbcTypes(JdbcType.VARCHAR)
-public class GeomMultiLineStringTypeHandlePg extends BaseTypeHandler<MultiLineString> {
-    private static final ObjectMapper objectMapper = new ObjectMapper();
-
-    /**
-     * 解析
-     *
-     * @param lineStr 值
-     * @return 多线
-     * @throws SQLException sql异常
-     */
-    public static MultiLineString parseString(String lineStr) throws SQLException {
-        //非空校验
-        if (lineStr == null || lineStr.isEmpty()) return null;
-        try {
-            //序列化
-            double[][][] array = objectMapper.readValue(lineStr, double[][][].class);
-            //构建线
-            return GeomUtil.ofArray(array);
-        } catch (IOException e) {
-            throw new SQLException("多线格式无效: " + lineStr);
-        }
-    }
-
-    /**
-     * 从多线对象转数据库字符串
-     *
-     * @param multiLineString 多线
-     * @return 字符串
-     * @throws SQLException sql异常
-     */
-    public static String toString(MultiLineString multiLineString) throws SQLException {
-        if (multiLineString == null) return null;
-        try {
-            //转数组
-            double[][][] array = GeomUtil.toArray(multiLineString);
-            //反序列化
-            return objectMapper.writeValueAsString(array);
-        } catch (IOException e) {
-            throw new SQLException("多线格式无效: " + multiLineString);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setNonNullParameter(PreparedStatement ps, int i, MultiLineString multiLineString, JdbcType jdbcType)
-            throws SQLException {
-        if (multiLineString != null && multiLineString.getCoordinates() != null) {
-            //将点序列化化为字符串
-            String lineStr = toString(multiLineString);
-            if (lineStr != null) {
-                ps.setString(i, lineStr);
-                return;
-            }
-        }
-        //处理空值
-        ps.setNull(i, JdbcType.VARCHAR.TYPE_CODE);
-
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MultiLineString getNullableResult(ResultSet rs, String columnName) throws SQLException {
-        return rs.wasNull() ? null : parseString(rs.getString(columnName));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MultiLineString getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
-        return rs.wasNull() ? null : parseString(rs.getString(columnIndex));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MultiLineString getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
-        return cs.wasNull() ? null : parseString(cs.getString(columnIndex));
-    }
-}

+ 20 - 40
src/main/java/com/shkpr/service/alambizplugin/dbdao/pgtype/GeomPointTypeHandlePg.java

@@ -1,7 +1,6 @@
 package com.shkpr.service.alambizplugin.dbdao.pgtype;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.shkpr.service.alambizplugin.commtools.GeomUtil;
 import org.apache.ibatis.type.BaseTypeHandler;
 import org.apache.ibatis.type.JdbcType;
 import org.apache.ibatis.type.MappedJdbcTypes;
@@ -12,6 +11,7 @@ import org.locationtech.jts.geom.Point;
 import org.locationtech.jts.geom.PrecisionModel;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -37,18 +37,19 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
      * @return 点
      * @throws SQLException sql异常
      */
-    public static Point parseString(String pointStr) throws SQLException {
+    public static Point parsePoint(String pointStr) throws SQLException {
         //非空校验
         if (pointStr == null || pointStr.isEmpty()) return null;
         try {
             //序列化
-            double[] array = objectMapper.readValue(pointStr, double[].class);
+            double[] coordinate = objectMapper.readValue(pointStr, double[].class);
             //判断格式
-            if (array.length == 2) {
-                //转坐标
-                Coordinate coordinate = GeomUtil.ofArray(array);
+            if (coordinate.length == 2) {
+                //获取值
+                double longitude = coordinate[0];
+                double latitude = coordinate[1];
                 //构建点
-                return factory.createPoint(coordinate);
+                return factory.createPoint(new Coordinate(longitude, latitude));
             }
         } catch (IOException e) {
             throw new SQLException("点格式无效: " + pointStr);
@@ -57,42 +58,21 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
     }
 
     /**
-     * 从Point对象转数据库字符串
-     *
-     * @param point 点
-     * @return 字符串
-     * @throws SQLException sql异常
-     */
-    public static String toString(Point point) throws SQLException {
-        if (point == null) return null;
-        //获取坐标
-        Coordinate coordinate = point.getCoordinate();
-        if (coordinate == null) return null;
-        try {
-            //转数组
-            double[] array = GeomUtil.toArray(coordinate);
-            //反序列化
-            return objectMapper.writeValueAsString(array);
-        } catch (IOException e) {
-            throw new SQLException("点格式无效: " + point);
-        }
-    }
-
-    /**
      * 将Java类型Point写入数据库
      */
     @Override
     public void setNonNullParameter(PreparedStatement ps, int i, Point point, JdbcType jdbcType) throws SQLException {
         if (point != null && point.getCoordinate() != null) {
-            //将点序列化化为字符串
-            String pointStr = toString(point);
-            if (pointStr != null) {
-                ps.setString(i, pointStr);
-                return;
-            }
+            //将 Point 序列化化为 [x,y] 字符串
+            String pointStr = String.format("[%s,%s]",
+                    BigDecimal.valueOf(point.getX()).toPlainString(),
+                    BigDecimal.valueOf(point.getY()).toPlainString()
+            );
+            ps.setString(i, pointStr);
+        } else {
+            //处理空值
+            ps.setNull(i, Types.VARCHAR);
         }
-        //处理空值
-        ps.setNull(i, Types.VARCHAR);
     }
 
     /**
@@ -101,7 +81,7 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
     @Override
     public Point getNullableResult(ResultSet rs, String columnName) throws SQLException {
         String pointStr = rs.getString(columnName);
-        return rs.wasNull() ? null : parseString(pointStr);
+        return rs.wasNull() ? null : parsePoint(pointStr);
     }
 
     /**
@@ -110,7 +90,7 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
     @Override
     public Point getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
         String pointStr = rs.getString(columnIndex);
-        return rs.wasNull() ? null : parseString(pointStr);
+        return rs.wasNull() ? null : parsePoint(pointStr);
     }
 
     /**
@@ -119,6 +99,6 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
     @Override
     public Point getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
         String pointStr = cs.getString(columnIndex);
-        return cs.wasNull() ? null : parseString(pointStr);
+        return cs.wasNull() ? null : parsePoint(pointStr);
     }
 }

+ 54 - 54
src/main/java/com/shkpr/service/alambizplugin/dbdao/pgtype/GeomTypeHandlePg.java

@@ -6,11 +6,13 @@ import org.apache.ibatis.type.BaseTypeHandler;
 import org.apache.ibatis.type.JdbcType;
 import org.apache.ibatis.type.MappedJdbcTypes;
 import org.apache.ibatis.type.MappedTypes;
+import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.MultiLineString;
+import org.locationtech.jts.geom.LineString;
 import org.locationtech.jts.geom.Point;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -27,6 +29,54 @@ import java.sql.SQLException;
 public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
     private static final ObjectMapper objectMapper = new ObjectMapper();
 
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Geometry geometry, JdbcType jdbcType) throws SQLException {
+        if (geometry instanceof Point) {
+            //将 Point 序列化化为 [x,y] 字符串
+            Point point = (Point) geometry;
+            if (point.getCoordinate() != null) {
+                String pointStr = String.format("[%s,%s]",
+                        BigDecimal.valueOf(point.getX()).toPlainString(),
+                        BigDecimal.valueOf(point.getY()).toPlainString()
+                );
+                ps.setString(i, pointStr);
+                return;
+            }
+        } else if (geometry instanceof LineString) {
+            //将 LineString 序列化为 [[x1,y1],[x2,y2]] 字符串
+            LineString lineString = (LineString) geometry;
+            if (lineString.getCoordinates() != null && lineString.getCoordinates().length == 2) {
+                Coordinate p0 = lineString.getCoordinateN(0);
+                Coordinate p1 = lineString.getCoordinateN(1);
+                String value = String.format("[[%s,%s],[%s,%s]]",
+                        BigDecimal.valueOf(p0.x).toPlainString(),
+                        BigDecimal.valueOf(p0.y).toPlainString(),
+                        BigDecimal.valueOf(p1.x).toPlainString(),
+                        BigDecimal.valueOf(p1.y).toPlainString()
+                );
+                ps.setString(i, value);
+                return;
+            }
+        }
+        //处理空值
+        ps.setNull(i, JdbcType.VARCHAR.TYPE_CODE);
+    }
+
+    @Override
+    public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return rs.wasNull() ? null : parseGeom(rs.getString(columnName));
+    }
+
+    @Override
+    public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.wasNull() ? null : parseGeom(rs.getString(columnIndex));
+    }
+
+    @Override
+    public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.wasNull() ? null : parseGeom(cs.getString(columnIndex));
+    }
+
     /**
      * 解析
      *
@@ -34,7 +84,7 @@ public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
      * @return 地理对象
      * @throws SQLException sql异常
      */
-    public static Geometry parseGeom(String geomStr) throws SQLException {
+    public Geometry parseGeom(String geomStr) throws SQLException {
         //非空校验
         if (geomStr == null || geomStr.isEmpty()) return null;
         try {
@@ -42,11 +92,11 @@ public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
             if (jsonNode.isArray() && jsonNode.size() > 0) {
                 //点处理
                 if (jsonNode.get(0).isNumber() && jsonNode.get(1).isNumber()) {
-                    return GeomPointTypeHandlePg.parseString(geomStr);
+                    return GeomPointTypeHandlePg.parsePoint(geomStr);
                 }
                 //线处理
                 else if (jsonNode.get(0).isArray()) {
-                    return GeomMultiLineStringTypeHandlePg.parseString(geomStr);
+                    return GeomLineStringTypeHandlePg.parseLineString(geomStr);
                 }
             }
 
@@ -55,54 +105,4 @@ public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
         }
         throw new SQLException("地理数据格式无效: " + geomStr);
     }
-
-    /**
-     * 从Geometry对象转数据库字符串
-     *
-     * @param geometry 点
-     * @return 字符串
-     * @throws SQLException sql异常
-     */
-    public static String toGeomString(Geometry geometry) throws SQLException {
-        if (geometry instanceof Point) {
-            Point point = (Point) geometry;
-            //转字符串
-            return GeomPointTypeHandlePg.toString(point);
-
-        } else if (geometry instanceof MultiLineString) {
-            MultiLineString multiLineString = (MultiLineString) geometry;
-            //转字符串
-            return GeomMultiLineStringTypeHandlePg.toString(multiLineString);
-        }
-        return null;
-    }
-
-    @Override
-    public void setNonNullParameter(PreparedStatement ps, int i, Geometry geometry, JdbcType jdbcType) throws SQLException {
-        if (geometry != null && geometry.getCoordinate() != null) {
-            //将geom序列化化为字符串
-            String geomString = toGeomString(geometry);
-            if (geomString != null) {
-                ps.setString(i, geomString);
-                return;
-            }
-        }
-        //处理空值
-        ps.setNull(i, JdbcType.VARCHAR.TYPE_CODE);
-    }
-
-    @Override
-    public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException {
-        return rs.wasNull() ? null : parseGeom(rs.getString(columnName));
-    }
-
-    @Override
-    public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
-        return rs.wasNull() ? null : parseGeom(rs.getString(columnIndex));
-    }
-
-    @Override
-    public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
-        return cs.wasNull() ? null : parseGeom(cs.getString(columnIndex));
-    }
 }

+ 2 - 2
src/main/java/com/shkpr/service/alambizplugin/dto/GisSurveyLayerApplyLine.java

@@ -1,7 +1,7 @@
 package com.shkpr.service.alambizplugin.dto;
 
 import lombok.Data;
-import org.locationtech.jts.geom.MultiLineString;
+import org.locationtech.jts.geom.LineString;
 
 /**
  * 采集元素处理申请线
@@ -34,7 +34,7 @@ public class GisSurveyLayerApplyLine {
     /**
      * 坐标值
      */
-    private MultiLineString gis;
+    private LineString gis;
     /**
      * 操作标记:add/update/delete
      */

+ 71 - 71
src/main/resources/mapper/GisSurveyLayerApplyMapper.xml

@@ -50,7 +50,7 @@
         <result column="name" jdbcType="VARCHAR" property="name"/>
         <result column="kind" jdbcType="VARCHAR" property="kind"/>
         <result column="gis" jdbcType="VARCHAR" property="gis"
-                typeHandler="com.shkpr.service.alambizplugin.dbdao.pgtype.GeomMultiLineStringTypeHandlePg"/>
+                typeHandler="com.shkpr.service.alambizplugin.dbdao.pgtype.GeomLineStringTypeHandlePg"/>
         <result column="apply" jdbcType="VARCHAR" property="apply"/>
         <result column="source" jdbcType="SMALLINT" property="source"/>
         <result column="up_node" jdbcType="VARCHAR" property="upNode"/>
@@ -63,107 +63,107 @@
 
     <select id="findAddUpdatePointByProjId" fetchSize="3000" resultMap="Point">
         select la.code, la.job_id, la.layer, la.kind, la.gis, la.apply, la.source, la.elevation, la.no,
-        case when lt.name is null then
-        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
-        else lt.name end as name
+               case when lt.name is null then
+                        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
+                    else lt.name end as name
         from k3_gis_survey_layer_apply la
-        join k3_gis_survey_job_info jo on la.job_id = jo.uid
-        join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
-        left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
+                 join k3_gis_survey_job_info jo on la.job_id = jo.uid
+                 join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
+                 left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
         where pit.uid = #{projId,jdbcType=VARCHAR}
-        and jo.disused = 0
-        and (la.apply = 'add' or la.apply = 'update') and la.kind = 'point'
+          and jo.disused = 0
+          and (la.apply = 'add' or la.apply = 'update') and la.kind = 'point'
     </select>
 
     <select id="findAddUpdateLineByProjId" fetchSize="3000" resultMap="Line">
         select la.code, la.job_id, la.layer, la.kind, la.apply, la.source, la.up_node, la.down_node,
-        un.no as up_no, dn.no as down_no,
-        case when un.code is not null and dn.code is not null then concat('[[', un.gis, ',', dn.gis, ']]') else la.gis end
-        as gis,
-        abs(coalesce(un.elevation, 0)::numeric - coalesce(dn.elevation, 0)::numeric) as elevation_diff,
-        sl.value as survey_length,
-        case when lt.name is null then
-        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
-        else lt.name end as name
+               un.no as up_no, dn.no as down_no,
+               case when un.code is not null and dn.code is not null then concat('[', un.gis, ',', dn.gis, ']') else la.gis end
+                     as gis,
+               abs(coalesce(un.elevation, 0)::numeric - coalesce(dn.elevation, 0)::numeric) as elevation_diff,
+               sl.value as survey_length,
+               case when lt.name is null then
+                        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
+                    else lt.name end as name
         from k3_gis_survey_layer_apply as la
-        join k3_gis_survey_job_info jo on la.job_id = jo.uid
-        join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
-        left join k3_gis_survey_layer_apply as un
-        on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
-        left join k3_gis_survey_layer_apply as dn
-        on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
-        left join k3_gis_survey_property_value sl on la.code = sl.code and la.job_id = sl.job_id and property =
-        'survey_length'
-        left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
+                 join k3_gis_survey_job_info jo on la.job_id = jo.uid
+                 join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
+                 left join k3_gis_survey_layer_apply as un
+                           on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
+                 left join k3_gis_survey_layer_apply as dn
+                           on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
+                 left join k3_gis_survey_property_value sl on la.code = sl.code and la.job_id = sl.job_id and property =
+                                                                                                              'survey_length'
+                 left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
         where pit.uid = #{projId,jdbcType=VARCHAR}
-        and jo.disused = 0
-        and (la.apply = 'add' or la.apply = 'update') and la.kind = 'line';
+          and jo.disused = 0
+          and (la.apply = 'add' or la.apply = 'update') and la.kind = 'line';
     </select>
 
     <select id="findAddUpdatePointByJobId" fetchSize="3000" resultMap="Point">
         select la.code, la.job_id, la.layer, la.kind, la.gis, la.apply, la.source, la.elevation, la.no,
-        case when lt.name is null then
-        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
-        else lt.name end as name
+               case when lt.name is null then
+                        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
+                    else lt.name end as name
         from k3_gis_survey_layer_apply la
-        join k3_gis_survey_job_info jo on la.job_id = jo.uid
-        join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
-        left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
+                 join k3_gis_survey_job_info jo on la.job_id = jo.uid
+                 join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
+                 left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
         where jo.uid = #{jobId,jdbcType=VARCHAR}
-        and (la.apply = 'add' or la.apply = 'update') and la.kind = 'point'
+          and (la.apply = 'add' or la.apply = 'update') and la.kind = 'point'
     </select>
 
     <select id="findAddUpdateLineByJobId" fetchSize="3000" resultMap="Line">
         select la.code, la.job_id, la.layer, la.kind, la.apply, la.source, la.up_node, la.down_node,
-        un.no as up_no, dn.no as down_no,
-        case when un.code is not null and dn.code is not null then concat('[[', un.gis, ',', dn.gis, ']]') else la.gis end
-        as gis,
-        abs(coalesce(un.elevation, 0)::numeric - coalesce(dn.elevation, 0)::numeric) as elevation_diff,
-        sl.value as survey_length,
-        case when lt.name is null then
-        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
-        else lt.name end as name
+               un.no as up_no, dn.no as down_no,
+               case when un.code is not null and dn.code is not null then concat('[', un.gis, ',', dn.gis, ']') else la.gis end
+                     as gis,
+               abs(coalesce(un.elevation, 0)::numeric - coalesce(dn.elevation, 0)::numeric) as elevation_diff,
+               sl.value as survey_length,
+               case when lt.name is null then
+                        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
+                    else lt.name end as name
         from k3_gis_survey_layer_apply as la
-        join k3_gis_survey_job_info jo on la.job_id = jo.uid
-        join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
-        left join k3_gis_survey_layer_apply as un
-        on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
-        left join k3_gis_survey_layer_apply as dn
-        on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
-        left join k3_gis_survey_property_value sl on la.code = sl.code and la.job_id = sl.job_id and property =
-        'survey_length'
-        left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
+                 join k3_gis_survey_job_info jo on la.job_id = jo.uid
+                 join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
+                 left join k3_gis_survey_layer_apply as un
+                           on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
+                 left join k3_gis_survey_layer_apply as dn
+                           on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
+                 left join k3_gis_survey_property_value sl on la.code = sl.code and la.job_id = sl.job_id and property =
+                                                                                                              'survey_length'
+                 left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
         where jo.uid = #{jobId,jdbcType=VARCHAR}
-        and (la.apply = 'add' or la.apply = 'update') and la.kind = 'line';
+          and (la.apply = 'add' or la.apply = 'update') and la.kind = 'line';
     </select>
 
     <select id="findAllByJobIdAndKind" fetchSize="3000" resultMap="BaseResultMap">
         select la.code, la.job_id, la.layer, la.kind, la.apply, la.source, la.up_node, la.down_node,la.elevation,
-        la.depth, la.no,
-        case when la.kind = 'line' and un.code is not null and dn.code is not null
-        then concat('[[', un.gis, ',', dn.gis, ']]') else la.gis end as gis,
-        case when lt.name is null then
-        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
-        else lt.name end as name,
-        pv.property as property_property, pv.code as property_code, pv.job_id as property_job_id,
-        pv.value as property_value
+               la.depth, la.no,
+               case when la.kind = 'line' and un.code is not null and dn.code is not null
+                        then concat('[', un.gis, ',', dn.gis, ']') else la.gis end as gis,
+               case when lt.name is null then
+                        (select td.name from k2_type_define td where td.key = la.layer and td.kind = 7)
+                    else lt.name end as name,
+               pv.property as property_property, pv.code as property_code, pv.job_id as property_job_id,
+               pv.value as property_value
         from k3_gis_survey_layer_apply as la
-        join k3_gis_survey_job_info jo on la.job_id = jo.uid
-        join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
-        left join k3_gis_survey_layer_apply as un
-        on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
-        left join k3_gis_survey_layer_apply as dn
-        on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
-        left join k3_gis_survey_property_value pv on la.code = pv.code and la.job_id = pv.job_id
-        left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
+                 join k3_gis_survey_job_info jo on la.job_id = jo.uid
+                 join k3_gis_survey_project_info pit on jo.proj_id = pit.uid
+                 left join k3_gis_survey_layer_apply as un
+                           on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
+                 left join k3_gis_survey_layer_apply as dn
+                           on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
+                 left join k3_gis_survey_property_value pv on la.code = pv.code and la.job_id = pv.job_id
+                 left join k3_gis_metadata_layer_template lt on pit.nature = lt.nature and la.layer = lt.key
         where la.job_id = #{jobId,jdbcType=VARCHAR} and la.kind = #{kind,jdbcType=VARCHAR}
     </select>
 
     <insert id="mergeCopyByJobId">
         insert into k3_gis_survey_layer_apply(code, job_id, layer, kind, gis, apply, source, up_node,
-        down_node,elevation,depth,no)
+                                              down_node,elevation,depth,no)
         select code, job_id, layer, kind, gis, apply, source, up_node,
-        down_node,elevation,depth,no
+               down_node,elevation,depth,no
         from k3_gis_survey_layer_apply_third_copy
         where job_id = #{jobId,jdbcType=VARCHAR}
         order by job_id, code

+ 17 - 18
src/main/resources/mapper/GisSurveyLayerApplyThirdCopyMapper.xml

@@ -109,25 +109,24 @@
 
     <select id="findByJobId" resultMap="BaseResultMap">
         select
-        latc.code, latc.job_id, latc.layer, latc.kind, latc.gis, latc.apply, latc.source, latc.up_node, latc.down_node,
-        latc.elevation, latc.depth, latc.no,
-        pvtc.property as property_property, pvtc.code as property_code, pvtc.job_id as property_job_id,
-        pvtc.value as property_value
+            latc.code, latc.job_id, latc.layer, latc.kind, latc.gis, latc.apply, latc.source, latc.up_node, latc.down_node,
+            latc.elevation, latc.depth, latc.no,
+            pvtc.property as property_property, pvtc.code as property_code, pvtc.job_id as property_job_id,
+            pvtc.value as property_value
         from (
-        select la.code, la.job_id, la.layer, la.kind, la.apply, la.source, la.up_node, la.down_node,
-        la.elevation, la.depth, la.no,
-        case when un.code is not null and dn.code is not null then concat('[[', un.gis, ',', dn.gis, ']]') else la.gis
-        end
-        as gis
-        from k3_gis_survey_layer_apply_third_copy la
-        left join k3_gis_survey_layer_apply_third_copy as un
-        on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
-        left join k3_gis_survey_layer_apply_third_copy as dn
-        on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
-        where la.job_id = #{jobId,jdbcType=VARCHAR}
-        limit #{pageable.pageSize} offset #{pageable.offset}
-        ) latc
-        left join k3_gis_survey_property_value_third_copy pvtc on latc.code = pvtc.code and latc.job_id = pvtc.job_id
+                 select la.code, la.job_id, la.layer, la.kind, la.apply, la.source, la.up_node, la.down_node,
+                        la.elevation, la.depth, la.no,
+                        case when un.code is not null and dn.code is not null then concat('[', un.gis, ',', dn.gis, ']') else la.gis end
+                            as gis
+                 from k3_gis_survey_layer_apply_third_copy la
+                          left join k3_gis_survey_layer_apply_third_copy as un
+                                    on la.up_node = un.code and un.kind = 'point' and la.job_id = un.job_id
+                          left join k3_gis_survey_layer_apply_third_copy as dn
+                                    on la.down_node = dn.code and dn.kind = 'point' and la.job_id = dn.job_id
+                 where la.job_id = #{jobId,jdbcType=VARCHAR}
+                 limit #{pageable.pageSize} offset #{pageable.offset}
+             ) latc
+                 left join k3_gis_survey_property_value_third_copy pvtc on latc.code = pvtc.code and latc.job_id = pvtc.job_id
     </select>
 
     <select id="countByJobId" resultType="java.lang.Long">