From 9d7822ada88392e1b1a612e9b4f680fe6b09aedf Mon Sep 17 00:00:00 2001
From: 826220679@qq.com <826220679@qq.com>
Date: 星期六, 27 十二月 2025 22:25:38 +0800
Subject: [PATCH] 优化了路径规划
---
src/zhuye/MapRenderer.java | 161 +++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 136 insertions(+), 25 deletions(-)
diff --git a/src/zhuye/MapRenderer.java b/src/zhuye/MapRenderer.java
index dfffdf9..c39b39d 100644
--- a/src/zhuye/MapRenderer.java
+++ b/src/zhuye/MapRenderer.java
@@ -18,6 +18,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Set;
+import java.util.function.Consumer;
import java.io.File;
import set.Setsys;
import gecaoji.Device;
@@ -632,7 +633,7 @@
* 娣诲姞瀵艰埅棰勮杞ㄨ抗鐐�
*/
public void addNavigationPreviewTrackPoint(Point2D.Double point) {
- if (point != null && Double.isFinite(point.x) && Double.isFinite(point.y)) {
+ if (point != null && isFinite(point.x) && isFinite(point.y)) {
navigationPreviewTrack.add(new Point2D.Double(point.x, point.y));
if (visualizationPanel != null) {
visualizationPanel.repaint();
@@ -750,7 +751,7 @@
return;
}
Point2D.Double position = mower.getPosition();
- if (position == null || !Double.isFinite(position.x) || !Double.isFinite(position.y)) {
+ if (position == null || !isFinite(position.x) || !isFinite(position.y)) {
pendingTrackBreak = true;
return;
}
@@ -776,7 +777,7 @@
}
realtimeMowingTrack.add(candidate);
- if (!pendingTrackBreak && lastPoint != null && Double.isFinite(distance)) {
+ if (!pendingTrackBreak && lastPoint != null && isFinite(distance)) {
trackLengthMeters += distance;
}
@@ -807,7 +808,7 @@
}
Point2D.Double position = mower.getPosition();
- if (position == null || !Double.isFinite(position.x) || !Double.isFinite(position.y)) {
+ if (position == null || !isFinite(position.x) || !isFinite(position.y)) {
return;
}
@@ -852,7 +853,7 @@
// 鍒锋柊mower浣嶇疆锛屼娇鐢ㄦ渶鏂扮殑Device鏁版嵁
mower.refreshFromDevice();
Point2D.Double position = mower.getPosition();
- if (position == null || !Double.isFinite(position.x) || !Double.isFinite(position.y)) {
+ if (position == null || !isFinite(position.x) || !isFinite(position.y)) {
return;
}
@@ -963,7 +964,7 @@
}
private String formatTrackCoordinate(double value) {
- if (!Double.isFinite(value)) {
+ if (!isFinite(value)) {
return "0";
}
return String.format(Locale.US, "%.3f", value);
@@ -1154,7 +1155,7 @@
try {
double x = Double.parseDouble(parts[0].trim());
double y = Double.parseDouble(parts[1].trim());
- if (!Double.isFinite(x) || !Double.isFinite(y)) {
+ if (!isFinite(x) || !isFinite(y)) {
continue;
}
Point2D.Double current = new Point2D.Double(x, y);
@@ -1403,7 +1404,8 @@
// 灏嗕笘鐣屽潗鏍囪浆鎹负灞忓箷鍧愭爣锛堢敤浜庢枃瀛楁樉绀猴級
Point2D.Double worldMid = new Point2D.Double(midX, midY);
- Point2D.Double screenMid = worldToScreen(worldMid);
+ Point2D.Double screenMid = new Point2D.Double();
+ originalTransform.transform(worldMid, screenMid);
// 鎭㈠鍘熷鍙樻崲浠ョ粯鍒舵枃瀛楋紙鍥哄畾澶у皬锛屼笉闅忕缉鏀惧彉鍖栵級
g2d.setTransform(new AffineTransform());
@@ -1451,7 +1453,94 @@
private void drawCurrentPlannedPath(Graphics2D g2d) {
double arrowScale = previewSizingEnabled ? 0.5d : 1.0d;
- lujingdraw.drawPlannedPath(g2d, currentPlannedPath, scale, arrowScale);
+
+ // 灏濊瘯鑾峰彇鍦板潡淇℃伅浠ユ敮鎸佸尯鍒嗕綔涓氳矾寰勫拰绉诲姩璺緞锛屼互鍙婄粯鍒跺唴缂╄竟鐣�
+ String boundaryCoords = null;
+ String mowingWidth = null;
+ String safetyDistance = null;
+ String obstaclesCoords = null;
+ String mowingPattern = null;
+ String plannedPathStr = null;
+
+ // 浠庡綋鍓嶅湴鍧楃紪鍙疯幏鍙栧湴鍧椾俊鎭�
+ if (currentBoundaryLandNumber != null) {
+ Dikuai landData = Dikuai.getDikuai(currentBoundaryLandNumber);
+ if (landData != null) {
+ boundaryCoords = landData.getBoundaryCoordinates();
+ mowingWidth = landData.getMowingWidth();
+ safetyDistance = landData.getMowingSafetyDistance();
+ mowingPattern = landData.getMowingPattern();
+ // 浠庡湴鍧楄幏鍙杙lannedPath灞炴�у�间綔涓鸿矾寰�
+ plannedPathStr = landData.getPlannedPath();
+
+ // 鑾峰彇闅滅鐗╁潗鏍�
+ try {
+ java.io.File configFile = new java.io.File("Obstacledge.properties");
+ if (configFile.exists()) {
+ Obstacledge.ConfigManager manager = new Obstacledge.ConfigManager();
+ if (manager.loadFromFile(configFile.getAbsolutePath())) {
+ Obstacledge.Plot plot = manager.getPlotById(currentBoundaryLandNumber.trim());
+ if (plot != null && plot.getObstacles() != null && !plot.getObstacles().isEmpty()) {
+ obstaclesCoords = Obstacledge.buildPlannerPayload(plot.getObstacles());
+ }
+ }
+ }
+ } catch (Exception e) {
+ // 蹇界暐闅滅鐗╁姞杞介敊璇�
+ }
+ }
+ }
+
+ // 濡傛灉鏃犳硶浠庡湴鍧楄幏鍙栬竟鐣岋紝灏濊瘯浣跨敤褰撳墠鏄剧ず鐨勮竟鐣�
+ if (boundaryCoords == null || boundaryCoords.trim().isEmpty() || "-1".equals(boundaryCoords.trim())) {
+ if (currentBoundary != null && !currentBoundary.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < currentBoundary.size(); i++) {
+ Point2D.Double pt = currentBoundary.get(i);
+ if (i > 0) sb.append(";");
+ sb.append(String.format(java.util.Locale.US, "%.3f,%.3f", pt.x, pt.y));
+ }
+ boundaryCoords = sb.toString();
+ }
+ }
+
+ // 杞崲鍓茶崏瀹藉害浠庡帢绫冲埌绫筹紙濡傛灉瀛樺湪锛�
+ if (mowingWidth != null && !mowingWidth.trim().isEmpty() && !"-1".equals(mowingWidth.trim())) {
+ try {
+ double widthCm = Double.parseDouble(mowingWidth.trim());
+ double widthMeters = widthCm / 100.0;
+ mowingWidth = String.format(java.util.Locale.US, "%.3f", widthMeters);
+ } catch (NumberFormatException e) {
+ // 濡傛灉宸茬粡鏄背涓哄崟浣嶏紝淇濇寔鍘熷��
+ }
+ }
+
+ // 杞崲瀹夊叏璺濈浠庡帢绫冲埌绫筹紙濡傛灉瀛樺湪锛�
+ if (safetyDistance != null && !safetyDistance.trim().isEmpty() && !"-1".equals(safetyDistance.trim())) {
+ try {
+ double distCm = Double.parseDouble(safetyDistance.trim());
+ // 濡傛灉鍊煎ぇ浜�100锛岃涓烘槸鍘樼背锛岄渶瑕佽浆鎹负绫�
+ if (distCm > 100) {
+ double distMeters = distCm / 100.0;
+ safetyDistance = String.format(java.util.Locale.US, "%.3f", distMeters);
+ }
+ } catch (NumberFormatException e) {
+ // 濡傛灉宸茬粡鏄背涓哄崟浣嶏紝淇濇寔鍘熷��
+ }
+ }
+
+ // 濡傛灉浠庡湴鍧楄幏鍙栧埌浜嗚矾寰勶紝浣跨敤鍦板潡鐨勮矾寰勶紱鍚﹀垯浣跨敤currentPlannedPath
+ List<Point2D.Double> pathToDraw = currentPlannedPath;
+ if (plannedPathStr != null && !plannedPathStr.trim().isEmpty() && !"-1".equals(plannedPathStr.trim())) {
+ // 浠庡湴鍧楄幏鍙栫殑璺緞
+ pathToDraw = lujingdraw.parsePlannedPath(plannedPathStr);
+ }
+
+ // 璋冪敤甯﹀湴鍧椾俊鎭殑缁樺埗鏂规硶
+ if (pathToDraw != null && pathToDraw.size() >= 2) {
+ lujingdraw.drawPlannedPath(g2d, pathToDraw, scale, arrowScale,
+ boundaryCoords, mowingWidth, safetyDistance, obstaclesCoords, mowingPattern);
+ }
}
private void drawCircleSampleMarkers(Graphics2D g2d, List<double[]> markers, double scale) {
@@ -1473,7 +1562,7 @@
FontMetrics metrics = g2d.getFontMetrics(labelFont);
for (double[] pt : markers) {
- if (pt == null || pt.length < 2 || !Double.isFinite(pt[0]) || !Double.isFinite(pt[1])) {
+ if (pt == null || pt.length < 2 || !isFinite(pt[0]) || !isFinite(pt[1])) {
continue;
}
double x = pt[0];
@@ -1571,7 +1660,7 @@
}
double x = pt[0];
double y = pt[1];
- if (!Double.isFinite(x) || !Double.isFinite(y)) {
+ if (!isFinite(x) || !isFinite(y)) {
continue;
}
circleSampleMarkers.add(new double[]{x, y});
@@ -1794,7 +1883,7 @@
private double computeSelectionThresholdPixels() {
double scaleFactor = Math.max(0.5, scale);
double diameterScale = boundaryPointSizeScale * (previewSizingEnabled ? PREVIEW_BOUNDARY_MARKER_SCALE : 1.0d);
- if (!Double.isFinite(diameterScale) || diameterScale <= 0.0d) {
+ if (!isFinite(diameterScale) || diameterScale <= 0.0d) {
diameterScale = 1.0d;
}
double markerDiameterWorld = Math.max(1.0, (10.0 / scaleFactor) * 0.2 * diameterScale);
@@ -1883,6 +1972,7 @@
.append(',')
.append(formatCoordinate(point.y));
if (i < boundary.size() - 1) {
+
builder.append(';');
}
}
@@ -1958,7 +2048,7 @@
}
private boolean isPointInsideActiveBoundary(Point2D.Double point) {
- if (point == null || !Double.isFinite(point.x) || !Double.isFinite(point.y)) {
+ if (point == null || !isFinite(point.x) || !isFinite(point.y)) {
return false;
}
if (realtimeTrackLandNumber == null) {
@@ -1969,7 +2059,7 @@
}
private boolean isPointInsideBoundary(Point2D.Double point, Path2D.Double path) {
- if (point == null || path == null || !Double.isFinite(point.x) || !Double.isFinite(point.y)) {
+ if (point == null || path == null || !isFinite(point.x) || !isFinite(point.y)) {
return false;
}
if (path.contains(point.x, point.y)) {
@@ -1990,7 +2080,7 @@
Path2D.Double path = new Path2D.Double();
boolean started = false;
for (Point2D.Double point : boundary) {
- if (point == null || !Double.isFinite(point.x) || !Double.isFinite(point.y)) {
+ if (point == null || !isFinite(point.x) || !isFinite(point.y)) {
continue;
}
if (!started) {
@@ -2026,7 +2116,7 @@
// 璁剧疆鐐圭殑澶у皬锛堥殢缂╂斁鍙樺寲锛�
double scaleFactor = Math.max(0.5, scale);
double clampedScale = boundaryPointSizeScale * (previewSizingEnabled ? PREVIEW_BOUNDARY_MARKER_SCALE : 1.0d);
- if (!Double.isFinite(clampedScale) || clampedScale <= 0.0d) {
+ if (!isFinite(clampedScale) || clampedScale <= 0.0d) {
clampedScale = 1.0d;
}
double minimumDiameter = clampedScale < 1.0 ? 0.5 : 1.0;
@@ -2475,7 +2565,7 @@
}
double x = coord.getX();
double y = coord.getY();
- if (!Double.isFinite(x) || !Double.isFinite(y)) {
+ if (!isFinite(x) || !isFinite(y)) {
continue;
}
copy.add(new Obstacledge.XYCoordinate(x, y));
@@ -2813,7 +2903,7 @@
}
public void setBoundaryPointSizeScale(double sizeScale) {
- double normalized = (Double.isFinite(sizeScale) && sizeScale > 0.0d) ? sizeScale : 1.0d;
+ double normalized = (isFinite(sizeScale) && sizeScale > 0.0d) ? sizeScale : 1.0d;
if (Math.abs(boundaryPointSizeScale - normalized) < 1e-6) {
return;
}
@@ -2841,7 +2931,7 @@
}
public void setBoundaryPreviewMarkerScale(double markerScale) {
- double normalized = Double.isFinite(markerScale) && markerScale > 0.0d ? markerScale : 1.0d;
+ double normalized = isFinite(markerScale) && markerScale > 0.0d ? markerScale : 1.0d;
if (Math.abs(boundaryPreviewMarkerScale - normalized) < 1e-6) {
return;
}
@@ -2878,7 +2968,7 @@
}
public void addHandheldBoundaryPoint(double x, double y) {
- if (!Double.isFinite(x) || !Double.isFinite(y)) {
+ if (!isFinite(x) || !isFinite(y)) {
return;
}
if (!handheldBoundaryPreviewActive) {
@@ -2990,8 +3080,8 @@
Point2D.Double mowerPosition = mower.getPosition();
if (mowerPosition == null
- || !Double.isFinite(mowerPosition.x)
- || !Double.isFinite(mowerPosition.y)) {
+ || !isFinite(mowerPosition.x)
+ || !isFinite(mowerPosition.y)) {
return expanded;
}
@@ -3435,10 +3525,31 @@
/**
* 璁剧疆杈圭晫棰勮鏇存柊鍥炶皟
*/
- private java.util.function.Consumer<String> boundaryPreviewUpdateCallback;
+ private Consumer<String> boundaryPreviewUpdateCallback;
- public void setBoundaryPreviewUpdateCallback(java.util.function.Consumer<String> callback) {
+ public void setBoundaryPreviewUpdateCallback(Consumer<String> callback) {
this.boundaryPreviewUpdateCallback = callback;
}
-}
\ No newline at end of file
+ /**
+ * 灏嗚鍥句腑蹇冨鍑嗗綋鍓嶈竟鐣岀殑鍑犱綍涓績
+ */
+ public void centerViewOnBoundary() {
+ if (currentBoundary == null || currentBoundary.isEmpty()) {
+ return;
+ }
+
+ Rectangle2D.Double bounds = computeBounds(currentBoundary);
+ if (bounds != null) {
+ fitBoundsToView(bounds);
+ }
+ }
+
+ /**
+ * 妫�鏌ouble鍊兼槸鍚︽湁闄愶紙涓嶆槸NaN鎴栨棤绌峰ぇ锛�
+ * 鍏煎浣庣増鏈琂ava
+ */
+ private static boolean isFinite(double value) {
+ return !Double.isNaN(value) && !Double.isInfinite(value);
+ }
+}
--
Gitblit v1.10.0