模型库、矢量文件
This commit is contained in:
51
src/main/java/com/yj/earth/common/util/FileCommonUtil.java
Normal file
51
src/main/java/com/yj/earth/common/util/FileCommonUtil.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.yj.earth.common.util;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FileCommonUtil {
|
||||
|
||||
/**
|
||||
* 将本地文件转换为 MultipartFile
|
||||
*/
|
||||
public static MultipartFile convertToMultipartFile(File file) {
|
||||
try (FileInputStream inputStream = new FileInputStream(file)) {
|
||||
return new MockMultipartFile(
|
||||
"files",
|
||||
file.getName(),
|
||||
MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
||||
inputStream
|
||||
);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static MediaType getImageMediaType(String suffix) {
|
||||
String lowerSuffix = suffix.toLowerCase();
|
||||
switch (lowerSuffix) {
|
||||
case ".jpg":
|
||||
case ".jpeg":
|
||||
return MediaType.IMAGE_JPEG;
|
||||
case ".glb":
|
||||
return MediaType.valueOf("model/gltf-binary");
|
||||
case ".png":
|
||||
return MediaType.IMAGE_PNG;
|
||||
case ".gif":
|
||||
return MediaType.IMAGE_GIF;
|
||||
case ".bmp":
|
||||
return MediaType.valueOf("image/bmp");
|
||||
case ".webp":
|
||||
return MediaType.valueOf("image/webp");
|
||||
case ".svg":
|
||||
return MediaType.valueOf("image/svg+xml");
|
||||
default:
|
||||
return MediaType.APPLICATION_OCTET_STREAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package com.yj.earth.common.util;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
/**
|
||||
* 将本地文件转换为 MultipartFile
|
||||
*/
|
||||
public static MultipartFile convertToMultipartFile(File file) {
|
||||
try (FileInputStream inputStream = new FileInputStream(file)) {
|
||||
return new MockMultipartFile(
|
||||
"files",
|
||||
file.getName(),
|
||||
MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
||||
inputStream
|
||||
);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/main/java/com/yj/earth/common/util/GdalUtil.java
Normal file
82
src/main/java/com/yj/earth/common/util/GdalUtil.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.yj.earth.common.util;
|
||||
|
||||
import org.gdal.gdal.gdal;
|
||||
import org.gdal.ogr.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GdalUtil {
|
||||
|
||||
// 静态初始化
|
||||
static {
|
||||
gdal.SetConfigOption("PROJ_LIB", "./lib");
|
||||
gdal.AllRegister();
|
||||
}
|
||||
|
||||
public static String readVectorToJson(String filePath) {
|
||||
// 打开矢量文件
|
||||
DataSource dataSource = ogr.Open(filePath);
|
||||
if (dataSource == null) {
|
||||
throw new RuntimeException("无法打开矢量文件: " + filePath);
|
||||
}
|
||||
// 存储所有数据的Map
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
// 获取图层数量
|
||||
int layerCount = dataSource.GetLayerCount();
|
||||
result.put("layerCount", layerCount);
|
||||
// 存储所有图层数据
|
||||
List<Map<String, Object>> layers = new ArrayList<>();
|
||||
for (int i = 0; i < layerCount; i++) {
|
||||
Layer layer = dataSource.GetLayer(i);
|
||||
if (layer == null) continue;
|
||||
// 图层信息
|
||||
Map<String, Object> layerData = new HashMap<>();
|
||||
layerData.put("layerName", layer.GetName());
|
||||
layerData.put("featureCount", layer.GetFeatureCount());
|
||||
// 获取字段定义
|
||||
FeatureDefn featureDefn = layer.GetLayerDefn();
|
||||
int fieldCount = featureDefn.GetFieldCount();
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
for (int j = 0; j < fieldCount; j++) {
|
||||
FieldDefn fieldDefn = featureDefn.GetFieldDefn(j);
|
||||
Map<String, Object> fieldInfo = new HashMap<>();
|
||||
fieldInfo.put("name", fieldDefn.GetName());
|
||||
fieldInfo.put("type", fieldDefn.GetFieldTypeName(fieldDefn.GetFieldType()));
|
||||
fields.add(fieldInfo);
|
||||
}
|
||||
layerData.put("fields", fields);
|
||||
// 读取所有要素
|
||||
List<Map<String, Object>> features = new ArrayList<>();
|
||||
layer.ResetReading();
|
||||
Feature feature;
|
||||
|
||||
while ((feature = layer.GetNextFeature()) != null) {
|
||||
Map<String, Object> featureData = new HashMap<>();
|
||||
// 存储属性信息
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
for (int j = 0; j < fieldCount; j++) {
|
||||
attributes.put(featureDefn.GetFieldDefn(j).GetName(), feature.GetFieldAsString(j));
|
||||
}
|
||||
featureData.put("attributes", attributes);
|
||||
// 存储几何信息
|
||||
Geometry geometry = feature.GetGeometryRef();
|
||||
if (geometry != null) {
|
||||
featureData.put("geometryType", geometry.GetGeometryName());
|
||||
featureData.put("wkt", geometry.ExportToWkt());
|
||||
}
|
||||
features.add(featureData);
|
||||
feature.delete(); // 释放资源
|
||||
}
|
||||
layerData.put("features", features);
|
||||
layers.add(layerData);
|
||||
}
|
||||
result.put("layers", layers);
|
||||
// 关闭数据源
|
||||
dataSource.delete();
|
||||
// 转换为JSON并返回
|
||||
return JsonUtil.toJson(result);
|
||||
}
|
||||
}
|
||||
274
src/main/java/com/yj/earth/common/util/SQLiteConverter.java
Normal file
274
src/main/java/com/yj/earth/common/util/SQLiteConverter.java
Normal file
@ -0,0 +1,274 @@
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLiteConverter {
|
||||
// SQLite JDBC驱动
|
||||
private static final String JDBC_DRIVER = "org.sqlite.JDBC";
|
||||
|
||||
// 原始数据库路径
|
||||
private static final String ORIGINAL_DB_PATH = "jdbc:sqlite:D:\\YJEarth.model";
|
||||
|
||||
// 新数据库路径
|
||||
private static final String NEW_DB_PATH = "jdbc:sqlite:E:\\通用模型库.model";
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("===== 开始数据库转换程序 =====");
|
||||
System.out.println("原始数据库: " + ORIGINAL_DB_PATH);
|
||||
System.out.println("目标数据库: " + NEW_DB_PATH + "\n");
|
||||
|
||||
// 使用try-with-resources自动管理连接资源
|
||||
try (Connection originalConn = DriverManager.getConnection(ORIGINAL_DB_PATH);
|
||||
Connection newConn = DriverManager.getConnection(NEW_DB_PATH)) {
|
||||
|
||||
System.out.println("✅ 成功连接到原始数据库");
|
||||
System.out.println("✅ 成功创建并连接到新数据库\n");
|
||||
|
||||
// 在新数据库中创建表结构
|
||||
System.out.println("===== 开始创建新表结构 =====");
|
||||
createNewTables(newConn);
|
||||
System.out.println("===== 新表结构创建完成 =====");
|
||||
|
||||
// 迁移mode_types表数据到model_type表
|
||||
System.out.println("\n===== 开始迁移mode_types表数据 =====");
|
||||
MigrationResult modeTypesResult = migrateModeTypes(originalConn, newConn);
|
||||
System.out.println("===== mode_types表数据迁移完成 =====");
|
||||
System.out.printf(" 成功: %d 条, 失败: %d 条, 总计: %d 条%n",
|
||||
modeTypesResult.successCount,
|
||||
modeTypesResult.failureCount,
|
||||
modeTypesResult.totalCount);
|
||||
|
||||
// 迁移models表数据到model表
|
||||
System.out.println("\n===== 开始迁移models表数据 =====");
|
||||
MigrationResult modelsResult = migrateModels(originalConn, newConn);
|
||||
System.out.println("===== models表数据迁移完成 =====");
|
||||
System.out.printf(" 成功: %d 条, 失败: %d 条, 总计: %d 条%n",
|
||||
modelsResult.successCount,
|
||||
modelsResult.failureCount,
|
||||
modelsResult.totalCount);
|
||||
|
||||
if (modeTypesResult.failureCount > 0 || modelsResult.failureCount > 0) {
|
||||
System.out.println("\n⚠️ 注意:部分记录迁移失败、已跳过错误记录");
|
||||
}
|
||||
|
||||
System.out.println("\n===== 数据库转换处理完成! =====");
|
||||
|
||||
} catch (SQLException e) {
|
||||
System.err.println("\n❌ 数据库连接错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移结果数据类
|
||||
*/
|
||||
private static class MigrationResult {
|
||||
int successCount;
|
||||
int failureCount;
|
||||
int totalCount;
|
||||
|
||||
MigrationResult(int success, int failure, int total) {
|
||||
this.successCount = success;
|
||||
this.failureCount = failure;
|
||||
this.totalCount = total;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在新数据库中创建表结构
|
||||
*/
|
||||
private static void createNewTables(Connection conn) throws SQLException {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
// 创建model_type表
|
||||
System.out.println("正在创建model_type表...");
|
||||
String createModelTypeTable = "CREATE TABLE IF NOT EXISTS \"model_type\" (" +
|
||||
"\"id\" TEXT," +
|
||||
"\"name\" TEXT," +
|
||||
"\"parent_id\" TEXT," +
|
||||
"\"tree_index\" INTEGER," +
|
||||
"\"created_at\" TEXT," +
|
||||
"\"updated_at\" TEXT," +
|
||||
"PRIMARY KEY (\"id\")" +
|
||||
");";
|
||||
stmt.execute(createModelTypeTable);
|
||||
System.out.println("✅ model_type表创建完成");
|
||||
|
||||
// 创建model表
|
||||
System.out.println("正在创建model表...");
|
||||
String createModelTable = "CREATE TABLE IF NOT EXISTS \"model\" (" +
|
||||
"\"id\" TEXT," +
|
||||
"\"model_type_id\" TEXT," +
|
||||
"\"model_name\" TEXT," +
|
||||
"\"model_type\" TEXT," +
|
||||
"\"poster_type\" TEXT," +
|
||||
"\"poster\" TEXT," +
|
||||
"\"data\" TEXT," +
|
||||
"\"data_bytes\" BLOB," +
|
||||
"\"view\" TEXT," +
|
||||
"\"created_at\" TEXT," +
|
||||
"\"updated_at\" TEXT," +
|
||||
"PRIMARY KEY (\"id\")" +
|
||||
");";
|
||||
stmt.execute(createModelTable);
|
||||
System.out.println("✅ model表创建完成");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移mode_types表数据到model_type表
|
||||
*/
|
||||
private static MigrationResult migrateModeTypes(Connection originalConn, Connection newConn) throws SQLException {
|
||||
// 先获取记录总数、用于显示进度
|
||||
int totalCount;
|
||||
try (PreparedStatement countStmt = originalConn.prepareStatement("SELECT COUNT(*) FROM mode_types");
|
||||
ResultSet countRs = countStmt.executeQuery()) {
|
||||
countRs.next();
|
||||
totalCount = countRs.getInt(1);
|
||||
System.out.println("发现 " + totalCount + " 条mode_types记录待迁移");
|
||||
}
|
||||
|
||||
// 查询原始表数据
|
||||
try (PreparedStatement selectStmt = originalConn.prepareStatement("SELECT * FROM mode_types");
|
||||
ResultSet rs = selectStmt.executeQuery()) {
|
||||
|
||||
// 插入到新表、关闭自动提交以提高性能
|
||||
newConn.setAutoCommit(false);
|
||||
|
||||
try (PreparedStatement insertStmt = newConn.prepareStatement(
|
||||
"INSERT INTO model_type (" +
|
||||
"id, name, parent_id, tree_index, created_at, updated_at" +
|
||||
") VALUES (?, ?, ?, ?, ?, ?)")) {
|
||||
|
||||
int successCount = 0;
|
||||
int failureCount = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
try {
|
||||
// 生成新的UUID作为ID
|
||||
String newId = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
String typeName = rs.getString("type_name");
|
||||
|
||||
// 映射字段
|
||||
insertStmt.setString(1, newId);
|
||||
insertStmt.setString(2, typeName);
|
||||
insertStmt.setString(3, rs.getString("p_id"));
|
||||
insertStmt.setInt(4, 0);
|
||||
insertStmt.setString(5, rs.getString("created_at"));
|
||||
insertStmt.setString(6, rs.getString("updated_at"));
|
||||
|
||||
insertStmt.executeUpdate();
|
||||
successCount++;
|
||||
|
||||
// 每迁移10条记录或最后一批记录时打印进度
|
||||
if (successCount % 10 == 0 || (successCount + failureCount) == totalCount) {
|
||||
printProgress(successCount + failureCount, totalCount);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// 捕获单条记录的异常、跳过该记录
|
||||
failureCount++;
|
||||
System.err.printf("\n❌ 迁移mode_types记录失败 (序号: %d): %s%n",
|
||||
successCount + failureCount, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
newConn.commit();
|
||||
return new MigrationResult(successCount, failureCount, totalCount);
|
||||
} catch (SQLException e) {
|
||||
newConn.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
newConn.setAutoCommit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移models表数据到model表
|
||||
*/
|
||||
private static MigrationResult migrateModels(Connection originalConn, Connection newConn) throws SQLException {
|
||||
// 先获取记录总数、用于显示进度
|
||||
int totalCount;
|
||||
try (PreparedStatement countStmt = originalConn.prepareStatement("SELECT COUNT(*) FROM models");
|
||||
ResultSet countRs = countStmt.executeQuery()) {
|
||||
countRs.next();
|
||||
totalCount = countRs.getInt(1);
|
||||
System.out.println("发现 " + totalCount + " 条models记录待迁移");
|
||||
}
|
||||
|
||||
// 查询原始表数据
|
||||
try (PreparedStatement selectStmt = originalConn.prepareStatement("SELECT * FROM models");
|
||||
ResultSet rs = selectStmt.executeQuery()) {
|
||||
|
||||
// 插入到新表、关闭自动提交以提高性能
|
||||
newConn.setAutoCommit(false);
|
||||
|
||||
try (PreparedStatement insertStmt = newConn.prepareStatement(
|
||||
"INSERT INTO model (" +
|
||||
"id, model_type_id, model_name, model_type, poster_type, " +
|
||||
"poster, data, data_bytes, view, created_at, updated_at" +
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
|
||||
|
||||
int successCount = 0;
|
||||
int failureCount = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
try {
|
||||
// 生成新的UUID作为ID
|
||||
String newId = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
String modelName = rs.getString("model_name");
|
||||
|
||||
// 映射字段
|
||||
insertStmt.setString(1, newId);
|
||||
insertStmt.setString(2, rs.getString("p_id"));
|
||||
insertStmt.setString(3, modelName);
|
||||
insertStmt.setString(4, rs.getString("model_type"));
|
||||
insertStmt.setString(5, rs.getString("poster_type"));
|
||||
|
||||
// 处理BLOB字段
|
||||
byte[] posterBlob = rs.getBytes("poster");
|
||||
insertStmt.setString(6, posterBlob != null ? new String(posterBlob) : null);
|
||||
insertStmt.setString(7, null);
|
||||
|
||||
byte[] dataBlob = rs.getBytes("data");
|
||||
insertStmt.setBytes(8, dataBlob);
|
||||
insertStmt.setString(9, null);
|
||||
|
||||
insertStmt.setString(10, rs.getString("created_at"));
|
||||
insertStmt.setString(11, rs.getString("updated_at"));
|
||||
|
||||
insertStmt.executeUpdate();
|
||||
successCount++;
|
||||
|
||||
// 每迁移10条记录或最后一批记录时打印进度
|
||||
if (successCount % 10 == 0 || (successCount + failureCount) == totalCount) {
|
||||
printProgress(successCount + failureCount, totalCount);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// 捕获单条记录的异常、跳过该记录
|
||||
failureCount++;
|
||||
System.err.printf("\n❌ 迁移models记录失败 (序号: %d, 名称: %s): %s%n",
|
||||
successCount + failureCount,
|
||||
rs.getString("model_name"),
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
newConn.commit();
|
||||
return new MigrationResult(successCount, failureCount, totalCount);
|
||||
} catch (SQLException e) {
|
||||
newConn.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
newConn.setAutoCommit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印迁移进度
|
||||
*/
|
||||
private static void printProgress(int current, int total) {
|
||||
double percentage = (current * 100.0) / total;
|
||||
System.out.printf("迁移进度: %d/%d (%.1f%%)\r", current, total, percentage);
|
||||
System.out.flush();
|
||||
}
|
||||
}
|
||||
@ -41,8 +41,7 @@ public class SQLiteUtil {
|
||||
/**
|
||||
* 执行查询并返回对象列表
|
||||
*/
|
||||
public static <T> List<T> queryForList(String dbFilePath, String sql, List<Object> params, Class<T> clazz)
|
||||
throws SQLException, IllegalAccessException, InstantiationException {
|
||||
public static <T> List<T> queryForList(String dbFilePath, String sql, List<Object> params, Class<T> clazz) throws SQLException, IllegalAccessException, InstantiationException {
|
||||
List<T> resultList = new ArrayList<>();
|
||||
|
||||
// 使用try-with-resources确保资源自动关闭
|
||||
@ -320,10 +319,9 @@ public class SQLiteUtil {
|
||||
"model_type_id" TEXT,
|
||||
"model_name" TEXT,
|
||||
"model_type" TEXT,
|
||||
"model_data" BLOB,
|
||||
"poster_type" TEXT,
|
||||
"poster" TEXT,
|
||||
"data" TEXT,
|
||||
"view" TEXT,
|
||||
"poster_data" BLOB,
|
||||
"created_at" TEXT,
|
||||
"updated_at" TEXT,
|
||||
PRIMARY KEY ("id")
|
||||
|
||||
@ -175,7 +175,7 @@ public class SdkUtil {
|
||||
} catch (IOException e) {
|
||||
log.error("读取sdk配置文件失败", e);
|
||||
} catch (ClassCastException e) {
|
||||
log.error("sdk配置文件中server.port格式错误,应为数字类型", e);
|
||||
log.error("sdk配置文件中server.port格式错误、应为数字类型", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user