| | |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.Comparator; |
| | | import java.awt.geom.Point2D; |
| | | |
| | | import bianjie.jisuanmianjie; |
| | |
| | | |
| | | private List<ObstacleSummary> loadExistingObstacles() { |
| | | List<ObstacleSummary> summaries = new ArrayList<>(); |
| | | List<ExistingObstacle> obstacles = fetchExistingObstacleDetails(); |
| | | |
| | | 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)) { |
| | | if (obstacles.isEmpty()) { |
| | | 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()) { |
| | | for (ExistingObstacle obstacle : obstacles) { |
| | | if (obstacle == null) { |
| | | 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)) { |
| | | String name = obstacle.getName(); |
| | | if (!isMeaningfulValue(name)) { |
| | | 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)); |
| | | String coords = obstacle.getDisplayCoordinates(); |
| | | String fullCoords = isMeaningfulValue(coords) ? coords.trim() : ""; |
| | | String preview = buildCoordinatePreview(fullCoords, 20); |
| | | summaries.add(new ObstacleSummary(name.trim(), fullCoords, preview)); |
| | | } |
| | | |
| | | return summaries; |
| | | } |
| | | |
| | | private List<ExistingObstacle> fetchExistingObstacleDetails() { |
| | | File configFile = new File("Obstacledge.properties"); |
| | | if (!configFile.exists()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | List<ExistingObstacle> result = new ArrayList<>(); |
| | | try { |
| | | Obstacledge.ConfigManager manager = new Obstacledge.ConfigManager(); |
| | | if (!manager.loadFromFile(configFile.getAbsolutePath())) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | for (Obstacledge.Plot plot : manager.getPlots()) { |
| | | if (plot == null) { |
| | | continue; |
| | | } |
| | | String landNumber = isMeaningfulValue(plot.getPlotId()) ? plot.getPlotId().trim() : ""; |
| | | List<Obstacledge.Obstacle> plotObstacles = plot.getObstacles(); |
| | | if (plotObstacles == null || plotObstacles.isEmpty()) { |
| | | continue; |
| | | } |
| | | for (Obstacledge.Obstacle obstacle : plotObstacles) { |
| | | if (obstacle == null) { |
| | | continue; |
| | | } |
| | | String name = obstacle.getObstacleName(); |
| | | if (!isMeaningfulValue(name)) { |
| | | continue; |
| | | } |
| | | String coords = extractObstacleCoordinates(obstacle); |
| | | result.add(new ExistingObstacle(landNumber, name.trim(), coords)); |
| | | } |
| | | } |
| | | } catch (Exception ex) { |
| | | System.err.println("加载已有障碍物失败: " + ex.getMessage()); |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | if (result.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | result.sort(Comparator.comparing(ExistingObstacle::getName, String.CASE_INSENSITIVE_ORDER)); |
| | | return result; |
| | | } |
| | | |
| | | private String extractObstacleCoordinates(Obstacledge.Obstacle obstacle) { |
| | | if (obstacle == null) { |
| | | return ""; |
| | | } |
| | | String xy = obstacle.getXyCoordsString(); |
| | | if (isMeaningfulValue(xy)) { |
| | | return xy.trim(); |
| | | } |
| | | String original = obstacle.getOriginalCoordsString(); |
| | | if (isMeaningfulValue(original)) { |
| | | return original.trim(); |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | private String buildCoordinatePreview(String coords, int keepLength) { |
| | | if (!isMeaningfulValue(coords)) { |
| | | return "无坐标"; |
| | | } |
| | | String sanitized = sanitizeCoordinateString(coords); |
| | | if (sanitized.length() <= keepLength) { |
| | | return sanitized; |
| | | } |
| | | if (keepLength <= 0) { |
| | | return "..."; |
| | | } |
| | | return sanitized.substring(0, keepLength) + "..."; |
| | | } |
| | | |
| | | private List<String> splitObstacleEntries(String data) { |
| | | List<String> entries = new ArrayList<>(); |
| | | if (data.indexOf('|') >= 0) { |
| | |
| | | return displayCoords; |
| | | } |
| | | } |
| | | |
| | | private static final class ExistingObstacle { |
| | | private final String landNumber; |
| | | private final String name; |
| | | private final String coordinates; |
| | | |
| | | ExistingObstacle(String landNumber, String name, String coordinates) { |
| | | this.landNumber = landNumber != null ? landNumber : ""; |
| | | this.name = name != null ? name : ""; |
| | | this.coordinates = coordinates != null ? coordinates : ""; |
| | | } |
| | | |
| | | String getLandNumber() { |
| | | return landNumber; |
| | | } |
| | | |
| | | String getName() { |
| | | return name; |
| | | } |
| | | |
| | | String getDisplayCoordinates() { |
| | | return coordinates; |
| | | } |
| | | } |
| | | |
| | | private JPanel createStep2Panel() { |
| | | JPanel stepPanel = new JPanel(); |
| | |
| | | } |
| | | |
| | | String obstacleCoords = null; |
| | | if (dikuai != null) { |
| | | obstacleCoords = normalizeCoordinateValue(dikuai.getObstacleCoordinates()); |
| | | String landNumber = getPendingLandNumber(); |
| | | if (isMeaningfulValue(landNumber)) { |
| | | obstacleCoords = normalizeCoordinateValue(resolveObstaclePayloadFromConfig(landNumber)); |
| | | } |
| | | if (obstacleCoords == null) { |
| | | obstacleCoords = normalizeCoordinateValue(dikuaiData.get("obstacleCoordinates")); |
| | |
| | | return isMeaningfulValue(dikuaiData.get("plannedPath")); |
| | | } |
| | | |
| | | private String resolveObstaclePayloadFromConfig(String landNumber) { |
| | | if (!isMeaningfulValue(landNumber)) { |
| | | return null; |
| | | } |
| | | try { |
| | | File configFile = new File("Obstacledge.properties"); |
| | | if (!configFile.exists()) { |
| | | return null; |
| | | } |
| | | Obstacledge.ConfigManager manager = new Obstacledge.ConfigManager(); |
| | | if (!manager.loadFromFile(configFile.getAbsolutePath())) { |
| | | return null; |
| | | } |
| | | Obstacledge.Plot plot = manager.getPlotById(landNumber.trim()); |
| | | if (plot == null) { |
| | | return null; |
| | | } |
| | | return Obstacledge.buildPlannerPayload(plot.getObstacles()); |
| | | } catch (Exception ex) { |
| | | System.err.println("加载障碍物配置失败: " + ex.getMessage()); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private static String normalizeCoordinateValue(String value) { |
| | | return isMeaningfulValue(value) ? value.trim() : null; |
| | | } |