|
@@ -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;
|
|
|
+ }
|
|
|
+}
|