From 6b1447fb1794e08f8e5f580b83ae5eabe4e617d8 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期三, 24 十二月 2025 16:28:46 +0800
Subject: [PATCH] 登录页面启用

---
 src/zhangaiwu/AddDikuai.java | 1370 ++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 922 insertions(+), 448 deletions(-)

diff --git a/src/zhangaiwu/AddDikuai.java b/src/zhangaiwu/AddDikuai.java
index 32a7a4f..65e96d6 100644
--- a/src/zhangaiwu/AddDikuai.java
+++ b/src/zhangaiwu/AddDikuai.java
@@ -1,7 +1,5 @@
 package zhangaiwu;
-
 import javax.swing.*;
-
 import java.awt.*;
 import java.awt.event.*;
 import java.io.File;
@@ -9,10 +7,8 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -20,20 +16,23 @@
 import java.util.Map;
 import java.util.Comparator;
 import java.awt.geom.Point2D;
-
 import baseStation.BaseStation;
 import bianjie.jisuanmianjie;
 import dikuai.Dikuai;
 import dikuai.Dikuaiguanli;
-import bianjie.bianjieguihua2;
+import dikuai.Gecaokuanjisuan;
+import dikuai.Gecaoanquanjuli;
+import bianjie.Bianjieyouhuatoxy;
 import lujing.Lunjingguihua;
-import publicway.buttonset;
+import lujing.Qufenxingzhuang;
+import lujing.AoxinglujingNoObstacle;
+import lujing.YixinglujingNoObstacle;
 import set.Setsys;
 import ui.UIConfig;
 import zhuye.MowerLocationData;
 import zhuye.Shouye;
 import zhuye.Coordinate;
-import gecaoji.Device;
+import publicway.buttonset;
 
 /**
  * 鏂板鍦板潡瀵硅瘽妗� - 澶氭楠よ〃鍗曡璁�
@@ -66,10 +65,9 @@
     private JTextField landNumberField;
     private JTextField areaNameField;
     private JComboBox<String> mowingPatternCombo;
-    private JTextField mowingWidthField; // 鍓茶崏鏈哄壊鍒�瀹藉害
-    private JTextField overlapDistanceField; // 鐩搁偦琛岄噸鍙犺窛绂�
-    private JTextField mowingSafetyDistanceField; // 鍓茶崏瀹夊叏璺濈
-    private JLabel calculatedMowingWidthLabel; // 璁$畻鍚庣殑鍓茶崏瀹藉害鏄剧ず
+    private JTextField bladeWidthField;  // 鍓茶崏鏈哄壊鍒�瀹藉害锛坢锛�
+    private JTextField mowingWidthField;  // 鍓茶崏瀹藉害锛坢锛屽彲缂栬緫锛�
+    private JTextField safetyDistanceField;  // 鍓茶崏瀹夊叏璺濈锛坢锛屽彲缂栬緫锛�
     private JPanel previewPanel;
     private Map<String, JPanel> drawingOptionPanels = new HashMap<>();
     
@@ -78,9 +76,12 @@
     private JButton prevButton;
     private JButton nextButton;
     private JButton createButton;
-    private JButton previewButton;
+    private JButton previewButton;  // 姝ラ3鐨勯瑙堟寜閽紙棰勮鍓茶崏璺緞锛�
+    private JButton boundaryPreviewButton;  // 姝ラ2鐨勯瑙堟寜閽紙棰勮杈圭晫锛�
     private Component previewButtonSpacer;
     private JLabel boundaryCountLabel;
+    private JTextArea boundaryXYTextArea;  // 鏄剧ず杈圭晫XY鍧愭爣鐨勬枃鏈煙
+    private JScrollPane boundaryXYScrollPane;  // 杈圭晫XY鍧愭爣鏂囨湰鍩熺殑婊氬姩闈㈡澘
     private JPanel obstacleListContainer;
     private JTextArea pathGenerationMessageArea;
     private JPanel pathMessageWrapper;
@@ -263,7 +264,7 @@
         ));
         areaNameField.setAlignmentX(Component.LEFT_ALIGNMENT);
         
-        // 娣诲姞杈撳叆妗嗙劍鐐规晥鏋�
+        // 娣诲姞杈撳叆妗嗙劍鐐规晥鏋滃拰鏂囨湰鍙樺寲鐩戝惉
         areaNameField.addFocusListener(new FocusAdapter() {
             @Override
             public void focusGained(FocusEvent e) {
@@ -279,6 +280,16 @@
                     BorderFactory.createLineBorder(BORDER_COLOR, 2),
                     BorderFactory.createEmptyBorder(12, 15, 12, 15)
                 ));
+                // 鏇存柊涓嬩竴姝ユ寜閽姸鎬�
+                updateStep1ButtonState();
+            }
+        });
+        
+        // 娣诲姞鏂囨湰鍙樺寲鐩戝惉锛屽疄鏃舵洿鏂版寜閽姸鎬�
+        areaNameField.addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyReleased(KeyEvent e) {
+                updateStep1ButtonState();
             }
         });
         
@@ -296,6 +307,10 @@
         formGroup.add(areaNameField);
         formGroup.add(Box.createRigidArea(new Dimension(0, 8)));
         formGroup.add(hintLabel);
+
+    formGroup.add(Box.createRigidArea(new Dimension(0, 20)));
+    JPanel obstacleSection = createObstacleSummarySection();
+    formGroup.add(obstacleSection);
         
         stepPanel.add(formGroup);
         stepPanel.add(Box.createVerticalGlue());
@@ -653,10 +668,39 @@
         startEndDrawingBtn.setAlignmentX(Component.LEFT_ALIGNMENT);
         startEndDrawingBtn.setMaximumSize(new Dimension(400, 55));
         startEndDrawingBtn.setEnabled(false); // 鍒濆涓嶅彲鐢�
+        startEndDrawingBtn.setBackground(MEDIUM_GRAY); // 鍒濆鐏拌壊鑳屾櫙
         
         startEndDrawingBtn.addActionListener(e -> toggleDrawing());
         
         stepPanel.add(startEndDrawingBtn);
+        
+        // 杈圭晫XY鍧愭爣鏄剧ず鏂囨湰鍩燂紙3琛岋紝甯︽粴鍔ㄦ潯锛屽湪宸插畬鎴愭寜閽笅鏂癸級
+        boundaryXYTextArea = new JTextArea(3, 0);
+        boundaryXYTextArea.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 12));
+        boundaryXYTextArea.setForeground(TEXT_COLOR);
+        boundaryXYTextArea.setEditable(false);
+        boundaryXYTextArea.setBackground(LIGHT_GRAY);
+        boundaryXYTextArea.setLineWrap(true);
+        boundaryXYTextArea.setWrapStyleWord(true);
+        boundaryXYTextArea.setAlignmentX(Component.LEFT_ALIGNMENT);
+        boundaryXYTextArea.setVisible(false);
+        
+        // 鍒涘缓婊氬姩闈㈡澘锛岄粯璁ゆ樉绀�3琛�
+        boundaryXYScrollPane = new JScrollPane(boundaryXYTextArea);
+        boundaryXYScrollPane.setBorder(BorderFactory.createCompoundBorder(
+            BorderFactory.createLineBorder(BORDER_COLOR, 1),
+            BorderFactory.createEmptyBorder(0, 0, 0, 0)
+        ));
+        boundaryXYScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        boundaryXYScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        boundaryXYScrollPane.getVerticalScrollBar().setUnitIncrement(16);
+        boundaryXYScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
+        boundaryXYScrollPane.setVisible(false);
+        boundaryXYScrollPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, 80));
+        
+        stepPanel.add(Box.createRigidArea(new Dimension(0, 15)));
+        stepPanel.add(boundaryXYScrollPane);
+        
         boundaryCountLabel = new JLabel("宸查噰闆嗗埌杈圭晫鐐�0涓�");
         boundaryCountLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
         boundaryCountLabel.setForeground(LIGHT_TEXT);
@@ -744,7 +788,7 @@
                     return;
                 }
                 if (selectDrawingOption(optionPanel, type, true)) {
-                    startEndDrawingBtn.setEnabled(true); // 閫夋嫨鍚庡惎鐢ㄦ寜閽�
+                    updateStartDrawingButtonState(); // 閫夋嫨鍚庢洿鏂版寜閽姸鎬�
                 }
             }
             
@@ -772,7 +816,7 @@
             return false;
         }
         if (userTriggered && "handheld".equalsIgnoreCase(type) && !hasConfiguredHandheldMarker()) {
-            JOptionPane.showMessageDialog(this, "璇峰厛鍘荤郴缁熻缃坊鍔犱究鎼烘墦鐐瑰櫒缂栧彿", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            JOptionPane.showMessageDialog(this, "璇峰厛娣诲姞渚挎惡鎵撶偣鍣ㄧ紪鍙�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             return false;
         }
 
@@ -825,12 +869,20 @@
             // 鐢ㄦ埛鍦ㄥ璇濇鍐呬富鍔ㄧ粨鏉燂紙鏈Е鍙戝閮ㄦ祦绋嬶級
             isDrawing = false;
             Coordinate.setStartSaveGngga(false);
-            startEndDrawingBtn.setText("寮�濮嬬粯鍒�");
-            startEndDrawingBtn.setBackground(PRIMARY_COLOR);
-            updateOtherOptionsState(false);
+            startEndDrawingBtn.setText("宸插畬鎴�");
+            startEndDrawingBtn.setBackground(MEDIUM_GRAY);
+            startEndDrawingBtn.setEnabled(false);
+            updateOtherOptionsState(true);
+            
+            // 浼樺寲杈圭晫
+            optimizeBoundaryAndSave();
+            
             dikuaiData.put("boundaryDrawn", "true");
             JOptionPane.showMessageDialog(this, "杈圭晫缁樺埗宸插畬鎴�", "鎻愮ず", JOptionPane.INFORMATION_MESSAGE);
             showBoundaryPointSummary();
+            updateBoundaryXYDisplay();
+            // 鏇存柊棰勮鍜屼笅涓�姝ユ寜閽姸鎬侊紙鑳屾櫙棰滆壊鍙樼豢鑹诧紝鍙偣鍑伙級
+            updateStep2ButtonsAfterDrawing();
         }
     }
 
@@ -881,6 +933,80 @@
         hideBoundaryPointSummary();
     }
     
+    /**
+     * 浼樺寲杈圭晫骞朵繚瀛樹紭鍖栧悗鐨勬暟鎹�
+     */
+    private void optimizeBoundaryAndSave() {
+        try {
+            // 鑾峰彇鍩哄噯绔欏潗鏍�
+            BaseStation baseStation = new BaseStation();
+            baseStation.load();
+            String baseStationCoordinates = normalizeCoordinateValue(baseStation.getInstallationCoordinates());
+            if (!isMeaningfulValue(baseStationCoordinates)) {
+                System.err.println("鏈幏鍙栧埌鏈夋晥鐨勫熀鍑嗙珯鍧愭爣锛屾棤娉曚紭鍖栬竟鐣�");
+                return;
+            }
+            
+            // 鑾峰彇鍘熷鍧愭爣鍒楄〃
+            List<Coordinate> uniqueCoordinates;
+            synchronized (Coordinate.coordinates) {
+                uniqueCoordinates = sanitizeCoordinateList(Coordinate.coordinates);
+            }
+            
+            if (uniqueCoordinates.size() < 3) {
+                System.err.println("閲囬泦鐨勮竟鐣岀偣涓嶈冻锛屾棤娉曚紭鍖栬竟鐣�");
+                return;
+            }
+            
+            // 鏋勫缓杈圭晫瀛楃涓诧紝鏍煎紡涓� "(lat1,lon1,alt1;lat2,lon2,alt2;...)"
+            String boundaryStr = buildBoundaryStringForOptimization(uniqueCoordinates);
+            
+            // 璋冪敤浼樺寲鏂规硶
+            String optimizedXYStr = Bianjieyouhuatoxy.optimizeBoundary(baseStationCoordinates, boundaryStr);
+            
+            // 淇濆瓨浼樺寲鍚庣殑XY鍧愭爣瀛楃涓�
+            if (optimizedXYStr != null && !optimizedXYStr.isEmpty() && !optimizedXYStr.startsWith("ERROR")) {
+                dikuaiData.put("optimizedBoundaryXY", optimizedXYStr);
+                if (activeSession != null) {
+                    activeSession.data.put("optimizedBoundaryXY", optimizedXYStr);
+                }
+            } else {
+                System.err.println("杈圭晫浼樺寲澶辫触: " + optimizedXYStr);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println("浼樺寲杈圭晫鏃跺彂鐢熼敊璇�: " + e.getMessage());
+        }
+    }
+    
+    /**
+     * 鏋勫缓鐢ㄤ簬浼樺寲鐨勮竟鐣屽瓧绗︿覆锛屾牸寮忎负 "(lat1,lon1,alt1;lat2,lon2,alt2;...)"
+     * 鍏朵腑lat鍜宭on鏄害鍒嗘牸寮忥紙DMM鏍煎紡锛夛紝渚嬪 "3949.89151752"
+     */
+    private static String buildBoundaryStringForOptimization(List<Coordinate> coordinates) {
+        if (coordinates == null || coordinates.isEmpty()) {
+            return "()";
+        }
+        StringBuilder sb = new StringBuilder("(");
+        DecimalFormat elevationFormat = new 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();
+    }
+    
     private JPanel createStep3Panel() {
         JPanel stepPanel = new JPanel();
         stepPanel.setLayout(new BoxLayout(stepPanel, BoxLayout.Y_AXIS));
@@ -902,7 +1028,7 @@
         settingsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
         
         // 鍓茶崏妯″紡閫夋嫨
-        JPanel patternPanel = createFormGroupWithoutHint("鍓茶崏妯″紡");
+        JPanel patternPanel = createFormGroup("鍓茶崏妯″紡", "");
         mowingPatternCombo = new JComboBox<>(new String[]{"骞宠绾�", "铻烘棆寮�"});
         mowingPatternCombo.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
         mowingPatternCombo.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
@@ -934,23 +1060,65 @@
         
         patternPanel.add(mowingPatternCombo);
         settingsPanel.add(patternPanel);
-        settingsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+        settingsPanel.add(Box.createRigidArea(new Dimension(0, 20)));
         
         // 鍓茶崏鏈哄壊鍒�瀹藉害璁剧疆
-        JPanel widthPanel = createFormGroupWithoutHint("鍓茶崏鏈哄壊鍒�瀹藉害");
+        JPanel bladeWidthPanel = createFormGroup("鍓茶崏鏈哄壊鍒�瀹藉害", "");
+        JPanel bladeWidthInputPanel = new JPanel(new BorderLayout());
+        bladeWidthInputPanel.setBackground(WHITE);
+        bladeWidthInputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
+        bladeWidthInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+        
+        bladeWidthField = new JTextField("0.50");
+        bladeWidthField.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
+        bladeWidthField.setBorder(BorderFactory.createCompoundBorder(
+            BorderFactory.createLineBorder(BORDER_COLOR, 2),
+            BorderFactory.createEmptyBorder(10, 12, 10, 12)
+        ));
+        bladeWidthField.addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                bladeWidthField.setBorder(BorderFactory.createCompoundBorder(
+                    BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
+                    BorderFactory.createEmptyBorder(10, 12, 10, 12)
+                ));
+            }
+            
+            @Override
+            public void focusLost(FocusEvent e) {
+                bladeWidthField.setBorder(BorderFactory.createCompoundBorder(
+                    BorderFactory.createLineBorder(BORDER_COLOR, 2),
+                    BorderFactory.createEmptyBorder(10, 12, 10, 12)
+                ));
+                updateMowingWidthAndSafetyDistance();
+            }
+        });
+        
+        JLabel bladeUnitLabel = new JLabel("m");
+        bladeUnitLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
+        bladeUnitLabel.setForeground(LIGHT_TEXT);
+        bladeUnitLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
+        
+        bladeWidthInputPanel.add(bladeWidthField, BorderLayout.CENTER);
+        bladeWidthInputPanel.add(bladeUnitLabel, BorderLayout.EAST);
+        
+        bladeWidthPanel.add(bladeWidthInputPanel);
+        settingsPanel.add(bladeWidthPanel);
+        settingsPanel.add(Box.createRigidArea(new Dimension(0, 20)));
+        
+        // 鍓茶崏瀹藉害璁剧疆锛堝彲缂栬緫锛�
+        JPanel widthPanel = createFormGroup("鍓茶崏瀹藉害", "璁$畻鏂规硶锛氬壊鑽夊搴� = 鍓插垁瀹� 脳85%");
         JPanel widthInputPanel = new JPanel(new BorderLayout());
         widthInputPanel.setBackground(WHITE);
         widthInputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
         widthInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
         
