Pārlūkot izejas kodu

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

欧阳劲驰 1 mēnesi atpakaļ
vecāks
revīzija
43011de082

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

@@ -11,7 +11,10 @@ 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;
@@ -75,7 +78,7 @@ public class GeomUtil {
         //上节点判断
         if (Objects.equals(point.getCode(), line.getUpNode())) {
             //线坐标
-            Coordinate lineCcoordinate = line.getGis().getCoordinateN(0);
+            Coordinate lineCcoordinate = line.getGis().getCoordinates()[0];
             //点坐标
             Coordinate pointCoordinate = point.getGis().getCoordinate();
             //比较x和y
@@ -86,7 +89,7 @@ public class GeomUtil {
         //下节点判断
         if (Objects.equals(point.getCode(), line.getDownNode())) {
             //线坐标
-            Coordinate lineCcoordinate = line.getGis().getCoordinateN(line.getGis().getCoordinates().length - 1);
+            Coordinate lineCcoordinate = line.getGis().getCoordinates()[line.getGis().getCoordinates().length - 1];
             //点坐标
             Coordinate pointCoordinate = point.getGis().getCoordinate();
             //比较x和y
@@ -116,6 +119,105 @@ 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  圆心

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

@@ -39,6 +39,8 @@ 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;
@@ -427,8 +429,8 @@ public class GisSurveyThirdImporter {
 
         //采集元素象集合
         List<GisSurveyLayerApplyThirdCopy> result = new ArrayList<>();
-        //点映射,用于线写入上下游节点
-        Map<String, String> pointNoMapping = new HashMap<>();
+        //点映射,用于线写入上下游节点
+        Map<String, GisSurveyLayerApplyThirdCopy> pointMapping = new HashMap<>();
         //格式化点
         for (Map<String, String> point : points) {
             //获取模版
@@ -436,19 +438,25 @@ public class GisSurveyThirdImporter {
             //解码点对象
             GisSurveyLayerApplyThirdCopy layerApply = decodePointToLayerApply(point, layerTemplate, params);
             //存入点号
-            pointNoMapping.put(layerApply.getNo(), layerApply.getCode());
+            pointMapping.put(layerApply.getNo(), layerApply);
 
             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, pointNoMapping);
+            GisSurveyLayerApplyThirdCopy layerApply = decodeLineToLayerApply(line, layerTemplate, params, pointMapping);
 
             result.add(layerApply);
         }
+        //清除点映射和线缓存
+        pointMapping.clear();
+        lines.clear();
 
         long end = System.currentTimeMillis();
         LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
@@ -548,13 +556,14 @@ public class GisSurveyThirdImporter {
     /**
      * 解码线数据到采集元素对象
      *
-     * @param line           线数据
-     * @param layerTemplate  图层模版
-     * @param params         导入参数
-     * @param pointNoMapping 点号映射
+     * @param line          线数据
+     * @param layerTemplate 图层模版
+     * @param params        导入参数
+     * @param pointMapping  点号映射
      * @return 采集元素拷贝对象
      */
-    private GisSurveyLayerApplyThirdCopy decodeLineToLayerApply(Map<String, String> line, GisMetadataLayerTemplate layerTemplate, GisSurveyThirdImportParams params, Map<String, String> pointNoMapping) {
+    private GisSurveyLayerApplyThirdCopy decodeLineToLayerApply(Map<String, String> line, GisMetadataLayerTemplate layerTemplate
+            , GisSurveyThirdImportParams params, Map<String, GisSurveyLayerApplyThirdCopy> pointMapping) {
         GisSurveyLayerApplyThirdCopy layerApply = new GisSurveyLayerApplyThirdCopy();
         //必填项
         layerApply.setJobId(params.getJobId());
@@ -564,14 +573,26 @@ 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);
-        if (StringUtils.isNotBlank(upNoStr)) {
-            layerApply.setUpNode(pointNoMapping.get(upNoStr));
-        }
+        GisSurveyLayerApplyThirdCopy upNo = StringUtils.isNotBlank(upNoStr) ? pointMapping.get(upNoStr) : null;
+        if (upNo != null) layerApply.setUpNode(upNo.getCode());
+        //下游节点
         String downNoStr = ThirdImportTemplateUtils.getValue(line, layerTemplate, GisSurveyExcelDefine.TEMPLATE.DOWN_NO);
-        if (StringUtils.isNotBlank(downNoStr)) {
-            layerApply.setDownNode(pointNoMapping.get(downNoStr));
+        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);
         }
         //遍历属性模版
         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.LineString;
+import org.locationtech.jts.geom.MultiLineString;
 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;
-            LineString line = layerApplyLine.getGis();
+            MultiLineString 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.LineString;
+import org.locationtech.jts.geom.MultiLineString;
 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;
-            LineString line = layerApplyLine.getGis();
+            MultiLineString 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().getCoordinateN(0);
-        Coordinate b = line1.getGis().getCoordinateN(1);
-        Coordinate c = line2.getGis().getCoordinateN(0);
-        Coordinate d = line2.getGis().getCoordinateN(1);
+        Coordinate a = line1.getGis().getCoordinates()[0];
+        Coordinate b = line1.getGis().getCoordinates()[1];
+        Coordinate c = line2.getGis().getCoordinates()[0];
+        Coordinate d = line2.getGis().getCoordinates()[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().getCoordinateN(0);
-        Coordinate b = line1.getGis().getCoordinateN(1);
-        Coordinate c = line2.getGis().getCoordinateN(0);
-        Coordinate d = line2.getGis().getCoordinateN(1);
+        Coordinate a = line1.getGis().getCoordinates()[0];
+        Coordinate b = line1.getGis().getCoordinates()[1];
+        Coordinate c = line2.getGis().getCoordinates()[0];
+        Coordinate d = line2.getGis().getCoordinates()[1];
         //点数量判断
         if (a == null || b == null || c == null || d == null) return false;
         //检查C和D是否在AB的直线上(叉积为0,则方向一致)

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

@@ -1,107 +0,0 @@
-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));
-    }
-}

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

@@ -0,0 +1,109 @@
+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));
+    }
+}

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

