Przeglądaj źródła

生成shp文件及枚举类创建

chenendian 1 miesiąc temu
rodzic
commit
19d0ce5590

+ 39 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/enums/ConvergeTableEnum.java

@@ -0,0 +1,39 @@
+package com.siwei.apply.enums;
+
+/**
+ *  汇交表名枚举
+ */
+public enum ConvergeTableEnum {
+
+    TABLE_0("0", "行政区","gj_xzqh_shp"),
+    TABLE_1("1", "地籍区","djq"),
+    TABLE_2("2", "地籍子区","djzq"),
+    TABLE_3("3", "宗地数据","zd_shp"),
+    TABLE_4("4", "房屋","fw"),
+    TABLE_5("5", "界址点","jzd"),
+    TABLE_6("6", "界址线","jzx"),
+    TABLE_7("7", "房地产权(项目属性) --只是mdb数据","fdcqxm"),
+    TABLE_8("8", "建筑物区分所有权业主共有部分属性结构mdb","fdcq3"),
+    TABLE_9("9", "房地产权(项目内多幢房屋-有数据)属性结构描述mdb","fdcq1");
+
+    private final String index;
+    private final String name;
+    private final String tableName;
+
+    ConvergeTableEnum(String index, String name, String tableName)
+    {
+        this.index = index;
+        this.name = name;
+        this.tableName = tableName;
+    }
+    public String getIndex() {
+        return index;
+    }
+    public String getName() {
+        return name;
+    }
+    public String getTableName() {
+        return tableName;
+    }
+
+}

+ 49 - 7
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/CadastreManageServiceImpl.java

