张世豪
6 天以前 c498385fb7e372d13e2ee76d7b54ae2381728082
src/dikuai/ObstacleManagementPage.java
@@ -14,6 +14,8 @@
import zhangaiwu.Obstacledge;
import zhuye.Shouye;
import zhuye.Coordinate;
import bianjie.bianjieguihua2;
/**
 * 障碍物管理页面 - UI优化版
@@ -307,15 +309,21 @@
        actionPanel.setLayout(new BoxLayout(actionPanel, BoxLayout.X_AXIS));
        actionPanel.setOpaque(false);
        
        JButton generateBtn = createStyledButton("重新生成坐标", PRIMARY_COLOR, true);
        generateBtn.addActionListener(e -> generateObstacleCoordinates(obstacle, xyArea));
        // 对于圆形障碍物,不显示"重新生成坐标"按钮,只显示预览按钮
        Obstacledge.ObstacleShape shape = obstacle.getShape();
        boolean isCircle = (shape == Obstacledge.ObstacleShape.CIRCLE);
        if (!isCircle) {
            // 只有非圆形障碍物才显示"重新生成坐标"按钮
            JButton generateBtn = createStyledButton("重新生成坐标", PRIMARY_COLOR, true);
            generateBtn.addActionListener(e -> generateObstacleCoordinates(obstacle, xyArea));
            actionPanel.add(generateBtn);
            actionPanel.add(Box.createHorizontalStrut(10));
        }
        
        JButton previewBtn = createStyledButton("预览", TEXT_SECONDARY, false);
        previewBtn.setPreferredSize(new Dimension(70, 36)); // 稍微窄一点
        previewBtn.addActionListener(e -> previewObstacle(obstacle));
        actionPanel.add(generateBtn);
        actionPanel.add(Box.createHorizontalStrut(10));
        actionPanel.add(previewBtn);
        
        card.add(actionPanel);
@@ -618,23 +626,23 @@
                return;
            }
            
            double baseLat = parseDMToDecimal(baseParts[0].trim(), baseParts[1].trim());
            double baseLon = parseDMToDecimal(baseParts[2].trim(), baseParts[3].trim());
            Obstacledge.ObstacleShape shape = obstacle.getShape();
            List<Obstacledge.XYCoordinate> xyCoords;
            
            List<Obstacledge.XYCoordinate> xyCoords = new ArrayList<>();
            for (int i = 0; i < originalCoordsList.size(); i += 2) {
                if (i + 1 >= originalCoordsList.size()) break;
                double lat = originalCoordsList.get(i).toDecimalDegree();
                double lon = originalCoordsList.get(i + 1).toDecimalDegree();
                if (Double.isFinite(lat) && Double.isFinite(lon)) {
                    double[] localXY = convertLatLonToLocal(lat, lon, baseLat, baseLon);
                    xyCoords.add(new Obstacledge.XYCoordinate(localXY[0], localXY[1]));
                }
            // 根据障碍物形状调用不同的算法
            if (shape == Obstacledge.ObstacleShape.POLYGON) {
                // 多边形:使用 bianjieguihua2 算法
                xyCoords = generatePolygonCoordinates(originalCoordsList, baseStation);
            } else if (shape == Obstacledge.ObstacleShape.CIRCLE) {
                // 圆形:使用简单的坐标转换(保持原有逻辑)
                xyCoords = generateCircleCoordinates(originalCoordsList, baseStation);
            } else {
                JOptionPane.showMessageDialog(this, "未知的障碍物形状", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
            if (xyCoords.isEmpty()) {
                JOptionPane.showMessageDialog(this, "坐标转换失败", "错误", JOptionPane.ERROR_MESSAGE);
            if (xyCoords == null || xyCoords.isEmpty()) {
                JOptionPane.showMessageDialog(this, "坐标生成失败", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
@@ -647,6 +655,132 @@
        }
    }
    
    /**
     * 使用 bianjieguihua2 算法生成多边形坐标
     */
    private List<Obstacledge.XYCoordinate> generatePolygonCoordinates(
            List<Obstacledge.DMCoordinate> originalCoordsList, String baseStation) {
        // 保存当前的 Coordinate.coordinates
        List<Coordinate> savedCoordinates = new ArrayList<>(Coordinate.coordinates);
        try {
            // 将障碍物的原始坐标转换为 Coordinate 对象列表
            List<Coordinate> coordinateList = new ArrayList<>();
            for (int i = 0; i < originalCoordsList.size(); i += 2) {
                if (i + 1 >= originalCoordsList.size()) break;
                Obstacledge.DMCoordinate latCoord = originalCoordsList.get(i);
                Obstacledge.DMCoordinate lonCoord = originalCoordsList.get(i + 1);
                // 转换为 Coordinate 对象
                // DMCoordinate 的 degreeMinute 是度分格式(如 2324.200273 表示 23度24.200273分)
                // 需要格式化为字符串,保持度分格式
                double latDM = latCoord.getDegreeMinute();
                double lonDM = lonCoord.getDegreeMinute();
                // 格式化度分格式:确保整数部分至少2位(度),小数部分是分
                String latStr = formatDegreeMinute(latDM);
                String lonStr = formatDegreeMinute(lonDM);
                char latDir = latCoord.getDirection();
                char lonDir = lonCoord.getDirection();
                Coordinate coord = new Coordinate(
                    latStr,
                    String.valueOf(latDir),
                    lonStr,
                    String.valueOf(lonDir),
                    0.0 // 高程数据,障碍物可能没有,设为0
                );
                coordinateList.add(coord);
            }
            if (coordinateList.isEmpty()) {
                return null;
            }
            // 设置到全局坐标列表
            Coordinate.coordinates.clear();
            Coordinate.coordinates.addAll(coordinateList);
            // 调用 bianjieguihua2 算法生成优化后的多边形坐标
            String optimizedCoordsStr = bianjieguihua2.processCoordinateListAuto(baseStation);
            if (optimizedCoordsStr == null || optimizedCoordsStr.trim().isEmpty()) {
                return null;
            }
            // 解析返回的坐标字符串,格式:"X0,Y0;X1,Y1;X2,Y2;..."
            List<Obstacledge.XYCoordinate> xyCoords = new ArrayList<>();
            String[] pointStrings = optimizedCoordsStr.split(";");
            for (String pointStr : pointStrings) {
                pointStr = pointStr.trim();
                if (pointStr.isEmpty()) continue;
                String[] parts = pointStr.split(",");
                if (parts.length >= 2) {
                    try {
                        double x = Double.parseDouble(parts[0].trim());
                        double y = Double.parseDouble(parts[1].trim());
                        if (Double.isFinite(x) && Double.isFinite(y)) {
                            xyCoords.add(new Obstacledge.XYCoordinate(x, y));
                        }
                    } catch (NumberFormatException e) {
                        // 跳过无效的坐标点
                        continue;
                    }
                }
            }
            return xyCoords;
        } finally {
            // 恢复原来的坐标列表
            Coordinate.coordinates.clear();
            Coordinate.coordinates.addAll(savedCoordinates);
        }
    }
    /**
     * 格式化度分格式坐标
     * @param degreeMinute 度分值,如 2324.200273 表示 23度24.200273分
     * @return 格式化的字符串
     */
    private String formatDegreeMinute(double degreeMinute) {
        // 度分格式:整数部分是度,小数部分是分
        // 例如 2324.200273 -> "2324.200273"
        return String.format("%.6f", degreeMinute);
    }
    /**
     * 生成圆形坐标(保持原有简单转换逻辑)
     */
    private List<Obstacledge.XYCoordinate> generateCircleCoordinates(
            List<Obstacledge.DMCoordinate> originalCoordsList, String baseStation) {
        String[] baseParts = baseStation.split(",");
        if (baseParts.length < 4) {
            return null;
        }
        double baseLat = parseDMToDecimal(baseParts[0].trim(), baseParts[1].trim());
        double baseLon = parseDMToDecimal(baseParts[2].trim(), baseParts[3].trim());
        List<Obstacledge.XYCoordinate> xyCoords = new ArrayList<>();
        for (int i = 0; i < originalCoordsList.size(); i += 2) {
            if (i + 1 >= originalCoordsList.size()) break;
            double lat = originalCoordsList.get(i).toDecimalDegree();
            double lon = originalCoordsList.get(i + 1).toDecimalDegree();
            if (Double.isFinite(lat) && Double.isFinite(lon)) {
                double[] localXY = convertLatLonToLocal(lat, lon, baseLat, baseLon);
                xyCoords.add(new Obstacledge.XYCoordinate(localXY[0], localXY[1]));
            }
        }
        return xyCoords;
    }
    private void saveObstacleUpdate(Obstacledge.Obstacle obstacle, JTextArea coordArea) {
        String landNumber = dikuai.getLandNumber();
        try {