package com.zy.acs.fake.service; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.common.constant.RedisConstant; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.fake.domain.DynamicNode; import com.zy.acs.fake.entity.Code; import com.zy.acs.fake.enums.CodeNodeType; import com.zy.acs.fake.enums.DynamicNodeType; import com.zy.acs.fake.enums.MapNodeType; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.exception.CoolException; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** * Created by vincent on 6/6/2024 */ @Slf4j public class MapDataDispatcher { public static final Integer MAP_DEFAULT_LEV = 1; private final RedisSupport redis = RedisSupport.defaultRedisSupport; public static final Boolean CACHE_CODE_MATRIX = Boolean.FALSE; private String[][] codeMatrix; private final CodeService codeService; private final RouteService routeService; public MapDataDispatcher(CodeService codeService, RouteService routeService) { this.codeService = codeService; this.routeService = routeService; } public DynamicNode[][] getDynamicMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); DynamicNode[][] dynamicMatrix; String dynamicMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_DYNAMIC_FLAG, String.valueOf(lev)); if (Cools.isEmpty(dynamicMatrixStr)) { throw new CoolException("the floor " + lev + " cannot found dynamic matrix !!!"); } else { dynamicMatrix = JSON.parseObject(dynamicMatrixStr, DynamicNode[][].class); } if (null == dynamicMatrix) { throw new CoolException("the floor " + lev + " cannot found dynamic matrix !!!"); } return dynamicMatrix; } public void setDynamicMatrix(Integer lev, DynamicNode[][] dynamicMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_DYNAMIC_FLAG, String.valueOf(lev), JSON.toJSONString(dynamicMatrix)); } public String[][] getCodeMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix; if (!CACHE_CODE_MATRIX) { if (null == this.codeMatrix) { codeMatrix = this.initCodeMatrix(lev); setCodeMatrix(lev, codeMatrix); } else { codeMatrix = this.codeMatrix; } } else { String codeMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_CODE_FLAG, String.valueOf(lev)); if (Cools.isEmpty(codeMatrixStr)) { codeMatrix = this.initCodeMatrix(lev); setCodeMatrix(lev, codeMatrix); } else { codeMatrix = JSON.parseObject(codeMatrixStr, String[][].class); } } if (null == codeMatrix) { throw new CoolException("the floor " + lev + " cannot found code matrix !!!"); } return codeMatrix; } public void setCodeMatrix(Integer lev, String[][] codeMatrix) { if (!CACHE_CODE_MATRIX) { this.codeMatrix = codeMatrix; } else { redis.setValue(RedisConstant.AGV_MAP_ASTAR_CODE_FLAG, String.valueOf(lev), JSON.toJSONString(codeMatrix)); } } public synchronized String[][] initCodeMatrix(Integer lev) { log.info("【ASTAR】正在计算矩阵数据......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); List codeList = codeService.list(new LambdaQueryWrapper() .eq(Code::getStatus, 1) .orderByAsc(Code::getY) .orderByAsc(Code::getX) ); // int xCount = codeService.selectDistinctCountFromX(); // int yCount = codeService.selectDistinctCountFromY(); // // [][] 第一个是排的数量 第二个是列的数量 // String[][] codeMatrix = new String[yCount][xCount]; List xIdxList = new ArrayList<>(); List yIdxList = new ArrayList<>(); for (Code code : codeList) { Double x = code.getX(); Double y = code.getY(); if (null == x || null == y) { continue; } if (!xIdxList.contains(x)) { xIdxList.add(x); } if (!yIdxList.contains(y)) { yIdxList.add(y); } } xIdxList.sort((o1, o2) -> (int) ((o1 * 100) - (o2 * 100))); yIdxList.sort((o1, o2) -> (int) ((o1 * 100) - (o2 * 100))); // [][] 第一个是排的数量 第二个是列的数量 String[][] codeMatrix = new String[yIdxList.size()][xIdxList.size()]; int idxX = -1; int idxY = -1; double lastX = -1; double lastY = -1; for (Code code : codeList) { Double x = code.getX(); Double y = code.getY(); // if (y != lastY) { // idxY ++; // idxX = 0; // lastY = y; // lastX = x; // } // if (x != lastX) { // idxX++; // lastX = x; // } // codeMatrix[idxY][idxX] = code.getData(); codeMatrix[yIdxList.indexOf(y)][xIdxList.indexOf(x)] = code.getData(); } for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { if (codeMatrix[i][j] == null) { codeMatrix[i][j] = CodeNodeType.NONE.val; } } } printMatrix(codeMatrix); return codeMatrix; } public int[] getCodeMatrixIdx(Integer lev, String codeData) { if (Cools.isEmpty(codeData)) { return null; } lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = this.getCodeMatrix(lev); for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { if (codeMatrix[i][j].equals(codeData)) { return new int[]{i, j}; } } } return null; } public void modifyDynamicMatrix(Integer lev, List codeList, String vehicle) { this.modifyDynamicMatrix(lev, codeList, vehicle, false); } public synchronized void modifyDynamicMatrix(Integer lev, List codeList, String vehicle, boolean reset) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); DynamicNode[][] dynamicMatrix = getDynamicMatrix(lev); if (!reset) { if (Cools.isEmpty(codeList, vehicle)) { return; } int serial = 1; for (String code : codeList) { int[] node = getCodeMatrixIdx(lev, code); dynamicMatrix[node[0]][node[1]] = new DynamicNode(vehicle, serial); serial++; } } else { if (Cools.isEmpty(vehicle)) { return; } for (int i = 0; i < dynamicMatrix.length; i++) { for (int j = 0; j < dynamicMatrix[i].length; j++) { DynamicNode dynamicNode = dynamicMatrix[i][j]; if (vehicle.equals(dynamicNode.getVehicle())) { dynamicMatrix[i][j] = new DynamicNode(DynamicNodeType.ACCESS.val); } } } } setDynamicMatrix(lev, dynamicMatrix); } public void clearDynamicMatrixByCodeList(Integer lev, List codeList) { this.modifyDynamicMatrix(lev, codeList, DynamicNodeType.ACCESS.val); } public int[][] filterMapData(int[][] mapMatrix, Integer lev, List lockNodes) { String[][] codeMatrix = getCodeMatrix(lev); for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { String code = codeMatrix[i][j]; if (lockNodes.contains(code)) { mapMatrix[i][j] = MapNodeType.LOCKED.val; } } } return mapMatrix; } public void printMatrix(T[][] matrix) { for (T[] list : matrix) { for (T t : list) { System.out.format("%10s", t); } System.out.println(); } } public void printMatrix(int[][] matrix) { for (int[] list : matrix) { for (int t : list) { System.out.format("%10s", t); } System.out.println(); } } }