Browse Source

新增java读取gis相关文件获取空间属性

chenjun 1 year ago
commit
a83442a0aa

+ 19 - 0
.gitignore

@@ -0,0 +1,19 @@
+# ---> Java
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.log
+*.iml
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+.idea
+target
+logs

+ 154 - 0
pom.xml

@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.zjugis</groupId>
+    <artifactId>nature-gis</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <project.repository.host>http://60.191.110.204:8081/nexus/content/repositories</project.repository.host>
+        <geotools.version>19.0</geotools.version>
+        <lombok.version>1.18.24</lombok.version>
+    </properties>
+
+    <dependencies>
+        <!--   解析mdb     -->
+        <dependency>
+            <groupId>com.healthmarketscience.jackcess</groupId>
+            <artifactId>jackcess</artifactId>
+            <version>3.5.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-lang</groupId>
+                    <artifactId>commons-lang</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!--    geotools    -->
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-shapefile</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+
+        <!-- fastjson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.83</version>
+        </dependency>
+
+        <!-- gis相关依赖 -->
+        <dependency>
+            <groupId>com.zjugis</groupId>
+            <artifactId>gis</artifactId>
+            <scope>system</scope>
+            <version>1.4.2-SNAPSHOT</version>
+            <systemPath>${project.basedir}/src/lib/gis-1.4.2-SNAPSHOT.jar</systemPath>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/org.kabeja/kabeja -->
+        <dependency>
+            <groupId>org.kabeja</groupId>
+            <artifactId>kabeja</artifactId>
+            <version>0.4</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/lib/kabeja-0.4.jar</systemPath>
+        </dependency>
+
+        <!-- 验证相关 -->
+        <dependency>
+            <groupId>org.hibernate.validator</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>6.0.7.Final</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.tika</groupId>
+            <artifactId>tika-core</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tika</groupId>
+            <artifactId>tika-parsers-standard-package</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.1spatial/dwg-lib -->
+        <dependency>
+            <groupId>com.1spatial</groupId>
+            <artifactId>dwg-lib</artifactId>
+            <version>0.8</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
+            <plugins>
+                <plugin>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>3.0.0</version>
+                </plugin>
+                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+                <plugin>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>3.0.2</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.7.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.20.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>3.0.2</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-install-plugin</artifactId>
+                    <version>2.5.2</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>2.8.2</version>
+                </plugin>
+                <!-- 要将源码放上去,需要加入这个插件 -->
+                <plugin>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>3.0.1</version>
+                    <configuration>
+                        <attach>true</attach>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>compile</phase>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 75 - 0
src/main/java/com/zjugis/nature/gis/dwg/DwgUtils.java

@@ -0,0 +1,75 @@
+package com.zjugis.nature.gis.dwg;
+
+import com.onespatial.dwglib.Reader;
+import com.onespatial.dwglib.objects.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/17 9:18
+ * @Version 1.0
+ */
+public class DwgUtils {
+
+    /**
+     * 读取dwg文件获取lwPolyline转为wkt字符串格式
+     * @param dwgFile
+     * @return
+     * @throws IOException
+     */
+    public static String getWkt(File dwgFile) throws IOException {
+        Reader reader = new Reader(dwgFile);
+        BlockControlObj blockControl = reader.getBlockControlObject();
+        BlockHeader ms = (BlockHeader)blockControl.getModelSpace();
+        List<LwPolyline> lwPolylines = new ArrayList<>();
+        if (ms != null) {
+            for (CadObject entity : ms.getOwnedObjects()) {
+                if (entity instanceof LwPolyline){
+                    lwPolylines.add((LwPolyline) entity);
+                }
+            }
+        }
+        if(lwPolylines.isEmpty()){
+            return "";
+        }else{
+            StringBuilder sb = new StringBuilder();
+            if(lwPolylines.size()>1){
+                sb.append("MULTIPOLYGON (");
+            }else{
+                sb.append("POLYGON ");
+            }
+            lwPolylines.forEach(lwPolyline -> {
+                String firstPoint = "";
+                String endPoint = "";
+                sb.append("((");
+                List<LwPolyline.VertexOfLwPolyline> points = lwPolyline.points;
+                for (int i = 0; i < points.size(); i++) {
+                    String x = points.get(i).vertex.x + "";
+                    String y = points.get(i).vertex.y + "";
+                    String point = " " + x + " " + y + ",";
+                    if (i == 0) {
+                        firstPoint = point;
+                    }
+                    if(i == points.size()-1){
+                        endPoint = point;
+                    }
+                    sb.append(point);
+                }
+                if(!firstPoint.equals(endPoint)){
+                    sb.append(firstPoint);
+                }
+                sb.delete(sb.length() - 1, sb.length());
+                sb.append(" )),");
+            });
+            sb.delete(sb.length() - 1, sb.length());
+            if (lwPolylines.size() > 1) {
+                sb.append(")");
+            }
+            return sb.toString();
+        }
+    }
+}

