Parcourir la source

第三方导出shapeFile,增加按模版导出元素属性至shapeFile属性

欧阳劲驰 il y a 1 mois
Parent
commit
619045155f

+ 20 - 18
src/main/java/com/shkpr/service/alambizplugin/commtools/ShapeUtils.java

@@ -1,17 +1,17 @@
 package com.shkpr.service.alambizplugin.commtools;
 
-import com.shkpr.service.alambizplugin.constants.GisTypeEnum;
+import com.shkpr.service.alambizplugin.constants.GisSurveyExcelDefine;
 import org.geotools.data.Transaction;
 import org.geotools.data.collection.ListFeatureCollection;
 import org.geotools.data.shapefile.ShapefileDataStore;
 import org.geotools.data.shapefile.ShapefileDataStoreFactory;
 import org.geotools.data.simple.SimpleFeatureStore;
 import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.locationtech.jts.geom.Geometry;
 import org.opengis.feature.simple.SimpleFeatureType;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
@@ -31,38 +31,39 @@ public class ShapeUtils {
     /**
      * 输出shape文件
      *
-     * @param geometryData  地理对象数据(key为gis类型)
+     * @param datas         数据
      * @param directoryPath 文件夹路径
      * @throws IOException io异常
      */
-    public static void writeShape(Map<String, List<Geometry>> geometryData, Path directoryPath) throws IOException {
-        for (Map.Entry<String, List<Geometry>> entry : geometryData.entrySet()) {
-            String key = entry.getKey();
-            List<Geometry> data = entry.getValue();
+    public static void writeShape(Map<SimpleFeatureType, List<Map<String, Object>>> datas, Path directoryPath) throws IOException {
+        for (Map.Entry<SimpleFeatureType, List<Map<String, Object>>> entry : datas.entrySet()) {
+            final SimpleFeatureType KEY = entry.getKey();
+            List<Map<String, Object>> value = entry.getValue();
 
-            GisTypeEnum gisTypeEnum = GisTypeEnum.get(key);
-            if (gisTypeEnum != null) writeShape(data, Paths.get(directoryPath + "/" + key + ".shp"), gisTypeEnum);
+            writeShape(KEY, value, Paths.get(directoryPath + "/" + KEY.getTypeName() + ".shp"));
         }
     }
 
     /**
      * 输出shape文件
      *
-     * @param geometries 地理对象集合
-     * @param filePath   文件路径
-     * @param gisType    gis类型
+     * @param data     数据
+     * @param filePath 文件路径
      * @throws IOException io异常
      */
-    public static void writeShape(List<Geometry> geometries, Path filePath, GisTypeEnum gisType) throws IOException {
-        //类型
-        final SimpleFeatureType TYPE = GisTypeEnum.featureType(gisType);
-        if (TYPE == null) return;
+    public static void writeShape(final SimpleFeatureType TYPE, List<Map<String, Object>> data, Path filePath) throws IOException {
         //特征构建
         final SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
         //特征集合
         ListFeatureCollection collection = new ListFeatureCollection(TYPE);
-        geometries.forEach(geometry -> {
-            featureBuilder.set("the_geom", geometry);
+        //遍历数据
+        data.forEach(it -> {
+            //设置geom
+            featureBuilder.set(GisSurveyExcelDefine.FILE.THE_GEOM, it.get(GisSurveyExcelDefine.FILE.THE_GEOM));
+            //设置属性
+            it.forEach((k, v) -> {
+                if (TYPE.getDescriptor(k) != null) featureBuilder.set(k, v);
+            });
             collection.add(featureBuilder.buildFeature(null));
         });
 
@@ -72,6 +73,7 @@ public class ShapeUtils {
         params.put(ShapefileDataStoreFactory.CREATE_SPATIAL_INDEX.key, Boolean.TRUE);
 
         ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createDataStore(params);
+        dataStore.setCharset(StandardCharsets.UTF_8);
         dataStore.createSchema(TYPE);
 
         //启动事务

+ 105 - 39
src/main/java/com/shkpr/service/alambizplugin/components/GisSurveyThirdExporter.java

@@ -21,7 +21,9 @@ import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApply;
 import com.shkpr.service.alambizplugin.dto.GisSurveyPropertyValue;
 import org.apache.commons.compress.archivers.ArchiveException;
 import org.apache.commons.lang3.StringUtils;
-import org.locationtech.jts.geom.Geometry;
+import org.geotools.data.DataUtilities;
+import org.geotools.feature.SchemaException;
+import org.opengis.feature.simple.SimpleFeatureType;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
 import org.springframework.stereotype.Component;
@@ -90,12 +92,20 @@ public class GisSurveyThirdExporter {
             List<GisSurveyLayerApply> points = gisSurveyLayerApplyService.findAllByJobIdAndKind(jobId, GisMetadataDefine.TYPE_KINE.POINT);
             List<GisSurveyLayerApply> lines = gisSurveyLayerApplyService.findAllByJobIdAndKind(jobId, GisMetadataDefine.TYPE_KINE.LINE);
 
+            //获取图层key
+            List<String> pointLayer = getLayerKeys(points);
+            List<String> lineLayer = getLayerKeys(lines);
+            //查询点图层模版
+            List<GisMetadataLayerTemplate> pointLayerTemplates = layerTemplateService.findByKeyIn(pointLayer);
+            //查询线图层模版
+            List<GisMetadataLayerTemplate> lineLayerTemplates = layerTemplateService.findByKeyIn(lineLayer);
+
             //根据文件类型导出
             Path resultPath = null;
             if (fileType == FileTypeEnum.EXCEL)
-                resultPath = exportExcel(points, lines);
+                resultPath = exportExcel(points, lines, pointLayerTemplates, lineLayerTemplates);
             if (fileType == FileTypeEnum.SHAPE_FILE)
-                resultPath = exportShape(points, lines);
+                resultPath = exportShape(points, lines, pointLayerTemplates, lineLayerTemplates);
 
             //导出文件判断
             if (resultPath == null || !Files.exists(resultPath)) {
@@ -120,7 +130,7 @@ public class GisSurveyThirdExporter {
             );
 
             return new AsyncResult<>(result);
-        } catch (InterruptedException | IOException | ArchiveException e) {
+        } catch (InterruptedException | IOException | ArchiveException | SchemaException e) {
             //打印报错信息
             LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
                     , String.format("第三方导出异常 任务id:%s error:%s", jobId, e)
@@ -132,20 +142,14 @@ public class GisSurveyThirdExporter {
     /**
      * 导出excel
      *
-     * @param points 点
-     * @param lines  线
+     * @param points              点
+     * @param lines               线
+     * @param pointLayerTemplates 点图层模版
+     * @param lineLayerTemplates  线图层模版
      * @return excel路径
      * @throws IOException io异常
      */
-    private Path exportExcel(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) throws IOException {
-        //获取图层key
-        List<String> pointLayer = getLayerKeys(points);
-        List<String> lineLayer = getLayerKeys(lines);
-        //查询点图层模版
-        List<GisMetadataLayerTemplate> pointLayerTemplates = layerTemplateService.findByKeyIn(pointLayer);
-        //查询线图层模版
-        List<GisMetadataLayerTemplate> lineLayerTemplates = layerTemplateService.findByKeyIn(lineLayer);
-
+    private Path exportExcel(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines, List<GisMetadataLayerTemplate> pointLayerTemplates, List<GisMetadataLayerTemplate> lineLayerTemplates) throws IOException {
         //构建excel头
         Map<String, Map<String, String>> excelHeader = buildExcelHeader(pointLayerTemplates, lineLayerTemplates);
         //构建excel数据
@@ -161,15 +165,17 @@ public class GisSurveyThirdExporter {
     /**
      * 导出shape
      *
-     * @param points 点
-     * @param lines  线
+     * @param points              点
+     * @param lines               线
+     * @param pointLayerTemplates 点图层模版
+     * @param lineLayerTemplates  线图层模版
      * @return shape路径
      * @throws IOException      io异常
      * @throws ArchiveException 压缩异常
      */
-    private Path exportShape(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) throws IOException, ArchiveException {
+    private Path exportShape(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines, List<GisMetadataLayerTemplate> pointLayerTemplates, List<GisMetadataLayerTemplate> lineLayerTemplates) throws IOException, ArchiveException, SchemaException {
         //构建shape数据
-        Map<String, List<Geometry>> shapeData = buildShapeData(points, lines);
+        Map<SimpleFeatureType, List<Map<String, Object>>> shapeData = buildShapeData(points, lines, pointLayerTemplates, lineLayerTemplates);
 
         //创建临时文件夹
         Path directory = Files.createTempDirectory(tempFileProperties.getResourcePath(), "third-export-");
@@ -280,7 +286,8 @@ public class GisSurveyThirdExporter {
                     //处理模版数据
                     Map<String, Object> rowData = it.getPropertyValues().stream()
                             .filter(it1 -> !StringUtils.isAnyBlank(it1.getProperty(), it1.getValue()))
-                            .collect(Collectors.toMap(GisSurveyPropertyValue::getProperty, GisSurveyPropertyValue::getValue));
+                            .collect(Collectors.toMap(GisSurveyPropertyValue::getProperty, GisSurveyPropertyValue::getValue
+                                    , (i1, i2) -> i1));
                     //处理图层数据
                     if (StringUtils.isNotBlank(it.getLayer())) {
                         //获取模版
@@ -298,37 +305,96 @@ public class GisSurveyThirdExporter {
     /**
      * 构建shape数据
      *
-     * @param points 点元素
-     * @param lines  线元素
+     * @param points              点元素
+     * @param lines               线元素
+     * @param pointLayerTemplates 点图层模版
+     * @param lineLayerTemplates  线图层模版
      * @return excel数据
      */
-    private Map<String, List<Geometry>> buildShapeData(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) {
-        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始构建shape数据   ======>");
+    private Map<SimpleFeatureType, List<Map<String, Object>>> buildShapeData(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines
+            , List<GisMetadataLayerTemplate> pointLayerTemplates, List<GisMetadataLayerTemplate> lineLayerTemplates) throws SchemaException {
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始构建shape属性头和数据   ======>");
         long begin = System.currentTimeMillis();
 
-        //点excel数据
-        List<Geometry> pointExcelData = points.parallelStream()
-                .map(GisSurveyLayerApply::getGis)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-        //线excel数据
-        List<Geometry> lineExcelData = lines.parallelStream()
-                .map(GisSurveyLayerApply::getGis)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
+        //点模版规格
+        String pointTemplateSpec = pointLayerTemplates.stream()
+                .flatMap(it -> it.getPropertyTemplates().stream())
+                .sorted(Comparator.comparing(GisMetadataPropertyTemplate::getOrdering))
+                .map(it ->
+                        StringUtils.substring(it.getKey(), 0, 10) + ":"
+                                + (StringUtils.isBlank(it.getType()) ? "string" : it.getType())
+                )
+                .distinct()
+                .collect(Collectors.joining(","));
+        //线模版规格
+        String lineTemplateSpec = lineLayerTemplates.stream()
+                .flatMap(it -> it.getPropertyTemplates().stream())
+                .sorted(Comparator.comparing(GisMetadataPropertyTemplate::getOrdering))
+                .map(it ->
+                        StringUtils.substring(it.getKey(), 0, 10) + ":"
+                                + (StringUtils.isBlank(it.getType()) ? "string" : it.getType())
+                )
+                .distinct()
+                .collect(Collectors.joining(","));
 
-        //excel数据
-        Map<String, List<Geometry>> shapeData = new HashMap<>();
-        shapeData.put(GisMetadataDefine.TYPE_KINE.POINT, pointExcelData);
-        shapeData.put(GisMetadataDefine.TYPE_KINE.LINE, lineExcelData);
+
+        //创建点类型
+        final SimpleFeatureType POINT_TYPE = DataUtilities.createType(
+                "point",
+                GisSurveyExcelDefine.FILE_HANDLE.POINT_SPEC + pointTemplateSpec
+        );
+        //创建线类型
+        final SimpleFeatureType LINE_TYPE = DataUtilities.createType(
+                "line",
+                GisSurveyExcelDefine.FILE_HANDLE.LINE_SPEC + lineTemplateSpec
+        );
+
+        //shape数据
+        Map<SimpleFeatureType, List<Map<String, Object>>> shapeData = new HashMap<>();
+        shapeData.put(POINT_TYPE, buildShapeItemData(points, pointLayerTemplates));
+        shapeData.put(LINE_TYPE, buildShapeItemData(lines, lineLayerTemplates));
 
         long end = System.currentTimeMillis();
         LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
                 , String.format(
-                        "结束构建shape数据,用时(毫秒):%d"
+                        "结束构建shape属性头和数据,用时(毫秒):%d"
                         , (end - begin)
                 )
         );
         return shapeData;
     }
+
+    /**
+     * 构建shape项数据
+     *
+     * @param layerApplies   采集元素集合
+     * @param layerTemplates 图层模版
+     * @return excel数据
+     */
+    private List<Map<String, Object>> buildShapeItemData(List<GisSurveyLayerApply> layerApplies, List<GisMetadataLayerTemplate> layerTemplates) {
+        return layerApplies.parallelStream()
+                .map(it -> {
+                    //处理模版数据
+                    Map<String, Object> rowData = it.getPropertyValues().stream()
+                            .filter(it1 -> !StringUtils.isAnyBlank(it1.getProperty(), it1.getValue()))
+                            .collect(Collectors.toMap(gisSurveyPropertyValue ->
+                                            StringUtils.substring(gisSurveyPropertyValue.getProperty(), 0, 10)
+                                    , GisSurveyPropertyValue::getValue
+                                    , (i1, i2) -> i1)
+                            );
+                    //处理图层数据
+                    if (StringUtils.isNotBlank(it.getLayer())) {
+                        //获取模版
+                        GisMetadataLayerTemplate gisMetadataLayerTemplate = layerTemplates.stream()
+                                .filter(it1 -> Objects.equals(it1.getKey(), it.getLayer()))
+                                .findFirst().orElse(null);
+                        //存入图层
+                        if (gisMetadataLayerTemplate != null)
+                            rowData.put(GisSurveyExcelDefine.FILE.LAYER, gisMetadataLayerTemplate.getName());
+                        //存入geom
+                        rowData.put(GisSurveyExcelDefine.FILE.THE_GEOM, it.getGis());
+                    }
+                    return rowData;
+                }).collect(Collectors.toList());
+    }
 }

+ 4 - 0
src/main/java/com/shkpr/service/alambizplugin/constants/GisSurveyExcelDefine.java

@@ -13,12 +13,16 @@ public interface GisSurveyExcelDefine {
     interface FILE_HANDLE {
         Integer HEADER_ROW_NUM = 1;
         Integer DATA_ROW_NUM = 2;
+        String POINT_SPEC = "the_geom:Point:srid=4490,layer:String,";
+        String LINE_SPEC = "the_geom:LineString:srid=4490,layer:String,";
     }
 
     /**
      * 文件映射
      */
     interface FILE {
+        String THE_GEOM = "the_geom";
+        String LAYER = "layer";
         String POINT_LAYER = "点类型";
         String LINE_LAYER = "线类型";
     }

+ 0 - 59
src/main/java/com/shkpr/service/alambizplugin/constants/GisTypeEnum.java

@@ -1,59 +0,0 @@
-package com.shkpr.service.alambizplugin.constants;
-
-import org.geotools.data.DataUtilities;
-import org.opengis.feature.simple.SimpleFeatureType;
-
-/**
- * gis类型枚举
- *
- * @author 欧阳劲驰
- * @since 1.0.0
- */
-public enum GisTypeEnum {
-    //点
-    POINT,
-    //线
-    LINE;
-
-    /**
-     * 获取枚举
-     *
-     * @param kine 类型
-     * @return gis枚举
-     */
-    public static GisTypeEnum get(String kine) {
-        switch (kine) {
-            case GisMetadataDefine.TYPE_KINE.POINT:
-                return POINT;
-            case GisMetadataDefine.TYPE_KINE.LINE:
-                return LINE;
-        }
-        return null;
-    }
-
-    /**
-     * 特征类型
-     *
-     * @param typeEnum 类型枚举
-     * @return 特征类型
-     */
-    public static SimpleFeatureType featureType(GisTypeEnum typeEnum) {
-        try {
-            switch (typeEnum) {
-                case POINT:
-                    return DataUtilities.createType(
-                            "Point",
-                            "the_geom:Point:srid=4490,name:String"
-                    );
-                case LINE:
-                    return DataUtilities.createType(
-                            "LineString",
-                            "the_geom:LineString:srid=4490,name:String"
-                    );
-            }
-            return null;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-}