package com.algo.util; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * JSON文件读取 */ public class JsonUtils { /** * @param filePath 文件路径 * @return JSON字符串内容 * @throws IOException 文件读取异常 */ public static String readJsonFile(String filePath) throws IOException { StringBuilder content = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { String line; while ((line = reader.readLine()) != null) { content.append(line).append("\n"); } } return content.toString(); } /** * 解析路径映射JSON * * @param jsonContent JSON内容 * @return 路径映射Map,key为路径编号,value为坐标信息 */ public static Map> parsePathMapping(String jsonContent) { Map> pathMapping = new HashMap<>(); try { String pathIdSection = extractJsonSection(jsonContent, "path_id_to_coordinates"); if (pathIdSection == null) { System.err.println("未找到path_id_to_coordinates部分"); return pathMapping; } String[] lines = pathIdSection.split("\n"); String currentKey = null; for (String line : lines) { line = line.trim(); // 查找路径ID if (line.startsWith("\"") && line.contains("\":[")) { int endIndex = line.indexOf("\":["); currentKey = line.substring(1, endIndex); pathMapping.put(currentKey, new HashMap<>()); } // 查找坐标信息 if (currentKey != null && line.contains("\"x\":")) { String xStr = line.substring(line.indexOf("\"x\":") + 4); xStr = xStr.substring(0, xStr.indexOf(",")).trim(); try { int x = Integer.parseInt(xStr); pathMapping.get(currentKey).put("x", x); } catch (NumberFormatException e) { // 忽略解析错误 } } if (currentKey != null && line.contains("\"y\":")) { String yStr = line.substring(line.indexOf("\"y\":") + 4); if (yStr.contains(",")) { yStr = yStr.substring(0, yStr.indexOf(",")).trim(); } else if (yStr.contains("}")) { yStr = yStr.substring(0, yStr.indexOf("}")).trim(); } try { int y = Integer.parseInt(yStr); pathMapping.get(currentKey).put("y", y); } catch (NumberFormatException e) { // 忽略解析错误 } } } System.out.println("成功解析路径映射,包含 " + pathMapping.size() + " 个路径点"); } catch (Exception e) { System.err.println("解析路径映射JSON时发生错误: " + e.getMessage()); } return pathMapping; } /** * 路径映射 * * @param filePath 文件地址 * @return 路径映射Map,key为路径编号,value为坐标信息 */ public static Map> loadPathMapping(String filePath) { // 转换为目标结构 Map> Map> pathMapping = new HashMap<>(); ObjectMapper objectMapper = new ObjectMapper(); try { Map topLevelMap = objectMapper.readValue( new File(filePath), Map.class ); if (!topLevelMap.containsKey("path_id_to_coordinates")) { System.err.println("未找到path_id_to_coordinates部分"); return pathMapping; } // 处理 path_id_to_coordinates Map pathIdCoords = (Map) topLevelMap.get("path_id_to_coordinates"); for (Map.Entry entry : pathIdCoords.entrySet()) { String pathId = entry.getKey(); Object coordsObj = entry.getValue(); if (coordsObj instanceof List) { List coordsList = (List) coordsObj; if (!coordsList.isEmpty()) { Map coordMap = (Map) coordsList.get(0); int x = ((Number) coordMap.get("x")).intValue(); int y = ((Number) coordMap.get("y")).intValue(); Map pointMap = new HashMap<>(); pointMap.put("x", x); pointMap.put("y", y); pathMapping.put(pathId, pointMap); } } } System.out.println("成功解析路径映射,包含 " + pathMapping.size() + " 个路径点"); } catch (FileNotFoundException e) { System.err.println("路径映射文件不存在: " + e.getMessage()); } catch (IOException e) { System.err.println("路径映射文件读取错误: " + e.getMessage()); } catch (Exception e) { System.err.println("加载路径映射文件失败: " + e.getMessage()); } return pathMapping; } /** * 环境配置JSON * * @param jsonContent JSON内容 * @return 环境配置Map */ public static Map parseEnvironmentConfig(String jsonContent) { Map config = new HashMap<>(); try { if (jsonContent.contains("\"width\":")) { String widthStr = jsonContent.substring(jsonContent.indexOf("\"width\":") + 8); widthStr = widthStr.substring(0, widthStr.indexOf(",")).trim(); try { config.put("width", Integer.parseInt(widthStr)); } catch (NumberFormatException e) { config.put("width", 78); } } if (jsonContent.contains("\"height\":")) { String heightStr = jsonContent.substring(jsonContent.indexOf("\"height\":") + 9); heightStr = heightStr.substring(0, heightStr.indexOf(",")).trim(); try { config.put("height", Integer.parseInt(heightStr)); } catch (NumberFormatException e) { config.put("height", 50); } } Map> stations = parseStations(jsonContent); config.put("stations", stations); config.put("stationCount", stations.size()); System.out.println("成功解析环境配置,包含 " + stations.size() + " 个工作站"); } catch (Exception e) { System.err.println("解析环境配置JSON时发生错误: " + e.getMessage()); } return config; } /** * 解析environment.json中的stations信息 * * @param filePath 文件地址 * @return 环境配置Map */ public static Map loadEnvironment(String filePath) { // 转换为目标结构 Map Map environmentMap = new HashMap<>(); ObjectMapper objectMapper = new ObjectMapper(); try { // 先解析为顶层Map Map topLevelMap = objectMapper.readValue( new File(filePath), Map.class ); if (topLevelMap.containsKey("width")) { environmentMap.put("width", Integer.parseInt(topLevelMap.get("width").toString())); } else { environmentMap.put("width", 78); } if (topLevelMap.containsKey("width")) { environmentMap.put("height", Integer.parseInt(topLevelMap.get("height").toString())); } else { environmentMap.put("height", 50); } if (topLevelMap.containsKey("stations")) { Map> stations = new HashMap<>(); Map stationMap = (Map) topLevelMap.get("stations"); for (Map.Entry stationEntry : stationMap.entrySet()) { // 工作站ID String pathId = stationEntry.getKey(); Map stationInfo = (Map) stationEntry.getValue(); Map map = new HashMap<>(); // 解析capacity if (stationInfo.containsKey("capacity")) { map.put("capacity", Integer.parseInt(stationInfo.get("capacity").toString())); } // 解析load_position和unload_position if (stationInfo.containsKey("load_position")) { List loadPos = (List) stationInfo.get("load_position"); map.put("load_position", loadPos); } if (stationInfo.containsKey("unload_position")) { List unloadPos = (List) stationInfo.get("unload_position"); map.put("unload_position", unloadPos); } stations.put(pathId, map); } environmentMap.put("stations", stations); environmentMap.put("stationCount", stations.size()); System.out.println("成功解析环境配置,包含 " + stations.size() + " 个工作站"); } } catch (FileNotFoundException e) { System.err.println("环境配置文件不存在: " + e.getMessage()); } catch (IOException e) { System.err.println("环境配置文件读取错误: " + e.getMessage()); } catch (Exception e) { System.err.println("加载环境配置文件失败: " + e.getMessage()); } return environmentMap; } /** * 解析stations信息 * * @param jsonContent JSON内容 * @return stations Map */ private static Map> parseStations(String jsonContent) { Map> stations = new HashMap<>(); try { String stationsSection = extractJsonSection(jsonContent, "stations"); if (stationsSection == null) { return stations; } String[] lines = stationsSection.split("\n"); String currentStation = null; for (String line : lines) { line = line.trim(); if (line.startsWith("\"") && line.contains("\":{")) { int endIndex = line.indexOf("\":{"); currentStation = line.substring(1, endIndex); stations.put(currentStation, new HashMap<>()); } if (currentStation != null && line.contains("\"capacity\":")) { String capacityStr = line.substring(line.indexOf("\"capacity\":") + 11); capacityStr = capacityStr.substring(0, capacityStr.indexOf(",")).trim(); try { int capacity = Integer.parseInt(capacityStr); stations.get(currentStation).put("capacity", capacity); } catch (NumberFormatException e) { // 忽略解析错误 } } if (currentStation != null && line.contains("\"load_position\":")) { List loadPos = parsePosition(stationsSection, currentStation, "load_position"); if (loadPos != null) { stations.get(currentStation).put("load_position", loadPos); } } if (currentStation != null && line.contains("\"unload_position\":")) { List unloadPos = parsePosition(stationsSection, currentStation, "unload_position"); if (unloadPos != null) { stations.get(currentStation).put("unload_position", unloadPos); } } } } catch (Exception e) { System.err.println("解析stations信息时发生错误: " + e.getMessage()); } return stations; } /** * 解析位置信息 * * @param content JSON内容 * @param stationId 工作站ID * @param positionType 位置类型(load_position或unload_position) * @return 位置坐标列表 */ private static List parsePosition(String content, String stationId, String positionType) { try { String stationSection = content.substring(content.indexOf("\"" + stationId + "\":{")); String positionSection = stationSection.substring(stationSection.indexOf("\"" + positionType + "\":")); String[] lines = positionSection.split("\n"); List position = new ArrayList<>(); for (String line : lines) { line = line.trim(); if (line.matches("\\d+,?")) { String numStr = line.replaceAll("[,\\s]", ""); try { position.add(Integer.parseInt(numStr)); } catch (NumberFormatException e) { // 忽略解析错误 } } if (line.contains("]")) { break; } } return position.size() == 2 ? position : null; } catch (Exception e) { return null; } } /** * 提取JSON中特定部分 * * @param jsonContent JSON内容 * @param sectionName 部分名称 * @return 提取的部分内容 */ private static String extractJsonSection(String jsonContent, String sectionName) { try { String startPattern = "\"" + sectionName + "\": {"; int startIndex = jsonContent.indexOf(startPattern); if (startIndex == -1) { return null; } int braceCount = 0; int currentIndex = startIndex + startPattern.length() - 1; while (currentIndex < jsonContent.length()) { char ch = jsonContent.charAt(currentIndex); if (ch == '{') { braceCount++; } else if (ch == '}') { braceCount--; if (braceCount == 0) { break; } } currentIndex++; } return jsonContent.substring(startIndex + startPattern.length() - 1, currentIndex + 1); } catch (Exception e) { return null; } } /** * 获取路径点的坐标 * * @param pathId 路径点ID * @param pathMapping 路径映射 * @return 坐标数组 [x, y],如果未找到返回null */ public static int[] getCoordinate(String pathId, Map> pathMapping) { Map coordMap = pathMapping.get(pathId); if (coordMap != null && coordMap.containsKey("x") && coordMap.containsKey("y")) { return new int[]{coordMap.get("x"), coordMap.get("y")}; } return null; } /** * 加载实际物理坐标映射 * * @param filePath 文件路径 * @return 实际坐标映射 Map */ public static Map loadRealCoordinateMapping(String filePath) { Map coordinateMapping = new HashMap<>(); ObjectMapper objectMapper = new ObjectMapper(); try { Map topLevelMap = objectMapper.readValue(new File(filePath), Map.class); if (!topLevelMap.containsKey("path_id_to_coordinates")) { System.err.println("未找到path_id_to_coordinates部分"); return coordinateMapping; } Map pathIdCoords = (Map) topLevelMap.get("path_id_to_coordinates"); for (Map.Entry entry : pathIdCoords.entrySet()) { String pathId = entry.getKey(); Object coordsObj = entry.getValue(); if (coordsObj instanceof List) { List coordsList = (List) coordsObj; if (!coordsList.isEmpty()) { Map coordMap = (Map) coordsList.get(0); double x = ((Number) coordMap.get("x")).doubleValue(); double y = ((Number) coordMap.get("y")).doubleValue(); coordinateMapping.put(pathId, new double[]{x, y}); } } } System.out.println("成功加载实际坐标映射,包含 " + coordinateMapping.size() + " 个路径点"); } catch (FileNotFoundException e) { System.err.println("实际坐标文件不存在: " + e.getMessage()); } catch (IOException e) { System.err.println("实际坐标文件读取错误: " + e.getMessage()); } catch (Exception e) { System.err.println("加载实际坐标文件失败: " + e.getMessage()); } return coordinateMapping; } /** * 获取路径点的实际坐标 * * @param pathId 路径点ID * @param realCoordinateMap 实际坐标映射 * @return 坐标数组 [x_mm, y_mm],如果未找到返回null */ public static double[] getRealCoordinate(String pathId, Map realCoordinateMap) { return realCoordinateMap.get(pathId); } /** * 获取工作站信息 * * @param stationId 工作站ID * @param environmentConfig 环境配置 * @return 工作站信息Map */ @SuppressWarnings("unchecked") public static Map getStationInfo(String stationId, Map environmentConfig) { Map> stations = (Map>) environmentConfig.get("stations"); if (stations != null) { return stations.get(stationId); } return null; } /** * 判断位置是否为工作站 * * @param position 位置字符串 * @param environmentConfig 环境配置 * @return 是否为工作站 */ public static boolean isStation(String position, Map environmentConfig) { return getStationInfo(position, environmentConfig) != null; } /** * 计算两点之间的曼哈顿距离 * * @param coord1 坐标1 [x, y] * @param coord2 坐标2 [x, y] * @return 曼哈顿距离 */ public static double calculateManhattanDistance(int[] coord1, int[] coord2) { if (coord1 == null || coord2 == null || coord1.length != 2 || coord2.length != 2) { return Double.MAX_VALUE; } return Math.abs(coord1[0] - coord2[0]) + Math.abs(coord1[1] - coord2[1]); } /** * 计算两点之间的欧几里得距离 * * @param coord1 坐标1 [x, y] * @param coord2 坐标2 [x, y] * @return 欧几里得距离 */ public static double calculateEuclideanDistance(int[] coord1, int[] coord2) { if (coord1 == null || coord2 == null || coord1.length != 2 || coord2.length != 2) { return Double.MAX_VALUE; } int dx = coord1[0] - coord2[0]; int dy = coord1[1] - coord2[1]; return Math.sqrt(dx * dx + dy * dy); } /** * 加载环境路径连通性数据(environment.json中的paths和obstacles) * * @param filePath 环境文件路径 * @return 环境连通性数据 */ public static EnvironmentConnectivity loadEnvironmentConnectivity(String filePath) { EnvironmentConnectivity connectivity = new EnvironmentConnectivity(); ObjectMapper objectMapper = new ObjectMapper(); try { Map topLevelMap = objectMapper.readValue(new File(filePath), Map.class); // 加载可通行路径 if (topLevelMap.containsKey("paths")) { List> pathsList = (List>) topLevelMap.get("paths"); for (Map pathPoint : pathsList) { Integer x = (Integer) pathPoint.get("x"); Integer y = (Integer) pathPoint.get("y"); if (x != null && y != null) { connectivity.addValidPath(x, y); } } } // 加载障碍物 if (topLevelMap.containsKey("obstacles")) { List> obstaclesList = (List>) topLevelMap.get("obstacles"); for (Map obstacle : obstaclesList) { Integer x = (Integer) obstacle.get("x"); Integer y = (Integer) obstacle.get("y"); if (x != null && y != null) { connectivity.addObstacle(x, y); } } } System.out.println("成功加载环境连通性数据:" + connectivity.getValidPathsCount() + " 个可通行点," + connectivity.getObstaclesCount() + " 个障碍物点"); } catch (FileNotFoundException e) { System.err.println("环境文件不存在: " + e.getMessage()); } catch (IOException e) { System.err.println("环境文件读取错误: " + e.getMessage()); } catch (Exception e) { System.err.println("加载环境连通性数据失败: " + e.getMessage()); } return connectivity; } /** * 环境连通性数据类 */ public static class EnvironmentConnectivity { private final Set validPaths = new HashSet<>(); private final Set obstacles = new HashSet<>(); public void addValidPath(int x, int y) { validPaths.add(x + "," + y); } public void addObstacle(int x, int y) { obstacles.add(x + "," + y); } public boolean isValidPath(int x, int y) { return validPaths.contains(x + "," + y); } public boolean isObstacle(int x, int y) { return obstacles.contains(x + "," + y); } public boolean isTraversable(int x, int y) { return isValidPath(x, y) && !isObstacle(x, y); } public int getValidPathsCount() { return validPaths.size(); } public int getObstaclesCount() { return obstacles.size(); } /** * 获取有效的相邻节点 */ public List getValidNeighbors(int x, int y) { List neighbors = new ArrayList<>(); int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 上下左右 for (int[] dir : directions) { int newX = x + dir[0]; int newY = y + dir[1]; if (isTraversable(newX, newY)) { neighbors.add(new int[]{newX, newY}); } } return neighbors; } } }