@@ -858,26 +858,68 @@ public class CadastreManageServiceImpl implements CadastreManageService {
     private boolean isSameData(Map<String, Object> map1, Map<String, Object> map2) {
         if (map1 == map2) return true;
         if (map1 == null || map2 == null) return false;
-        List<String> compareFields = new ArrayList<>(map1.keySet());
-        for (String field : compareFields) {
+
+        // 比较两个map的交集字段(排除valid_flag)
+        Set<String> keys1 = new HashSet<>(map1.keySet());
+        Set<String> keys2 = new HashSet<>(map2.keySet());
+        keys1.retainAll(keys2); // 取交集
+        if (keys1.isEmpty()) return false;
+
+        for (String field : keys1) {
+            if ("valid_flag".equalsIgnoreCase(field)) {
+                continue; // 忽略版本标识
+            }
             Object val1 = map1.get(field);
             Object val2 = map2.get(field);
 
             if (val1 == null && val2 == null) continue;
             if (val1 == null || val2 == null) return false;
 
-            // 处理数值类型的比较(numeric/decimal在Java中可能是BigDecimal)
+            // 特殊处理geom字段:以字符串比较,去掉空白
+            if ("geom".equalsIgnoreCase(field)) {
+                String s1 = String.valueOf(val1).trim();
+                String s2 = String.valueOf(val2).trim();
+                if (!s1.equals(s2)) {
+                    return false;
+                } else {
+                    continue;
+                }
+            }
+
+            // 数值类型比较
             if (val1 instanceof Number && val2 instanceof Number) {
                 if (Double.compare(((Number) val1).doubleValue(), ((Number) val2).doubleValue()) != 0) {
                     return false;
                 }
-            } else if (!val1.equals(val2)) {
+                continue;
+            }
+
+            // 尝试将字符串数字与数字类型做比较(例如数据库返回Integer/String混合)
+            if (val1 instanceof Number && val2 instanceof String) {
+                try {
+                    double d2 = Double.parseDouble(((String) val2).trim());
+                    if (Double.compare(((Number) val1).doubleValue(), d2) != 0) return false;
+                    else continue;
+                } catch (Exception ignored) {
+                    // fallthrough to string compare
+                }
+            }
+            if (val2 instanceof Number && val1 instanceof String) {
+                try {
+                    double d1 = Double.parseDouble(((String) val1).trim());
+                    if (Double.compare(((Number) val2).doubleValue(), d1) != 0) return false;
+                    else continue;
+                } catch (Exception ignored) {
+                    // fallthrough to string compare
+                }
+            }
+
+            // 默认字符串比较(去除首尾空白)
+            if (!String.valueOf(val1).trim().equals(String.valueOf(val2).trim())) {
                 return false;
             }
         }
-        Object geom1 = map1.get("geom");
-        Object geom2 = map2.get("geom");
-        if (geom1 != null && geom2 != null && !geom1.equals(geom2)) return false;
+
         return true;
     }
 

+ 8 - 8
siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/CadastreFileMapper.xml

@@ -206,7 +206,7 @@
     <select id="countByValidFlag" resultType="int">
         SELECT COUNT(*)
         FROM vector.${tableName}
-        WHERE valid_flag = ${validFlag}
+        WHERE valid_flag = #{validFlag}
     </select>
 
     <update id="addValidFlagColumn">
@@ -266,20 +266,20 @@
     </select>
 
     <update id="updateValidFlag">
-        UPDATE vector.${tableName}  SET  valid_flag  = ${validFlag} WHERE 1=1
+        UPDATE vector.${tableName}  SET  valid_flag  = #{validFlag} WHERE 1=1
         <if test="oldValidFlag != null and oldValidFlag != ''">
-            and valid_flag= ${oldValidFlag}
+            and valid_flag= #{oldValidFlag}
         </if>
     </update>
 
     <delete id="deleteByValidFlag">
-        DELETE  FROM  vector.${tableName}   WHERE valid_flag = ${validFlag}
+        DELETE  FROM  vector.${tableName}   WHERE valid_flag = #{validFlag}
     </delete>
 
     <select id="selectTableData"   resultType="Map">
         SELECT *
         FROM vector.${tableName}
-        WHERE valid_flag = ${validFlag}
+        WHERE valid_flag = #{validFlag}
     </select>
 
     <select id="selectTableDataByCondition"   resultType="Map">
@@ -287,7 +287,7 @@
         FROM vector.${tableName}
         WHERE 1=1
         <if test="validFlag != null and validFlag != ''">
-            and valid_flag = ${validFlag}
+            and valid_flag = #{validFlag}
         </if>
 
         <if test="bsm != null and bsm != ''">
@@ -302,7 +302,7 @@
 
     <select id="selectExistsSameData"   resultType="Map">
         SELECT * FROM vector.${tableName}
-        WHERE valid_flag = ${validFlag}
+        WHERE valid_flag = #{validFlag}
         <if test="data.rwbsm != null and data.rwbsm!=''  ">
             AND  rwbsm = #{data.rwbsm}
         </if>
@@ -360,7 +360,7 @@
         FROM  vector.${tableName} inTbale
         where public.st_intersects(inTbale.geom,public.st_geomfromewkt(#{ewkt}))
           <if test="validFlag != null and validFlag != ''">
-            and valid_flag = ${validFlag}
+            and valid_flag = #{validFlag}
         </if>
     </select>
 

+ 3 - 1
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/controller/file/SpatialFilesDbController.java

@@ -198,7 +198,9 @@ public class SpatialFilesDbController extends BaseController {
     @PostMapping("/getShpFile")
     public void dealShpFileDownLoad(HttpServletResponse response, String  ywh) {
         try {
-            iSpatialFilesDbService.dealShpFileDownLoad(response,ywh);
+            //iSpatialFilesDbService.dealShpFileDownLoad(response,ywh);
+            String filePath = "C:\\Users\\Administrator\\Desktop\\08\\shp_create\\zd_shp";
+            iSpatialFilesDbService.writeShapefileByTable("zd_shp",filePath,"zd_shp");
         } catch (Exception e) {
             e.printStackTrace();
         }

+ 6 - 3
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/mapper/file/TGeomDbDetailsMapper.java

@@ -101,7 +101,10 @@ public interface TGeomDbDetailsMapper
 
     List<Map<String,Object>> selectTableDjzq(@Param("ysdm") String ysdm,@Param("validFlag") Integer validFlag);
 
-
-
-
+    /**
+     * 查询表字段信息
+     * @param tableName 表名
+     * @return 字段列表
+     */
+    List<Map<String, Object>> selectTableColumns(@Param("tableName") String tableName);
 }

+ 4 - 0
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/service/file/ISpatialFilesDbService.java

@@ -33,4 +33,8 @@ public interface ISpatialFilesDbService {
     void  dealShpFileDownLoad(HttpServletResponse response, String ysdm );
 
 
+    void writeShapefileByTable(String tableName, String filePath, String fileName) throws Exception ;
+
+
+
 }

+ 167 - 0
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/service/file/impl/SpatialFilesDbServiceImpl.java

@@ -789,6 +789,173 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
     }
 
 
+    /**
+     *  动态传入表名称,根据表结构生成 SHP 文件
+     * @param tableName 表名
+     * @param filePath 生成路径
+     * @param fileName 文件名
+     * @throws Exception
+     */
+    @Override
+    public void writeShapefileByTable(String tableName, String filePath, String fileName) throws Exception {
+        // 1. 获取表字段信息
+        List<Map<String, Object>> columns = tGeomDbDetailsMapper.selectTableColumns(tableName);
+        if (columns == null || columns.isEmpty()) {
+            throw new RuntimeException("无法获取表字段信息: " + tableName);
+        }
+
+        // 2. 获取数据
+        List<Map<String, Object>> dataList = tGeomDbDetailsMapper.selectTableDataAndGeom(tableName);
+        if (dataList == null || dataList.isEmpty()) {
+            return;
+        }
+
+        // 3. 定义要素类型 (SimpleFeatureType)
+        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
+        typeBuilder.setName(tableName);
+        
+        // 设置坐标系 CGCS2000 (EPSG:4490)
+        CoordinateReferenceSystem crs = CRS.decode("EPSG:4490");
+        typeBuilder.setCRS(crs);
+
+        // 存储字段名和对应的类型,用于后续数据读取
+        Map<String, String> columnTypeMap = new LinkedHashMap<>();
+
+        // 添加几何字段 (固定为 the_geom)
+        typeBuilder.add("the_geom", MultiPolygon.class);
+
+        for (Map<String, Object> col : columns) {
+            String colName = (String) col.get("column_name");
+            String dataType = (String) col.get("data_type");
+
+            if ("geom".equalsIgnoreCase(colName)) {
+                continue; // 已经处理过几何字段
+            }
+
+            // SHP 字段名长度限制为 10 字符
+            String shpColName = colName.length() > 10 ? colName.substring(0, 10) : colName;
+            Class<?> javaType = mapDatabaseTypeToJavaClass(dataType);
+            typeBuilder.add(shpColName, javaType);
+            columnTypeMap.put(colName, shpColName);
+        }
+
+        SimpleFeatureType featureType = typeBuilder.buildFeatureType();
+
+        // 4. 创建要素集合
+        List<SimpleFeature> features = new ArrayList<>();
+        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
+        WKTReader wktReader = new WKTReader();
+        WKBReader wkbReader = new WKBReader();
+
+        for (Map<String, Object> data : dataList) {
+            // 获取几何数据,优先从 geom2 (EWKT) 获取
+            Object geomObj = data.get("geom2");
+            if (geomObj == null) {
+                geomObj = data.get("geom");
+            }
+            if (geomObj == null) continue;
+
+            Geometry geometry = null;
+            if (geomObj instanceof Geometry) {
+                geometry = (Geometry) geomObj;
+            } else {
+                String geomStr = geomObj.toString();
+                if (StringUtils.isEmpty(geomStr)) continue;
+
+                try {
+                    if (geomStr.startsWith("01") || geomStr.startsWith("00")) {
+                        geometry = wkbReader.read(WKBReader.hexToBytes(geomStr));
+                    } else {
+                        String wkt = geomStr;
+                        if (wkt.contains(";")) {
+                            wkt = wkt.split(";")[1];
+                        }
+                        geometry = wktReader.read(wkt);
+                    }
+                } catch (ParseException e) {
+                    log.warn("无法解析几何数据: {}, 错误: {}", geomStr, e.getMessage());
+                    continue;
+                }
+            }
+
+            if (geometry != null) {
+                // 强制转为 MultiPolygon
+                if (geometry instanceof org.locationtech.jts.geom.Polygon) {
+                    geometry = geometry.getFactory().createMultiPolygon(new org.locationtech.jts.geom.Polygon[]{(org.locationtech.jts.geom.Polygon) geometry});
+                }
+                
+                featureBuilder.add(geometry);
+
+                // 添加属性字段
+                for (String originColName : columnTypeMap.keySet()) {
+                    featureBuilder.add(data.get(originColName));
+                }
+
+                features.add(featureBuilder.buildFeature(null));
+            }
+        }
+
+        // 5. 写入文件
+        File shpFile = new File(filePath + File.separator + fileName + ".shp");
+        ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
+        Map<String, Serializable> params = new HashMap<>();
+        params.put("url", shpFile.toURI().toURL());
+        params.put("create spatial index", Boolean.TRUE);
+
+        ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
+        dataStore.setCharset(Charset.forName("UTF-8"));
+        dataStore.createSchema(featureType);
+
+        Transaction transaction = new DefaultTransaction("create");
+        String typeName = dataStore.getTypeNames()[0];
+        SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
+
+        if (featureSource instanceof SimpleFeatureStore) {
+            SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
+            SimpleFeatureCollection collection = new ListFeatureCollection(featureType, features);
+            featureStore.setTransaction(transaction);
+            try {
+                featureStore.addFeatures(collection);
+                transaction.commit();
+            } catch (Exception e) {
+                transaction.rollback();
+                throw e;
+            } finally {
+                transaction.close();
+            }
+        }
+        dataStore.dispose();
+
+        // 6. 生成 .cpg 文件
+        File cpgFile = new File(filePath + File.separator + fileName + ".cpg");
+        try (PrintWriter writer = new PrintWriter(cpgFile)) {
+            writer.print("UTF-8");
+        }
+    }
+
+    private Class<?> mapDatabaseTypeToJavaClass(String dataType) {
+        if (dataType == null) return String.class;
+        dataType = dataType.toLowerCase();
+        if (dataType.contains("char") || dataType.contains("text")) {
+            return String.class;
+        } else if (dataType.contains("int")) {
+            return Integer.class;
+        } else if (dataType.contains("numeric") || dataType.contains("decimal") || dataType.contains("double") || dataType.contains("float") || dataType.contains("real")) {
+            return Double.class;
+        } else if (dataType.contains("date") || dataType.contains("time")) {
+            return java.util.Date.class;
+        } else if (dataType.contains("boolean")) {
+            return Boolean.class;
+        }
+        return String.class;
+    }
+
+
+
+
+
+
+
 
 
 }

+ 6 - 1
siwei-modules/siwei-spatial/src/main/resources/mapper/postgresql/spatial/file/TGeomDbDetailsMapper.xml

@@ -413,5 +413,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LIMIT  1000
     </select>
 
-
+    <select id="selectTableColumns" resultType="Map">
+        SELECT column_name, data_type 
+        FROM information_schema.columns 
+        WHERE table_schema = 'vector' 
+        AND table_name = #{tableName}
+    </select>
 </mapper>