-        mowingWidthField = new JTextField("0.40");
+        mowingWidthField = new JTextField();
         mowingWidthField.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
         mowingWidthField.setBorder(BorderFactory.createCompoundBorder(
             BorderFactory.createLineBorder(BORDER_COLOR, 2),
             BorderFactory.createEmptyBorder(10, 12, 10, 12)
         ));
-        
-        // 娣诲姞鏂囨湰妗嗙劍鐐规晥鏋滃拰鍙樺寲鐩戝惉
         mowingWidthField.addFocusListener(new FocusAdapter() {
             @Override
             public void focusGained(FocusEvent e) {
@@ -966,11 +1134,10 @@
                     BorderFactory.createLineBorder(BORDER_COLOR, 2),
                     BorderFactory.createEmptyBorder(10, 12, 10, 12)
                 ));
-                updateCalculatedMowingWidth();
             }
         });
         
-        JLabel unitLabel = new JLabel("绫�");
+        JLabel unitLabel = new JLabel("m");
         unitLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
         unitLabel.setForeground(LIGHT_TEXT);
         unitLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
@@ -980,107 +1147,25 @@
         
         widthPanel.add(widthInputPanel);
         settingsPanel.add(widthPanel);
-        settingsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+        settingsPanel.add(Box.createRigidArea(new Dimension(0, 20)));
         
-        // 鐩搁偦琛岄噸鍙犺窛绂昏缃�
-        JPanel overlapPanel = createFormGroupWithoutHint("鐩搁偦琛岄噸鍙犺窛绂�");
-        JPanel overlapInputPanel = new JPanel(new BorderLayout());
-        overlapInputPanel.setBackground(WHITE);
-        overlapInputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
-        overlapInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
-        
-        overlapDistanceField = new JTextField("0.06");
-        overlapDistanceField.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
-        overlapDistanceField.setBorder(BorderFactory.createCompoundBorder(
-            BorderFactory.createLineBorder(BORDER_COLOR, 2),
-            BorderFactory.createEmptyBorder(10, 12, 10, 12)
-        ));
-        
-        // 娣诲姞鏂囨湰妗嗙劍鐐规晥鏋滃拰鍙樺寲鐩戝惉
-        overlapDistanceField.addFocusListener(new FocusAdapter() {
-            @Override
-            public void focusGained(FocusEvent e) {
-                overlapDistanceField.setBorder(BorderFactory.createCompoundBorder(
-                    BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
-                    BorderFactory.createEmptyBorder(10, 12, 10, 12)
-                ));
-            }
-            
-            @Override
-            public void focusLost(FocusEvent e) {
-                overlapDistanceField.setBorder(BorderFactory.createCompoundBorder(
-                    BorderFactory.createLineBorder(BORDER_COLOR, 2),
-                    BorderFactory.createEmptyBorder(10, 12, 10, 12)
-                ));
-                updateCalculatedMowingWidth();
-            }
-        });
-        
-        JLabel overlapUnitLabel = new JLabel("绫�");
-        overlapUnitLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
-        overlapUnitLabel.setForeground(LIGHT_TEXT);
-        overlapUnitLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
-        
-        overlapInputPanel.add(overlapDistanceField, BorderLayout.CENTER);
-        overlapInputPanel.add(overlapUnitLabel, BorderLayout.EAST);
-        
-        overlapPanel.add(overlapInputPanel);
-        settingsPanel.add(overlapPanel);
-        settingsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
-        
-        // 鍓茶崏瀹藉害鏄剧ず锛堣嚜鍔ㄨ绠楋紝涓嶅彲淇敼锛�
-        JPanel calculatedWidthPanel = createFormGroup("鍓茶崏瀹藉害", "鍓茶崏瀹藉害 = 鍓茶崏鏈哄壊鍒�瀹藉害 - 閲嶅彔璺濈锛堣嚜鍔ㄨ绠楋級");
-        JPanel calculatedWidthDisplayPanel = new JPanel(new BorderLayout());
-        calculatedWidthDisplayPanel.setBackground(LIGHT_GRAY);
-        calculatedWidthDisplayPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
-        calculatedWidthDisplayPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
-        calculatedWidthDisplayPanel.setBorder(BorderFactory.createCompoundBorder(
-            BorderFactory.createLineBorder(BORDER_COLOR, 2),
-            BorderFactory.createEmptyBorder(10, 12, 10, 12)
-        ));
-        
-        calculatedMowingWidthLabel = new JLabel("0.00 绫�");
-        calculatedMowingWidthLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
-        calculatedMowingWidthLabel.setForeground(TEXT_COLOR);
-        calculatedWidthDisplayPanel.add(calculatedMowingWidthLabel, BorderLayout.CENTER);
-        
-        calculatedWidthPanel.add(calculatedWidthDisplayPanel);
-        settingsPanel.add(calculatedWidthPanel);
-        settingsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
-        
-        // 鍓茶崏瀹夊叏璺濈
-        JPanel safetyDistancePanel = createFormGroupWithoutHint("鍓茶崏瀹夊叏璺濈");
+        // 鍓茶崏瀹夊叏璺濈璁剧疆锛堝彲缂栬緫锛�
+        JPanel safetyDistancePanel = createFormGroup("鍓茶崏瀹夊叏璺濈", "鏍规嵁鍓茶崏鏈哄昂瀵歌嚜鍔ㄨ绠楃殑瀹夊叏璺濈");
         JPanel safetyDistanceInputPanel = new JPanel(new BorderLayout());
         safetyDistanceInputPanel.setBackground(WHITE);
         safetyDistanceInputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
         safetyDistanceInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
         
-        // 鑾峰彇榛樿鍊�
-        String defaultSafetyDistance = "0.5"; // 榛樿鍊�
-        try {
-            Device device = Device.getGecaoji();
-            if (device != null) {
-                String safetyDistance = device.getMowingSafetyDistance();
-                if (safetyDistance != null && !safetyDistance.trim().isEmpty() && !"-1".equals(safetyDistance.trim())) {
-                    defaultSafetyDistance = safetyDistance.trim();
-                }
-            }
-        } catch (Exception e) {
-            // 濡傛灉鑾峰彇澶辫触锛屼娇鐢ㄩ粯璁ゅ��
-        }
-        
-        mowingSafetyDistanceField = new JTextField(defaultSafetyDistance);
-        mowingSafetyDistanceField.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
-        mowingSafetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
+        safetyDistanceField = new JTextField();
+        safetyDistanceField.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
+        safetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
             BorderFactory.createLineBorder(BORDER_COLOR, 2),
             BorderFactory.createEmptyBorder(10, 12, 10, 12)
         ));
-        
-        // 娣诲姞鏂囨湰妗嗙劍鐐规晥鏋�
-        mowingSafetyDistanceField.addFocusListener(new FocusAdapter() {
+        safetyDistanceField.addFocusListener(new FocusAdapter() {
             @Override
             public void focusGained(FocusEvent e) {
-                mowingSafetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
+                safetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
                     BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
                     BorderFactory.createEmptyBorder(10, 12, 10, 12)
                 ));
@@ -1088,29 +1173,37 @@
             
             @Override
             public void focusLost(FocusEvent e) {
-                mowingSafetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
+                safetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
                     BorderFactory.createLineBorder(BORDER_COLOR, 2),
                     BorderFactory.createEmptyBorder(10, 12, 10, 12)
                 ));
             }
         });
         
