From 1cf1ecbc75c6d14b40efb3161e7db0b8b64f7de2 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期三, 17 十二月 2025 12:05:27 +0800
Subject: [PATCH] 新增有障碍物的路径规划算法和优化没有障碍物的路径算法

---
 src/dikuai/Dikuaiguanli.java |  280 ++++++++++++++++++++++---------------------------------
 1 files changed, 111 insertions(+), 169 deletions(-)

diff --git a/src/dikuai/Dikuaiguanli.java b/src/dikuai/Dikuaiguanli.java
index a5e31b6..5f0218e 100644
--- a/src/dikuai/Dikuaiguanli.java
+++ b/src/dikuai/Dikuaiguanli.java
@@ -24,6 +24,7 @@
 import java.util.Properties;
 
 import lujing.Lunjingguihua;
+import lujing.MowingPathGenerationPage;
 import zhangaiwu.AddDikuai;
 import zhangaiwu.Obstacledge;
 import zhuye.MapRenderer;
@@ -334,8 +335,8 @@
 		JButton deleteBtn = createDeleteButton();
 		deleteBtn.addActionListener(e -> deleteDikuai(dikuai));
 
-		JButton generatePathBtn = createPrimaryFooterButton("鐢熸垚鍓茶崏璺緞");
-		generatePathBtn.addActionListener(e -> generateMowingPath(dikuai));
+		JButton generatePathBtn = createPrimaryFooterButton("璺緞瑙勫垝");
+		generatePathBtn.addActionListener(e -> showPathPlanningPage(dikuai));
 
 		JPanel footerPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 		footerPanel.setBackground(CARD_BACKGROUND);
@@ -828,6 +829,77 @@
 		return trimmed;
 	}
 
