浏览代码

副表对象gis字段改为geometry类型

欧阳劲驰 2 月之前
父节点
当前提交
262920e1c4

+ 11 - 4
src/main/java/com/shkpr/service/alambizplugin/components/GisSurveyThirdImporter.java

@@ -27,6 +27,10 @@ import com.shkpr.service.alambizplugin.dto.GisSurveyThirdImportSubtask;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.PrecisionModel;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
 import org.springframework.stereotype.Component;
@@ -37,7 +41,6 @@ import java.io.InputStream;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -60,6 +63,7 @@ public class GisSurveyThirdImporter {
      */
     private final String mStrClassName;
     private final String mBizType;
+    private final GeometryFactory geometryFactory;
     private final GisMetadataLayerTemplateService layerTemplateService;
     private final GisSurveyLayerApplyThirdCopyService gisSurveyLayerApplyThirdCopyService;
     private final DuplicatePointsFinder duplicatePointsFinder;
@@ -70,6 +74,7 @@ public class GisSurveyThirdImporter {
             , DuplicatePointsFinder duplicatePointsFinder, InvalidLinesFinder invalidLinesFinder, InvalidPropertiesFinder invalidPropertiesFinder) {
         mStrClassName = "GisSurveyThirdImporter";
         mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
+        geometryFactory = new GeometryFactory(new PrecisionModel(), 4490);
         this.layerTemplateService = layerTemplateService;
         this.gisSurveyLayerApplyThirdCopyService = gisSurveyLayerApplyThirdCopyService;
         this.duplicatePointsFinder = duplicatePointsFinder;
@@ -383,9 +388,11 @@ public class GisSurveyThirdImporter {
         layerApply.setLayer(layerTemplate.getKey());
         layerApply.setKind(GisMetadataDefine.TYPE_KINE.POINT);
         //解析坐标
-        double[] coordinate = {Double.parseDouble(point.get(GisSurveyImportDefine.POINT.LNG)),
-                Double.parseDouble(point.get(GisSurveyImportDefine.POINT.LAT))};
-        layerApply.setGis(Arrays.toString(coordinate));
+        Point geometry = geometryFactory.createPoint(new Coordinate(
+                Double.parseDouble(point.get(GisSurveyImportDefine.POINT.LNG))
+                , Double.parseDouble(point.get(GisSurveyImportDefine.POINT.LAT))
+        ));
+        layerApply.setGis(geometry);
         //默认值
         layerApply.setApply(GisSurveyImportDefine.DEFAULT_VALUE.APPLY);
         layerApply.setSource(GisSurveyImportDefine.DEFAULT_VALUE.SOURCE);

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

@@ -25,8 +25,37 @@ import java.sql.SQLException;
 @MappedTypes({LineString.class})
 @MappedJdbcTypes(JdbcType.VARCHAR)
 public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
-    GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4490);
-    ObjectMapper objectMapper = new ObjectMapper();
+    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}
@@ -35,7 +64,7 @@ public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
     public void setNonNullParameter(PreparedStatement ps, int i, LineString lineString, JdbcType jdbcType)
             throws SQLException {
         //将 LineString 序列化为 [[x1,y1],[x2,y2]] 字符串
-        if (lineString != null) {
+        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]]", p0.x, p0.y, p1.x, p1.y);
@@ -51,7 +80,7 @@ public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
      */
     @Override
     public LineString getNullableResult(ResultSet rs, String columnName) throws SQLException {
-        return parseString(rs.getString(columnName));
+        return rs.wasNull() ? null : parseLineString(rs.getString(columnName));
     }
 
     /**
@@ -59,7 +88,7 @@ public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
      */
     @Override
     public LineString getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
-        return parseString(rs.getString(columnIndex));
+        return rs.wasNull() ? null : parseLineString(rs.getString(columnIndex));
     }
 
     /**
@@ -67,35 +96,6 @@ public class GeomLineStringTypeHandlePg extends BaseTypeHandler<LineString> {
      */
     @Override
     public LineString getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
-        return parseString(cs.getString(columnIndex));
-    }
-
-    /**
-     * 解析
-     *
-     * @param value 值
-     * @return 线段
-     * @throws SQLException sql异常
-     */
-    private LineString parseString(String value) throws SQLException {
-        //非空校验
-        if (value == null || value.isEmpty()) return null;
-        try {
-            //序列化
-            double[][] coordinates = objectMapper.readValue(value, 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("线段格式无效: " + value);
-        }
-        throw new SQLException("线段格式无效: " + value);
+        return cs.wasNull() ? null : parseLineString(cs.getString(columnIndex));
     }
 }

+ 32 - 24
src/main/java/com/shkpr/service/alambizplugin/dbdao/pgtype/GeomPointTypeHandlePg.java

@@ -1,5 +1,6 @@
 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;
@@ -9,6 +10,7 @@ import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.Point;
 import org.locationtech.jts.geom.PrecisionModel;
 
+import java.io.IOException;
 import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -24,14 +26,42 @@ import java.sql.Types;
 @MappedTypes({Point.class})
 @MappedJdbcTypes(JdbcType.VARCHAR)
 public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
