From b272034a1fdbfe32b355fc6c264a4c45df107190 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 23 十二月 2025 14:55:03 +0800
Subject: [PATCH] 优化了新增地块功能
---
src/zhangaiwu/AddDikuai.java | 539 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 457 insertions(+), 82 deletions(-)
diff --git a/src/zhangaiwu/AddDikuai.java b/src/zhangaiwu/AddDikuai.java
index 8333117..07d238c 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,12 +16,13 @@
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 set.Setsys;
import ui.UIConfig;
@@ -65,7 +62,9 @@
private JTextField landNumberField;
private JTextField areaNameField;
private JComboBox<String> mowingPatternCombo;
- private JSpinner mowingWidthSpinner;
+ private JTextField bladeWidthField; // 鍓茶崏鏈哄壊鍒�瀹藉害锛坢锛�
+ private JTextField mowingWidthField; // 鍓茶崏瀹藉害锛坢锛屽彲缂栬緫锛�
+ private JTextField safetyDistanceField; // 鍓茶崏瀹夊叏璺濈锛坢锛屽彲缂栬緫锛�
private JPanel previewPanel;
private Map<String, JPanel> drawingOptionPanels = new HashMap<>();
@@ -77,6 +76,8 @@
private JButton previewButton;
private Component previewButtonSpacer;
private JLabel boundaryCountLabel;
+ private JTextArea boundaryXYTextArea; // 鏄剧ず杈圭晫XY鍧愭爣鐨勬枃鏈煙
+ private JScrollPane boundaryXYScrollPane; // 杈圭晫XY鍧愭爣鏂囨湰鍩熺殑婊氬姩闈㈡澘
private JPanel obstacleListContainer;
private JTextArea pathGenerationMessageArea;
private JPanel pathMessageWrapper;
@@ -657,6 +658,34 @@
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);
@@ -825,12 +854,18 @@
// 鐢ㄦ埛鍦ㄥ璇濇鍐呬富鍔ㄧ粨鏉燂紙鏈Е鍙戝閮ㄦ祦绋嬶級
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();
}
}
@@ -881,6 +916,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 +1011,7 @@
settingsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
// 鍓茶崏妯″紡閫夋嫨
- JPanel patternPanel = createFormGroup("鍓茶崏妯″紡", "閫夋嫨鍓茶崏璺緞鐨勭敓鎴愭ā寮�");
+ JPanel patternPanel = createFormGroup("鍓茶崏妯″紡", "");
mowingPatternCombo = new JComboBox<>(new String[]{"骞宠绾�", "铻烘棆寮�"});
mowingPatternCombo.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
mowingPatternCombo.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
@@ -936,27 +1045,23 @@
settingsPanel.add(patternPanel);
settingsPanel.add(Box.createRigidArea(new Dimension(0, 20)));
- // 鍓茶崏瀹藉害璁剧疆
- JPanel widthPanel = createFormGroup("鍓茶崏瀹藉害", "璁剧疆鍓茶崏鏈哄崟娆″壊鑽夌殑瀹藉害");
- JPanel widthInputPanel = new JPanel(new BorderLayout());
- widthInputPanel.setBackground(WHITE);
- widthInputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 48));
- widthInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ // 鍓茶崏鏈哄壊鍒�瀹藉害璁剧疆
+ 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);
- SpinnerNumberModel widthModel = new SpinnerNumberModel(40, 20, 60, 1);
- mowingWidthSpinner = new JSpinner(widthModel);
- mowingWidthSpinner.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 16));
- JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) mowingWidthSpinner.getEditor();
- editor.getTextField().setBorder(BorderFactory.createCompoundBorder(
+ 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)
));
-
- // 娣诲姞寰皟鍣ㄧ劍鐐规晥鏋�
- mowingWidthSpinner.addFocusListener(new FocusAdapter() {
+ bladeWidthField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
- editor.getTextField().setBorder(BorderFactory.createCompoundBorder(
+ bladeWidthField.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
BorderFactory.createEmptyBorder(10, 12, 10, 12)
));
@@ -964,26 +1069,124 @@
@Override
public void focusLost(FocusEvent e) {
- editor.getTextField().setBorder(BorderFactory.createCompoundBorder(
+ 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();
+ 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) {
+ mowingWidthField.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
+ BorderFactory.createEmptyBorder(10, 12, 10, 12)
+ ));
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ mowingWidthField.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(BORDER_COLOR, 2),
BorderFactory.createEmptyBorder(10, 12, 10, 12)
));
}
});
- 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));
- widthInputPanel.add(mowingWidthSpinner, BorderLayout.CENTER);
+ widthInputPanel.add(mowingWidthField, BorderLayout.CENTER);
widthInputPanel.add(unitLabel, BorderLayout.EAST);
widthPanel.add(widthInputPanel);
settingsPanel.add(widthPanel);
+ settingsPanel.add(Box.createRigidArea(new Dimension(0, 20)));
+
+ // 鍓茶崏瀹夊叏璺濈璁剧疆锛堝彲缂栬緫锛�
+ 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);
+
+ 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)
+ ));
+ safetyDistanceField.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ safetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(PRIMARY_COLOR, 2),
+ BorderFactory.createEmptyBorder(10, 12, 10, 12)
+ ));
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ safetyDistanceField.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(BORDER_COLOR, 2),
+ BorderFactory.createEmptyBorder(10, 12, 10, 12)
+ ));
+ }
+ });
+
+ 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(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();
+
+ // 灏嗚缃潰鏉挎斁鍏ユ粴鍔ㄩ潰鏉�
+ 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);
@@ -1058,19 +1261,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)));
+
+ // 鍙湁褰撴彁绀烘枃瀛椾笉涓虹┖鏃舵墠鏄剧ず
+ 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);
@@ -1108,35 +1359,64 @@
String patternDisplay = (String) mowingPatternCombo.getSelectedItem();
dikuaiData.put("mowingPattern", patternDisplay);
- Object widthObj = mowingWidthSpinner.getValue();
- if (!(widthObj instanceof Number)) {
- 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 widthCm = ((Number) widthObj).doubleValue();
- if (widthCm <= 0) {
+
+ double widthMeters;
+ try {
+ widthMeters = Double.parseDouble(mowingWidthStr);
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害鏍煎紡涓嶆纭�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ dikuaiData.remove("plannedPath");
+ showPathGenerationMessage("鍓茶崏瀹藉害鏍煎紡涓嶆纭紝璇烽噸鏂拌緭鍏ャ��", false);
+ setPathAvailability(false);
+ return;
+ }
+
+ if (widthMeters <= 0) {
JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
dikuaiData.remove("plannedPath");
showPathGenerationMessage("鍓茶崏瀹藉害蹇呴』澶т簬0锛岃閲嶆柊璁剧疆銆�", false);
setPathAvailability(false);
return;
}
- dikuaiData.put("mowingWidth", widthObj.toString());
+
+ // 淇濆瓨鍓茶崏瀹藉害锛堣浆鎹负鍘樼背淇濆瓨锛屼繚鎸佷笌鍘熸湁鏁版嵁鏍煎紡涓�鑷达級
+ double widthCm = widthMeters * 100.0;
+ dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
- String widthMeters = String.format(Locale.US, "%.2f", widthCm / 100.0);
+ // 鑾峰彇瀹夊叏璺濈
+ String safetyDistanceStr = safetyDistanceField.getText().trim();
+ double safetyDistanceMeters = Double.NaN;
+ if (safetyDistanceStr != null && !safetyDistanceStr.isEmpty()) {
+ try {
+ safetyDistanceMeters = Double.parseDouble(safetyDistanceStr);
+ } catch (NumberFormatException e) {
+ // 浣跨敤NaN锛岃绯荤粺鑷姩璁$畻
+ }
+ }
+
+ String widthMetersStr = String.format(Locale.US, "%.3f", widthMeters);
+ String safetyDistanceMetersStr = Double.isNaN(safetyDistanceMeters) ? null : String.format(Locale.US, "%.3f", safetyDistanceMeters);
String plannerMode = resolvePlannerMode(patternDisplay);
try {
- List<Lunjingguihua.PathSegment> segments = Lunjingguihua.generatePathSegments(
+ // 浣跨敤涓庤矾寰勮鍒掗〉闈㈢浉鍚岀殑鏂规硶锛歀unjingguihua.generatePathFromStrings
+ String plannedPath = Lunjingguihua.generatePathFromStrings(
boundaryCoords,
- obstacleCoords,
- widthMeters,
+ obstacleCoords != null ? obstacleCoords : "",
+ widthMetersStr,
+ safetyDistanceMetersStr,
plannerMode
);
- String plannedPath = Lunjingguihua.formatPathSegments(segments);
+
if (!isMeaningfulValue(plannedPath)) {
JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: 鐢熸垚缁撴灉涓虹┖", "閿欒", JOptionPane.ERROR_MESSAGE);
dikuaiData.remove("plannedPath");
@@ -1144,6 +1424,7 @@
setPathAvailability(false);
return;
}
+
if (isMeaningfulValue(boundaryCoords)) {
dikuaiData.put("boundaryCoordinates", boundaryCoords);
}
@@ -1153,7 +1434,7 @@
dikuaiData.put("plannedPath", plannedPath);
setPathAvailability(true);
showPathGenerationMessage(
- "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰勶紝鍏辩敓鎴� " + segments.size() + " 娈点�俓n鐐瑰嚮鈥滈瑙堚�濇寜閽彲鍦ㄤ富椤甸潰鏌ョ湅鏁堟灉銆�",
+ "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰勩�俓n鐐瑰嚮棰勮鎸夐挳鍙湪涓婚〉闈㈡煡鐪嬫晥鏋溿��",
true);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: " + ex.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
@@ -1249,13 +1530,18 @@
}
}
- if (mowingWidthSpinner != null) {
- Object widthValue = mowingWidthSpinner.getValue();
- if (widthValue instanceof Number) {
- int widthInt = ((Number) widthValue).intValue();
- dikuaiData.put("mowingWidth", Integer.toString(widthInt));
- } else if (widthValue != null) {
- dikuaiData.put("mowingWidth", widthValue.toString());
+ // 淇濆瓨鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛岃浆鎹负鍘樼背淇濆瓨锛�
+ if (mowingWidthField != null) {
+ String widthStr = mowingWidthField.getText().trim();
+ if (widthStr != null && !widthStr.isEmpty()) {
+ try {
+ double widthMeters = Double.parseDouble(widthStr);
+ double widthCm = widthMeters * 100.0;
+ dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
+ } catch (NumberFormatException e) {
+ // 淇濇寔鍘熷��
+ dikuaiData.put("mowingWidth", widthStr);
+ }
}
}
}
@@ -1384,10 +1670,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);
}
@@ -1519,6 +1815,53 @@
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() {
@@ -1587,8 +1930,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);
}
@@ -1732,7 +2081,20 @@
case 3:
dikuaiData.put("mowingPattern", (String) mowingPatternCombo.getSelectedItem());
- dikuaiData.put("mowingWidth", mowingWidthSpinner.getValue().toString());
+ // 淇濆瓨鍓茶崏瀹藉害锛堜粠鏂囨湰妗嗚幏鍙栵紝鍗曚綅锛氱背锛岃浆鎹负鍘樼背淇濆瓨锛�
+ if (mowingWidthField != null) {
+ String widthStr = mowingWidthField.getText().trim();
+ if (widthStr != null && !widthStr.isEmpty()) {
+ try {
+ double widthMeters = Double.parseDouble(widthStr);
+ double widthCm = widthMeters * 100.0;
+ dikuaiData.put("mowingWidth", String.format(Locale.US, "%.2f", widthCm));
+ } catch (NumberFormatException e) {
+ // 淇濇寔鍘熷��
+ dikuaiData.put("mowingWidth", widthStr);
+ }
+ }
+ }
if (!hasGeneratedPath()) {
JOptionPane.showMessageDialog(this, "璇峰厛鐢熸垚鍓茶崏璺緞", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
return false;
@@ -1977,6 +2339,7 @@
isDrawing = false;
showStep(2);
showBoundaryPointSummary();
+ updateBoundaryXYDisplay();
} else {
if (startEndDrawingBtn != null) {
startEndDrawingBtn.setText("寮�濮嬬粯鍒�");
@@ -2013,24 +2376,36 @@
}
}
- if (mowingWidthSpinner != null) {
- String width = data.get("mowingWidth");
- if (isMeaningfulValue(width)) {
- try {
- double parsed = Double.parseDouble(width.trim());
- SpinnerNumberModel model = (SpinnerNumberModel) mowingWidthSpinner.getModel();
- int min = ((Number) model.getMinimum()).intValue();
- int max = ((Number) model.getMaximum()).intValue();
- int rounded = (int) Math.round(parsed);
- if (rounded < min) {
- rounded = min;
- } else if (rounded > max) {
- rounded = max;
- }
- mowingWidthSpinner.setValue(rounded);
- } 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) {
+ // 淇濇寔褰撳墠鍊�
+ }
+ }
+
+ // 鎭㈠鍓插垁瀹藉害锛氫粠淇濆瓨鐨勫壊鑽夊搴﹀弽鎺ㄥ壊鍒�瀹藉害骞惰缃�
+ // 鐢变簬鍓茶崏瀹藉害 = 鍓插垁瀹藉害 * 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) {
+ // 淇濇寔褰撳墠鍊�
}
}
--
Gitblit v1.10.0