+ 83 - 0
src/main/java/com/zjugis/nature/gis/dxf/DxfUtils.java

@@ -0,0 +1,83 @@
+package com.zjugis.nature.gis.dxf;
+
+import com.zjugis.nature.gis.exception.LayerNotFoundException;
+import org.kabeja.dxf.*;
+import org.kabeja.parser.ParseException;
+import org.kabeja.parser.Parser;
+import org.kabeja.parser.ParserBuilder;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/15 14:20
+ * @Version 1.0
+ */
+public class DxfUtils {
+
+    /**
+     * 读取dxf文件获取lwPolyline转为wkt字符串格式
+     * @param dxfFile
+     * @return
+     * @throws FileNotFoundException
+     * @throws ParseException
+     */
+    public static String getWkt(File dxfFile) throws FileNotFoundException, ParseException, LayerNotFoundException {
+        Parser dxfParser = ParserBuilder.createDefaultParser();
+        //需要转换的dxf
+        dxfParser.parse(new FileInputStream(dxfFile), "UTF-8");
+        DXFDocument doc = dxfParser.getDocument();
+        Iterator dxfLayerIterator = doc.getDXFLayerIterator();
+        if(dxfLayerIterator.hasNext()){
+            DXFLayer dXFLayer = (DXFLayer) dxfLayerIterator.next();
+            StringBuilder sb = new StringBuilder();
+            if(dXFLayer.hasDXFEntities(DXFConstants.ENTITY_TYPE_LWPOLYLINE)) {
+                List plines = dXFLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_LWPOLYLINE);
+                if (plines.size() > 1) {
+                    sb.append("MULTIPOLYGON (");
+                } else {
+                    sb.append("POLYGON ");
+                }
+                plines.forEach(pline -> {
+                    DXFLWPolyline dxflwPolyline = (DXFLWPolyline) pline;
+                    Iterator vertexIterator = dxflwPolyline.getVertexIterator();
+                    int i = 0;
+                    String firstPoint = "";
+                    String endPoint = "";
+                    sb.append("((");
+                    while (vertexIterator.hasNext()) {
+                        DXFVertex dxfVertex = (DXFVertex) vertexIterator.next();
+                        String x = dxfVertex.getPoint().getX() + "";
+                        String y = dxfVertex.getPoint().getY() + "";
+                        String point = " " + x + " " + y + ",";
+                        if (i == 0) {
+                            firstPoint = point;
+                        }
+                        if(!vertexIterator.hasNext()){
+                            endPoint = point;
+                        }
+                        sb.append(point);
+                        i++;
+                    }
+                    if(!firstPoint.equals(endPoint)){
+                        sb.append(firstPoint);
+                    }
+                    sb.delete(sb.length() - 1, sb.length());
+                    sb.append(" )),");
+                });
+                sb.delete(sb.length() - 1, sb.length());
+                if (plines.size() > 1) {
+                    sb.append(")");
+                }
+                return sb.toString();
+            }
+        }else{
+            throw new LayerNotFoundException("dxf文件中找不到图层");
+        }
+        return "";
+    }
+}

