From d709e6dad60398fd599900cf781d0dd1e8c37c1c Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期一, 01 十二月 2025 19:55:14 +0800
Subject: [PATCH] 20251201
---
src/zhangaiwu/AddDikuai.java | 393 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 389 insertions(+), 4 deletions(-)
diff --git a/src/dikuai/AddDikuai.java b/src/zhangaiwu/AddDikuai.java
similarity index 78%
rename from src/dikuai/AddDikuai.java
rename to src/zhangaiwu/AddDikuai.java
index 8c59d2a..017bc55 100644
--- a/src/dikuai/AddDikuai.java
+++ b/src/zhangaiwu/AddDikuai.java
@@ -1,4 +1,4 @@
-package dikuai;
+package zhangaiwu;
import javax.swing.*;
@@ -14,11 +14,15 @@
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import bianjie.jisuanmianjie;
+import dikuai.Dikuai;
+import dikuai.Dikuaiguanli;
import gecaoji.Device;
import bianjie.bianjieguihua2;
+import lujing.Lunjingguihua;
import ui.UIConfig;
import zhuye.MowerLocationData;
import zhuye.Shouye;
@@ -62,6 +66,7 @@
private JButton nextButton;
private JButton createButton;
private JLabel boundaryCountLabel;
+ private JPanel obstacleListContainer;
// 鍦板潡鏁版嵁
private Map<String, String> dikuaiData = new HashMap<>();
@@ -218,6 +223,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());
@@ -226,6 +235,256 @@
return stepPanel;
}
+
+ private JPanel createObstacleSummarySection() {
+ JPanel section = new JPanel();
+ section.setLayout(new BoxLayout(section, BoxLayout.Y_AXIS));
+ section.setOpaque(false);
+ section.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ JLabel title = new JLabel("宸叉湁闅滅鐗�");
+ title.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 16));
+ title.setForeground(TEXT_COLOR);
+ title.setAlignmentX(Component.LEFT_ALIGNMENT);
+ section.add(title);
+ section.add(Box.createRigidArea(new Dimension(0, 8)));
+
+ obstacleListContainer = new JPanel();
+ obstacleListContainer.setLayout(new BoxLayout(obstacleListContainer, BoxLayout.Y_AXIS));
+ obstacleListContainer.setOpaque(false);
+ obstacleListContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
+ section.add(obstacleListContainer);
+
+ updateObstacleSummary();
+
+ return section;
+ }
+
+ private void updateObstacleSummary() {
+ if (obstacleListContainer == null) {
+ return;
+ }
+
+ obstacleListContainer.removeAll();
+ List<ObstacleSummary> summaries = loadExistingObstacles();
+
+ if (summaries.isEmpty()) {
+ JLabel emptyLabel = new JLabel("鏆傛棤闅滅鐗�");
+ emptyLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 13));
+ emptyLabel.setForeground(LIGHT_TEXT);
+ emptyLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ obstacleListContainer.add(emptyLabel);
+ } else {
+ int index = 1;
+ for (ObstacleSummary summary : summaries) {
+ JPanel row = new JPanel(new BorderLayout());
+ row.setOpaque(false);
+ row.setAlignmentX(Component.LEFT_ALIGNMENT);
+ row.setBorder(BorderFactory.createEmptyBorder(6, 0, 6, 0));
+
+ String labelText = String.format(Locale.CHINA, "%02d. %s", index++, summary.getName());
+ JLabel nameLabel = new JLabel(labelText);
+ nameLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 14));
+ nameLabel.setForeground(TEXT_COLOR);
+
+ JLabel coordLabel = new JLabel(summary.getDisplayCoords());
+ coordLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 13));
+ coordLabel.setForeground(LIGHT_TEXT);
+ coordLabel.setToolTipText(summary.getFullCoords());
+
+ row.add(nameLabel, BorderLayout.WEST);
+ row.add(coordLabel, BorderLayout.CENTER);
+ obstacleListContainer.add(row);
+ }
+ }
+
+ obstacleListContainer.revalidate();
+ obstacleListContainer.repaint();
+ }
+
+ private List<ObstacleSummary> loadExistingObstacles() {
+ List<ObstacleSummary> summaries = new ArrayList<>();
+
+ String landNumber = getPendingLandNumber();
+ String raw = null;
+ if (landNumber != null) {
+ Dikuai dikuai = Dikuai.getDikuai(landNumber);
+ if (dikuai != null) {
+ raw = normalizeCoordinateValue(dikuai.getObstacleCoordinates());
+ }
+ }
+ if (raw == null) {
+ raw = normalizeCoordinateValue(dikuaiData.get("obstacleCoordinates"));
+ }
+ if (!isMeaningfulValue(raw)) {
+ return summaries;
+ }
+
+ String normalized = stripInlineComment(raw);
+ if (normalized.isEmpty()) {
+ return summaries;
+ }
+
+ List<String> entries = splitObstacleEntries(normalized);
+ int defaultIndex = 1;
+
+ for (String entry : entries) {
+ String trimmedEntry = stripInlineComment(entry);
+ if (trimmedEntry.isEmpty()) {
+ continue;
+ }
+
+ String nameToken = null;
+ String shapeToken = null;
+ String coordsSection = trimmedEntry;
+
+ if (trimmedEntry.contains("::")) {
+ String[] parts = trimmedEntry.split("::", 3);
+ if (parts.length == 3) {
+ nameToken = parts[0].trim();
+ shapeToken = parts[1].trim();
+ coordsSection = parts[2].trim();
+ }
+ } else if (trimmedEntry.contains("@")) {
+ String[] parts = trimmedEntry.split("@", 3);
+ if (parts.length == 3) {
+ nameToken = parts[0].trim();
+ shapeToken = parts[1].trim();
+ coordsSection = parts[2].trim();
+ } else if (parts.length == 2) {
+ shapeToken = parts[0].trim();
+ coordsSection = parts[1].trim();
+ }
+ } else if (trimmedEntry.contains(":")) {
+ String[] parts = trimmedEntry.split(":", 3);
+ if (parts.length == 3) {
+ nameToken = parts[0].trim();
+ shapeToken = parts[1].trim();
+ coordsSection = parts[2].trim();
+ } else if (parts.length == 2) {
+ if (looksLikeShapeToken(parts[0])) {
+ shapeToken = parts[0].trim();
+ coordsSection = parts[1].trim();
+ } else {
+ nameToken = parts[0].trim();
+ coordsSection = parts[1].trim();
+ }
+ }
+ }
+
+ String sanitizedCoords = sanitizeCoordinateString(coordsSection);
+ if (!isMeaningfulValue(sanitizedCoords)) {
+ continue;
+ }
+
+ String resolvedName;
+ if (nameToken != null && !nameToken.isEmpty()) {
+ resolvedName = nameToken;
+ } else {
+ resolvedName = "闅滅鐗�" + defaultIndex++;
+ }
+
+ String displayCoords = truncateCoordinateForDisplay(sanitizedCoords, 12);
+ summaries.add(new ObstacleSummary(resolvedName, sanitizedCoords, displayCoords));
+ }
+
+ return summaries;
+ }
+
+ private List<String> splitObstacleEntries(String data) {
+ List<String> entries = new ArrayList<>();
+ if (data.indexOf('|') >= 0) {
+ String[] parts = data.split("\\|");
+ for (String part : parts) {
+ if (part != null && !part.trim().isEmpty()) {
+ entries.add(part.trim());
+ }
+ }
+ } else if (data.contains("\n")) {
+ String[] lines = data.split("\r?\n");
+ for (String line : lines) {
+ if (line != null && !line.trim().isEmpty()) {
+ entries.add(line.trim());
+ }
+ }
+ } else {
+ entries.add(data);
+ }
+ return entries;
+ }
+
+ private String stripInlineComment(String text) {
+ if (text == null) {
+ return "";
+ }
+ int hashIndex = text.indexOf('#');
+ if (hashIndex >= 0) {
+ return text.substring(0, hashIndex).trim();
+ }
+ return text.trim();
+ }
+
+ private boolean looksLikeShapeToken(String token) {
+ if (token == null) {
+ return false;
+ }
+ String normalized = token.trim().toLowerCase(Locale.ROOT);
+ return "circle".equals(normalized)
+ || "polygon".equals(normalized)
+ || "鍦嗗舰".equals(normalized)
+ || "澶氳竟褰�".equals(normalized)
+ || "0".equals(normalized)
+ || "1".equals(normalized);
+ }
+
+ private String sanitizeCoordinateString(String value) {
+ if (value == null) {
+ return "";
+ }
+ String stripped = stripInlineComment(value);
+ if (stripped.isEmpty()) {
+ return "";
+ }
+ return stripped.replace("\r", "").replace("\n", "").replace("\t", "").replace(" ", "");
+ }
+
+ private String truncateCoordinateForDisplay(String coords, int maxLength) {
+ if (coords == null) {
+ return "";
+ }
+ String trimmed = coords.trim();
+ if (trimmed.length() <= maxLength) {
+ return trimmed;
+ }
+ if (maxLength <= 3) {
+ return trimmed.substring(0, maxLength);
+ }
+ return trimmed.substring(0, maxLength - 3) + "...";
+ }
+
+ private static final class ObstacleSummary {
+ private final String name;
+ private final String fullCoords;
+ private final String displayCoords;
+
+ ObstacleSummary(String name, String fullCoords, String displayCoords) {
+ this.name = name;
+ this.fullCoords = fullCoords;
+ this.displayCoords = displayCoords;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getFullCoords() {
+ return fullCoords;
+ }
+
+ public String getDisplayCoords() {
+ return displayCoords;
+ }
+ }
private JPanel createStep2Panel() {
JPanel stepPanel = new JPanel();
@@ -675,9 +934,89 @@
showStep(2);
return;
}
- dikuaiData.put("mowingPattern", (String) mowingPatternCombo.getSelectedItem());
- dikuaiData.put("mowingWidth", mowingWidthSpinner.getValue().toString());
- JOptionPane.showMessageDialog(this, "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰�", "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
+ Dikuai dikuai = getOrCreatePendingDikuai();
+ String boundaryCoords = null;
+ if (dikuai != null) {
+ boundaryCoords = normalizeCoordinateValue(dikuai.getBoundaryCoordinates());
+ }
+ if (boundaryCoords == null) {
+ boundaryCoords = normalizeCoordinateValue(dikuaiData.get("boundaryCoordinates"));
+ }
+ if (boundaryCoords == null) {
+ JOptionPane.showMessageDialog(this, "鏈壘鍒版湁鏁堢殑鍦板潡杈圭晫鍧愭爣锛屾棤娉曠敓鎴愯矾寰�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ return;
+ }
+
+ String obstacleCoords = null;
+ if (dikuai != null) {
+ obstacleCoords = normalizeCoordinateValue(dikuai.getObstacleCoordinates());
+ }
+ if (obstacleCoords == null) {
+ obstacleCoords = normalizeCoordinateValue(dikuaiData.get("obstacleCoordinates"));
+ }
+
+ String patternDisplay = (String) mowingPatternCombo.getSelectedItem();
+ dikuaiData.put("mowingPattern", patternDisplay);
+
+ Object widthObj = mowingWidthSpinner.getValue();
+ if (!(widthObj instanceof Number)) {
+ JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害杈撳叆鏃犳晥", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ return;
+ }
+ double widthCm = ((Number) widthObj).doubleValue();
+ if (widthCm <= 0) {
+ JOptionPane.showMessageDialog(this, "鍓茶崏瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ return;
+ }
+ dikuaiData.put("mowingWidth", widthObj.toString());
+
+ String widthMeters = String.format(Locale.US, "%.2f", widthCm / 100.0);
+ String plannerMode = resolvePlannerMode(patternDisplay);
+
+ try {
+ List<Lunjingguihua.PathSegment> segments = Lunjingguihua.generatePathSegments(
+ boundaryCoords,
+ obstacleCoords,
+ widthMeters,
+ plannerMode
+ );
+ String plannedPath = Lunjingguihua.formatPathSegments(segments);
+ if (!isMeaningfulValue(plannedPath)) {
+ JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: 鐢熸垚缁撴灉涓虹┖", "閿欒", JOptionPane.ERROR_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ return;
+ }
+ dikuaiData.put("plannedPath", plannedPath);
+ if (createButton != null) {
+ createButton.setEnabled(true);
+ }
+ JOptionPane.showMessageDialog(this,
+ "宸叉牴鎹綋鍓嶈缃敓鎴愬壊鑽夎矾寰勶紝鍏辩敓鎴� " + segments.size() + " 娈点��",
+ "鎴愬姛",
+ JOptionPane.INFORMATION_MESSAGE);
+ } catch (IllegalArgumentException ex) {
+ JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: " + ex.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞鏃跺彂鐢熷紓甯�: " + ex.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
+ if (createButton != null) {
+ createButton.setEnabled(false);
+ }
+ }
}
private JButton createPrimaryButton(String text, int fontSize) {
@@ -732,6 +1071,7 @@
nextButton = createPrimaryButton("涓嬩竴姝�", 16);
createButton = createPrimaryButton("淇濆瓨", 16);
createButton.setVisible(false);
+ createButton.setEnabled(false);
buttonPanel.add(prevButton);
buttonPanel.add(Box.createHorizontalGlue());
@@ -880,6 +1220,36 @@
boundaryCountLabel.setVisible(false);
}
}
+
+ private boolean hasGeneratedPath() {
+ return isMeaningfulValue(dikuaiData.get("plannedPath"));
+ }
+
+ private String normalizeCoordinateValue(String value) {
+ return isMeaningfulValue(value) ? value.trim() : null;
+ }
+
+ private boolean isMeaningfulValue(String value) {
+ if (value == null) {
+ return false;
+ }
+ String trimmed = value.trim();
+ return !trimmed.isEmpty() && !"-1".equals(trimmed);
+ }
+
+ private String resolvePlannerMode(String patternDisplay) {
+ if (patternDisplay == null) {
+ return "parallel";
+ }
+ String trimmed = patternDisplay.trim();
+ if (trimmed.isEmpty()) {
+ return "parallel";
+ }
+ if ("铻烘棆寮�".equals(trimmed) || "spiral".equalsIgnoreCase(trimmed) || "1".equals(trimmed)) {
+ return "spiral";
+ }
+ return "parallel";
+ }
private void setupEventHandlers() {
// 涓婁竴姝ユ寜閽�
@@ -922,6 +1292,10 @@
currentStep = step;
cardLayout.show(stepsPanel, "step" + step);
+ if (step == 1) {
+ updateObstacleSummary();
+ }
+
// 鏇存柊鎸夐挳鐘舵��
updateButtonState(step);
}
@@ -932,9 +1306,11 @@
if (step < 3) {
nextButton.setVisible(true);
createButton.setVisible(false);
+ createButton.setEnabled(false);
} else {
nextButton.setVisible(false);
createButton.setVisible(true);
+ createButton.setEnabled(hasGeneratedPath());
}
Container parent = prevButton.getParent();
@@ -977,6 +1353,10 @@
case 3:
dikuaiData.put("mowingPattern", (String) mowingPatternCombo.getSelectedItem());
dikuaiData.put("mowingWidth", mowingWidthSpinner.getValue().toString());
+ if (!hasGeneratedPath()) {
+ JOptionPane.showMessageDialog(this, "璇峰厛鐢熸垚鍓茶崏璺緞", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return false;
+ }
break;
}
return true;
@@ -1271,6 +1651,11 @@
dikuai.setMowingWidth(dikuaiData.get("mowingWidth"));
}
+ String plannedPath = dikuaiData.get("plannedPath");
+ if (isMeaningfulValue(plannedPath)) {
+ dikuai.setPlannedPath(plannedPath);
+ }
+
Dikuai.putDikuai(landNumber, dikuai);
Dikuai.saveToProperties();
--
Gitblit v1.10.0