| | |
| | | |
| | | public class bianjieguihua2 { |
| | | /** |
| | | * 优化边界XY坐标字符串 |
| | | * |
| | | * @param boundaryXYString 边界XY坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..." |
| | | * @return 优化后的边界坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..." |
| | | */ |
| | | public static String optimizeBoundaryXYString(String boundaryXYString) { |
| | | try { |
| | | // 检查输入数据 |
| | | if (boundaryXYString == null || boundaryXYString.trim().isEmpty()) { |
| | | throw new IllegalArgumentException("边界坐标字符串不能为空"); |
| | | } |
| | | |
| | | // 解析XY坐标字符串 |
| | | List<BoundaryAlgorithm.Coordinate> localCoordinates = parseXYString(boundaryXYString); |
| | | |
| | | if (localCoordinates == null || localCoordinates.isEmpty()) { |
| | | throw new IllegalArgumentException("无法解析边界坐标字符串"); |
| | | } |
| | | |
| | | // 三角形小区域特殊处理,避免过度插值导致点数扩增 |
| | | if (localCoordinates.size() == 3) { |
| | | double triangleArea = calculatePolygonArea(localCoordinates); |
| | | double trianglePerimeter = calculatePerimeter(localCoordinates); |
| | | |
| | | System.out.println("检测到三角形边界,面积=" + String.format("%.2f", triangleArea) + |
| | | "m², 周长=" + String.format("%.2f", trianglePerimeter) + "m"); |
| | | |
| | | if (triangleArea < 100.0 || trianglePerimeter < 30.0) { |
| | | System.out.println("小三角形,跳过插值优化"); |
| | | BoundaryAlgorithm.Coordinate firstPoint = localCoordinates.get(0); |
| | | List<BoundaryAlgorithm.Coordinate> trianglePoints = new ArrayList<>(localCoordinates); |
| | | trianglePoints.add(new BoundaryAlgorithm.Coordinate( |
| | | firstPoint.x, |
| | | firstPoint.y, |
| | | firstPoint.lat, |
| | | firstPoint.lon)); |
| | | return convertBoundaryPointsToString(trianglePoints); |
| | | } |
| | | } |
| | | |
| | | // 创建算法实例 |
| | | BoundaryAlgorithm algorithm = new BoundaryAlgorithm(); |
| | | |
| | | // 自动场景分析(基于XY坐标,无高程数据) |
| | | BoundaryAlgorithm.SceneAnalysis sceneAnalysis = analyzeSceneFromXYCoordinates(localCoordinates); |
| | | System.out.println("自动场景分析结果:"); |
| | | System.out.println(sceneAnalysis.toString()); |
| | | |
| | | // 根据场景分析结果获取参数 |
| | | BoundaryAlgorithm.BoundaryParameters params = |
| | | algorithm.getParametersForPreset(sceneAnalysis.suggestedPreset); |
| | | |
| | | System.out.println("自动选择的参数: 间隔=" + params.interval + "米, 角度阈值=" + |
| | | params.angleThreshold + "度"); |
| | | |
| | | // 使用优化算法处理边界 |
| | | List<BoundaryAlgorithm.Coordinate> optimizedPoints = |
| | | algorithm.optimizeBoundaryPointsAdvanced(localCoordinates, params); |
| | | |
| | | // 质量评估 |
| | | BoundaryAlgorithm.BoundaryQuality boundaryQuality = |
| | | algorithm.evaluateBoundaryQuality(optimizedPoints); |
| | | |
| | | System.out.println("边界质量评估结果:"); |
| | | System.out.println(boundaryQuality.toString()); |
| | | |
| | | // 转换为输出字符串格式 |
| | | return convertBoundaryPointsToString(optimizedPoints); |
| | | |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("优化边界坐标字符串时发生错误: " + e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 解析XY坐标字符串为Coordinate列表 |
| | | * |
| | | * @param xyString XY坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..." |
| | | * @return Coordinate列表 |
| | | */ |
| | | private static List<BoundaryAlgorithm.Coordinate> parseXYString(String xyString) { |
| | | List<BoundaryAlgorithm.Coordinate> coordinates = new ArrayList<>(); |
| | | |
| | | if (xyString == null || xyString.trim().isEmpty()) { |
| | | return coordinates; |
| | | } |
| | | |
| | | String[] points = xyString.split(";"); |
| | | for (String point : points) { |
| | | point = point.trim(); |
| | | if (point.isEmpty()) { |
| | | continue; |
| | | } |
| | | |
| | | String[] parts = point.split(","); |
| | | if (parts.length >= 2) { |
| | | try { |
| | | double x = Double.parseDouble(parts[0].trim()); |
| | | double y = Double.parseDouble(parts[1].trim()); |
| | | // lat和lon设为0,因为我们只需要XY坐标 |
| | | coordinates.add(new BoundaryAlgorithm.Coordinate(x, y, 0.0, 0.0)); |
| | | } catch (NumberFormatException e) { |
| | | System.err.println("解析坐标失败: " + point + ", 错误: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return coordinates; |
| | | } |
| | | |
| | | /** |
| | | * 基于XY坐标进行场景分析(无高程数据) |
| | | */ |
| | | private static BoundaryAlgorithm.SceneAnalysis analyzeSceneFromXYCoordinates( |
| | | List<BoundaryAlgorithm.Coordinate> localCoords) { |
| | | |
| | | BoundaryAlgorithm.SceneAnalysis analysis = new BoundaryAlgorithm.SceneAnalysis(); |
| | | |
| | | if (localCoords.size() < 3) { |
| | | analysis.suggestedPreset = "复杂小区域"; |
| | | return analysis; |
| | | } |
| | | |
| | | // 计算基本统计信息 |
| | | calculateBasicStatisticsFromCoordinates(localCoords, analysis); |
| | | |
| | | // 计算边界复杂度 |
| | | calculateBoundaryComplexityFromCoordinates(localCoords, analysis); |
| | | |
| | | // 无高程数据,设置为0 |
| | | analysis.elevationRange = 0; |
| | | |
| | | // 自动选择预设场景(不考虑高程因素) |
| | | selectPresetAutomaticallyFromXYCoordinates(analysis); |
| | | |
| | | return analysis; |
| | | } |
| | | |
| | | /** |
| | | * 从XY坐标自动选择预设场景(不考虑高程因素) |
| | | */ |
| | | private static void selectPresetAutomaticallyFromXYCoordinates(BoundaryAlgorithm.SceneAnalysis analysis) { |
| | | // 决策逻辑基于面积和复杂度 |
| | | double areaWeight = 0.6; |
| | | double complexityWeight = 0.4; |
| | | |
| | | // 计算综合得分 |
| | | double score = 0; |
| | | |
| | | // 面积因素:面积越大,越适合大间隔 |
| | | double areaScore = Math.min(1.0, analysis.area / 1000.0); // 1000平方米为基准 |
| | | score += areaScore * areaWeight; |
| | | |
| | | // 复杂度因素:复杂度越高,越需要小间隔 |
| | | double complexityScore = analysis.complexity; |
| | | score += complexityScore * complexityWeight; |
| | | |
| | | // 根据得分选择预设 |
| | | if (score < 0.3) { |
| | | analysis.suggestedPreset = "平坦大区域"; |
| | | } else if (score < 0.6) { |
| | | analysis.suggestedPreset = "常规区域"; |
| | | } else { |
| | | analysis.suggestedPreset = "复杂小区域"; |
| | | } |
| | | |
| | | System.out.println("自动场景选择得分: " + String.format("%.2f", score) + " -> " + analysis.suggestedPreset); |
| | | } |
| | | |
| | | /** |
| | | * 自动处理Coordinate列表并生成优化后的边界坐标(无需传入间隔和角度阈值) |
| | | * |
| | | * @param coordinates Coordinate对象列表 |