From b272034a1fdbfe32b355fc6c264a4c45df107190 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 23 十二月 2025 14:55:03 +0800
Subject: [PATCH] 优化了新增地块功能

---
 src/dikuai/ObstacleManagementPage.java |  179 +++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 148 insertions(+), 31 deletions(-)

diff --git a/src/dikuai/ObstacleManagementPage.java b/src/dikuai/ObstacleManagementPage.java
index 9dc7c5d..5a4d6c5 100644
--- a/src/dikuai/ObstacleManagementPage.java
+++ b/src/dikuai/ObstacleManagementPage.java
@@ -1,5 +1,4 @@
 package dikuai;
-
 import javax.swing.*;
 import javax.swing.border.EmptyBorder;
 import javax.swing.plaf.basic.BasicScrollBarUI;
@@ -11,15 +10,16 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-
 import zhangaiwu.Obstacledge;
 import zhuye.Shouye;
 import zhuye.Coordinate;
-import bianjie.bianjieguihua2;
+import bianjie.Bianjieyouhuatoxy;
 
 /**
  * 闅滅鐗╃鐞嗛〉闈� - UI浼樺寲鐗�
  */
+import publicway.Gpstoxuzuobiao;
+
 public class ObstacleManagementPage extends JDialog {
     private static final long serialVersionUID = 1L;
     
@@ -299,7 +299,17 @@
         JTextArea xyArea = createDataTextArea(genCoords, 3); // 寮曠敤浠ヤ究鏇存柊
         JScrollPane scrollXY = new JScrollPane(xyArea);
         scrollXY.setBorder(BorderFactory.createEmptyBorder()); // 澶栭儴鐢盤anel鎻愪緵杈规
-        
+        // 璁剧疆婊氬姩鏉$瓥鐣ワ細闇�瑕佹椂鏄剧ず鍨傜洿婊氬姩鏉★紝涓嶄娇鐢ㄦ按骞虫粴鍔ㄦ潯锛堝洜涓哄惎鐢ㄤ簡鑷姩鎹㈣锛�
+        scrollXY.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        scrollXY.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        // 璁剧疆婊氬姩鏉″崟浣嶅閲忥紝浣挎粴鍔ㄦ洿娴佺晠
+        scrollXY.getVerticalScrollBar().setUnitIncrement(16);
+        // 璁剧疆婊氬姩闈㈡澘鐨勯閫夊ぇ灏忥紝纭繚鍦ㄥ唴瀹硅秴鍑烘椂鏄剧ず婊氬姩鏉�
+        int lineHeight = xyArea.getFontMetrics(xyArea.getFont()).getHeight();
+        int preferredHeight = 3 * lineHeight + 10; // 3琛岀殑楂樺害
+        scrollXY.setPreferredSize(new Dimension(Integer.MAX_VALUE, preferredHeight));
+        scrollXY.setMaximumSize(new Dimension(Integer.MAX_VALUE, 200)); // 鏈�澶ч珮搴�200鍍忕礌
+
         JPanel xyWrapper = createWrapperPanel("鐢熸垚鍧愭爣 (XY绫�)", scrollXY);
         card.add(xyWrapper);
         card.add(Box.createVerticalStrut(15));
@@ -338,6 +348,16 @@
         JTextArea area = createDataTextArea(content, rows);
         JScrollPane scroll = new JScrollPane(area);
         scroll.setBorder(BorderFactory.createEmptyBorder());
+        // 璁剧疆婊氬姩鏉$瓥鐣ワ細闇�瑕佹椂鏄剧ず鍨傜洿婊氬姩鏉★紝涓嶄娇鐢ㄦ按骞虫粴鍔ㄦ潯锛堝洜涓哄惎鐢ㄤ簡鑷姩鎹㈣锛�
+        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        // 璁剧疆婊氬姩鏉″崟浣嶅閲忥紝浣挎粴鍔ㄦ洿娴佺晠
+        scroll.getVerticalScrollBar().setUnitIncrement(16);
+        // 璁剧疆婊氬姩闈㈡澘鐨勯閫夊ぇ灏忥紝纭繚鍦ㄥ唴瀹硅秴鍑烘椂鏄剧ず婊氬姩鏉�
+        int lineHeight = area.getFontMetrics(area.getFont()).getHeight();
+        int preferredHeight = rows * lineHeight + 10; // 鏍规嵁琛屾暟璁$畻棣栭�夐珮搴�
+        scroll.setPreferredSize(new Dimension(Integer.MAX_VALUE, preferredHeight));
+        scroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, 200)); // 鏈�澶ч珮搴�200鍍忕礌
         return createWrapperPanel(title, scroll);
     }
 
@@ -366,12 +386,13 @@
         JTextArea area = new JTextArea(text);
         area.setRows(rows);
         area.setEditable(false);