+	/**
+	 * 鏄剧ず璺緞瑙勫垝椤甸潰
+	 */
+	private void showPathPlanningPage(Dikuai dikuai) {
+		if (dikuai == null) {
+			return;
+		}
+
+		Window owner = SwingUtilities.getWindowAncestor(this);
+
+		// 鑾峰彇鍦板潡鍩烘湰鏁版嵁
+		String baseStationValue = prepareCoordinateForEditor(dikuai.getBaseStationCoordinates());
+		String boundaryValue = prepareCoordinateForEditor(dikuai.getBoundaryCoordinates());
+		List<Obstacledge.Obstacle> configuredObstacles = getConfiguredObstacles(dikuai);
+		String obstacleValue = determineInitialObstacleValue(dikuai, configuredObstacles);
+		String widthValue = sanitizeWidthString(dikuai.getMowingWidth());
+		if (widthValue != null) {
+			try {
+				double widthCm = Double.parseDouble(widthValue);
+				widthValue = formatWidthForStorage(widthCm);
+			} catch (NumberFormatException ignored) {
+				// 淇濇寔鍘熷瀛楃涓诧紝绋嶅悗鏍¢獙鎻愮ず
+			}
+		}
+		String modeValue = sanitizeValueOrNull(dikuai.getMowingPattern());
+		String existingPath = prepareCoordinateForEditor(dikuai.getPlannedPath());
+
+		// 鍒涘缓淇濆瓨鍥炶皟鎺ュ彛瀹炵幇
+		MowingPathGenerationPage.PathSaveCallback callback = new MowingPathGenerationPage.PathSaveCallback() {
+			@Override
+			public boolean saveBaseStationCoordinates(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "baseStationCoordinates", value);
+			}
+
+			@Override
+			public boolean saveBoundaryCoordinates(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "boundaryCoordinates", value);
+			}
+
+			@Override
+			public boolean saveObstacleCoordinates(Dikuai dikuai, String baseStationValue, String obstacleValue) {
+				return persistObstaclesForLand(dikuai, baseStationValue, obstacleValue);
+			}
+
+			@Override
+			public boolean saveMowingWidth(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "mowingWidth", value);
+			}
+
+			@Override
+			public boolean savePlannedPath(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "plannedPath", value);
+			}
+		};
+
+		// 鏄剧ず璺緞瑙勫垝椤甸潰
+		MowingPathGenerationPage dialog = new MowingPathGenerationPage(
+			owner,
+			dikuai,
+			baseStationValue,
+			boundaryValue,
+			obstacleValue,
+			widthValue,
+			modeValue,
+			existingPath,
+			callback
+		);
+
+		dialog.setVisible(true);
+	}
+
 	private void generateMowingPath(Dikuai dikuai) {
 		if (dikuai == null) {
 			return;
@@ -866,178 +938,48 @@
 		String modeValue,
 		String initialGeneratedPath) {
 		Window owner = SwingUtilities.getWindowAncestor(this);
-		JDialog dialog = new JDialog(owner, "鐢熸垚鍓茶崏璺緞", Dialog.ModalityType.APPLICATION_MODAL);
-		dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-		dialog.getContentPane().setLayout(new BorderLayout());
-		dialog.getContentPane().setBackground(BACKGROUND_COLOR);
-
-		JPanel contentPanel = new JPanel();
-		contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
-		contentPanel.setBackground(BACKGROUND_COLOR);
-		contentPanel.setBorder(BorderFactory.createEmptyBorder(12, 16, 12, 16));
-
-		String landName = getDisplayValue(dikuai.getLandName(), "鏈煡鍦板潡");
-		String landNumber = getDisplayValue(dikuai.getLandNumber(), "鏈煡缂栧彿");
-		JLabel headerLabel = new JLabel(landName + " / " + landNumber);
-		headerLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 16));
-		headerLabel.setForeground(TEXT_COLOR);
-		headerLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
-		contentPanel.add(headerLabel);
-		contentPanel.add(Box.createVerticalStrut(12));
-
-		JTextField baseStationField = createInfoTextField(baseStationValue != null ? baseStationValue : "", true);
-		contentPanel.add(createTextFieldSection("鍩虹珯鍧愭爣", baseStationField));
-
-		JTextArea boundaryArea = createInfoTextArea(boundaryValue != null ? boundaryValue : "", true, 6);
-		contentPanel.add(createTextAreaSection("鍦板潡杈圭晫", boundaryArea));
-
-		JTextArea obstacleArea = createInfoTextArea(obstacleValue != null ? obstacleValue : "", true, 6);
-		contentPanel.add(createTextAreaSection("闅滅鐗╁潗鏍�", obstacleArea));
-
-		JTextField widthField = createInfoTextField(widthValue != null ? widthValue : "", true);
-		contentPanel.add(createTextFieldSection("鍓茶崏瀹藉害 (鍘樼背)", widthField));
-		contentPanel.add(createInfoValueSection("鍓茶崏妯″紡", formatMowingPatternForDialog(modeValue)));
-
-		String existingPath = prepareCoordinateForEditor(dikuai.getPlannedPath());
-		String pathSeed = initialGeneratedPath != null ? initialGeneratedPath : existingPath;
-		JTextArea pathArea = createInfoTextArea(pathSeed != null ? pathSeed : "", true, 10);
-		contentPanel.add(createTextAreaSection("鍓茶崏璺緞鍧愭爣", pathArea));
-
-		JScrollPane dialogScrollPane = new JScrollPane(contentPanel);
-		dialogScrollPane.setBorder(BorderFactory.createEmptyBorder());
-		dialogScrollPane.getVerticalScrollBar().setUnitIncrement(16);
-		dialog.add(dialogScrollPane, BorderLayout.CENTER);
-
-		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 12, 12));
-		buttonPanel.setBackground(BACKGROUND_COLOR);
-
-		JButton generateBtn = createPrimaryFooterButton("鐢熸垚鍓茶崏璺緞");
-		JButton saveBtn = createPrimaryFooterButton("淇濆瓨璺緞");
-		JButton cancelBtn = createPrimaryFooterButton("鍙栨秷");
-
-		generateBtn.addActionListener(e -> {
-			String sanitizedWidth = sanitizeWidthString(widthField.getText());
-			if (sanitizedWidth != null) {
-				try {
-					double widthCm = Double.parseDouble(sanitizedWidth);
-					widthField.setText(formatWidthForStorage(widthCm));
-					sanitizedWidth = formatWidthForStorage(widthCm);
-				} catch (NumberFormatException ex) {
-					widthField.setText(sanitizedWidth);
-				}
+		
+		// 鍒涘缓淇濆瓨鍥炶皟鎺ュ彛瀹炵幇
+		MowingPathGenerationPage.PathSaveCallback callback = new MowingPathGenerationPage.PathSaveCallback() {
+			@Override
+			public boolean saveBaseStationCoordinates(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "baseStationCoordinates", value);
 			}
-			String generated = attemptMowingPathPreview(
-				boundaryArea.getText(),
-				obstacleArea.getText(),
-				sanitizedWidth,
-				modeValue,
-				dialog,
-				true
-			);
-			if (generated != null) {
-				pathArea.setText(generated);
-				pathArea.setCaretPosition(0);
+			
+			@Override
+			public boolean saveBoundaryCoordinates(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "boundaryCoordinates", value);
 			}
-		});
-
-		saveBtn.addActionListener(e -> {
-			String baseStationNormalized = normalizeCoordinateInput(baseStationField.getText());
-			String boundaryNormalized = normalizeCoordinateInput(boundaryArea.getText());
-			if (!"-1".equals(boundaryNormalized)) {
-				boundaryNormalized = boundaryNormalized
-					.replace("\r\n", ";")
-					.replace('\r', ';')
-					.replace('\n', ';')
-					.replaceAll(";+", ";")
-					.replaceAll("\\s*;\\s*", ";")
-					.trim();
-				if (boundaryNormalized.isEmpty()) {
-					boundaryNormalized = "-1";
-				}
+			
+			@Override
+			public boolean saveObstacleCoordinates(Dikuai dikuai, String baseStationValue, String obstacleValue) {
+				return persistObstaclesForLand(dikuai, baseStationValue, obstacleValue);
 			}
-			String obstacleNormalized = normalizeCoordinateInput(obstacleArea.getText());
-			if (!"-1".equals(obstacleNormalized)) {
-				obstacleNormalized = obstacleNormalized
-					.replace("\r\n", " ")
-					.replace('\r', ' ')
-					.replace('\n', ' ')
-					.replaceAll("\\s{2,}", " ")
-					.trim();
-				if (obstacleNormalized.isEmpty()) {
-					obstacleNormalized = "-1";
-				}
+			
+			@Override
+			public boolean saveMowingWidth(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "mowingWidth", value);
 			}
-			String rawWidthInput = widthField.getText() != null ? widthField.getText().trim() : "";
-			String widthSanitized = sanitizeWidthString(widthField.getText());
-			if (widthSanitized == null) {
-				String message = rawWidthInput.isEmpty() ? "璇峰厛璁剧疆鍓茶崏瀹藉害(鍘樼背)" : "鍓茶崏瀹藉害鏍煎紡涓嶆纭�";
-				JOptionPane.showMessageDialog(dialog, message, "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-				return;
+			
+			@Override
+			public boolean savePlannedPath(Dikuai dikuai, String value) {
+				return saveFieldAndRefresh(dikuai, "plannedPath", value);
 			}
-			double widthCm;
-			try {
-				widthCm = Double.parseDouble(widthSanitized);
-			} catch (NumberFormatException ex) {
-				JOptionPane.showMessageDialog(dialog, "鍓茶崏瀹藉害鏍煎紡涓嶆纭�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-				return;
-			}
-			if (widthCm <= 0) {
-				JOptionPane.showMessageDialog(dialog, "鍓茶崏瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
-				return;
-			}
-			String widthNormalized = formatWidthForStorage(widthCm);
-			widthField.setText(widthNormalized);
-			String pathNormalized = normalizeCoordinateInput(pathArea.getText());
-			if (!"-1".equals(pathNormalized)) {
-				pathNormalized = pathNormalized
-					.replace("\r\n", ";")
-					.replace('\r', ';')
-					.replace('\n', ';')
-					.replaceAll(";+", ";")
-					.replaceAll("\\s*;\\s*", ";")
-					.trim();
-				if (pathNormalized.isEmpty()) {
-					pathNormalized = "-1";
-				}
-			}
-			if ("-1".equals(pathNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "璇峰厛鐢熸垚鍓茶崏璺緞", "鎻愮ず", JOptionPane.INFORMATION_MESSAGE);
-				return;
-			}
-			if (!saveFieldAndRefresh(dikuai, "baseStationCoordinates", baseStationNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍩虹珯鍧愭爣", "閿欒", JOptionPane.ERROR_MESSAGE);
-				return;
-			}
-			if (!saveFieldAndRefresh(dikuai, "boundaryCoordinates", boundaryNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍦板潡杈圭晫", "閿欒", JOptionPane.ERROR_MESSAGE);
-				return;
-			}
-			if (!persistObstaclesForLand(dikuai, baseStationNormalized, obstacleNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨闅滅鐗╁潗鏍�", "閿欒", JOptionPane.ERROR_MESSAGE);
-				return;
-			}
-			if (!saveFieldAndRefresh(dikuai, "mowingWidth", widthNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍓茶崏瀹藉害", "閿欒", JOptionPane.ERROR_MESSAGE);
-				return;
-			}
-			if (!saveFieldAndRefresh(dikuai, "plannedPath", pathNormalized)) {
-				JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍓茶崏璺緞", "閿欒", JOptionPane.ERROR_MESSAGE);
-				return;
-			}
-			JOptionPane.showMessageDialog(dialog, "鍓茶崏璺緞宸蹭繚瀛�", "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
-			dialog.dispose();
-		});
-
-		cancelBtn.addActionListener(e -> dialog.dispose());
-
-		buttonPanel.add(generateBtn);
-		buttonPanel.add(saveBtn);
-		buttonPanel.add(cancelBtn);
-		dialog.add(buttonPanel, BorderLayout.SOUTH);
-
-		dialog.pack();
-		dialog.setSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
-		dialog.setLocationRelativeTo(owner);
+		};
+		
+		// 浣跨敤鏂扮殑鐙珛椤甸潰绫�
+		MowingPathGenerationPage dialog = new MowingPathGenerationPage(
+			owner,
+			dikuai,
+			baseStationValue,
+			boundaryValue,
+			obstacleValue,
+			widthValue,
+			modeValue,
+			initialGeneratedPath,
+			callback
+		);
+		
 		dialog.setVisible(true);
 	}
 

--
Gitblit v1.10.0