package bianjie; import java.util.List; public class BoundaryProcessor { /** * 处理GNGGA数据并生成优化后的边界坐标 * * @param gnggaData GNGGA格式的GPS数据 * @param baseStationStr 基站坐标,格式:"纬度,N/S,经度,E/W" 例如:"2324.194945,N,11330.938547,E" * @param interval 边界点间隔(米) * @param angleThreshold 角度阈值(度) * @return 优化后的边界坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..." */ public static String processBoundaryData(String gnggaData, String baseStationStr, double interval, double angleThreshold) { try { // 检查输入数据 if (gnggaData == null || gnggaData.trim().isEmpty()) { throw new IllegalArgumentException("GNGGA数据不能为空"); } if (baseStationStr == null || baseStationStr.trim().isEmpty()) { throw new IllegalArgumentException("基站坐标不能为空"); } // 解析基准站坐标 String[] baseParts = baseStationStr.split(","); if (baseParts.length != 4) { throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W"); } double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]); double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]); // 创建算法实例 BoundaryAlgorithm algorithm = new BoundaryAlgorithm(); // 场景分析 BoundaryAlgorithm.SceneAnalysis sceneAnalysis = algorithm.analyzeGNGGAData(gnggaData, baseLat, baseLon); // 获取参数(使用场景分析推荐的预设) BoundaryAlgorithm.BoundaryParameters params = algorithm.getParametersForPreset(sceneAnalysis.suggestedPreset); // 生成边界 List boundaryPoints = algorithm.processBoundaryDataAdvanced(gnggaData, baseLat, baseLon, params); // 质量评估 BoundaryAlgorithm.BoundaryQuality boundaryQuality = algorithm.evaluateBoundaryQuality(boundaryPoints); // 转换为输出字符串格式 return convertBoundaryPointsToString(boundaryPoints); } catch (Exception e) { throw new RuntimeException("处理边界数据时发生错误: " + e.getMessage(), e); } } /** * 解析度分格式坐标 */ private static double parseDMCoordinate(String dmCoord, String direction) { try { if (dmCoord == null || dmCoord.isEmpty()) { return 0; } int dotIndex = dmCoord.indexOf('.'); if (dotIndex < 2) { return 0; } int degrees = Integer.parseInt(dmCoord.substring(0, dotIndex - 2)); double minutes = Double.parseDouble(dmCoord.substring(dotIndex - 2)); double decimal = degrees + minutes / 60.0; if ("S".equals(direction) || "W".equals(direction)) { decimal = -decimal; } return decimal; } catch (Exception e) { throw new IllegalArgumentException("度分坐标解析错误: " + dmCoord, e); } } /** * 将边界点列表转换为字符串格式 */ private static String convertBoundaryPointsToString(List points) { if (points == null || points.isEmpty()) { return ""; } StringBuilder coordinatesBuilder = new StringBuilder(); for (int i = 0; i < points.size(); i++) { BoundaryAlgorithm.Coordinate point = points.get(i); coordinatesBuilder.append(String.format("%.2f,%.2f", point.x, point.y)); if (i < points.size() - 1) { coordinatesBuilder.append(";"); } } return coordinatesBuilder.toString(); } /** * 高级处理方法 - 允许自定义所有参数 * * @param gnggaData GNGGA格式的GPS数据 * @param baseStationStr 基站坐标 * @param params 边界参数对象 * @return 优化后的边界坐标字符串 */ public static String processBoundaryDataAdvanced(String gnggaData, String baseStationStr, BoundaryAlgorithm.BoundaryParameters params) { try { // 检查输入数据 if (gnggaData == null || gnggaData.trim().isEmpty()) { throw new IllegalArgumentException("GNGGA数据不能为空"); } if (baseStationStr == null || baseStationStr.trim().isEmpty()) { throw new IllegalArgumentException("基站坐标不能为空"); } if (params == null) { throw new IllegalArgumentException("边界参数不能为空"); } // 解析基准站坐标 String[] baseParts = baseStationStr.split(","); if (baseParts.length != 4) { throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W"); } double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]); double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]); // 创建算法实例并处理数据 BoundaryAlgorithm algorithm = new BoundaryAlgorithm(); List boundaryPoints = algorithm.processBoundaryDataAdvanced(gnggaData, baseLat, baseLon, params); // 转换为输出字符串格式 return convertBoundaryPointsToString(boundaryPoints); } catch (Exception e) { throw new RuntimeException("处理边界数据时发生错误: " + e.getMessage(), e); } } /** * 仅进行场景分析,不生成边界 * * @param gnggaData GNGGA格式的GPS数据 * @param baseStationStr 基站坐标 * @return 场景分析结果 */ public static BoundaryAlgorithm.SceneAnalysis analyzeScene(String gnggaData, String baseStationStr) { try { // 检查输入数据 if (gnggaData == null || gnggaData.trim().isEmpty()) { throw new IllegalArgumentException("GNGGA数据不能为空"); } if (baseStationStr == null || baseStationStr.trim().isEmpty()) { throw new IllegalArgumentException("基站坐标不能为空"); } // 解析基准站坐标 String[] baseParts = baseStationStr.split(","); if (baseParts.length != 4) { throw new IllegalArgumentException("基准站坐标格式错误,应为: 纬度,N/S,经度,E/W"); } double baseLat = parseDMCoordinate(baseParts[0], baseParts[1]); double baseLon = parseDMCoordinate(baseParts[2], baseParts[3]); // 创建算法实例并进行分析 BoundaryAlgorithm algorithm = new BoundaryAlgorithm(); return algorithm.analyzeGNGGAData(gnggaData, baseLat, baseLon); } catch (Exception e) { throw new RuntimeException("场景分析时发生错误: " + e.getMessage(), e); } } /** * 从根目录的properties文件读取GNGGA数据 * * @param fileName properties文件名 * @return GNGGA格式的GPS数据字符串 */ public static String getGNGGAFromProperties(String fileName) { try { // 首先尝试从类路径加载 java.io.InputStream input = BoundaryProcessor.class.getClassLoader() .getResourceAsStream(fileName); if (input == null) { // 如果类路径没有,尝试从当前工作目录加载 java.io.File file = new java.io.File(fileName); if (file.exists()) { input = new java.io.FileInputStream(file); } } if (input == null) { throw new RuntimeException("文件未找到: " + fileName); } java.util.Properties props = new java.util.Properties(); props.load(input); // 从properties中获取GNGGA数据 String gnggaData = props.getProperty("gngga.data"); if (gnggaData == null || gnggaData.trim().isEmpty()) { throw new RuntimeException("properties文件中未找到gngga.data属性"); } input.close(); return gnggaData; } catch (Exception e) { throw new RuntimeException("读取properties文件时发生错误: " + e.getMessage(), e); } } }