+        // 鍚敤鑷姩鎹㈣
         area.setLineWrap(true);
         area.setWrapStyleWord(true);
         area.setBackground(BG_INPUT);
         area.setForeground(new Color(50, 50, 50));
         // 浣跨敤绛夊瀛椾綋鏄剧ず鏁版嵁锛岀湅璧锋潵鏇翠笓涓�
-        area.setFont(new Font("Monospaced", Font.PLAIN, 12)); 
+        area.setFont(new Font("Monospaced", Font.PLAIN, 12));
         return area;
     }
 
@@ -545,6 +566,9 @@
             return;
         }
         
+        // 璁$畻闅滅鐗╃殑涓績鐐瑰潗鏍�
+        double[] centerCoords = calculateObstacleCenter(obstacle);
+        
         List<Obstacledge.Obstacle> allObstacles = loadObstacles();
         String allObstaclesCoords = buildAllObstaclesCoordinates(allObstacles);
         
@@ -568,11 +592,85 @@
                         newPage.setVisible(true);
                     })
                 );
+                
+                // 灏嗗湴鍥捐鍥句腑蹇冭缃负闅滅鐗╃殑涓績浣嶇疆
+                if (centerCoords != null && shouye.getMapRenderer() != null) {
+                    double currentScale = shouye.getMapRenderer().getScale();
+                    // 灏嗚鍥句腑蹇冭缃负闅滅鐗╀腑蹇冿紙浣跨敤璐熷�硷紝鍥犱负translate鏄浉瀵逛簬鍘熺偣鐨勫亸绉伙級
+                    shouye.getMapRenderer().setViewTransform(currentScale, -centerCoords[0], -centerCoords[1]);
+                }
             } else {
                 JOptionPane.showMessageDialog(null, "鏃犳硶鎵撳紑涓婚〉闈㈣繘琛岄瑙�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             }
         });
     }
+    
+    /**
+     * 璁$畻闅滅鐗╃殑涓績鐐瑰潗鏍�
+     * @param obstacle 闅滅鐗�
+     * @return 涓績鐐瑰潗鏍� [centerX, centerY]锛屽鏋滄棤娉曡绠楀垯杩斿洖null
+     */
+    private double[] calculateObstacleCenter(Obstacledge.Obstacle obstacle) {
+        if (obstacle == null) {
+            return null;
+        }
+        
+        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
+        if (xyCoords == null || xyCoords.isEmpty()) {
+            return null;
+        }
+        
+        Obstacledge.ObstacleShape shape = obstacle.getShape();
+        double centerX, centerY;
+        
+        if (shape == Obstacledge.ObstacleShape.CIRCLE) {
+            // 鍦嗗舰闅滅鐗╋細绗竴涓潗鏍囩偣灏辨槸鍦嗗績
+            if (xyCoords.size() < 1) {
+                return null;
+            }
+            Obstacledge.XYCoordinate centerCoord = xyCoords.get(0);
+            centerX = centerCoord.getX();
+            centerY = centerCoord.getY();
+        } else if (shape == Obstacledge.ObstacleShape.POLYGON) {
+            // 澶氳竟褰㈤殰纰嶇墿锛氳绠楅噸蹇�
+            centerX = 0.0;
+            centerY = 0.0;
+            double area = 0.0;
+            int n = xyCoords.size();
+            
+            for (int i = 0; i < n; i++) {
+                Obstacledge.XYCoordinate current = xyCoords.get(i);
+                Obstacledge.XYCoordinate next = xyCoords.get((i + 1) % n);
+                double x0 = current.getX();
+                double y0 = current.getY();
+                double x1 = next.getX();
+                double y1 = next.getY();
+                double cross = x0 * y1 - x1 * y0;
+                area += cross;
+                centerX += (x0 + x1) * cross;
+                centerY += (y0 + y1) * cross;
+            }
+            
+            double areaFactor = area * 0.5;
+            if (Math.abs(areaFactor) < 1e-9) {
+                // 濡傛灉闈㈢Н涓�0鎴栨帴杩�0锛屼娇鐢ㄧ畝鍗曞钩鍧�
+                for (Obstacledge.XYCoordinate coord : xyCoords) {
+                    centerX += coord.getX();
+                    centerY += coord.getY();
+                }
+                int size = Math.max(1, xyCoords.size());
+                centerX /= size;
+                centerY /= size;
+            } else {
+                centerX = centerX / (6.0 * areaFactor);
+                centerY = centerY / (6.0 * areaFactor);
+            }
+        } else {
+            return null;
+        }
+        
+        return new double[]{centerX, centerY};
+    }
 
     private String buildAllObstaclesCoordinates(List<Obstacledge.Obstacle> obstacles) {
         if (obstacles == null || obstacles.isEmpty()) return null;
@@ -699,14 +797,13 @@
                 return null;
             }
             
