|
|
@@ -15,17 +15,13 @@ import com.siwei.common.core.exception.ServiceException;
|
|
|
import com.siwei.common.core.utils.DateUtils;
|
|
|
import com.siwei.common.core.utils.bean.BeanUtils;
|
|
|
import com.siwei.common.core.utils.uuid.IdUtils;
|
|
|
-import com.vividsolutions.jts.geom.Geometry;
|
|
|
-import com.vividsolutions.jts.geom.MultiPolygon;
|
|
|
-import com.vividsolutions.jts.geom.Polygon;
|
|
|
-import com.vividsolutions.jts.io.ParseException;
|
|
|
-import com.vividsolutions.jts.io.WKBReader;
|
|
|
-import com.vividsolutions.jts.io.WKTReader;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.geotools.data.DefaultTransaction;
|
|
|
+import org.geotools.data.FeatureSource;
|
|
|
+import org.geotools.data.FeatureWriter;
|
|
|
import org.geotools.data.Transaction;
|
|
|
import org.geotools.data.collection.ListFeatureCollection;
|
|
|
import org.geotools.data.shapefile.ShapefileDataStore;
|
|
|
@@ -36,7 +32,12 @@ import org.geotools.data.simple.SimpleFeatureStore;
|
|
|
import org.geotools.feature.simple.SimpleFeatureBuilder;
|
|
|
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
|
|
|
import org.geotools.referencing.CRS;
|
|
|
-
|
|
|
+import org.locationtech.jts.geom.Geometry;
|
|
|
+import org.locationtech.jts.geom.MultiPolygon;
|
|
|
+import org.locationtech.jts.geom.Polygon;
|
|
|
+import org.locationtech.jts.io.ParseException;
|
|
|
+import org.locationtech.jts.io.WKBReader;
|
|
|
+import org.locationtech.jts.io.WKTReader;
|
|
|
import org.opengis.feature.simple.SimpleFeature;
|
|
|
import org.opengis.feature.simple.SimpleFeatureType;
|
|
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|
|
@@ -50,7 +51,9 @@ import java.io.File;
|
|
|
import java.io.FileInputStream;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.io.Serializable;
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.nio.charset.Charset;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
|
import java.nio.file.Paths;
|
|
|
@@ -315,6 +318,7 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
try {
|
|
|
operationFileStrategy(convergeTableList);
|
|
|
} catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
throw new ServiceException("汇交失败,数据错误"+e);
|
|
|
}
|
|
|
|
|
|
@@ -408,7 +412,22 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
// SHP 字段名长度限制为 10 字符
|
|
|
String shpColName = colName.length() > 10 ? colName.substring(0, 10) : colName;
|
|
|
Class<?> javaType = mapDatabaseTypeToJavaClass(dataType);
|
|
|
- typeBuilder.add(shpColName, javaType);
|
|
|
+
|
|
|
+ // 明确指定字段长度和精度,防止 GeoTools 默认长度过小
|
|
|
+ if (javaType == String.class) {
|
|
|
+ // 设置为 254 字节,但数据输入时会截断到 80 字符以防万一
|
|
|
+ typeBuilder.length(254).add(shpColName, javaType);
|
|
|
+ } else if (Number.class.isAssignableFrom(javaType)) {
|
|
|
+ if (javaType == Double.class || javaType == Float.class || javaType == BigDecimal.class) {
|
|
|
+ // GeoTools SimpleFeatureTypeBuilder 不直接支持 precision 方法
|
|
|
+ // 需通过 userData 传递给 ShapefileDataStore
|
|
|
+ typeBuilder.length(31).userData("precision", 6).add(shpColName, javaType);
|
|
|
+ } else {
|
|
|
+ typeBuilder.length(20).add(shpColName, javaType);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ typeBuilder.add(shpColName, javaType);
|
|
|
+ }
|
|
|
columnTypeMap.put(colName, shpColName);
|
|
|
}
|
|
|
|
|
|
@@ -461,7 +480,18 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
|
|
|
// 添加属性字段
|
|
|
for (String originColName : columnTypeMap.keySet()) {
|
|
|
- featureBuilder.add(data.get(originColName));
|
|
|
+ Object val = data.get(originColName);
|
|
|
+ if (val instanceof String) {
|
|
|
+ String sVal = (String) val;
|
|
|
+ // DBF 字符串最大长度为 254 字节,而非字符数
|
|
|
+ // 这里使用更保守的 80 字符,以兼容 UTF-8 多字节情况
|
|
|
+ if (sVal.length() > 80) {
|
|
|
+ sVal = sVal.substring(0, 80);
|
|
|
+ }
|
|
|
+ featureBuilder.add(sVal);
|
|
|
+ } else {
|
|
|
+ featureBuilder.add(val);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
features.add(featureBuilder.buildFeature(null));
|
|
|
@@ -486,25 +516,20 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
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();
|
|
|
+ // 使用 FeatureWriter 代替 SimpleFeatureStore.addFeatures,更稳定且易于调试
|
|
|
+ try (FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(Transaction.AUTO_COMMIT)) {
|
|
|
+ for (SimpleFeature feature : features) {
|
|
|
+ try {
|
|
|
+ SimpleFeature next = writer.next();
|
|
|
+ next.setAttributes(feature.getAttributes());
|
|
|
+ writer.write();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("写入要素失败,跳过: {}", e.getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
+ } finally {
|
|
|
+ dataStore.dispose();
|
|
|
}
|
|
|
- dataStore.dispose();
|
|
|
|
|
|
// 6. 生成 .cpg 文件
|
|
|
File cpgFile = new File(filePath + File.separator + fileName + ".cpg");
|
|
|
@@ -518,6 +543,8 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
dataType = dataType.toLowerCase();
|
|
|
if (dataType.contains("char") || dataType.contains("text")) {
|
|
|
return String.class;
|
|
|
+ } else if (dataType.contains("int8") || dataType.contains("bigint")) {
|
|
|
+ return Long.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")) {
|
|
|
@@ -534,7 +561,7 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
try {
|
|
|
// 1. 构造完整的文件路径
|
|
|
String mdbPath = filePath;
|
|
|
- if (!mdbPath.endsWith(File.separator)) {
|
|
|
+ if (!mdbPath.endsWith("/") && !mdbPath.endsWith("\\")) {
|
|
|
mdbPath += File.separator;
|
|
|
}
|
|
|
mdbPath += fileName;
|
|
|
@@ -542,9 +569,12 @@ public class ConvergeServiceImpl implements ConvergeService {
|
|
|
mdbPath += ".mdb";
|
|
|
}
|
|
|
|
|
|
- // 2. 调用工具类生成 MDB 文件并写入数据
|
|
|
- MdbUtil.writeMdbByTable(mdbPath, tableName, columns, dataList);
|
|
|
+ // 统一路径分隔符,防止 Linux 环境下出现反斜杠导致的路径错误
|
|
|
+ mdbPath = mdbPath.replace("\\", File.separator).replace("/", File.separator);
|
|
|
|
|
|
+ // 4. 调用工具类生成 MDB 文件并写入数据
|
|
|
+ MdbUtil.writeMdbByTable(mdbPath, tableName, columns, dataList);
|
|
|
+
|
|
|
log.info("MDB 文件生成成功: {}", mdbPath);
|
|
|
} catch (Exception e) {
|
|
|
log.error("生成 MDB 文件失败: {}", tableName, e);
|