From 32c98d4855b6178554c787103dc956d161e152b3 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 19 十二月 2025 19:45:30 +0800
Subject: [PATCH] 增加了异形分析逻辑

---
 src/zhangaiwu/Obstacledge.java |  281 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 281 insertions(+), 0 deletions(-)

diff --git a/src/zhangaiwu/Obstacledge.java b/src/zhangaiwu/Obstacledge.java
index 2bd39e4..a174214 100644
--- a/src/zhangaiwu/Obstacledge.java
+++ b/src/zhangaiwu/Obstacledge.java
@@ -1,6 +1,7 @@
 package zhangaiwu;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * 鍓茶崏鏈哄湴鍧楅殰纰嶇墿绫�
@@ -482,6 +483,14 @@
             this.baseStationLat = lat;
             this.baseStationLon = lon;
         }
+
+        /**
+         * 娓呴櫎鍩哄噯绔欏潗鏍�
+         */
+        public void clearBaseStation() {
+            this.baseStationLat = null;
+            this.baseStationLon = null;
+        }
         
         /**
          * 璁剧疆鍩哄噯绔欏潗鏍囧瓧绗︿覆
@@ -824,4 +833,276 @@
         }
     }    
    
+    /**
+     * 灏嗚矾寰勮鍒掍娇鐢ㄧ殑闅滅鐗╁潗鏍囧瓧绗︿覆瑙f瀽涓洪殰纰嶇墿鍒楄〃銆�
+     * @param payload 闅滅鐗╁潗鏍囧瓧绗︿覆
+     * @param landNumber 鍦板潡缂栧彿
+     * @return 瑙f瀽寰楀埌鐨勯殰纰嶇墿鍒楄〃
+     */
+    public static List<Obstacle> parsePlannerPayload(String payload, String landNumber) {
+        return ObstaclePayloadConverter.parse(payload, landNumber);
+    }
+
+    /**
+     * 灏嗛殰纰嶇墿鍒楄〃杞崲涓鸿矾寰勮鍒掍娇鐢ㄧ殑鍧愭爣瀛楃涓层��
+     * @param obstacles 闅滅鐗╁垪琛�
+     * @return 鍧愭爣瀛楃涓诧紝鑻ュ垪琛ㄤ负绌鸿繑鍥瀗ull
+     */
+    public static String buildPlannerPayload(List<Obstacle> obstacles) {
+        return ObstaclePayloadConverter.build(obstacles);
+    }
+
+    /**
+     * 闅滅鐗╁潗鏍囧瓧绗︿覆涓庢暟鎹璞′箣闂寸殑杞崲宸ュ叿銆�
+     */
+    private static final class ObstaclePayloadConverter {
+        private ObstaclePayloadConverter() {
+        }
+
+        private static List<Obstacle> parse(String payload, String landNumber) {
+            List<Obstacle> obstacles = new ArrayList<>();
+            if (payload == null) {
+                return obstacles;
+            }
+
+            String normalizedPayload = stripInlineComment(payload.trim());
+            if (normalizedPayload.isEmpty() || "-1".equals(normalizedPayload)) {
+                return obstacles;
+            }
+
+            String normalizedLand = landNumber != null ? landNumber.trim() : null;
+            List<String> entries = splitEntries(normalizedPayload);
+            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<XYCoordinate> xyCoordinates = parseCoordinates(coordsSection);
+                if (xyCoordinates.size() < 2) {
+                    continue;
+                }
+
+                ObstacleShape shape = resolveShape(shapeToken, xyCoordinates.size());
+                if (shape == null) {
+                    continue;
+                }
+
+                String obstacleName;
+                if (nameToken != null && !nameToken.isEmpty()) {
+                    obstacleName = nameToken;
+                } else {
+                    obstacleName = "闅滅鐗�" + defaultIndex++;
+                }
+
+                Obstacle obstacle = new Obstacle(normalizedLand, obstacleName, shape);
+                obstacle.setPlotId(normalizedLand);
+                obstacle.setObstacleName(obstacleName);
+                obstacle.setShape(shape);
+                obstacle.setXyCoordinates(new ArrayList<>(xyCoordinates));
+                populatePlaceholderOriginalCoords(obstacle, xyCoordinates.size());
+
+                if (obstacle.isValid()) {
+                    obstacles.add(obstacle);
+                }
+            }
+
+            return obstacles;
+        }
+
+        private static String build(List<Obstacle> obstacles) {
+            if (obstacles == null || obstacles.isEmpty()) {
+                return null;
+            }
+            StringBuilder builder = new StringBuilder();
+            for (Obstacle obstacle : obstacles) {
+                if (obstacle == null) {
+                    continue;
+                }
+                List<XYCoordinate> coords = obstacle.getXyCoordinates();
+                if (coords == null || coords.isEmpty()) {
+                    continue;
+                }
+                if (builder.length() > 0) {
+                    builder.append(' ');
+                }
+                builder.append('(');
+                for (int i = 0; i < coords.size(); i++) {
+                    XYCoordinate coord = coords.get(i);
+                    if (coord == null) {
+                        continue;
+                    }
+                    if (i > 0) {
+                        builder.append(';');
+                    }
+                    builder.append(formatDouble(coord.getX())).append(',').append(formatDouble(coord.getY()));
+                }
+                builder.append(')');
+            }
+            return builder.length() == 0 ? null : builder.toString();
+        }
+
+        private static 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 static List<XYCoordinate> parseCoordinates(String coordsSection) {
+            List<XYCoordinate> coords = new ArrayList<>();
+            if (coordsSection == null) {
+                return coords;
+            }
+
+            String sanitized = stripInlineComment(coordsSection.trim());
+            if (sanitized.isEmpty() || "-1".equals(sanitized)) {
+                return coords;
+            }
+
+            // Remove wrapper characters like parentheses that surround persisted payloads
+            sanitized = sanitized.replace("(", "").replace(")", "");
+
+            String[] pairs = sanitized.split(";");
+            for (String pair : pairs) {
+                if (pair == null) {
+                    continue;
+                }
+                String trimmed = stripInlineComment(pair.trim());
+                if (trimmed.isEmpty()) {
+                    continue;
+                }
+                trimmed = trimmed.replace("(", "").replace(")", "");
+                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 XYCoordinate(x, y));
+                } catch (NumberFormatException ignored) {
+                    // 蹇界暐鏍煎紡閿欒鐨勫潗鏍囩偣
+                }
+            }
+
+            return coords;
+        }
+
+        private static ObstacleShape resolveShape(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 ObstacleShape.CIRCLE;
+                }
+                if ("polygon".equals(normalized) || "澶氳竟褰�".equals(normalized) || "1".equals(normalized)) {
+                    return ObstacleShape.POLYGON;
+                }
+            }
+
+            if (coordinateCount == 2) {
+                return ObstacleShape.CIRCLE;
+            }
+            if (coordinateCount >= 3) {
+                return ObstacleShape.POLYGON;
+            }
+            return null;
+        }
+
+        private static void populatePlaceholderOriginalCoords(Obstacle obstacle, int xyCount) {
+            List<DMCoordinate> dmCoordinates = new ArrayList<>();
+            int points = Math.max(1, xyCount);
+            for (int i = 0; i < points; i++) {
+                dmCoordinates.add(new DMCoordinate(0.0, 'N'));
+                dmCoordinates.add(new DMCoordinate(0.0, 'E'));
+            }
+            obstacle.setOriginalCoordinates(dmCoordinates);
+        }
+
+        private static 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 static List<String> splitEntries(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 static String formatDouble(double value) {
+            return String.format(Locale.ROOT, "%.2f", value);
+        }
+    }
 }
\ No newline at end of file

--
Gitblit v1.10.0