-            // 璁剧疆鍒板叏灞�鍧愭爣鍒楄〃
-            Coordinate.coordinates.clear();
-            Coordinate.coordinates.addAll(coordinateList);
+            // 鏋勫缓杈圭晫瀛楃涓诧紝鏍煎紡涓� "(lat1,lon1,alt1;lat2,lon2,alt2;...)"
+            String boundaryStr = buildBoundaryStringForOptimization(coordinateList);
             
-            // 璋冪敤 bianjieguihua2 绠楁硶鐢熸垚浼樺寲鍚庣殑澶氳竟褰㈠潗鏍�
-            String optimizedCoordsStr = bianjieguihua2.processCoordinateListAuto(baseStation);
+            // 璋冪敤 Bianjieyouhuatoxy.optimizeBoundary 鏂规硶鐢熸垚浼樺寲鍚庣殑澶氳竟褰㈠潗鏍�
+            String optimizedCoordsStr = Bianjieyouhuatoxy.optimizeBoundary(baseStation, boundaryStr);
             
-            if (optimizedCoordsStr == null || optimizedCoordsStr.trim().isEmpty()) {
+            if (optimizedCoordsStr == null || optimizedCoordsStr.trim().isEmpty() || optimizedCoordsStr.startsWith("ERROR")) {
                 return null;
             }
             
@@ -742,6 +839,34 @@
     }
     
     /**
+     * 鏋勫缓鐢ㄤ簬浼樺寲鐨勮竟鐣屽瓧绗︿覆锛屾牸寮忎负 "(lat1,lon1,alt1;lat2,lon2,alt2;...)"
+     * 鍏朵腑lat鍜宭on鏄害鍒嗘牸寮忥紙DMM鏍煎紡锛夛紝渚嬪 "3949.89151752"
+     */
+    private String buildBoundaryStringForOptimization(List<Coordinate> coordinates) {
+        if (coordinates == null || coordinates.isEmpty()) {
+            return "()";
+        }
+        StringBuilder sb = new StringBuilder("(");
+        java.text.DecimalFormat elevationFormat = new java.text.DecimalFormat("0.00");
+        for (int i = 0; i < coordinates.size(); i++) {
+            Coordinate coord = coordinates.get(i);
+            // Coordinate绫讳腑鐨刧etLatitude()鍜実etLongitude()宸茬粡杩斿洖搴﹀垎鏍煎紡锛圖MM鏍煎紡锛�
+            String latDMM = coord.getLatitude();
+            String lonDMM = coord.getLongitude();
+            double elevation = coord.getElevation();
+            
+            if (i > 0) {
+                sb.append(";");
+            }
+            sb.append(latDMM).append(",")
+              .append(lonDMM).append(",")
+              .append(elevationFormat.format(elevation));
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+    
+    /**
      * 鏍煎紡鍖栧害鍒嗘牸寮忓潗鏍�
      * @param degreeMinute 搴﹀垎鍊硷紝濡� 2324.200273 琛ㄧず 23搴�24.200273鍒�
      * @return 鏍煎紡鍖栫殑瀛楃涓�
@@ -806,29 +931,11 @@
     }
 
     private double parseDMToDecimal(String dmm, String direction) {
-        if (dmm == null || dmm.trim().isEmpty()) return Double.NaN;
-        try {
-            String trimmed = dmm.trim();
-            int dotIndex = trimmed.indexOf('.');
-            if (dotIndex < 2) return Double.NaN;
-            int degrees = Integer.parseInt(trimmed.substring(0, dotIndex - 2));
-            double minutes = Double.parseDouble(trimmed.substring(dotIndex - 2));
-            double decimal = degrees + minutes / 60.0;
-            if ("S".equalsIgnoreCase(direction) || "W".equalsIgnoreCase(direction)) decimal = -decimal;
-            return decimal;
-        } catch (NumberFormatException ex) {
-            return Double.NaN;
-        }
+        return Gpstoxuzuobiao.parseDMToDecimal(dmm, direction);
     }
     
     private double[] convertLatLonToLocal(double lat, double lon, double baseLat, double baseLon) {
-        double deltaLat = lat - baseLat;
-        double deltaLon = lon - baseLon;
-        double meanLatRad = Math.toRadians((baseLat + lat) / 2.0);
-        double METERS_PER_DEGREE_LAT = 111320.0;
-        double eastMeters = deltaLon * METERS_PER_DEGREE_LAT * Math.cos(meanLatRad);
-        double northMeters = deltaLat * METERS_PER_DEGREE_LAT;
-        return new double[]{eastMeters, northMeters};
+        return Gpstoxuzuobiao.convertLatLonToLocal(lat, lon, baseLat, baseLon);
     }
     
     private void deleteObstacle(Obstacledge.Obstacle obstacle) {
@@ -897,3 +1004,13 @@
         return value != null && !value.trim().isEmpty() && !"-1".equals(value.trim());
     }
 }
+
+
+
+
+
+
+
+
+
+

--
Gitblit v1.10.0