+ 53 - 0
src/main/java/com/zjugis/nature/gis/exception/BusinessException.java

@@ -0,0 +1,53 @@
+package com.zjugis.nature.gis.exception;
+
+/**
+ * @Author 陈俊
+ * @Date 2022/3/15 9:39
+ * @Version 1.0
+ */
+
+/** 这里继承RuntimeException异常 **/
+public class BusinessException extends RuntimeException {
+    private static final long serialVersionUID = 2332608236621015980L;
+    private String type = "B-";
+    private Object[] msgArgs;
+    /** 用于存放后端返回的数据 **/
+    private Object data;
+
+    public BusinessException(Throwable cause) {
+        super(cause);
+    }
+
+    public BusinessException(String message) {
+        super(message);
+    }
+
+    public BusinessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public Object[] getMsgArgs() {
+        return this.msgArgs;
+    }
+
+    public void setMsgArgs(Object[] msgArgs) {
+        this.msgArgs = msgArgs;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Object getData() {
+        return this.data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+}

+ 44 - 0
src/main/java/com/zjugis/nature/gis/exception/ErrorCode.java

@@ -0,0 +1,44 @@
+package com.zjugis.nature.gis.exception;
+
+import com.zjugis.nature.gis.exception.enums.GlobalErrorCodeConstants;
+
+/**
+ * 错误码对象
+ *
+ * 全局错误码,占用 [0, 999], 参见 {@link GlobalErrorCodeConstants}
+ * 业务异常错误码,占用 [1 000 000 000, +∞),
+ *
+ * TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备
+ */
+public class ErrorCode {
+
+    /**
+     * 错误码
+     */
+    private final Integer code;
+    /**
+     * 错误提示
+     */
+    private final String msg;
+
+    public ErrorCode(Integer code, String message) {
+        this.code = code;
+        this.msg = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    @Override
+    public String toString() {
+        return "ErrorCode{" +
+                "code=" + code +
+                ", msg='" + msg + '\'' +
+                '}';
+    }
+}

+ 25 - 0
src/main/java/com/zjugis/nature/gis/exception/LayerNotFoundException.java

@@ -0,0 +1,25 @@
+package com.zjugis.nature.gis.exception;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/15 14:33
+ * @Version 1.0
+ */
+public class LayerNotFoundException extends RuntimeException {
+
+    public LayerNotFoundException(String message) {
+        super(message);
+    }
+
+    public LayerNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public LayerNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+    public LayerNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}

+ 25 - 0
src/main/java/com/zjugis/nature/gis/exception/MutiDataException.java

@@ -0,0 +1,25 @@
+package com.zjugis.nature.gis.exception;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/15 14:33
+ * @Version 1.0
+ */
+public class MutiDataException extends RuntimeException {
+
+    public MutiDataException(String message) {
+        super(message);
+    }
+
+    public MutiDataException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MutiDataException(Throwable cause) {
+        super(cause);
+    }
+
+    public MutiDataException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}

+ 32 - 0
src/main/java/com/zjugis/nature/gis/exception/enums/GlobalErrorCodeConstants.java

@@ -0,0 +1,32 @@
+package com.zjugis.nature.gis.exception.enums;
+
+
+import com.zjugis.nature.gis.exception.ErrorCode;
+
+/**
+ * 全局错误码枚举
+ * 0-999 系统异常编码保留
+ *
+ * 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
+ * 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
+ * 比较特殊的是,因为之前一直使用 0 作为成功,就不使用 200 啦。
+ *
+ * @author 
+ */
+public interface GlobalErrorCodeConstants {
+
+    // ========== 图形数据 90001000 ==========
+    ErrorCode CRS_CODE_ERROR = new ErrorCode(90001001, "坐标系错误!检查是否为4490坐标系!");
+    ErrorCode CPG_FILE_NOT_FOUND = new ErrorCode(90001011, "找不到cpg文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode DBF_FILE_NOT_FOUND = new ErrorCode(90001012, "找不到dbf文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode PRJ_FILE_NOT_FOUND = new ErrorCode(90001013, "找不到prj文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode SBN_FILE_NOT_FOUND = new ErrorCode(90001014, "找不到sbn文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode SBX_FILE_NOT_FOUND = new ErrorCode(90001015, "找不到sbx文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode SHP_FILE_NOT_FOUND = new ErrorCode(90001016, "找不到shp文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode SHX_FILE_NOT_FOUND = new ErrorCode(90001017, "找不到shx文件!需要cpg、dbf、prj、sbn、sbx、shp、shx七个文件!");
+    ErrorCode SHAPE_ANALYSIS_ERROR = new ErrorCode(90001018, "解析出错!请检查7个文件是否同名!");
+
+
+    ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
+
+}

+ 37 - 0
src/main/java/com/zjugis/nature/gis/mdb/MdbBaseDTO.java

@@ -0,0 +1,37 @@
+package com.zjugis.nature.gis.mdb;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/3 14:56
+ * @Version 1.0
+ */
+public class MdbBaseDTO {
+
+    @JSONField(name = "SHAPE_GEOMETRY")
+    @NotEmpty(message = "图形属性不能为空")
+    private JSONObject shapeGeometry;
+
+    @JSONField(serialize = false , deserialize = false)
+    private String shape;
+
+    public JSONObject getShapeGeometry() {
+        return shapeGeometry;
+    }
+
+    public void setShapeGeometry(JSONObject shapeGeometry) {
+        this.shapeGeometry = shapeGeometry;
+    }
+
+    public String getShape() {
+        return shape;
+    }
+
+    public void setShape(String shape) {
+        this.shape = shape;
+    }
+}

+ 149 - 0
src/main/java/com/zjugis/nature/gis/mdb/MdbUtils.java

@@ -0,0 +1,149 @@
+package com.zjugis.nature.gis.mdb;
+
+import com.alibaba.fastjson.JSONObject;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+import com.vividsolutions.jts.operation.valid.IsValidOp;
+import com.vividsolutions.jts.operation.valid.TopologyValidationError;
+import com.zjugis.gis.consts.GeometryType;
+import com.zjugis.gis.entity.MdbTable;
+import com.zjugis.gis.entity.MultiPolygon;
+import com.zjugis.gis.entity.Polygon;
+import com.zjugis.gis.reader.mdb.MdbReader;
+import com.zjugis.nature.gis.exception.BusinessException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/3 14:33
+ * @Version 1.0
+ */
+public class MdbUtils {
+
+    public static final String[] errMsg = {
+            "拓扑验证错误",
+            "重复点",
+            "存在外环",
+            "存在嵌套环",
+            "内部不相连",
+            "自相交",
+            "环形自相交",
+            "嵌套的洞",
+            "重复环",
+            "构成图形的点太少",
+            "无效的坐标点",
+            "环未关闭"
+    };
+
+    public static final List<Integer> ignores = new ArrayList<Integer>(){{
+//        add(5); // 自相交
+//        add(6); // 环形自相交
+        add(7); // 嵌套的洞
+    }};
+
+    public static final List<String> ignoresInspect = new ArrayList<String>(){{
+        add("MultiLineString");
+        add("MultiPoint");
+        add("Point");
+        add("LineString");
+    }};
+
+    public static <T extends MdbBaseDTO> List<String> mdbInspect(MdbTable mdbTable, List<String> existColumns, Class<T> clazz) {
+        List<String> inspect = new ArrayList<>();
+        try {
+            if (mdbTable == null || mdbTable.getSize() == 0) {
+                throw new BusinessException("mdb数据为空");
+            }
+            if (mdbTable.getSRID() == -1 || "unknow".equals(mdbTable.getSRIDInfo()) || !"4490".equals(mdbTable.getEpsg())) {
+                throw new BusinessException("请检查坐标系是否为CGCS2000大地坐标系,wkid为4490,请务必使用模板进行数据导入");
+            }
+            //检查mdb图形列表字段是否包含必须字段
+            inspect.addAll(inspectMdbColumns(mdbTable, existColumns));
+            //检查列表数据是否符合规范
+            List<String> vaildMdbMessage = inspectMdbTableData(mdbTable, clazz);
+            inspect.addAll(vaildMdbMessage);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return inspect;
+    }
+
+    public static <T extends MdbBaseDTO> List<String> inspectMdbTableData(MdbTable mdbTable, Class<T> clazz) {
+        List<T> TDataList = JSONObject.parseArray(JSONObject.toJSONString(mdbTable.getData()), clazz);
+        List<String> inspectResult = new ArrayList<>();
+        AtomicInteger i = new AtomicInteger(1);
+        TDataList.forEach(TData -> {
+            String validResult = inspectTData(TData);
+            if (validResult.length() > 0) {
+                inspectResult.add(String.format("第%s行数据校验出错:%s", i, validResult));
+            }
+            i.getAndIncrement();
+        });
+        return inspectResult;
+    }
+
+    public static <T extends MdbBaseDTO> String inspectTData(T tData) {
+        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+        // 校验
+        Set<ConstraintViolation<MdbBaseDTO>> result = validator.validate(tData);
+        //排序
+        List<ConstraintViolation<MdbBaseDTO>> orderResult = result.stream().sorted(Comparator.comparing(constraintViolation -> constraintViolation.getMessage())).collect(Collectors.toList());
+        // 拼接错误
+        StringBuilder detailMessage = new StringBuilder();
+        // 获取校验结果
+        for (ConstraintViolation<MdbBaseDTO> constraintViolation : orderResult) {
+            // 拼接校验结果
+            if (detailMessage.length() > 0) {
+                detailMessage.append(";");
+            }
+            detailMessage.append(constraintViolation.getMessage());
+        }
+        if (detailMessage.length() == 0) {
+            JSONObject shapeGeometry = tData.getShapeGeometry();
+            String geometryType = (String) shapeGeometry.get("geometryType");
+            String wkt = "";
+            if ("MULTIPOLYGON".equals(geometryType)) {
+                MultiPolygon multiPolygon = JSONObject.parseObject(JSONObject.toJSONString(shapeGeometry), MultiPolygon.class);
+                wkt = multiPolygon.toClobJSON();
+            }
+            if ("POLYGON".equals(geometryType)) {
+                Polygon polygon = JSONObject.parseObject(JSONObject.toJSONString(shapeGeometry), Polygon.class);
+                wkt = polygon.toClobJSON();
+            }
+            try {
+                IsValidOp isValidOp = new IsValidOp(new WKTReader().read(wkt));
+                if(!isValidOp.isValid()) {
+                    TopologyValidationError error = isValidOp.getValidationError();
+                    if(!ignores.contains(error.getErrorType())) {
+                        detailMessage.append("\n存在图形错误" + errMsg[error.getErrorType()]);
+                    }
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+        }
+        return detailMessage.toString();
+    }
+
+    public static List<String> inspectMdbColumns(MdbTable mdbTable, List<String> existColumns) {
+        List<String> inspectResult = new ArrayList<>();
+        List<String> columnNames = mdbTable.getColumnNames();
+        existColumns.forEach(s -> {
+            boolean contains = columnNames.contains(s);
+            if (!contains) {
+                inspectResult.add("上传mbd中不包含" + s + "字段");
+            }
+        });
+        return inspectResult;
+    }
+}

+ 66 - 0
src/main/java/com/zjugis/nature/gis/shp/ShpUtils.java

@@ -0,0 +1,66 @@
+package com.zjugis.nature.gis.shp;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import com.zjugis.nature.gis.exception.BusinessException;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.shapefile.ShapefileDataStore;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.opengis.feature.Property;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.*;
+
+import static com.zjugis.nature.gis.exception.enums.GlobalErrorCodeConstants.CRS_CODE_ERROR;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/3 16:07
+ * @Version 1.0
+ */
+public class ShpUtils {
+
+    public static String parse(File file) throws IOException {
+        ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURI().toURL());
+        shpDataStore.setCharset(Charset.forName("UTF-8"));
+        String typeName = shpDataStore.getTypeNames()[0];
+        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+        featureSource = shpDataStore.getFeatureSource(typeName);
+        FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures();
+        FeatureIterator<SimpleFeature> iterator = result.features();
+
+        List<Polygon> list= new ArrayList<>();
+        GeometryFactory factory = null;
+
+        while(iterator.hasNext()) {
+            SimpleFeature feature = iterator.next();
+            String crsCode = feature.getBounds().getCoordinateReferenceSystem().getCoordinateSystem().getName().getCode();
+            if(!"GCS_China_Geodetic_Coordinate_System_2000".equals(crsCode)){
+                throw new BusinessException(CRS_CODE_ERROR.getMsg());
+            }
+            Collection<Property> p = feature.getProperties();
+            Iterator<Property> it = p.iterator();
+            while(it.hasNext()) {
+                Property pro = it.next();
+                if (pro.getValue() instanceof MultiPolygon) {
+                    MultiPolygon var12 = (MultiPolygon)pro.getValue();
+
+                    for (int i = 0; i < var12.getNumGeometries(); i++) {
+                        Polygon polygon = (Polygon) var12.getGeometryN(i);
+                        list.add(polygon);
+                    }
+                    factory = var12.getFactory();
+
+                }
+            }
+        }
+        MultiPolygon geometryCollection = factory.createMultiPolygon(list.toArray(new Polygon[0]));
+        return geometryCollection.toString();
+    }
+}

+ 56 - 0
src/main/java/com/zjugis/nature/gis/txt/TxtUtils.java

@@ -0,0 +1,56 @@
+package com.zjugis.nature.gis.txt;
+
+import com.zjugis.nature.gis.exception.MutiDataException;
+import org.apache.tika.Tika;
+import org.apache.tika.exception.TikaException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @Author 陈俊
+ * @Date 2023/8/18 9:03
+ * @Version 1.0
+ */
+public class TxtUtils {
+
+    /**
+     * 读取txt文件获取点位信息转为wkt字符串
+     * @param txtFile
+     * @return
+     * @throws IOException
+     * @throws TikaException
+     */
+    public static String getWkt(File txtFile) throws IOException, TikaException, MutiDataException {
+        Tika tika = new Tika();
+        String s = tika.parseToString(txtFile);
+        // 获取坐标点文本
+        String txt_cod = s.substring(s.indexOf("@") + 1);
+        if(txt_cod.contains("@")){
+            throw new MutiDataException("不支持解析多条数据!");
+        }
+        // 根据换行符分解坐标点文本
+        String[] list_point = txt_cod.split("\n");
+        StringBuilder sb = new StringBuilder();
+        sb.append("POLYGON ");
+        sb.append("((");
+        for (String point  : list_point) {
+            // 跳过无坐标部份的文本
+            if (!point.contains("J"))
+            {
+                continue;
+            }
+            String[] split = point.split(",");
+            String x = split[3].replaceAll("\\s*|\r|\n|\t","");
+            String y = split[2].replaceAll("\\s*|\r|\n|\t","");
+            sb.append(" ");
+            sb.append(x);
+            sb.append(" ");
+            sb.append(y);
+            sb.append(",");
+        }
+        sb.delete(sb.length() - 1, sb.length());
+        sb.append(" ))");
+        return sb.toString();
+    }
+}