模型库、矢量文件
This commit is contained in:
		| @ -27,6 +27,8 @@ public class SaTokenConfig implements WebMvcConfigurer { | ||||
|         excludePathPatterns.add("/data/clt/**"); | ||||
|         excludePathPatterns.add("/data/mbtiles/**"); | ||||
|         excludePathPatterns.add("/data/pak/**"); | ||||
|         excludePathPatterns.add("/systemService/**"); | ||||
|         excludePathPatterns.add("/**"); | ||||
|  | ||||
|         // 注册 Sa-Token 拦截器 | ||||
|         registry.addInterceptor(new SaInterceptor(handle -> { | ||||
|  | ||||
							
								
								
									
										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
	 ZZX9599
					ZZX9599