-        JLabel safetyDistanceUnitLabel = new JLabel("绫�");
-        safetyDistanceUnitLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
-        safetyDistanceUnitLabel.setForeground(LIGHT_TEXT);
-        safetyDistanceUnitLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
+        JLabel safetyUnitLabel = new JLabel("m");
+        safetyUnitLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
+        safetyUnitLabel.setForeground(LIGHT_TEXT);
+        safetyUnitLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
         
-        safetyDistanceInputPanel.add(mowingSafetyDistanceField, BorderLayout.CENTER);
-        safetyDistanceInputPanel.add(safetyDistanceUnitLabel, BorderLayout.EAST);
+        safetyDistanceInputPanel.add(safetyDistanceField, BorderLayout.CENTER);
+        safetyDistanceInputPanel.add(safetyUnitLabel, BorderLayout.EAST);
         
         safetyDistancePanel.add(safetyDistanceInputPanel);
         settingsPanel.add(safetyDistancePanel);
         settingsPanel.add(Box.createRigidArea(new Dimension(0, 25)));
         
-        stepPanel.add(settingsPanel);
+        // 鍒濆鍖栬绠楀��
+        updateMowingWidthAndSafetyDistance();
         
-        // 鍒濆鍖栬绠楀悗鐨勫壊鑽夊搴�
-        updateCalculatedMowingWidth();
+        // 灏嗚缃潰鏉挎斁鍏ユ粴鍔ㄩ潰鏉�
+        JScrollPane scrollPane = new JScrollPane(settingsPanel);
+        scrollPane.setBorder(null);
+        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        scrollPane.getVerticalScrollBar().setUnitIncrement(16);
+        scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
+        
+        stepPanel.add(scrollPane);
         
         JButton generatePathButton = createPrimaryButton("鐢熸垚鍓茶崏璺緞", 16);
         generatePathButton.setAlignmentX(Component.LEFT_ALIGNMENT);
@@ -1147,41 +1240,6 @@
         return stepPanel;
     }
     
-    /**
-     * 鏇存柊璁$畻鍚庣殑鍓茶崏瀹藉害鏄剧ず
-     */
-    private void updateCalculatedMowingWidth() {
-        if (calculatedMowingWidthLabel == null || mowingWidthField == null || overlapDistanceField == null) {
-            return;
-        }
-        
-        try {
-            String widthText = mowingWidthField.getText().trim();
-            String overlapText = overlapDistanceField.getText().trim();
-            
-            if (widthText.isEmpty() || overlapText.isEmpty()) {
-                calculatedMowingWidthLabel.setText("0.00 绫�");
-                return;
-            }
-            
-            double bladeWidthMeters = Double.parseDouble(widthText);
-            double overlapMeters = Double.parseDouble(overlapText);
-            double calculatedWidthMeters = bladeWidthMeters - overlapMeters;
-            
-            if (calculatedWidthMeters <= 0) {
-                calculatedMowingWidthLabel.setText("鏃犳晥锛堝壊鍒�瀹藉害闇�澶т簬閲嶅彔璺濈锛�");
-                calculatedMowingWidthLabel.setForeground(ERROR_COLOR);
-            } else {
-                calculatedMowingWidthLabel.setText(String.format(Locale.US, "%.2f 绫�", calculatedWidthMeters));
-                calculatedMowingWidthLabel.setForeground(TEXT_COLOR);
-            }
-        } catch (NumberFormatException e) {
-            calculatedMowingWidthLabel.setText("0.00 绫�");
-        } catch (Exception e) {
-            calculatedMowingWidthLabel.setText("0.00 绫�");
-        }
-    }
-    
     private JPanel createInstructionPanel(String text) {
         JPanel instructionPanel = new JPanel(new BorderLayout());
         instructionPanel.setBackground(PRIMARY_LIGHT);
@@ -1220,36 +1278,67 @@
         nameLabel.setForeground(TEXT_COLOR);
         nameLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
         
-        JLabel hintLabel = new JLabel(hint);
-        hintLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 13));
-        hintLabel.setForeground(LIGHT_TEXT);
-        hintLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
-        
         formGroup.add(nameLabel);
-        formGroup.add(Box.createRigidArea(new Dimension(0, 6)));
-        formGroup.add(hintLabel);
-        formGroup.add(Box.createRigidArea(new Dimension(0, 8)));
         
-        return formGroup;
-    }
-    
-    private JPanel createFormGroupWithoutHint(String label) {
-        JPanel formGroup = new JPanel();
-        formGroup.setLayout(new BoxLayout(formGroup, BoxLayout.Y_AXIS));
-        formGroup.setBackground(WHITE);
-        formGroup.setAlignmentX(Component.LEFT_ALIGNMENT);
-        
-        JLabel nameLabel = new JLabel(label);
-        nameLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 16));
-        nameLabel.setForeground(TEXT_COLOR);
-        nameLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
-        
-        formGroup.add(nameLabel);
-        formGroup.add(Box.createRigidArea(new Dimension(0, 8)));
+        // 鍙湁褰撴彁绀烘枃瀛椾笉涓虹┖鏃舵墠鏄剧ず
+        if (hint != null && !hint.trim().isEmpty()) {
+            formGroup.add(Box.createRigidArea(new Dimension(0, 6)));
+            JLabel hintLabel = new JLabel(hint);
+            hintLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 13));
+            hintLabel.setForeground(LIGHT_TEXT);
+            hintLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
+            formGroup.add(hintLabel);
+            formGroup.add(Box.createRigidArea(new Dimension(0, 8)));
+        } else {
+            formGroup.add(Box.createRigidArea(new Dimension(0, 8)));
+        }
         
         return formGroup;
     }
 
