From d709e6dad60398fd599900cf781d0dd1e8c37c1c Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期一, 01 十二月 2025 19:55:14 +0800
Subject: [PATCH] 20251201
---
src/zhuye/MapRenderer.java | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 284 insertions(+), 5 deletions(-)
diff --git a/src/zhuye/MapRenderer.java b/src/zhuye/MapRenderer.java
index 32049b4..aebc291 100644
--- a/src/zhuye/MapRenderer.java
+++ b/src/zhuye/MapRenderer.java
@@ -11,10 +11,13 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import gecaoji.Device;
import gecaoji.Gecaoji;
import dikuai.Dikuaiguanli;
import dikuai.Dikuai;
+import zhangaiwu.Obstacledraw;
+import zhangaiwu.Obstacledge;
/**
* 鍦板浘娓叉煋鍣� - 璐熻矗鍧愭爣绯荤粯鍒躲�佽鍥惧彉鎹㈢瓑鍔熻兘
@@ -43,6 +46,9 @@
private Rectangle2D.Double boundaryBounds;
private List<Point2D.Double> currentPlannedPath;
private Rectangle2D.Double plannedPathBounds;
+ private List<Obstacledge.Obstacle> currentObstacles;
+ private Rectangle2D.Double obstacleBounds;
+ private String selectedObstacleName;
private String boundaryName;
private boolean boundaryPointsVisible;
private String currentBoundaryLandNumber;
@@ -202,11 +208,16 @@
boolean hasBoundary = currentBoundary != null && currentBoundary.size() >= 2;
boolean hasPlannedPath = currentPlannedPath != null && currentPlannedPath.size() >= 2;
+ boolean hasObstacles = currentObstacles != null && !currentObstacles.isEmpty();
if (hasBoundary) {
drawCurrentBoundary(g2d);
}
+ if (hasObstacles) {
+ Obstacledraw.drawObstacles(g2d, currentObstacles, scale, selectedObstacleName);
+ }
+
if (hasPlannedPath) {
drawCurrentPlannedPath(g2d);
}
@@ -759,6 +770,264 @@
currentBoundaryLandNumber = null;
}
+ public void setCurrentObstacles(String obstaclesData, String landNumber) {
+ if (landNumber == null) {
+ clearObstacleData();
+ if (!hasRenderableBoundary() && !hasRenderablePlannedPath()) {
+ resetView();
+ } else {
+ visualizationPanel.repaint();
+ }
+ return;
+ }
+
+ List<Obstacledge.Obstacle> parsed = parseObstacles(obstaclesData, landNumber);
+ if (parsed.isEmpty()) {
+ clearObstacleData();
+ if (!hasRenderableBoundary() && !hasRenderablePlannedPath()) {
+ resetView();
+ } else {
+ visualizationPanel.repaint();
+ }
+ return;
+ }
+
+ currentObstacles = parsed;
+ obstacleBounds = convertObstacleBounds(Obstacledraw.getAllObstaclesBounds(parsed));
+ selectedObstacleName = null;
+
+ if (!hasRenderableBoundary() && !hasRenderablePlannedPath() && obstacleBounds != null) {
+ Rectangle2D.Double bounds = obstacleBounds;
+ SwingUtilities.invokeLater(() -> {
+ fitBoundsToView(bounds);
+ visualizationPanel.repaint();
+ });
+ } else {
+ visualizationPanel.repaint();
+ }
+ }
+
+ private void clearObstacleData() {
+ currentObstacles = null;
+ obstacleBounds = null;
+ selectedObstacleName = null;
+ }
+
+ private List<Obstacledge.Obstacle> parseObstacles(String obstaclesData, String landNumber) {
+ List<Obstacledge.Obstacle> obstacles = new ArrayList<>();
+ if (obstaclesData == null) {
+ return obstacles;
+ }
+
+ String normalized = stripInlineComment(obstaclesData.trim());
+ if (normalized.isEmpty() || "-1".equals(normalized)) {
+ return obstacles;
+ }
+
+ 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();
+ }
+ }
+ }
+
+ List<Obstacledge.XYCoordinate> xyCoordinates = parseObstacleCoordinates(coordsSection);
+ if (xyCoordinates.size() < 2) {
+ continue;
+ }
+
+ Obstacledge.ObstacleShape shape = resolveObstacleShape(shapeToken, xyCoordinates.size());
+ if (shape == null) {
+ continue;
+ }
+
+ String obstacleName = (nameToken != null && !nameToken.isEmpty())
+ ? nameToken
+ : "闅滅鐗�" + defaultIndex++;
+
+ Obstacledge.Obstacle obstacle = new Obstacledge.Obstacle(landNumber, obstacleName, shape);
+ obstacle.setXyCoordinates(new ArrayList<>(xyCoordinates));
+ populateDummyOriginalCoordinates(obstacle, xyCoordinates.size());
+
+ if (obstacle.isValid()) {
+ obstacles.add(obstacle);
+ }
+ }
+
+ return obstacles;
+ }
+
+ 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 List<Obstacledge.XYCoordinate> parseObstacleCoordinates(String coordsSection) {
+ List<Obstacledge.XYCoordinate> coords = new ArrayList<>();
+ if (coordsSection == null) {
+ return coords;
+ }
+
+ String sanitized = stripInlineComment(coordsSection.trim());
+ if (sanitized.isEmpty() || "-1".equals(sanitized)) {
+ return coords;
+ }
+
+ String[] pairs = sanitized.split(";");
+ for (String pair : pairs) {
+ if (pair == null) {
+ continue;
+ }
+ String trimmed = stripInlineComment(pair.trim());
+ if (trimmed.isEmpty()) {
+ continue;
+ }
+ String[] parts = trimmed.split(",");
+ if (parts.length < 2) {
+ continue;
+ }
+ try {
+ double x = Double.parseDouble(parts[0].trim());
+ double y = Double.parseDouble(parts[1].trim());
+ coords.add(new Obstacledge.XYCoordinate(x, y));
+ } catch (NumberFormatException ignored) {
+ // Skip malformed coordinate pair
+ }
+ }
+
+ return coords;
+ }
+
+ private Obstacledge.ObstacleShape resolveObstacleShape(String shapeToken, int coordinateCount) {
+ if (shapeToken != null && !shapeToken.trim().isEmpty()) {
+ String normalized = shapeToken.trim().toLowerCase(Locale.ROOT);
+ if ("circle".equals(normalized) || "鍦嗗舰".equals(normalized) || "0".equals(normalized)) {
+ return Obstacledge.ObstacleShape.CIRCLE;
+ }
+ if ("polygon".equals(normalized) || "澶氳竟褰�".equals(normalized) || "1".equals(normalized)) {
+ return Obstacledge.ObstacleShape.POLYGON;
+ }
+ }
+
+ if (coordinateCount == 2) {
+ return Obstacledge.ObstacleShape.CIRCLE;
+ }
+ if (coordinateCount >= 3) {
+ return Obstacledge.ObstacleShape.POLYGON;
+ }
+ return null;
+ }
+
+ private void populateDummyOriginalCoordinates(Obstacledge.Obstacle obstacle, int xyCount) {
+ List<Obstacledge.DMCoordinate> dmCoordinates = new ArrayList<>();
+ int points = Math.max(1, xyCount);
+ for (int i = 0; i < points; i++) {
+ dmCoordinates.add(new Obstacledge.DMCoordinate(0.0, 'N'));
+ dmCoordinates.add(new Obstacledge.DMCoordinate(0.0, 'E'));
+ }
+ obstacle.setOriginalCoordinates(dmCoordinates);
+ }
+
+ 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 Rectangle2D.Double convertObstacleBounds(double[] bounds) {
+ if (bounds == null || bounds.length < 4) {
+ return null;
+ }
+ double minX = bounds[0];
+ double minY = bounds[1];
+ double maxX = bounds[2];
+ double maxY = bounds[3];
+ return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
+ }
+
+ private boolean hasRenderableBoundary() {
+ return currentBoundary != null && currentBoundary.size() >= 2;
+ }
+
+ private boolean hasRenderablePlannedPath() {
+ return currentPlannedPath != null && currentPlannedPath.size() >= 2;
+ }
+
private void adjustViewAfterBoundaryReset() {
if (plannedPathBounds != null) {
Rectangle2D.Double bounds = plannedPathBounds;
@@ -766,16 +1035,26 @@
fitBoundsToView(bounds);
visualizationPanel.repaint();
});
- } else {
- resetView();
+ return;
}
+
+ if (obstacleBounds != null) {
+ Rectangle2D.Double bounds = obstacleBounds;
+ SwingUtilities.invokeLater(() -> {
+ fitBoundsToView(bounds);
+ visualizationPanel.repaint();
+ });
+ return;
+ }
+
+ resetView();
}
public void setCurrentPlannedPath(String plannedPath) {
if (plannedPath == null) {
currentPlannedPath = null;
plannedPathBounds = null;
- if (currentBoundary == null || currentBoundary.size() < 2) {
+ if (!hasRenderableBoundary()) {
resetView();
} else {
visualizationPanel.repaint();
@@ -787,7 +1066,7 @@
if (parsed.size() < 2) {
currentPlannedPath = null;
plannedPathBounds = null;
- if (currentBoundary == null || currentBoundary.size() < 2) {
+ if (!hasRenderableBoundary()) {
resetView();
} else {
visualizationPanel.repaint();
@@ -800,7 +1079,7 @@
Rectangle2D.Double bounds = plannedPathBounds;
SwingUtilities.invokeLater(() -> {
- if (currentBoundary == null || currentBoundary.size() < 2) {
+ if (!hasRenderableBoundary()) {
fitBoundsToView(bounds);
}
visualizationPanel.repaint();
--
Gitblit v1.10.0