1
0
فهرست منبع

数据上传修改

gushoubang 2 ماه پیش
والد
کامیت
bbb5d9ade6

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

@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -37,8 +38,8 @@ public class SpatialFilesDbController extends BaseController {
     private ITGeomDbService itGeomDbService;
 
     @PostMapping("/read/shp")
-    @InnerAuth
-    public R<TGeomDb> readShp(String shpFileName, String shpFilePath, String fromRoute) {
+    // @InnerAuth
+    public R<TGeomDb> readShp(String shpFileName, String shpFilePath, String fromRoute) throws IOException {
         return R.ok(iSpatialFilesDbService.readShpFile(shpFileName, shpFilePath, fromRoute));
     }
 
@@ -50,7 +51,7 @@ public class SpatialFilesDbController extends BaseController {
 
     @PostMapping("/read/geom")
     @InnerAuth
-    public R<TGeomDb> readWkt(String shpFileName, String geom, String fromRoute, String fromType) {
+    public R<TGeomDb> readWkt(String shpFileName, String geom, String fromRoute, String fromType) throws IOException {
         if (StringUtils.isEmpty(fromType)) {
             return R.fail(-1, "执行失败,空间类型为空");
         }

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

@@ -2,8 +2,11 @@ package com.siwei.spatial.service.file;
 
 import com.siwei.spatial.api.domain.file.TGeomDb;
 
+import java.io.IOException;
+
 public interface ISpatialFilesDbService {
 
-    TGeomDb readShpFile(String shpFileName, String shpFilePath, String fromRoute);
+    TGeomDb readShpFile(String shpFileName, String shpFilePath, String fromRoute) throws IOException;
+
     TGeomDb readGeom(String shpFileName, String geom, String fromRoute);
 }

+ 30 - 18
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/service/file/impl/SpatialFilesDbServiceImpl.java

@@ -8,6 +8,7 @@ import com.siwei.spatial.api.domain.file.TGeomDbDetails;
 import com.siwei.spatial.service.file.ISpatialFilesDbService;
 import com.siwei.spatial.service.file.ITGeomDbDetailsService;
 import com.siwei.spatial.service.file.ITGeomDbService;
+import com.siwei.spatial.utils.FileUtils;
 import org.geotools.data.FeatureSource;
 import org.geotools.data.shapefile.ShapefileDataStore;
 import org.geotools.data.simple.SimpleFeatureCollection;
@@ -67,26 +68,37 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public TGeomDb readShpFile(String shpFileName, String shpFilePath, String fromRoute) {
+    public TGeomDb readShpFile(String shpFileName, String shpFilePath, String fromRoute) throws IOException {
         if (StringUtils.isEmpty(shpFilePath)) {
             log.error("读取SHP文件路径失败");
             return null;
         }
-        String path = shpFilePath.substring(0, shpFilePath.length() - 4);
-        File shpFile = new File(localFilePath + path + ".shp");
-        File dbfFile = new File(localFilePath + path + ".dbf");
-        File shxFile = new File(localFilePath + path + ".shx");
+        String shpDir = shpFilePath.substring(0, shpFilePath.lastIndexOf(".zip"));
+        FileUtils.unzipAutoCharset(shpFilePath, shpDir);
+        List<Map<String, String>> shpFiles = FileUtils.readShpFiles(shpDir);
+
+        if (shpFiles.isEmpty()) {
+            log.error("读取SHP文件失败");
+            return null;
+        }
+        // TODO 目前只用了一个.shp文件,后续如果有多个shp文件,可能需要处理
+        Map<String, String> shpFileMap = shpFiles.get(0);
+        File shpFile = new File(shpFileMap.get("shp"));
+        File dbfFile = new File(shpFileMap.get("dbf"));
+        File shxFile = new File(shpFileMap.get("shx"));
+        File prjFile = new File(shpFileMap.get("prj"));
         if (!shpFile.exists() || !dbfFile.exists() || !shxFile.exists()) {
             log.error("读取SHP文件缺失");
             return null;
         }
+
         if (StringUtils.isEmpty(shpFileName)) {
             shpFileName = shpFile.getName().substring(0, shpFileName.length() - 4);
         }
         TGeomDb dto = new TGeomDb();
         dto.setId(IdUtils.fastSimpleUUID());
         dto.setName(shpFileName);
-        dto.setShppath(path + ".shp");
+        dto.setShppath(shpFileMap.get("shp"));
         dto.setFiletype("2");
         dto.setFromroute(fromRoute);
 
@@ -165,25 +177,25 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
 
 
     private String convertShpFieldType2H2GISOrPG(Class value) throws Exception {
-        if (value == String.class) {//文本
+        if (value == String.class) {// 文本
             return "varchar";
         }
-        if (value == Integer.class) {//短整型
+        if (value == Integer.class) {// 短整型
             return "int";
         }
-        if (value == Long.class) {//长整型
+        if (value == Long.class) {// 长整型
             return "bigint";
         }
-        if (value == Double.class || value == Float.class) {//浮点型 双精度 保留精度,比如在金币上运算更安全
+        if (value == Double.class || value == Float.class) {// 浮点型 双精度 保留精度,比如在金币上运算更安全
             return "numeric";
         }
         if (value == Date.class) {
-            return "timestamp without time zone";//日期, 使用包含时区的来处理
+            return "timestamp without time zone";// 日期, 使用包含时区的来处理
         }
         if (Geometry.class.isAssignableFrom(value)) {
             return "public.geometry";
         }
-        //除了上述,真不知道还会有啥了。除非arcgis的shp又增加了新类型?!那无能为力了,抛出异常吧
+        // 除了上述,真不知道还会有啥了。除非arcgis的shp又增加了新类型?!那无能为力了,抛出异常吧
         throw new Exception("不支持的类型!" + value.getName());
     }
 
@@ -206,7 +218,7 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
         try {
             shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL());
             shapefileDataStore.setCharset(Charset.forName(readShpBM(shpFile.getAbsolutePath())));
-            //这个typeNamae不传递,默认是文件名称
+            // 这个typeNamae不传递,默认是文件名称
             FeatureSource featuresource = shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]);
 
             // 获取 srid
@@ -216,7 +228,7 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
                 throw new Exception("SHP文件坐标系未查到");
             }
 
-            //获取当前数据的geometry类型(点、线、面)
+            // 获取当前数据的geometry类型(点、线、面)
 //            GeometryType geometryType = featuresource.getSchema().getGeometryDescriptor().getType();
 //            System.out.println(geometryType.getName());
 //            if ("Polygon".equals(geometryType.get) {
@@ -224,11 +236,11 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
 //            } else if ("MultiPolygon".equals(geomTypeData.getGeometryType())) {
 //                tb.add("the_geom", MultiPolygon.class);
 //            }
-            //读取要素
+            // 读取要素
             SimpleFeatureCollection simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
-            //获取当前矢量数据有哪些属性字段值
+            // 获取当前矢量数据有哪些属性字段值
 
-            //获取字段列表
+            // 获取字段列表
             List<String> attributesList = new ArrayList<>();
             List<Map<String, String>> tableCommsList = new ArrayList<>();
             List<AttributeDescriptor> attributes = simpleFeatureCollection.getSchema().getAttributeDescriptors();
@@ -243,7 +255,7 @@ public class SpatialFilesDbServiceImpl implements ISpatialFilesDbService {
 //                }
             }
 
-            //获取属性
+            // 获取属性
             simpleFeatureIterator = simpleFeatureCollection.features();
             while (simpleFeatureIterator.hasNext()) {
                 Map<String, Object> pg_rk = new LinkedHashMap<>();

+ 105 - 0
siwei-modules/siwei-spatial/src/main/java/com/siwei/spatial/utils/FileUtils.java

@@ -0,0 +1,105 @@
+package com.siwei.spatial.utils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * 文件工具类
+ */
+public class FileUtils {
+    /**
+     * 解压缩zip文件到指定目录
+     *
+     * @param zipFilePath
+     * @param destDir
+     * @throws IOException
+     */
+    public static void unzipAutoCharset(String zipFilePath, String destDir) throws IOException {
+        try {
+            // 先尝试 UTF-8
+            unzipWithCharset(zipFilePath, destDir, Charset.forName("UTF-8"));
+        } catch (IllegalArgumentException | java.nio.charset.MalformedInputException e) {
+            // 如果失败,切换到 GBK
+            unzipWithCharset(zipFilePath, destDir, Charset.forName("GBK"));
+        }
+    }
+
+    /**
+     * 解压缩zip文件到指定目录,使用指定字符集
+     *
+     * @param zipFilePath
+     * @param destDir
+     * @param charset
+     * @throws IOException
+     */
+    private static void unzipWithCharset(String zipFilePath, String destDir, Charset charset) throws IOException {
+        File dir = new File(destDir);
+        if (!dir.exists()) dir.mkdirs();
+
+        try (ZipFile zipFile = new ZipFile(zipFilePath, charset)) {
+            Enumeration<? extends ZipEntry> entries = zipFile.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = entries.nextElement();
+                File newFile = new File(destDir, entry.getName());
+                if (entry.isDirectory()) {
+                    newFile.mkdirs();
+                } else {
+                    new File(newFile.getParent()).mkdirs();
+                    try (InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(newFile)) {
+                        byte[] buffer = new byte[1024];
+                        int len;
+                        while ((len = is.read(buffer)) > 0) {
+                            fos.write(buffer, 0, len);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 读取文件夹中及子文件夹中的所有shp相关文件(.shp,.dbf,.prj,.qix,.shx),返回map结构,后缀名为key,文件路径为value
+     *
+     * @param dirPath 文件夹路径
+     */
+    public static List<Map<String, String>> readShpFiles(String dirPath) {
+        File dir = new File(dirPath);
+        if (!dir.exists() || !dir.isDirectory()) {
+            throw new IllegalArgumentException("Provided path is not a valid directory: " + dirPath);
+        }
+        Map<String, Map<String, String>> groupedFiles = new HashMap<>();
+        readShpFilesRecursively(dir, groupedFiles);
+        return new ArrayList<>(groupedFiles.values());
+    }
+
+    /**
+     * 递归读取目录中的shp相关文件,并将它们按文件名分组
+     *
+     * @param dir
+     * @param groupedFiles
+     */
+    private static void readShpFilesRecursively(File dir, Map<String, Map<String, String>> groupedFiles) {
+        File[] files = dir.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    readShpFilesRecursively(file, groupedFiles);
+                } else {
+                    String fileName = file.getName();
+                    String lowerName = fileName.toLowerCase();
+                    if (lowerName.endsWith(".shp") || lowerName.endsWith(".dbf") || lowerName.endsWith(".prj") || lowerName.endsWith(".qix") || lowerName.endsWith(".shx")) {
+                        String baseName = fileName.substring(0, fileName.lastIndexOf('.'));
+                        String ext = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
+                        groupedFiles.computeIfAbsent(baseName, k -> new HashMap<>()).put(ext, file.getAbsolutePath());
+                    }
+                }
+            }
+        }
+    }
+}