+    /**
+     * 鏍规嵁鍓插垁瀹藉害鏇存柊鍓茶崏瀹藉害鍜屽畨鍏ㄨ窛绂�
+     */
+    private void updateMowingWidthAndSafetyDistance() {
+        try {
+            String bladeWidthStr = bladeWidthField.getText().trim();
+            if (bladeWidthStr == null || bladeWidthStr.isEmpty()) {
+                mowingWidthField.setText("");
+                safetyDistanceField.setText("");
+                return;
+            }
+            
+            double bladeWidthMeters = Double.parseDouble(bladeWidthStr);
+            if (bladeWidthMeters <= 0) {
+                mowingWidthField.setText("");
+                safetyDistanceField.setText("");
+                return;
+            }
+            
+            // 璋冪敤 Gecaokuanjisuan 绫昏绠楀壊鑽夊搴︼紙杩斿洖鍘樼背锛屼繚鐣�2浣嶅皬鏁帮紝闇�瑕佽浆鎹负绫筹級
+            double mowingWidthCm = Gecaokuanjisuan.calculateMowingWidth(bladeWidthMeters);
+            if (mowingWidthCm > 0) {
+                // 灏嗗帢绫宠浆鎹负绫筹紝骞朵繚鐣�2浣嶅皬鏁�
+                double mowingWidthMeters = mowingWidthCm / 100.0;
+                mowingWidthField.setText(String.format(Locale.US, "%.2f", mowingWidthMeters));
+            } else {
+                mowingWidthField.setText("");
+            }
+            
+            // 璋冪敤 Gecaoanquanjuli 绫昏绠楀畨鍏ㄨ窛绂�
+            String safetyDistanceStr = Gecaoanquanjuli.calculateSafetyDistanceFromString(bladeWidthStr);
+            safetyDistanceField.setText(safetyDistanceStr);
+            
+        } catch (NumberFormatException e) {
+            mowingWidthField.setText("");
+            safetyDistanceField.setText("");
+        } catch (Exception e) {
+            e.printStackTrace();
+            mowingWidthField.setText("");
+            safetyDistanceField.setText("");
+        }
+    }
+    
     private void generateMowingPath() {
         if (!dikuaiData.containsKey("boundaryDrawn")) {
             JOptionPane.showMessageDialog(this, "璇峰厛瀹屾垚杈圭晫缁樺埗鍚庡啀鐢熸垚璺緞", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
@@ -1259,15 +1348,34 @@
             showStep(2);
             return;
         }
-        Dikuai dikuai = getOrCreatePendingDikuai();
+        // 浠庢楠�2鐨勮竟鐣屽潗鏍囨枃鏈煙鑾峰彇杈圭晫鍧愭爣
         String boundaryCoords = null;
-        if (dikuai != null) {
-            boundaryCoords = normalizeCoordinateValue(dikuai.getBoundaryCoordinates());
+        if (boundaryXYTextArea != null) {
+            String boundaryText = boundaryXYTextArea.getText();
+            if (boundaryText != null && !boundaryText.trim().isEmpty() && !boundaryText.startsWith("ERROR")) {
+                boundaryCoords = boundaryText.trim();
+            }
         }
-        if (boundaryCoords == null) {
+        
+        // 濡傛灉鏂囨湰鍩熶腑娌℃湁锛屽皾璇曚粠dikuaiData鑾峰彇
+        if (boundaryCoords == null || boundaryCoords.isEmpty()) {
+            boundaryCoords = normalizeCoordinateValue(dikuaiData.get("optimizedBoundaryXY"));
+        }
+        
+        // 濡傛灉杩樻槸娌℃湁锛屽皾璇曚粠Dikuai瀵硅薄鑾峰彇
+        if (boundaryCoords == null || boundaryCoords.isEmpty()) {
+            Dikuai dikuai = getOrCreatePendingDikuai();
+            if (dikuai != null) {
+                boundaryCoords = normalizeCoordinateValue(dikuai.getBoundaryCoordinates());
+            }
+        }
+        
+        // 濡傛灉杩樻槸娌℃湁锛屼粠dikuaiData鑾峰彇boundaryCoordinates
+        if (boundaryCoords == null || boundaryCoords.isEmpty()) {
             boundaryCoords = normalizeCoordinateValue(dikuaiData.get("boundaryCoordinates"));
         }
-        if (boundaryCoords == null) {
+        
+        if (boundaryCoords == null || boundaryCoords.isEmpty()) {
             JOptionPane.showMessageDialog(this, "鏈壘鍒版湁鏁堢殑鍦板潡杈圭晫鍧愭爣锛屾棤娉曠敓鎴愯矾寰�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             dikuaiData.remove("plannedPath");
             showPathGenerationMessage("鏈壘鍒版湁鏁堢殑鍦板潡杈圭晫鍧愭爣锛屾棤娉曠敓鎴愯矾寰勩��", false);
@@ -1287,89 +1395,93 @@
         String patternDisplay = (String) mowingPatternCombo.getSelectedItem();
         dikuaiData.put("mowingPattern", patternDisplay);
 
-        String widthText = mowingWidthField.getText().trim();
-        if (widthText.isEmpty()) {
-            JOptionPane.showMessageDialog(this, "鍓茶崏鏈哄壊鍒�瀹藉害涓嶈兘涓虹┖", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+        // 鑾峰彇鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗭紝鍗曚綅锛氱背锛�
+        String mowingWidthStr = mowingWidthField.getText().trim();
+        if (mowingWidthStr == null || mowingWidthStr.isEmpty()) {
+            JOptionPane.showMessageDialog(this, "璇峰厛杈撳叆鍓茶崏瀹藉害", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鍓茶崏鏈哄壊鍒�瀹藉害涓嶈兘涓虹┖锛岃閲嶆柊杈撳叆銆�", false);
+            showPathGenerationMessage("璇峰厛杈撳叆鍓茶崏瀹藉害銆�", false);
             setPathAvailability(false);
             return;
         }
-        double bladeWidthMeters;
+        
+        double widthMeters;
         try {
-            bladeWidthMeters = Double.parseDouble(widthText);
+            widthMeters = Double.parseDouble(mowingWidthStr);
         } catch (NumberFormatException e) {
-            JOptionPane.showMessageDialog(this, "鍓茶崏鏈哄壊鍒�瀹藉害杈撳叆鏃犳晥", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害鏍煎紡涓嶆纭�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鍓茶崏鏈哄壊鍒�瀹藉害杈撳叆鏃犳晥锛岃閲嶆柊杈撳叆銆�", false);
-            setPathAvailability(false);
-            return;
-        }
-        if (bladeWidthMeters <= 0) {
-            JOptionPane.showMessageDialog(this, "鍓茶崏鏈哄壊鍒�瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-            dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鍓茶崏鏈哄壊鍒�瀹藉害蹇呴』澶т簬0锛岃閲嶆柊璁剧疆銆�", false);
-            setPathAvailability(false);
-            return;
-        }
-        // 淇濆瓨鍓茶崏鏈哄壊鍒�瀹藉害锛堢背锛�
-        dikuaiData.put("mowingBladeWidth", String.format(Locale.US, "%.2f", bladeWidthMeters));
-        
-        // 鑾峰彇閲嶅彔璺濈
-        String overlapText = overlapDistanceField.getText().trim();
-        if (overlapText.isEmpty()) {
-            JOptionPane.showMessageDialog(this, "鐩搁偦琛岄噸鍙犺窛绂讳笉鑳戒负绌�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-            dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鐩搁偦琛岄噸鍙犺窛绂讳笉鑳戒负绌猴紝璇烽噸鏂拌緭鍏ャ��", false);
-            setPathAvailability(false);
-            return;
-        }
-        double overlapMeters;
-        try {
-            overlapMeters = Double.parseDouble(overlapText);
-        } catch (NumberFormatException e) {
-            JOptionPane.showMessageDialog(this, "鐩搁偦琛岄噸鍙犺窛绂昏緭鍏ユ棤鏁�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-            dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鐩搁偦琛岄噸鍙犺窛绂昏緭鍏ユ棤鏁堬紝璇烽噸鏂拌緭鍏ャ��", false);
-            setPathAvailability(false);
-            return;
-        }
-        if (overlapMeters < 0) {
-            JOptionPane.showMessageDialog(this, "鐩搁偦琛岄噸鍙犺窛绂讳笉鑳戒负璐熸暟", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-            dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("鐩搁偦琛岄噸鍙犺窛绂讳笉鑳戒负璐熸暟锛岃閲嶆柊璁剧疆銆�", false);
+            showPathGenerationMessage("鍓茶崏瀹藉害鏍煎紡涓嶆纭紝璇烽噸鏂拌緭鍏ャ��", false);
             setPathAvailability(false);
             return;
         }
         
-        // 淇濆瓨閲嶅彔璺濈鍒板湴鍧楁暟鎹�
-        dikuaiData.put("mowingOverlapDistance", String.format(Locale.US, "%.2f", overlapMeters));
-        
-        // 璁$畻瀹為檯浣跨敤鐨勫壊鑽夊搴︼紙鍓插垁瀹藉害 - 閲嶅彔璺濈锛�
-        double calculatedWidthMeters = bladeWidthMeters - overlapMeters;
-        if (calculatedWidthMeters <= 0) {
-            JOptionPane.showMessageDialog(this, "璁$畻鍚庣殑鍓茶崏瀹藉害蹇呴』澶т簬0锛堝壊鍒�瀹藉害蹇呴』澶т簬閲嶅彔璺濈锛�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+        if (widthMeters <= 0) {
+            JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             dikuaiData.remove("plannedPath");
-            showPathGenerationMessage("璁$畻鍚庣殑鍓茶崏瀹藉害蹇呴』澶т簬0锛岃璋冩暣鍓插垁瀹藉害鎴栭噸鍙犺窛绂汇��", false);
+            showPathGenerationMessage("鍓茶崏瀹藉害蹇呴』澶т簬0锛岃閲嶆柊璁剧疆銆�", false);
             setPathAvailability(false);
             return;
         }
+        
+        // 淇濆瓨鍓茶崏瀹藉害锛堣浆鎹负鍘樼背淇濆瓨锛屼繚鎸佷笌鍘熸湁鏁版嵁鏍煎紡涓�鑷达級
+        double widthCm = widthMeters * 100.0;
+        dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
 
-        // 淇濆瓨鍓茶崏瀹藉害锛堣绠楀悗鐨勫�硷紝杞崲涓哄帢绫冲瓨鍌紝淇濇寔涓庡師鏈夋暟鎹牸寮忓吋瀹癸級
-        double calculatedWidthCm = calculatedWidthMeters * 100.0;
-        dikuaiData.put("mowingWidth", String.format(Locale.US, "%.0f", calculatedWidthCm));
-
-        String widthMeters = String.format(Locale.US, "%.2f", calculatedWidthMeters);
-        String plannerMode = resolvePlannerMode(patternDisplay);
+        // 鑾峰彇瀹夊叏璺濈
+        String safetyDistanceStr = safetyDistanceField.getText().trim();
+        double safetyDistanceMeters = Double.NaN;
+        if (safetyDistanceStr != null && !safetyDistanceStr.isEmpty()) {
+            try {
+                safetyDistanceMeters = Double.parseDouble(safetyDistanceStr);
+            } catch (NumberFormatException e) {
+                // 浣跨敤NaN锛岃绯荤粺鑷姩璁$畻
+            }
+        }
+        
+        // 鏍煎紡鍖栧壊鑽夊搴﹀拰瀹夊叏璺濈锛堝崟浣嶏細绫筹紝淇濈暀3浣嶅皬鏁帮級
+        String widthMetersStr = String.format(Locale.US, "%.3f", widthMeters);
+        String safetyDistanceMetersStr = Double.isNaN(safetyDistanceMeters) ? null : String.format(Locale.US, "%.3f", safetyDistanceMeters);
+        
+        // 濡傛灉娌℃湁瀹夊叏璺濈锛屼娇鐢ㄩ粯璁ゅ��
+        if (safetyDistanceMetersStr == null) {
+            double defaultSafetyDistance = widthMeters / 2.0 + 0.2;
+            safetyDistanceMetersStr = String.format(Locale.US, "%.3f", defaultSafetyDistance);
+        }
 
         try {
-            List<Lunjingguihua.PathSegment> segments = Lunjingguihua.generatePathSegments(
-                boundaryCoords,
-                obstacleCoords,
-                widthMeters,
-                plannerMode
-            );
-            String plannedPath = Lunjingguihua.formatPathSegments(segments);
+            // 1. 璋冪敤Qufenxingzhuang涓殑judgeGrassType鏂规硶璁$畻鍦板潡杈圭晫鐨勫舰鐘�
+            Qufenxingzhuang shapeJudger = new Qufenxingzhuang();
+            int grassType = shapeJudger.judgeGrassType(boundaryCoords);
+            // grassType: 0=鏃犳硶鍒ゆ柇, 1=鍑稿舰, 2=寮傚舰
+            
+            String plannedPath = null;
+            
+            // 2. 鏍规嵁璁$畻鍚庣殑缁撴灉鍐冲畾璋冪敤鍝釜鏂规硶鐢熸垚鍓茶崏璺緞
+            if (grassType == 1) {
+                // 鍑稿舰鍦板潡 -> 璋冪敤AoxinglujingNoObstacle绫讳腑鐨勬柟娉�
+                List<AoxinglujingNoObstacle.PathSegment> segments = 
+                    AoxinglujingNoObstacle.planPath(boundaryCoords, widthMetersStr, safetyDistanceMetersStr);
+                plannedPath = formatAoxingPathSegments(segments);
+            } else if (grassType == 2) {
+                // 寮傚舰鍦板潡 -> 璋冪敤YixinglujingNoObstacle涓殑鏂规硶
+                List<YixinglujingNoObstacle.PathSegment> segments = 
+                    YixinglujingNoObstacle.planPath(boundaryCoords, widthMetersStr, safetyDistanceMetersStr);
+                plannedPath = formatYixingPathSegments(segments);
+            } else {
+                // 鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁ゆ柟娉曚綔涓哄悗澶�
+                JOptionPane.showMessageDialog(this, "鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁よ矾寰勭敓鎴愭柟娉�", 
+                    "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                String plannerMode = resolvePlannerMode(patternDisplay);
+                plannedPath = Lunjingguihua.generatePathFromStrings(
+                    boundaryCoords,
+                    obstacleCoords != null ? obstacleCoords : "",
+                    widthMetersStr,
+                    safetyDistanceMetersStr,
+                    plannerMode
+                );
+            }
+            
             if (!isMeaningfulValue(plannedPath)) {
                 JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: 鐢熸垚缁撴灉涓虹┖", "閿欒", JOptionPane.ERROR_MESSAGE);
                 dikuaiData.remove("plannedPath");
@@ -1377,6 +1489,7 @@
                 setPathAvailability(false);
                 return;
             }
+            
             if (isMeaningfulValue(boundaryCoords)) {
                 dikuaiData.put("boundaryCoordinates", boundaryCoords);
             }
@@ -1386,7 +1499,7 @@
             dikuaiData.put("plannedPath", plannedPath);
             setPathAvailability(true);
             showPathGenerationMessage(
-                "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰勶紝鍏辩敓鎴� " + segments.size() + " 娈点�俓n鐐瑰嚮鈥滈瑙堚�濇寜閽彲鍦ㄤ富椤甸潰鏌ョ湅鏁堟灉銆�",
+                "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰勩�俓n鐐瑰嚮棰勮鎸夐挳鍙湪涓婚〉闈㈡煡鐪嬫晥鏋溿��",
                 true);
         } catch (IllegalArgumentException ex) {
             JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: " + ex.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
@@ -1402,6 +1515,96 @@
         }
     }
 
+    /**
+     * 鏍煎紡鍖� AoxinglujingNoObstacle.PathSegment 鍒楄〃涓哄潗鏍囧瓧绗︿覆
+     */
+    private String formatAoxingPathSegments(List<AoxinglujingNoObstacle.PathSegment> segments) {
+        if (segments == null || segments.isEmpty()) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        AoxinglujingNoObstacle.Point last = null;
+        for (AoxinglujingNoObstacle.PathSegment segment : segments) {
+            // 鍙坊鍔犲壊鑽夊伐浣滄锛岃烦杩囪繃娓℃
+            if (segment.isMowing) {
+                // 濡傛灉璧风偣涓庝笂涓�涓粓鐐逛笉鍚岋紝娣诲姞璧风偣
+                if (last == null || !equalsAoxingPoint(last, segment.start)) {
+                    appendAoxingPoint(sb, segment.start);
+                }
+                // 娣诲姞缁堢偣
+                appendAoxingPoint(sb, segment.end);
+                last = segment.end;
+            }
+        }
+        return sb.toString();
+    }
+    
+    /**
+     * 鏍煎紡鍖� YixinglujingNoObstacle.PathSegment 鍒楄〃涓哄潗鏍囧瓧绗︿覆
+     */
+    private String formatYixingPathSegments(List<YixinglujingNoObstacle.PathSegment> segments) {
+        if (segments == null || segments.isEmpty()) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        YixinglujingNoObstacle.Point last = null;
+        for (YixinglujingNoObstacle.PathSegment segment : segments) {
+            // 鍙坊鍔犲壊鑽夊伐浣滄锛岃烦杩囪繃娓℃
+            if (segment.isMowing) {
+                // 濡傛灉璧风偣涓庝笂涓�涓粓鐐逛笉鍚岋紝娣诲姞璧风偣
+                if (last == null || !equalsYixingPoint(last, segment.start)) {
+                    appendYixingPoint(sb, segment.start);
+                }
+                // 娣诲姞缁堢偣
+                appendYixingPoint(sb, segment.end);
+                last = segment.end;
+            }
+        }
+        return sb.toString();
+    }
+    
+    /**
+     * 姣旇緝涓や釜 AoxinglujingNoObstacle.Point 鏄惁鐩稿悓锛堜娇鐢ㄥ皬鐨勫宸級
+     */
+    private boolean equalsAoxingPoint(AoxinglujingNoObstacle.Point p1, AoxinglujingNoObstacle.Point p2) {
+        if (p1 == null || p2 == null) {
+            return p1 == p2;
+        }
+        double tolerance = 1e-6;
+        return Math.abs(p1.x - p2.x) < tolerance && Math.abs(p1.y - p2.y) < tolerance;
+    }
+    
+    /**
+     * 娣诲姞 AoxinglujingNoObstacle.Point 鍒板瓧绗︿覆鏋勫缓鍣�
+     */
+    private void appendAoxingPoint(StringBuilder sb, AoxinglujingNoObstacle.Point point) {
+        if (sb.length() > 0) {
+            sb.append(";");
+        }
+        sb.append(String.format(Locale.US, "%.6f,%.6f", point.x, point.y));
+    }
+    
+    /**
+     * 姣旇緝涓や釜 YixinglujingNoObstacle.Point 鏄惁鐩稿悓锛堜娇鐢ㄥ皬鐨勫宸級
+     */
+    private boolean equalsYixingPoint(YixinglujingNoObstacle.Point p1, YixinglujingNoObstacle.Point p2) {
+        if (p1 == null || p2 == null) {
+            return p1 == p2;
+        }
+        double tolerance = 1e-6;
+        return Math.abs(p1.x - p2.x) < tolerance && Math.abs(p1.y - p2.y) < tolerance;
+    }
+    
+    /**
+     * 娣诲姞 YixinglujingNoObstacle.Point 鍒板瓧绗︿覆鏋勫缓鍣�
+     */
+    private void appendYixingPoint(StringBuilder sb, YixinglujingNoObstacle.Point point) {
+        if (sb.length() > 0) {
+            sb.append(";");
+        }
+        sb.append(String.format(Locale.US, "%.6f,%.6f", point.x, point.y));
+    }
+    
     private void previewMowingPath() {
         if (!hasGeneratedPath()) {
             showPathGenerationMessage("璇峰厛鐢熸垚鍓茶崏璺緞鍚庡啀棰勮銆�", false);
@@ -1467,6 +1670,11 @@
             JOptionPane.showMessageDialog(this, "鏃犳硶鍚姩棰勮锛岃绋嶅悗鍐嶈瘯", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
             return;
         }
+        
+        // 鍦ㄦ楠�3棰勮鏃讹紝涓嶆樉绀鸿竟鐣岀偣鍦嗗湀
+        if (shouye.getMapRenderer() != null) {
+            shouye.getMapRenderer().setBoundaryPointsVisible(false);
+        }
 
         closePreviewAndDispose();
     }
@@ -1482,53 +1690,20 @@
             }
         }
 
-        // 淇濆瓨鍓茶崏鏈哄壊鍒�瀹藉害
+        // 淇濆瓨鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛岃浆鎹负鍘樼背淇濆瓨锛�
         if (mowingWidthField != null) {
-            String bladeWidthText = mowingWidthField.getText().trim();
-            if (!bladeWidthText.isEmpty()) {
+            String widthStr = mowingWidthField.getText().trim();
+            if (widthStr != null && !widthStr.isEmpty()) {
                 try {
-                    double bladeWidthMeters = Double.parseDouble(bladeWidthText);
-                    dikuaiData.put("mowingBladeWidth", String.format(Locale.US, "%.2f", bladeWidthMeters));
+                    double widthMeters = Double.parseDouble(widthStr);
+                    double widthCm = widthMeters * 100.0;
+                    dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
                 } catch (NumberFormatException e) {
-                    // 濡傛灉瑙f瀽澶辫触锛岀洿鎺ヤ繚瀛樻枃鏈�
-                    dikuaiData.put("mowingBladeWidth", bladeWidthText);
+                    // 淇濇寔鍘熷��
+                    dikuaiData.put("mowingWidth", widthStr);
                 }
             }
         }
-        
-        // 淇濆瓨鐩搁偦琛岄噸鍙犺窛绂�
-        if (overlapDistanceField != null) {
-            String overlapText = overlapDistanceField.getText().trim();
-            if (!overlapText.isEmpty()) {
-                try {
-                    double overlapMeters = Double.parseDouble(overlapText);
-                    dikuaiData.put("mowingOverlapDistance", String.format(Locale.US, "%.2f", overlapMeters));
-                } catch (NumberFormatException e) {
-                    // 濡傛灉瑙f瀽澶辫触锛岀洿鎺ヤ繚瀛樻枃鏈�
-                    dikuaiData.put("mowingOverlapDistance", overlapText);
-                }
-            }
-        }
-        
-        // 璁$畻骞朵繚瀛樺壊鑽夊搴︼紙鍓插垁瀹藉害 - 閲嶅彔璺濈锛�
-        if (mowingWidthField != null && overlapDistanceField != null) {
-            try {
-                String bladeWidthText = mowingWidthField.getText().trim();
-                String overlapText = overlapDistanceField.getText().trim();
-                if (!bladeWidthText.isEmpty() && !overlapText.isEmpty()) {
-                    double bladeWidthMeters = Double.parseDouble(bladeWidthText);
-                    double overlapMeters = Double.parseDouble(overlapText);
-                    double calculatedWidthMeters = bladeWidthMeters - overlapMeters;
-                    if (calculatedWidthMeters > 0) {
-                        // 杞崲涓哄帢绫冲瓨鍌紝淇濇寔涓庡師鏈夋暟鎹牸寮忓吋瀹�
-                        int widthCm = (int) Math.round(calculatedWidthMeters * 100.0);
-                        dikuaiData.put("mowingWidth", Integer.toString(widthCm));
-                    }
-                }
-            } catch (NumberFormatException e) {
-                // 濡傛灉璁$畻澶辫触锛屼笉淇濆瓨鍓茶崏瀹藉害
-            }
-        }
     }
 
     private void captureSessionSnapshot() {
@@ -1560,14 +1735,23 @@
             @Override
             public void mouseEntered(MouseEvent e) {
                 if (button.isEnabled()) {
-                    button.setBackground(PRIMARY_DARK);
+                    // 濡傛灉鎸夐挳鍙敤锛岄紶鏍囨偓鍋滄椂鏄剧ず娣辩豢鑹�
+                    if (button.getBackground().equals(PRIMARY_COLOR)) {
+                        button.setBackground(PRIMARY_DARK);
+                    }
                 }
             }
 
             @Override
             public void mouseExited(MouseEvent e) {
                 if (button.isEnabled()) {
-                    button.setBackground(PRIMARY_COLOR);
+                    // 濡傛灉鎸夐挳鍙敤锛岄紶鏍囩寮�鏃舵仮澶嶇豢鑹�
+                    if (!button.getBackground().equals(MEDIUM_GRAY)) {
+                        button.setBackground(PRIMARY_COLOR);
+                    }
+                } else {
+                    // 濡傛灉鎸夐挳涓嶅彲鐢紝淇濇寔鐏拌壊
+                    button.setBackground(MEDIUM_GRAY);
                 }
             }
         });
@@ -1628,7 +1812,15 @@
         ));
         prevButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
 
+        boundaryPreviewButton = createPrimaryButton("棰勮", 16);
+        boundaryPreviewButton.setVisible(false);
+        boundaryPreviewButton.setEnabled(false);
+        boundaryPreviewButton.addActionListener(e -> previewBoundary());
+
         nextButton = createPrimaryButton("涓嬩竴姝�", 16);
+        nextButton.setBackground(MEDIUM_GRAY); // 鍒濆鐏拌壊鑳屾櫙
+        nextButton.setEnabled(false); // 鍒濆涓嶅彲鐢�
+        
         createButton = createPrimaryButton("淇濆瓨", 16);
         createButton.setVisible(false);
         createButton.setEnabled(false);
@@ -1642,6 +1834,8 @@
 
         buttonPanel.add(prevButton);
         buttonPanel.add(Box.createHorizontalGlue());
+        buttonPanel.add(boundaryPreviewButton);
+        buttonPanel.add(Box.createHorizontalStrut(15));
         buttonPanel.add(nextButton);
         buttonPanel.add(previewButtonSpacer);
         buttonPanel.add(previewButton);
@@ -1655,10 +1849,20 @@
         if (boundaryCountLabel == null) {
             return;
         }
-        int count = Coordinate.coordinates != null ? Coordinate.coordinates.size() : 0;
-        double area = jisuanmianjie.calculatePolygonArea();
-        DecimalFormat areaFormat = new DecimalFormat("0.00");
-        boundaryCountLabel.setText("宸查噰闆嗗埌杈圭晫鐐�" + count + "涓紝褰撳墠鍦板潡闈㈢Н涓�" + areaFormat.format(area) + "銕�");
+        
+        // 浣跨敤浼樺寲鍚庣殑杈圭晫鏁版嵁璁$畻鐐规暟鍜岄潰绉�
+        String optimizedXYStr = dikuaiData.get("optimizedBoundaryXY");
+        if (optimizedXYStr != null && !optimizedXYStr.isEmpty() && !optimizedXYStr.startsWith("ERROR")) {
+            int count = Bianjieyouhuatoxy.calculatePointCount(optimizedXYStr);
+            String areaStr = Bianjieyouhuatoxy.calculateArea(optimizedXYStr);
+            boundaryCountLabel.setText("宸查噰闆嗗埌杈圭晫鐐�" + count + "涓紝褰撳墠鍦板潡闈㈢Н涓�" + areaStr + "銕�");
+        } else {
+            // 濡傛灉娌℃湁浼樺寲鍚庣殑鏁版嵁锛屼娇鐢ㄥ師濮嬫暟鎹�
+            int count = Coordinate.coordinates != null ? Coordinate.coordinates.size() : 0;
+            double area = jisuanmianjie.calculatePolygonArea();
+            DecimalFormat areaFormat = new DecimalFormat("0.00");
+            boundaryCountLabel.setText("宸查噰闆嗗埌杈圭晫鐐�" + count + "涓紝褰撳墠鍦板潡闈㈢Н涓�" + areaFormat.format(area) + "銕�");
+        }
         boundaryCountLabel.setVisible(true);
     }
 
@@ -1679,6 +1883,11 @@
             dikuai.setLandArea(snapshot.areaSqMeters);
             dikuai.setBaseStationCoordinates(snapshot.baseStationCoordinates);
             dikuai.setUpdateTime(getCurrentTime());
+            // 璁$畻骞惰缃師濮嬭竟鐣孹Y鍧愭爣
+            String originalBoundaryXY = convertOriginalBoundaryToXY(snapshot.originalBoundary, snapshot.baseStationCoordinates);
+            if (originalBoundaryXY != null && !originalBoundaryXY.isEmpty()) {
+                dikuai.setBoundaryOriginalXY(originalBoundaryXY);
+            }
             Dikuai.putDikuai(landNumber, dikuai);
         }
 
@@ -1785,11 +1994,196 @@
         }
         return dikuai;
     }
+    
+    /**
+     * 灏嗗師濮嬭竟鐣屽潗鏍囷紙缁忕含搴︽牸寮忥級杞崲涓篨Y鍧愭爣
+     * @param originalBoundary 鍘熷杈圭晫鍧愭爣瀛楃涓诧紝鏍煎紡锛�"lat1,lon1,alt1;lat2,lon2,alt2;..."
+     * @param baseStationCoordinates 鍩哄噯绔欏潗鏍囷紝鏍煎紡锛�"lat,N/S,lon,E/W"
+     * @return XY鍧愭爣瀛楃涓诧紝鏍煎紡锛�"X0,Y0;X1,Y1;X2,Y2;..." 濡傛灉杞崲澶辫触杩斿洖null
+     */
+    private static String convertOriginalBoundaryToXY(String originalBoundary, String baseStationCoordinates) {
+        if (originalBoundary == null || originalBoundary.trim().isEmpty() || "-1".equals(originalBoundary.trim())) {
+            return null;
+        }
+        if (baseStationCoordinates == null || baseStationCoordinates.trim().isEmpty()) {
+            return null;
+        }
+        
+        try {
+            // 瑙f瀽鍩哄噯绔欏潗鏍�
+            String[] baseParts = baseStationCoordinates.trim().split(",");
+            if (baseParts.length != 4) {
+                return null;
+            }
+            double baseLat = convertToDecimalDegree(baseParts[0], baseParts[1]);
+            double baseLon = convertToDecimalDegree(baseParts[2], baseParts[3]);
+            
+            // 瑙f瀽鍘熷杈圭晫鍧愭爣
+            String[] points = originalBoundary.split(";");
+            StringBuilder xyStr = new StringBuilder();
+            
+            for (int i = 0; i < points.length; i++) {
+                String point = points[i].trim();
+                if (point.isEmpty()) {
+                    continue;
+                }
+                
+                String[] coords = point.split(",");
+                if (coords.length >= 2) {
+                    try {
+                        double lat = Double.parseDouble(coords[0].trim());
+                        double lon = Double.parseDouble(coords[1].trim());
+                        
+                        // 杞崲涓篨Y鍧愭爣
+                        double[] xy = publicway.Gpstoxuzuobiao.convertLatLonToLocal(lat, lon, baseLat, baseLon);
+                        if (xy != null && xy.length >= 2) {
+                            if (xyStr.length() > 0) {
+                                xyStr.append(";");
+                            }
+                            xyStr.append(String.format(Locale.US, "%.3f,%.3f", xy[0], xy[1]));
+                        }
+                    } catch (NumberFormatException e) {
+                        // 璺宠繃鏃犳晥鐨勫潗鏍囩偣
+                        continue;
+                    }
+                }
+            }
+            
+            return xyStr.length() > 0 ? xyStr.toString() : null;
+        } catch (Exception e) {
+            System.err.println("杞崲鍘熷杈圭晫鍧愭爣鍒癤Y澶辫触: " + e.getMessage());
+            return null;
+        }
+    }
+    
+    /**
+     * 棰勮杈圭晫
+     */
+    private void previewBoundary() {
+        if (!dikuaiData.containsKey("boundaryDrawn")) {
+            JOptionPane.showMessageDialog(this, "璇峰厛瀹屾垚杈圭晫缁樺埗鍚庡啀棰勮", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+        
+        // 鑾峰彇鎴栧垱寤哄湴鍧楀璞�
+        String landNumber = getPendingLandNumber();
+        Dikuai dikuai = getOrCreatePendingDikuai();
+        if (dikuai == null) {
+            JOptionPane.showMessageDialog(this, "鏃犳硶鑾峰彇鍦板潡淇℃伅", "閿欒", JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+        
+        // 纭繚鍦板潡鏁版嵁鏄渶鏂扮殑
+        String optimizedBoundaryXY = dikuaiData.get("optimizedBoundaryXY");
+        if (optimizedBoundaryXY == null || optimizedBoundaryXY.isEmpty() || optimizedBoundaryXY.startsWith("ERROR")) {
+            // 濡傛灉娌℃湁浼樺寲鍚庣殑杈圭晫锛屽皾璇曚粠boundaryCoordinates鑾峰彇
+            String boundaryCoords = dikuaiData.get("boundaryCoordinates");
+            if (boundaryCoords != null && !boundaryCoords.isEmpty() && !"-1".equals(boundaryCoords)) {
+                optimizedBoundaryXY = boundaryCoords;
+            } else {
+                // 灏濊瘯浠庡湴鍧楀璞¤幏鍙�
+                optimizedBoundaryXY = dikuai.getBoundaryCoordinates();
+            }
+        }
+        
+        if (optimizedBoundaryXY == null || optimizedBoundaryXY.isEmpty() || "-1".equals(optimizedBoundaryXY)) {
+            JOptionPane.showMessageDialog(this, "鏈壘鍒版湁鏁堢殑杈圭晫鍧愭爣锛屾棤娉曢瑙�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+        
+        // 纭繚鍘熷杈圭晫XY鍧愭爣宸茶绠�
+        String originalBoundaryXY = dikuai.getBoundaryOriginalXY();
+        if (originalBoundaryXY == null || originalBoundaryXY.isEmpty() || "-1".equals(originalBoundaryXY)) {
+            // 璁$畻鍘熷杈圭晫XY鍧愭爣
+            String originalBoundary = dikuaiData.get("boundaryOriginalCoordinates");
+            String baseStationCoordinates = dikuaiData.get("baseStationCoordinates");
+            if (originalBoundary != null && baseStationCoordinates != null) {
+                originalBoundaryXY = convertOriginalBoundaryToXY(originalBoundary, baseStationCoordinates);
+                if (originalBoundaryXY != null && !originalBoundaryXY.isEmpty()) {
+                    dikuai.setBoundaryOriginalXY(originalBoundaryXY);
+                    Dikuai.putDikuai(landNumber, dikuai);
+                }
+            }
+        }
+        
+        // 淇濆瓨浼氳瘽蹇収
+        captureSessionSnapshot();
+        
+        // 鍒涘缓final鍙橀噺渚沴ambda浣跨敤
+        final String finalOptimizedBoundaryXY = optimizedBoundaryXY;
+        final Dikuai finalDikuai = dikuai;
+        
+        // 鍏抽棴瀵硅瘽妗�
+        setVisible(false);
+        dispose();
+        
+        // 璋冪敤棣栭〉鏄剧ず棰勮锛堜笌杈圭晫绠$悊椤甸潰閫昏緫涓�鑷达級
+        SwingUtilities.invokeLater(() -> {
+            Shouye.showBoundaryPreview(finalDikuai, finalOptimizedBoundaryXY, () -> {
+                // 杩斿洖鍥炶皟锛氶噸鏂版墦寮�鏂板鍦板潡瀵硅瘽妗嗭紝骞舵樉绀烘楠�2
+                Component parent = Shouye.getInstance();
+                if (parent != null) {
+                    // 纭繚浼氳瘽鐘舵�佹纭紝浠ヤ究杩斿洖鏃舵樉绀烘楠�2
+                    if (activeSession != null && activeSession.drawingCompleted) {
+                        resumeRequested = true;
+                    }
+                    showAddDikuaiDialog(parent);
+                }
+            });
+        });
+    }
 
     private void hideBoundaryPointSummary() {
         if (boundaryCountLabel != null) {
             boundaryCountLabel.setVisible(false);
         }
+        if (boundaryXYTextArea != null) {
+            boundaryXYTextArea.setVisible(false);
+            boundaryXYTextArea.setText("");
+        }
+        if (boundaryXYScrollPane != null) {
+            boundaryXYScrollPane.setVisible(false);
+        }
+    }
+    
+    /**
+     * 鏇存柊杈圭晫XY鍧愭爣鏄剧ず
+     */
+    private void updateBoundaryXYDisplay() {
+        if (boundaryXYTextArea == null || boundaryXYScrollPane == null) {
+            return;
+        }
+        
+        // 鑾峰彇浼樺寲鍚庣殑杈圭晫XY鍧愭爣
+        String optimizedXYStr = dikuaiData.get("optimizedBoundaryXY");
+        if (optimizedXYStr != null && !optimizedXYStr.isEmpty() && !optimizedXYStr.startsWith("ERROR")) {
+            boundaryXYTextArea.setText(optimizedXYStr);
+            boundaryXYTextArea.setVisible(true);
+            boundaryXYScrollPane.setVisible(true);
+        } else {
+            // 濡傛灉娌℃湁浼樺寲鍚庣殑鏁版嵁锛屽皾璇曚粠鍘熷鍧愭爣浼樺寲骞舵樉绀�
+            // 濡傛灉宸茬粡鏈夊師濮嬪潗鏍囦絾杩樻病鏈変紭鍖栵紝鍒欒繘琛屼紭鍖�
+            if (dikuaiData.containsKey("boundaryDrawn") && 
+                (Coordinate.coordinates != null && !Coordinate.coordinates.isEmpty())) {
+                // 灏濊瘯浼樺寲杈圭晫
+                optimizeBoundaryAndSave();
+                // 鍐嶆鑾峰彇浼樺寲鍚庣殑鍧愭爣
+                optimizedXYStr = dikuaiData.get("optimizedBoundaryXY");
+                if (optimizedXYStr != null && !optimizedXYStr.isEmpty() && !optimizedXYStr.startsWith("ERROR")) {
+                    boundaryXYTextArea.setText(optimizedXYStr);
+                    boundaryXYTextArea.setVisible(true);
+                    boundaryXYScrollPane.setVisible(true);
+                } else {
+                    boundaryXYTextArea.setText("杈圭晫鍧愭爣鏁版嵁鏈氨缁�");
+                    boundaryXYTextArea.setVisible(true);
+                    boundaryXYScrollPane.setVisible(true);
+                }
+            } else {
+                boundaryXYTextArea.setText("杈圭晫鍧愭爣鏁版嵁鏈氨缁�");
+                boundaryXYTextArea.setVisible(true);
+                boundaryXYScrollPane.setVisible(true);
+            }
+        }
     }
 
     private boolean hasGeneratedPath() {
@@ -1858,8 +2252,14 @@
 
         String optimizedBoundary;
         try {
-            optimizedBoundary = bianjieguihua2.processCoordinateListAuto(baseStationCoordinates);
-        } catch (RuntimeException ex) {
+            // 鏋勫缓杈圭晫瀛楃涓诧紝鏍煎紡涓� "(lat1,lon1,alt1;lat2,lon2,alt2;...)"
+            String boundaryStr = buildBoundaryStringForOptimization(uniqueCoordinates);
+            // 璋冪敤 Bianjieyouhuatoxy.optimizeBoundary 鏂规硶
+            optimizedBoundary = Bianjieyouhuatoxy.optimizeBoundary(baseStationCoordinates, boundaryStr);
+            if (optimizedBoundary == null || optimizedBoundary.isEmpty() || optimizedBoundary.startsWith("ERROR")) {
+                return BoundarySnapshotResult.failure("鐢熸垚鍦板潡杈圭晫澶辫触: 浼樺寲鍚庣殑杈圭晫鍧愭爣鏃犳晥", JOptionPane.ERROR_MESSAGE);
+            }
+        } catch (Exception ex) {
             ex.printStackTrace();
             return BoundarySnapshotResult.failure("鐢熸垚鍦板潡杈圭晫澶辫触: " + ex.getMessage(), JOptionPane.ERROR_MESSAGE);
         }
@@ -1929,6 +2329,12 @@
     private void showStep(int step) {
         currentStep = step;
         cardLayout.show(stepsPanel, "step" + step);
+        
+        if (step == 1) {
+            updateObstacleSummary();
+            // 姝ラ1鏄剧ず鏃讹紝绔嬪嵆鏇存柊鎸夐挳鐘舵��
+            SwingUtilities.invokeLater(() -> updateStep1ButtonState());
+        }
 
         // 鏇存柊鎸夐挳鐘舵��
         updateButtonState(step);
@@ -1948,6 +2354,39 @@
             if (previewButtonSpacer != null) {
                 previewButtonSpacer.setVisible(false);
             }
+            // 姝ラ1锛氭牴鎹獙璇佺粨鏋滄洿鏂颁笅涓�姝ユ寜閽姸鎬�
+            if (step == 1) {
+                updateStep1ButtonState();
+            }
+            // 姝ラ2鏄剧ず杈圭晫棰勮鎸夐挳
+            if (step == 2) {
+                if (boundaryPreviewButton != null) {
+                    boundaryPreviewButton.setVisible(true);
+                    // 鏍规嵁鏄惁瀹屾垚杈圭晫缁樺埗鏉ヨ缃寜閽姸鎬佸拰鑳屾櫙棰滆壊
+                    boolean boundaryDrawn = dikuaiData.containsKey("boundaryDrawn");
+                    boundaryPreviewButton.setEnabled(boundaryDrawn);
+                    if (boundaryDrawn) {
+                        boundaryPreviewButton.setBackground(PRIMARY_COLOR); // 缁胯壊鑳屾櫙
+                    } else {
+                        boundaryPreviewButton.setBackground(MEDIUM_GRAY); // 鐏拌壊鑳屾櫙
+                    }
+                }
+                // 鏇存柊涓嬩竴姝ユ寜閽姸鎬侊紙鏍规嵁鏄惁瀹屾垚杈圭晫缁樺埗锛�
+                boolean boundaryDrawn = dikuaiData.containsKey("boundaryDrawn");
+                nextButton.setEnabled(boundaryDrawn);
+                if (boundaryDrawn) {
+                    nextButton.setBackground(PRIMARY_COLOR); // 缁胯壊鑳屾櫙
+                } else {
+                    nextButton.setBackground(MEDIUM_GRAY); // 鐏拌壊鑳屾櫙
+                }
+                // 鏇存柊寮�濮嬬粯鍒舵寜閽姸鎬�
+                updateStartDrawingButtonState();
+            } else {
+                if (boundaryPreviewButton != null) {
+                    boundaryPreviewButton.setVisible(false);
+                    boundaryPreviewButton.setEnabled(false);
+                }
+            }
         } else {
             nextButton.setVisible(false);
             createButton.setVisible(true);
@@ -1957,6 +2396,10 @@
             if (previewButtonSpacer != null) {
                 previewButtonSpacer.setVisible(true);
             }
+            if (boundaryPreviewButton != null) {
+                boundaryPreviewButton.setVisible(false);
+                boundaryPreviewButton.setEnabled(false);
+            }
             setPathAvailability(hasGeneratedPath());
         }
 
@@ -1967,6 +2410,85 @@
         }
     }
     
+    /**
+     * 鏇存柊姝ラ1鐨勪笅涓�姝ユ寜閽姸鎬�
+     * 鏍规嵁鍦板潡鍚嶇О鏄惁濉啓鏉ヨ缃寜閽殑鍚敤鐘舵�佸拰鑳屾櫙棰滆壊
+     */
+    private void updateStep1ButtonState() {
+        if (nextButton == null || currentStep != 1) {
+            return;
+        }
+        
+        String name = areaNameField.getText().trim();
+        boolean canProceed = !name.isEmpty();
+        
+        nextButton.setEnabled(canProceed);
+        if (canProceed) {
+            // 鍙偣鍑绘椂锛氱豢鑹茶儗鏅�
+            nextButton.setBackground(PRIMARY_COLOR);
+        } else {
+            // 涓嶅彲鐐瑰嚮鏃讹細鐏拌壊鑳屾櫙
+            nextButton.setBackground(MEDIUM_GRAY);
+        }
+    }
+    
+    /**
+     * 鏇存柊姝ラ2鐨勫紑濮嬬粯鍒舵寜閽姸鎬�
+     * 鏍规嵁鏄惁閫夋嫨浜嗙粯鍒舵柟寮忔潵璁剧疆鎸夐挳鐨勫惎鐢ㄧ姸鎬佸拰鑳屾櫙棰滆壊
+     */
+    private void updateStartDrawingButtonState() {
+        if (startEndDrawingBtn == null || currentStep != 2) {
+            return;
+        }
+        
+        boolean hasSelectedMethod = dikuaiData.containsKey("drawingMethod");
+        boolean isDrawingActive = isDrawing;
+        
+        // 濡傛灉姝e湪缁樺埗锛屾寜閽姸鎬佺敱toggleDrawing鏂规硶鎺у埗
+        if (isDrawingActive) {
+            return;
+        }
+        
+        // 濡傛灉宸茬粡瀹屾垚缁樺埗锛屾寜閽樉绀�"宸插畬鎴�"涓斾笉鍙敤
+        boolean boundaryDrawn = dikuaiData.containsKey("boundaryDrawn");
+        if (boundaryDrawn) {
+            startEndDrawingBtn.setEnabled(false);
+            startEndDrawingBtn.setBackground(MEDIUM_GRAY);
+            return;
+        }
+        
+        startEndDrawingBtn.setEnabled(hasSelectedMethod);
+        if (hasSelectedMethod) {
+            // 宸查�夋嫨缁樺埗鏂瑰紡锛氱豢鑹茶儗鏅紝鍙偣鍑�
+            startEndDrawingBtn.setBackground(PRIMARY_COLOR);
+        } else {
+            // 鏈�夋嫨缁樺埗鏂瑰紡锛氱伆鑹茶儗鏅紝涓嶅彲鐐瑰嚮
+            startEndDrawingBtn.setBackground(MEDIUM_GRAY);
+        }
+    }
+    
+    /**
+     * 鏇存柊姝ラ2鐨勯瑙堝拰涓嬩竴姝ユ寜閽姸鎬侊紙鍦ㄥ畬鎴愯竟鐣岀粯鍒跺悗璋冪敤锛�
+     * 灏嗘寜閽儗鏅鑹茶缃负缁胯壊锛岃〃绀哄彲浠ョ偣鍑绘搷浣�
+     */
+    private void updateStep2ButtonsAfterDrawing() {
+        if (currentStep != 2) {
+            return;
+        }
+        
+        // 鏇存柊棰勮鎸夐挳
+        if (boundaryPreviewButton != null) {
+            boundaryPreviewButton.setEnabled(true);
+            boundaryPreviewButton.setBackground(PRIMARY_COLOR); // 缁胯壊鑳屾櫙
+        }
+        
+        // 鏇存柊涓嬩竴姝ユ寜閽�
+        if (nextButton != null) {
+            nextButton.setEnabled(true);
+            nextButton.setBackground(PRIMARY_COLOR); // 缁胯壊鑳屾櫙
+        }
+    }
+    
     private boolean validateCurrentStep() {
         switch (currentStep) {
             case 1:
@@ -1999,53 +2521,20 @@
 
             case 3:
                 dikuaiData.put("mowingPattern", (String) mowingPatternCombo.getSelectedItem());
-                
-                // 淇濆瓨鍓茶崏鏈哄壊鍒�瀹藉害
+                // 淇濆瓨鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛岃浆鎹负鍘樼背淇濆瓨锛�
                 if (mowingWidthField != null) {
-                    String bladeWidthText = mowingWidthField.getText().trim();
-                    if (!bladeWidthText.isEmpty()) {
+                    String widthStr = mowingWidthField.getText().trim();
+                    if (widthStr != null && !widthStr.isEmpty()) {
                         try {
-                            double bladeWidthMeters = Double.parseDouble(bladeWidthText);
-                            dikuaiData.put("mowingBladeWidth", String.format(Locale.US, "%.2f", bladeWidthMeters));
+                            double widthMeters = Double.parseDouble(widthStr);
+                            double widthCm = widthMeters * 100.0;
+                            dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
                         } catch (NumberFormatException e) {
-                            dikuaiData.put("mowingBladeWidth", bladeWidthText);
+                            // 淇濇寔鍘熷��
+                            dikuaiData.put("mowingWidth", widthStr);
                         }
                     }
                 }
-                
-                // 淇濆瓨鐩搁偦琛岄噸鍙犺窛绂�
-                if (overlapDistanceField != null) {
-                    String overlapText = overlapDistanceField.getText().trim();
-                    if (!overlapText.isEmpty()) {
-                        try {
-                            double overlapMeters = Double.parseDouble(overlapText);
-                            dikuaiData.put("mowingOverlapDistance", String.format(Locale.US, "%.2f", overlapMeters));
-                        } catch (NumberFormatException e) {
-                            dikuaiData.put("mowingOverlapDistance", overlapText);
-                        }
-                    }
-                }
-                
-                // 璁$畻骞朵繚瀛樺壊鑽夊搴︼紙鍓插垁瀹藉害 - 閲嶅彔璺濈锛�
-                if (mowingWidthField != null && overlapDistanceField != null) {
-                    try {
-                        String bladeWidthText = mowingWidthField.getText().trim();
-                        String overlapText = overlapDistanceField.getText().trim();
-                        if (!bladeWidthText.isEmpty() && !overlapText.isEmpty()) {
-                            double bladeWidthMeters = Double.parseDouble(bladeWidthText);
-                            double overlapMeters = Double.parseDouble(overlapText);
-                            double calculatedWidthMeters = bladeWidthMeters - overlapMeters;
-                            if (calculatedWidthMeters > 0) {
-                                // 杞崲涓哄帢绫冲瓨鍌紝淇濇寔涓庡師鏈夋暟鎹牸寮忓吋瀹�
-                                int widthCm = (int) Math.round(calculatedWidthMeters * 100.0);
-                                dikuaiData.put("mowingWidth", Integer.toString(widthCm));
-                            }
-                        }
-                    } catch (NumberFormatException e) {
-                        // 濡傛灉璁$畻澶辫触锛屼笉淇濆瓨鍓茶崏瀹藉害
-                    }
-                }
-                
                 if (!hasGeneratedPath()) {
                     JOptionPane.showMessageDialog(this, "璇峰厛鐢熸垚鍓茶崏璺緞", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
                     return false;
@@ -2290,6 +2779,9 @@
             isDrawing = false;
             showStep(2);
             showBoundaryPointSummary();
+            updateBoundaryXYDisplay();
+            // 鏇存柊棰勮鍜屼笅涓�姝ユ寜閽姸鎬侊紙鑳屾櫙棰滆壊鍙樼豢鑹诧紝鍙偣鍑伙級
+            updateStep2ButtonsAfterDrawing();
         } else {
             if (startEndDrawingBtn != null) {
                 startEndDrawingBtn.setText("寮�濮嬬粯鍒�");
@@ -2326,54 +2818,36 @@
             }
         }
 
-        // 鎭㈠鍓茶崏鏈哄壊鍒�瀹藉害锛堜紭鍏堜粠mowingBladeWidth鑾峰彇锛�
-        if (mowingWidthField != null) {
-            String bladeWidth = data.get("mowingBladeWidth");
-            if (isMeaningfulValue(bladeWidth)) {
-                try {
-                    double bladeWidthMeters = Double.parseDouble(bladeWidth.trim());
-                    mowingWidthField.setText(String.format(Locale.US, "%.2f", bladeWidthMeters));
-                } catch (NumberFormatException ignored) {
-                    // 濡傛灉mowingBladeWidth涓嶅瓨鍦ㄦ垨瑙f瀽澶辫触锛屽皾璇曚粠mowingWidth鎭㈠
-                    String width = data.get("mowingWidth");
-                    if (isMeaningfulValue(width)) {
-                        try {
-                            // 濡傛灉瀛樺偍鐨勬槸鍘樼背锛岃浆鎹负绫虫樉绀�
-                            double parsed = Double.parseDouble(width.trim());
-                            // 鍋囪濡傛灉鍊煎ぇ浜�10锛屽垯鏄帢绫筹紝闇�瑕佽浆鎹负绫筹紱鍚﹀垯宸茬粡鏄背
-                            double widthMeters = parsed > 10 ? parsed / 100.0 : parsed;
-                            mowingWidthField.setText(String.format(Locale.US, "%.2f", widthMeters));
-                        } catch (NumberFormatException ignored2) {
-                            // 淇濇寔褰撳墠鍊�
-                        }
-                    }
-                }
-            } else {
-                // 濡傛灉mowingBladeWidth涓嶅瓨鍦紝灏濊瘯浠巑owingWidth鎭㈠
-                String width = data.get("mowingWidth");
-                if (isMeaningfulValue(width)) {
-                    try {
-                        // 濡傛灉瀛樺偍鐨勬槸鍘樼背锛岃浆鎹负绫虫樉绀�
-                        double parsed = Double.parseDouble(width.trim());
-                        // 鍋囪濡傛灉鍊煎ぇ浜�10锛屽垯鏄帢绫筹紝闇�瑕佽浆鎹负绫筹紱鍚﹀垯宸茬粡鏄背
-                        double widthMeters = parsed > 10 ? parsed / 100.0 : parsed;
-                        mowingWidthField.setText(String.format(Locale.US, "%.2f", widthMeters));
-                    } catch (NumberFormatException ignored) {
-                        // 淇濇寔褰撳墠鍊�
-                    }
-                }
+        // 鎭㈠鍓茶崏瀹藉害锛氫粠淇濆瓨鐨勫壊鑽夊搴︼紙鍘樼背锛夎浆鎹负绫冲苟璁剧疆
+        String width = data.get("mowingWidth");
+        if (isMeaningfulValue(width) && mowingWidthField != null) {
+            try {
+                double mowingWidthCm = Double.parseDouble(width.trim());
+                // 灏嗗帢绫宠浆鎹负绫�
+                double mowingWidthMeters = mowingWidthCm / 100.0;
+                mowingWidthField.setText(String.format(Locale.US, "%.3f", mowingWidthMeters));
+            } catch (NumberFormatException ignored) {
+                // 淇濇寔褰撳墠鍊�
             }
         }
         
-        if (overlapDistanceField != null) {
-            String overlap = data.get("mowingOverlapDistance");
-            if (isMeaningfulValue(overlap)) {
-                try {
-                    double overlapMeters = Double.parseDouble(overlap.trim());
-                    overlapDistanceField.setText(String.format(Locale.US, "%.2f", overlapMeters));
-                } catch (NumberFormatException ignored) {
-                    // 淇濇寔褰撳墠鍊�
+        // 鎭㈠鍓插垁瀹藉害锛氫粠淇濆瓨鐨勫壊鑽夊搴﹀弽鎺ㄥ壊鍒�瀹藉害骞惰缃�
+        // 鐢变簬鍓茶崏瀹藉害 = 鍓插垁瀹藉害 * 0.85锛屾墍浠ュ壊鍒�瀹藉害 = 鍓茶崏瀹藉害 / 0.85
+        if (isMeaningfulValue(width) && bladeWidthField != null) {
+            try {
+                double mowingWidthCm = Double.parseDouble(width.trim());
+                // 灏嗗帢绫宠浆鎹负绫筹紝鐒跺悗鍙嶆帹鍓插垁瀹藉害
+                double mowingWidthMeters = mowingWidthCm / 100.0;
+                double bladeWidthMeters = mowingWidthMeters / 0.85;
+                bladeWidthField.setText(String.format(Locale.US, "%.3f", bladeWidthMeters));
+                // 瑙﹀彂鑷姩璁$畻瀹夊叏璺濈
+                if (safetyDistanceField != null) {
+                    String safetyDistanceStr = Gecaoanquanjuli.calculateSafetyDistanceFromString(
+                        String.format(Locale.US, "%.3f", bladeWidthMeters));
+                    safetyDistanceField.setText(safetyDistanceStr);
                 }
+            } catch (NumberFormatException ignored) {
+                // 淇濇寔褰撳墠鍊�
             }
         }
 
@@ -2480,80 +2954,73 @@
             dikuai.setMowingPattern(dikuaiData.get("mowingPattern"));
         }
         
-        // 淇濆瓨鍓茶崏鏈哄壊鍒�瀹藉害锛堜紭鍏堜粠dikuaiData鑾峰彇锛屽惁鍒欎粠TextField鑾峰彇锛�
-        if (dikuaiData.containsKey("mowingBladeWidth")) {
-            dikuai.setMowingBladeWidth(dikuaiData.get("mowingBladeWidth"));
-        } else if (mowingWidthField != null) {
-            String bladeWidthText = mowingWidthField.getText().trim();
-            if (!bladeWidthText.isEmpty()) {
+        // 淇濆瓨鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛岃浆鎹负鍘樼背淇濆瓨锛�
+        if (mowingWidthField != null) {
+            String mowingWidthStr = mowingWidthField.getText().trim();
+            if (mowingWidthStr != null && !mowingWidthStr.isEmpty()) {
                 try {
-                    double bladeWidthMeters = Double.parseDouble(bladeWidthText);
+                    double mowingWidthMeters = Double.parseDouble(mowingWidthStr);
+                    // 杞崲涓哄帢绫充繚瀛�
+                    double mowingWidthCm = mowingWidthMeters * 100.0;
+                    dikuai.setMowingWidth(String.format(Locale.US, "%.2f", mowingWidthCm));
+                } catch (NumberFormatException e) {
+                    // 濡傛灉瑙f瀽澶辫触锛屽皾璇曚娇鐢╠ikuaiData涓殑鍊�
+                    if (dikuaiData.containsKey("mowingWidth")) {
+                        dikuai.setMowingWidth(dikuaiData.get("mowingWidth"));
+                    }
+                }
+            } else if (dikuaiData.containsKey("mowingWidth")) {
+                dikuai.setMowingWidth(dikuaiData.get("mowingWidth"));
+            }
+        } else if (dikuaiData.containsKey("mowingWidth")) {
+            dikuai.setMowingWidth(dikuaiData.get("mowingWidth"));
+        }
+        
+        // 淇濆瓨鍓茶崏鏈哄壊鍒�瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛�
+        if (bladeWidthField != null) {
+            String bladeWidthStr = bladeWidthField.getText().trim();
+            if (bladeWidthStr != null && !bladeWidthStr.isEmpty()) {
+                try {
+                    double bladeWidthMeters = Double.parseDouble(bladeWidthStr);
+                    // 淇濆瓨涓虹背锛屼繚鐣�2浣嶅皬鏁�
                     dikuai.setMowingBladeWidth(String.format(Locale.US, "%.2f", bladeWidthMeters));
                 } catch (NumberFormatException e) {
-                    dikuai.setMowingBladeWidth(bladeWidthText);
+                    // 瑙f瀽澶辫触鏃讹紝淇濆瓨鍘熷瀛楃涓�
+                    dikuai.setMowingBladeWidth(bladeWidthStr);
                 }
             }
         }
         
-        // 淇濆瓨鐩搁偦琛岄噸鍙犺窛绂伙紙浼樺厛浠巇ikuaiData鑾峰彇锛屽惁鍒欎粠TextField鑾峰彇锛�
-        if (dikuaiData.containsKey("mowingOverlapDistance")) {
-            dikuai.setMowingOverlapDistance(dikuaiData.get("mowingOverlapDistance"));
-        } else if (overlapDistanceField != null) {
-            String overlapText = overlapDistanceField.getText().trim();
-            if (!overlapText.isEmpty()) {
+        // 淇濆瓨鍓茶崏瀹夊叏璺濈锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛�
+        if (safetyDistanceField != null) {
+            String safetyDistanceStr = safetyDistanceField.getText().trim();
+            if (safetyDistanceStr != null && !safetyDistanceStr.isEmpty()) {
                 try {
-                    double overlapMeters = Double.parseDouble(overlapText);
-                    dikuai.setMowingOverlapDistance(String.format(Locale.US, "%.2f", overlapMeters));
+                    double safetyDistanceMeters = Double.parseDouble(safetyDistanceStr);
+                    // 淇濆瓨涓虹背锛屼繚鐣�2浣嶅皬鏁�
+                    String formattedValue = String.format(Locale.US, "%.2f", safetyDistanceMeters);
+                    dikuai.setMowingSafetyDistance(formattedValue);
+                    // 鍚屾椂淇濆瓨鍒癲ikuaiData涓紝浠ヤ究鍚庣画浣跨敤
+                    dikuaiData.put("mowingSafetyDistance", formattedValue);
                 } catch (NumberFormatException e) {
-                    dikuai.setMowingOverlapDistance(overlapText);
+                    // 瑙f瀽澶辫触鏃讹紝淇濆瓨鍘熷瀛楃涓�
+                    dikuai.setMowingSafetyDistance(safetyDistanceStr);
+                    dikuaiData.put("mowingSafetyDistance", safetyDistanceStr);
                 }
+            } else if (dikuaiData.containsKey("mowingSafetyDistance")) {
+                // 濡傛灉鏂囨湰妗嗕负绌猴紝灏濊瘯浠巇ikuaiData鑾峰彇
+                dikuai.setMowingSafetyDistance(dikuaiData.get("mowingSafetyDistance"));
             }
-        }
-        
-        // 淇濆瓨鍓茶崏瀹藉害锛堣绠楀悗鐨勫�硷紝浼樺厛浠巇ikuaiData鑾峰彇锛�
-        if (dikuaiData.containsKey("mowingWidth")) {
-            dikuai.setMowingWidth(dikuaiData.get("mowingWidth"));
-        } else {
-            // 濡傛灉娌℃湁鍦╠ikuaiData涓紝鍒欎粠TextField璁$畻
-            if (mowingWidthField != null && overlapDistanceField != null) {
-                try {
-                    String bladeWidthText = mowingWidthField.getText().trim();
-                    String overlapText = overlapDistanceField.getText().trim();
-                    if (!bladeWidthText.isEmpty() && !overlapText.isEmpty()) {
-                        double bladeWidthMeters = Double.parseDouble(bladeWidthText);
-                        double overlapMeters = Double.parseDouble(overlapText);
-                        double calculatedWidthMeters = bladeWidthMeters - overlapMeters;
-                        if (calculatedWidthMeters > 0) {
-                            // 杞崲涓哄帢绫冲瓨鍌紝淇濇寔涓庡師鏈夋暟鎹牸寮忓吋瀹�
-                            int widthCm = (int) Math.round(calculatedWidthMeters * 100.0);
-                            dikuai.setMowingWidth(Integer.toString(widthCm));
-                        }
-                    }
-                } catch (NumberFormatException e) {
-                    // 濡傛灉璁$畻澶辫触锛屼繚鎸佸師鏈夊�兼垨浣跨敤榛樿鍊�
-                }
-            }
+        } else if (dikuaiData.containsKey("mowingSafetyDistance")) {
+            // 濡傛灉safetyDistanceField涓簄ull锛屼粠dikuaiData鑾峰彇
+            dikuai.setMowingSafetyDistance(dikuaiData.get("mowingSafetyDistance"));
         }
 
+        // 淇濆瓨鍓茶崏璺緞鍧愭爣
         String plannedPath = dikuaiData.get("plannedPath");
         if (isMeaningfulValue(plannedPath)) {
             dikuai.setPlannedPath(plannedPath);
         }
-        
-        // 淇濆瓨鍓茶崏瀹夊叏璺濈锛堜紭鍏堜粠dikuaiData鑾峰彇锛屽惁鍒欎粠TextField鑾峰彇锛�
-        if (dikuaiData.containsKey("mowingSafetyDistance")) {
-            dikuai.setMowingSafetyDistance(dikuaiData.get("mowingSafetyDistance"));
-        } else if (mowingSafetyDistanceField != null) {
-            String safetyDistanceText = mowingSafetyDistanceField.getText().trim();
-            if (!safetyDistanceText.isEmpty()) {
-                try {
-                    double safetyDistanceMeters = Double.parseDouble(safetyDistanceText);
-                    dikuai.setMowingSafetyDistance(String.format(Locale.US, "%.2f", safetyDistanceMeters));
-                } catch (NumberFormatException e) {
-                    dikuai.setMowingSafetyDistance(safetyDistanceText);
-                }
-            }
-        }
 
         Dikuai.putDikuai(landNumber, dikuai);
         Dikuai.saveToProperties();
@@ -2604,6 +3071,13 @@
         if (resumeRequested && activeSession != null) {
             dialog.applySessionData(activeSession);
             resumeRequested = false;
+            // 濡傛灉浼氳瘽宸茬敓鎴愯矾寰勶紝浼樺厛鏄剧ず姝ラ3
+            if (activeSession.data != null && isMeaningfulValue(activeSession.data.get("plannedPath"))) {
+                dialog.showStep(3);
+            } else if (activeSession.drawingCompleted) {
+                // 濡傛灉浼氳瘽宸插畬鎴愮粯鍒讹紝鏄剧ず姝ラ2
+                dialog.showStep(2);
+            }
         }
         
         dialog.setVisible(true);

--
Gitblit v1.10.0