张世豪
11 小时以前 5b685e9066ccfbc432c29739b5524f1d42a20891
src/bianjie/bianjieguihua2.java
@@ -7,6 +7,176 @@
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对象列表
@@ -34,9 +204,30 @@
           double baseLat = parseDMToDecimal(baseParts[0], baseParts[1]);
           double baseLon = parseDMToDecimal(baseParts[2], baseParts[3]);
           
           // 将Coordinate列表转换为局部坐标系坐标
           List<BoundaryAlgorithm.Coordinate> localCoordinates =
               convertToLocalCoordinates(coordinates, baseLat, baseLon);
         // 将Coordinate列表转换为局部坐标系坐标
         List<BoundaryAlgorithm.Coordinate> localCoordinates =
            convertToLocalCoordinates(coordinates, baseLat, baseLon);
         // 三角形小区域特殊处理,避免过度插值导致点数扩增
         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();
@@ -264,6 +455,16 @@
       
       return Math.abs(area) / 2.0;
   }
   private static double calculatePerimeter(List<BoundaryAlgorithm.Coordinate> points) {
       if (points == null || points.size() != 3) {
           return 0.0;
       }
       double d1 = calculateDistance(points.get(0), points.get(1));
       double d2 = calculateDistance(points.get(1), points.get(2));
       double d3 = calculateDistance(points.get(2), points.get(0));
       return d1 + d2 + d3;
   }
   
   // ============ 其他方法保持不变 ============