@@ -1,6 +1,7 @@
 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;
@@ -11,7 +12,6 @@ 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,19 +37,18 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
      * @return 点
      * @throws SQLException sql异常
      */
-    public static Point parsePoint(String pointStr) throws SQLException {
+    public static Point parseString(String pointStr) throws SQLException {
         //非空校验
         if (pointStr == null || pointStr.isEmpty()) return null;
         try {
             //序列化
-            double[] coordinate = objectMapper.readValue(pointStr, double[].class);
+            double[] array = objectMapper.readValue(pointStr, double[].class);
             //判断格式
-            if (coordinate.length == 2) {
-                //获取值
-                double longitude = coordinate[0];
-                double latitude = coordinate[1];
+            if (array.length == 2) {
+                //转坐标
+                Coordinate coordinate = GeomUtil.ofArray(array);
                 //构建点
-                return factory.createPoint(new Coordinate(longitude, latitude));
+                return factory.createPoint(coordinate);
             }
         } catch (IOException e) {
             throw new SQLException("点格式无效: " + pointStr);
@@ -58,21 +57,42 @@ 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) {
-            //将 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);
+            //将点序列化化为字符串
+            String pointStr = toString(point);
+            if (pointStr != null) {
+                ps.setString(i, pointStr);
+                return;
+            }
         }
+        //处理空值
+        ps.setNull(i, Types.VARCHAR);
     }
 
     /**
@@ -81,7 +101,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 : parsePoint(pointStr);
+        return rs.wasNull() ? null : parseString(pointStr);
     }
 
     /**
@@ -90,7 +110,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 : parsePoint(pointStr);
+        return rs.wasNull() ? null : parseString(pointStr);
     }
 
     /**
@@ -99,6 +119,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 : parsePoint(pointStr);
+        return cs.wasNull() ? null : parseString(pointStr);
     }
 }

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

@@ -6,13 +6,11 @@ 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.LineString;
+import org.locationtech.jts.geom.MultiLineString;
 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;
@@ -29,54 +27,6 @@ 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));
-    }
-
     /**
      * 解析
      *
@@ -84,7 +34,7 @@ public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
      * @return 地理对象
      * @throws SQLException sql异常
      */
-    public Geometry parseGeom(String geomStr) throws SQLException {
+    public static Geometry parseGeom(String geomStr) throws SQLException {
         //非空校验
         if (geomStr == null || geomStr.isEmpty()) return null;
         try {
@@ -92,11 +42,11 @@ public class GeomTypeHandlePg extends BaseTypeHandler<Geometry> {
             if (jsonNode.isArray() && jsonNode.size() > 0) {
                 //点处理
                 if (jsonNode.get(0).isNumber() && jsonNode.get(1).isNumber()) {
-                    return GeomPointTypeHandlePg.parsePoint(geomStr);
+                    return GeomPointTypeHandlePg.parseString(geomStr);
                 }
                 //线处理
                 else if (jsonNode.get(0).isArray()) {
-                    return GeomLineStringTypeHandlePg.parseLineString(geomStr);
+                    return GeomMultiLineStringTypeHandlePg.parseString(geomStr);
                 }
             }
 
@@ -105,4 +55,54 @@ 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.LineString;
+import org.locationtech.jts.geom.MultiLineString;
 
 /**
  * 采集元素处理申请线
@@ -34,7 +34,7 @@ public class GisSurveyLayerApplyLine {
     /**
      * 坐标值
      */
-    private LineString gis;
+    private MultiLineString gis;
     /**
      * 操作标记:add/update/delete
      */

+ 4 - 4
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.GeomLineStringTypeHandlePg"/>
+                typeHandler="com.shkpr.service.alambizplugin.dbdao.pgtype.GeomMultiLineStringTypeHandlePg"/>
         <result column="apply" jdbcType="VARCHAR" property="apply"/>
         <result column="source" jdbcType="SMALLINT" property="source"/>
         <result column="up_node" jdbcType="VARCHAR" property="upNode"/>
@@ -78,7 +78,7 @@
     <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
+        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,
@@ -116,7 +116,7 @@
     <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
+        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,
@@ -141,7 +141,7 @@
         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,
+        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,

+ 2 - 1
src/main/resources/mapper/GisSurveyLayerApplyThirdCopyMapper.xml

@@ -116,7 +116,8 @@
         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
+        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