-    GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4490);
+    private static final GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4490);
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 从数据库字符串解析为Point对象
+     *
+     * @param pointStr 值
+     * @return 点
+     * @throws SQLException sql异常
+     */
+    public static Point parsePoint(String pointStr) throws SQLException {
+        //非空校验
+        if (pointStr == null || pointStr.isEmpty()) return null;
+        try {
+            //序列化
+            double[] coordinate = objectMapper.readValue(pointStr, double[].class);
+            //判断格式
+            if (coordinate.length == 2) {
+                //获取值
+                double longitude = coordinate[0];
+                double latitude = coordinate[1];
+                //构建点
+                return factory.createPoint(new Coordinate(longitude, latitude));
+            }
+        } catch (IOException e) {
+            throw new SQLException("点格式无效: " + pointStr);
+        }
+        throw new SQLException("点格式无效: " + pointStr);
+    }
 
     /**
      * 将Java类型Point写入数据库
      */
     @Override
     public void setNonNullParameter(PreparedStatement ps, int i, Point point, JdbcType jdbcType) throws SQLException {
-        if (point != null) {
+        if (point != null && point.getCoordinate() != null) {
             //将 Point 序列化化为 [x,y] 字符串
             String pointStr = String.format("[%f,%f]", point.getX(), point.getY());
             ps.setString(i, pointStr);
@@ -67,26 +97,4 @@ public class GeomPointTypeHandlePg extends BaseTypeHandler<Point> {
         String pointStr = cs.getString(columnIndex);
         return cs.wasNull() ? null : parsePoint(pointStr);
     }
-
-    /**
-     * 从数据库字符串解析为Point对象
-     */
-    private Point parsePoint(String pointStr) {
-        //非空校验
-        if (pointStr == null || pointStr.isEmpty()) return null;
-        //去除方括号和空白字符
-        String cleanStr = pointStr.replace("[", "").replace("]", "");
-        String[] coordinates = cleanStr.split(",");
-        //长度判断
-        if (coordinates.length != 2) throw new IllegalArgumentException("无效的点格式: " + pointStr);
-        try {
-            //获取值
-            double longitude = Double.parseDouble(coordinates[0]);
-            double latitude = Double.parseDouble(coordinates[1]);
-            //构建点
-            return factory.createPoint(new Coordinate(longitude, latitude));
-        } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("无效的坐标格式: " + pointStr, e);
-        }
-    }
 }

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

@@ -0,0 +1,99 @@
+package com.shkpr.service.alambizplugin.dbdao.pgtype;
+
+import com.fasterxml.jackson.databind.JsonNode;
+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.Geometry;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.Point;
+
+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({Geometry.class})
+@MappedJdbcTypes(JdbcType.VARCHAR)
+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]", point.getX(), point.getY());
+                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]]", p0.x, p0.y, p1.x, p1.y);
+                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));
+    }
+
+    /**
+     * 解析
+     *
+     * @param geomStr 值
+     * @return 地理对象
+     * @throws SQLException sql异常
+     */
+    public Geometry parseGeom(String geomStr) throws SQLException {
+        //非空校验
+        if (geomStr == null || geomStr.isEmpty()) return null;
+        try {
+            JsonNode jsonNode = objectMapper.readTree(geomStr);
+            if (jsonNode.isArray() && jsonNode.size() > 0) {
+                //点处理
+                if (jsonNode.get(0).isNumber() && jsonNode.get(1).isNumber()) {
+                    return GeomPointTypeHandlePg.parsePoint(geomStr);
+                }
+                //线处理
+                else if (jsonNode.get(0).isArray()) {
+                    return GeomLineStringTypeHandlePg.parseLineString(geomStr);
+                }
+            }
+
+        } catch (IOException e) {
+            throw new SQLException("地理数据格式无效: " + geomStr);
+        }
+        throw new SQLException("地理数据格式无效: " + geomStr);
+    }
+}

+ 8 - 1
src/main/java/com/shkpr/service/alambizplugin/dto/GisSurveyLayerApplyThirdCopy.java

@@ -1,6 +1,11 @@
 package com.shkpr.service.alambizplugin.dto;
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.shkpr.service.alambizplugin.controllerserializer.GeometryDeserializer;
+import com.shkpr.service.alambizplugin.controllerserializer.GeometrySerializer;
 import lombok.Data;
+import org.locationtech.jts.geom.Geometry;
 
 import java.util.List;
 
@@ -32,7 +37,9 @@ public class GisSurveyLayerApplyThirdCopy {
     /**
      * 坐标值
      */
-    private String gis;
+    @JsonSerialize(using = GeometrySerializer.class)
+    @JsonDeserialize(using = GeometryDeserializer.class)
+    private Geometry gis;
 
     /**
      * 固定操作标记为:add

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

@@ -7,7 +7,8 @@
         <id column="code" jdbcType="VARCHAR" property="code"/>
         <result column="layer" jdbcType="VARCHAR" property="layer"/>
         <result column="kind" jdbcType="VARCHAR" property="kind"/>
-        <result column="gis" jdbcType="VARCHAR" property="gis"/>
+        <result column="gis" jdbcType="VARCHAR" property="gis"
+                typeHandler="com.shkpr.service.alambizplugin.dbdao.pgtype.GeomTypeHandlePg"/>
         <result column="apply" jdbcType="VARCHAR" property="apply"/>
         <result column="source" jdbcType="SMALLINT" property="source"/>
         <result column="up_node" jdbcType="VARCHAR" property="upNode"/>
@@ -72,7 +73,7 @@
                 #{kind,jdbcType=VARCHAR},
             </if>
             <if test="gis != null">
-                #{gis,jdbcType=VARCHAR},
+                #{gis,jdbcType=VARCHAR,typeHandler=com.shkpr.service.alambizplugin.dbdao.pgtype.GeomTypeHandlePg},
             </if>
             <if test="apply != null">
                 #{apply,jdbcType=VARCHAR},