package com.zy.acs.manager.core.service; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.framework.common.Cools; import com.zy.acs.manager.common.domain.AreaShapeDto; import com.zy.acs.manager.common.domain.MapPointDto; import com.zy.acs.manager.core.service.astart.CodeNodeType; import com.zy.acs.manager.core.service.astart.MapDataDispatcher; import com.zy.acs.manager.manager.entity.Area; import com.zy.acs.manager.manager.enums.StatusType; import com.zy.acs.manager.manager.service.AreaAgvService; import com.zy.acs.manager.manager.service.AreaService; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Service public class AreaGovernService { // public static final Map> CODE_AGV = new ConcurrentHashMap<>(); public static final Map> AREA_CODE = new ConcurrentHashMap<>(); private final RedisSupport redis = RedisSupport.defaultRedisSupport; @Autowired private AreaService areaService; @Autowired private MapDataDispatcher mapDataDispatcher; @Autowired private AreaAgvService areaAgvService; // launcher ------------------------------------------------------- // @EventListener(ApplicationReadyEvent.class) @PostConstruct public void init() { List areaList = areaService.list(new LambdaQueryWrapper().eq(Area::getStatus, StatusType.ENABLE.val)); if (Cools.isEmpty(areaList)) { return; } List areaNodeList = new ArrayList<>(); for (Area area : areaList) { AreaShapeDto shapeDto = JSON.parseObject(area.getShapeData(), AreaShapeDto.class); MapPointDto start = shapeDto.getStart(); MapPointDto end = shapeDto.getEnd(); double minX = Math.min(start.getX(), end.getX()); double maxX = Math.max(start.getX(), end.getX()); double minY = Math.min(start.getY(), end.getY()); double maxY = Math.max(start.getY(), end.getY()); areaNodeList.add(new AreaNode(area.getId(), minX, maxX, minY, maxY)); } String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(MapDataDispatcher.MAP_DEFAULT_LEV); Double[][][] cdaMatrix = mapDataDispatcher.getCdaMatrix(MapDataDispatcher.MAP_DEFAULT_LEV); int rows = cdaMatrix.length; int cols = cdaMatrix[0].length; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { String code = codeMatrix[i][j]; if (CodeNodeType.NONE.val.equals(code)) { continue; } Double x = cdaMatrix[i][j][0]; Double y = cdaMatrix[i][j][1]; if (x == null || y == null) { continue; } for (AreaNode areaNode : areaNodeList) { if (this.inRect(x, y, areaNode.minX, areaNode.maxX, areaNode.minY, areaNode.maxY)) { List codeList = AREA_CODE.computeIfAbsent(areaNode.getId(), k -> new ArrayList<>()); codeList.add(code); } } } } // for (Map.Entry> entry : AREA_CODE.entrySet()) { // Long areaId = entry.getKey(); // List codeList = entry.getValue(); // // for (String code : codeList) { // Set agvList = CODE_AGV.computeIfAbsent(code, k -> new HashSet<>()); // // todo AreaAGV( man_area_agv ) // // // } // } // for (Area area : areaList) { // AreaShapeDto shapeDto = JSON.parseObject(area.getShapeData(), AreaShapeDto.class); // MapPointDto start = shapeDto.getStart(); // MapPointDto end = shapeDto.getEnd(); // // List codeList = this.findCodesInArea(start, end); // log.info("codeList: {}", JSON.toJSONString(codeList)); // // String redisKey = area.getName() + (area.getZoneId() != null ? "_" + area.getZoneId() : ""); // String areaDataStr = redis.getValue(RedisConstant.MAP_AREA_DATA_FLAG, redisKey); // // } } // checkout list of area by code data public List queryAreas(String code) { List areaIds = new ArrayList<>(); for (Map.Entry> entry : AREA_CODE.entrySet()) { List codeList = entry.getValue(); if (!Cools.isEmpty(codeList) && codeList.contains(code)) { areaIds.add(entry.getKey()); } } return areaIds; } // checkout list of code by code data public List queryCodesByOneCode(String code) { Set codeSet = new HashSet<>(); for (Map.Entry> entry : AREA_CODE.entrySet()) { List codeList = entry.getValue(); if (!Cools.isEmpty(codeList) && codeList.contains(code)) { codeSet.addAll(codeList); } } return new ArrayList<>(codeSet); } // checkout list of code by area ids public List queryCodes(List areaIds) { if (Cools.isEmpty(areaIds)) { return Collections.emptyList(); } Set codeList = new HashSet<>(); for (Long areaId : areaIds) { List strings = AREA_CODE.get(areaId); codeList.addAll(strings); } return new ArrayList<>(codeList); } // reset and set new area public List reSet(Area area) { AreaShapeDto shapeDto = JSON.parseObject(area.getShapeData(), AreaShapeDto.class); MapPointDto start = shapeDto.getStart(); MapPointDto end = shapeDto.getEnd(); List codeList = this.findCodesInArea(start, end); AREA_CODE.remove(area.getId()); AREA_CODE.put(area.getId(), codeList); return codeList; } // reset and set new area public Boolean removeArea(Long areaId) { if (null == areaId) { return false; } List codeList = AREA_CODE.get(areaId); if (!Cools.isEmpty(codeList)) { AREA_CODE.get(areaId).clear(); AREA_CODE.remove(areaId); } return Boolean.TRUE; } public List findCodesInArea(MapPointDto start, MapPointDto end) { double minX = Math.min(start.getX(), end.getX()); double maxX = Math.max(start.getX(), end.getX()); double minY = Math.min(start.getY(), end.getY()); double maxY = Math.max(start.getY(), end.getY()); List codeList = new ArrayList<>(); String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(MapDataDispatcher.MAP_DEFAULT_LEV); Double[][][] cdaMatrix = mapDataDispatcher.getCdaMatrix(MapDataDispatcher.MAP_DEFAULT_LEV); int rows = cdaMatrix.length; int cols = cdaMatrix[0].length; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { Double x = cdaMatrix[i][j][0]; Double y = cdaMatrix[i][j][1]; if (x == null || y == null) { continue; } if (this.inRect(x, y, minX, maxX, minY, maxY)) { String code = codeMatrix[i][j]; if (!CodeNodeType.NONE.val.equals(code)) { codeList.add(code); } } } } return codeList; } private boolean inRect(double x, double y, double minX, double maxX, double minY, double maxY) { return x >= minX && x <= maxX && y >= minY && y <= maxY; } @Data public static class AreaNode { public Long id; public double minX; public double maxX; public double minY; public double maxY; public AreaNode(Long id, double minX, double maxX, double minY, double maxY) { this.id = id; this.minX = minX; this.maxX = maxX; this.minY = minY; this.maxY = maxY; } } }