#
Junjie
3 天以前 dad4b7fd3a7fcaed73d28f0ebd9e90d86ca21225
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -2,7 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.MapNode;
import com.zy.common.model.NavigateNode;
@@ -10,6 +10,7 @@
import com.zy.core.News;
import com.zy.core.enums.MapNodeType;
import com.zy.core.model.PythonSimilarityResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -25,15 +26,16 @@
    @Value("${pythonCalcPath}")
    private String pythonCalcPath;
    @Value("${pythonCalcSimilarity}")
    private String pythonCalcSimilarity;
    @Autowired
    private NavigateMapData navigateMapData;
    public List<NavigateNode> calc(String startPoint, String endPoint, Integer mapType, List<int[]> shuttlePoints, List<int[]> whites) {
        return calcJava(startPoint, endPoint, mapType, shuttlePoints, whites);
    public List<NavigateNode> calc(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites) {
        return calcJava(startPoint, endPoint, mapTypes, shuttlePoints, whites);
    }
    public List<NavigateNode> calcJava(String startPoint, String endPoint, Integer mapType, List<int[]> shuttlePoints, List<int[]> whites) {
    public List<NavigateNode> calcJava(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites) {
        //通过开始编号和结束编号获取对应的xy轴坐标
        int[] startArr = NavigatePositionConvert.positionToXY(startPoint);//开始节点
        int[] endArr = NavigatePositionConvert.positionToXY(endPoint);//结束节点
@@ -46,14 +48,17 @@
        //获取当前节点计算的层高,并赋值到每一个节点中
        int lev = Utils.getLev(startPoint);
        NavigateSolution solution = new NavigateSolution(mapTypes, lev, whiteList, shuttlePoints);
        int[][] map = solution.map;
        //初始化开始节点
        NavigateNode start = new NavigateNode(startArr[0], startArr[1]);
        //开始节点无父节点
        start.setFather(null);
        start.setNodeValue(map[startArr[0]][startArr[1]]);
        NavigateNode end = new NavigateNode(endArr[0], endArr[1]);
        NavigateSolution solution = new NavigateSolution(mapType, lev, whiteList, shuttlePoints);
        end.setNodeValue(map[endArr[0]][endArr[1]]);
        //开始节点,不纳入禁用节点内计算
        NavigateNode res_node = solution.astarSearchJava(start, end);
@@ -103,7 +108,7 @@
        return list;
    }
    public List<NavigateNode> calcPython(String startPoint, String endPoint, Integer mapType, List<int[]> shuttlePoints, List<int[]> whites) {
    public List<NavigateNode> calcPython(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites) {
        //通过开始编号和结束编号获取对应的xy轴坐标
        int[] startArr = NavigatePositionConvert.positionToXY(startPoint);//开始节点
        int[] endArr = NavigatePositionConvert.positionToXY(endPoint);//结束节点
@@ -116,14 +121,17 @@
        //获取当前节点计算的层高,并赋值到每一个节点中
        int lev = Utils.getLev(startPoint);
        NavigateSolution solution = new NavigateSolution(mapTypes, lev, whiteList, shuttlePoints);
        int[][] map = solution.map;
        //初始化开始节点
        NavigateNode start = new NavigateNode(startArr[0], startArr[1]);
        start.setNodeValue(map[startArr[0]][startArr[1]]);
        //开始节点无父节点
        start.setFather(null);
        NavigateNode end = new NavigateNode(endArr[0], endArr[1]);
        NavigateSolution solution = new NavigateSolution(mapType, lev, whiteList, shuttlePoints);
        end.setNodeValue(map[endArr[0]][endArr[1]]);
        //开始节点,不纳入禁用节点内计算
        String pathStr = solution.astarSearchPython(start, end, pythonCalcPath);
@@ -177,6 +185,49 @@
        //更新节点列表
        list.set(0, startNode);
        return list;
    }
    //计算带末端段落路径
    public List<List<NavigateNode>> calcEndPath(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites, int lastPathPart) {
        //计算路径
        List<NavigateNode> navigateNodes = calc(startPoint, endPoint, mapTypes, shuttlePoints, whites);
        if (navigateNodes == null) {
            News.error("{} dash {} can't find navigate path!", startPoint, endPoint);
            return null;
        }
        //获取分段路径
        List<List<NavigateNode>> partList = this.getSectionPath(navigateNodes);
        //根据传入的末端段落路径,找到末端点位
        int partResult = partList.size() - lastPathPart;
        if (partResult == 0) {//路径数量相同无需分割
            return partList;
        } else if (partResult < 0) {
            throw new CoolException("分段路径与末端路径数量计算异常");
        }
        int pathIdx = partResult - 1;
        List<List<NavigateNode>> filterList = new ArrayList<>();
        for (int i = 0; i <= pathIdx; i++) {
            filterList.add(partList.get(i));
        }
        return filterList;
    }
    //计算末端段落地址
    public String calcEndLocation(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites, int lastPathPart) {
        List<List<NavigateNode>> endPath = calcEndPath(startPoint, endPoint, mapTypes, shuttlePoints, whites, lastPathPart);
        if (endPath == null) {
            return null;
        }
        return findTargetLocation(endPath);
    }
    public String findTargetLocation(List<List<NavigateNode>> partList) {
        List<NavigateNode> nodes = partList.get(partList.size() - 1);
        NavigateNode targetNode = nodes.get(0);
        String locNo = NavigatePositionConvert.nodeToLocNo(targetNode);
        return locNo;
    }
    //判断当前节点到下一个节点是否为拐点
@@ -235,11 +286,14 @@
     * 加转弯节点
     * 获取分段路径,每当有一个拐点则进行一次分段,最终返回总分段数据
     */
    public ArrayList<ArrayList<NavigateNode>> getSectionPath(List<NavigateNode> mapList) {
        ArrayList<ArrayList<NavigateNode>> list = new ArrayList<>();
    public List<List<NavigateNode>> getSectionPath(List<NavigateNode> mapList) {
        NavigateNode firstNode = mapList.get(0);
        //获取地图
        List<List<MapNode>> mapNodes = navigateMapData.getJsonData(firstNode.getZ(), NavigationMapType.getMapTypes(NavigationMapType.NONE), null, null);
        ArrayList<NavigateNode> data = new ArrayList<>();
        String direction = mapList.get(0).getDirection();//行走方向
        List<List<NavigateNode>> list = new ArrayList<>();
        List<NavigateNode> data = new ArrayList<>();
        String direction = firstNode.getDirection();//行走方向
        for (NavigateNode navigateNode : mapList) {
            data.add(navigateNode);
@@ -254,35 +308,83 @@
                //直行线路
                navigateNode.setDirection(direction);//设置行走方向
            }
            Integer distance = getXToNextDistance(navigateNode);//获取当前点到下一点的行走距离
            Integer distance = getXToNextDistance(mapNodes, navigateNode);//获取当前点到下一点的行走距离
            navigateNode.setMoveDistance(distance);
        }
        //将最后一段数据添加进入
        list.add(data);
        return list;
        List<List<NavigateNode>> paths = getSectionPathToSplitOverLength(list);
        return paths;
    }
    //分段路径-处理超长直线段路径
    public List<List<NavigateNode>> getSectionPathToSplitOverLength(List<List<NavigateNode>> list) {
        List<List<NavigateNode>> paths = new ArrayList<>();
        int overLength = 9;
        for (List<NavigateNode> nodes : list) {
            if (nodes.size() > overLength) {
                List<NavigateNode> copy = JSON.parseArray(JSON.toJSONString(nodes), NavigateNode.class);
                List<NavigateNode> tmp = new ArrayList<>();
                int tmpCount = 0;
                NavigateNode lastNode = null;
                for (NavigateNode node : copy) {
                    tmp.add(node);
                    tmpCount++;
                    if(tmpCount >= overLength) {
                        if (lastNode == null) {
                            NavigateNode startNode = tmp.get(0);
                            startNode.setLinePartAllowGo(true);//直线段超长部分允许直接行走
                            tmp.set(0, startNode);
                        }
                        NavigateNode targetNode = tmp.get(tmp.size() - 1);
                        targetNode.setLinePartAllowGo(true);//直线段超长部分允许直接行走
                        if (lastNode != null) {
                            tmp.add(0, lastNode);
                        }
                        paths.add(tmp);
                        tmp = new ArrayList<>();
                        tmpCount = 0;
                        lastNode = targetNode;
                    }
                }
                if (tmpCount > 0) {
                    tmp.add(0, lastNode);
                    paths.add(tmp);
                }
            }else {
                paths.add(nodes);
            }
        }
        return paths;
    }
    //获取从x点到下一点的行走距离
    public Integer getXToNextDistance(NavigateNode xNode) {
        NavigateMapData mapData = SpringUtils.getBean(NavigateMapData.class);
        List<List<MapNode>> lists = mapData.getJsonData(xNode.getZ(), NavigationMapType.NONE.id, null, null);
        if (lists != null) {
            MapNode mapNode = lists.get(xNode.getX()).get(xNode.getY());
            if (mapNode != null) {
                switch (xNode.getDirection()) {
                    case "top":
                        return mapNode.getTop();
                    case "bottom":
                        return mapNode.getBottom();
                    case "left":
                        return mapNode.getLeft();
                    case "right":
                        return mapNode.getRight();
                }
            }
    public Integer getXToNextDistance(List<List<MapNode>> mapLists, NavigateNode xNode) {
        if (mapLists == null) {
            return 0;
        }
        if (mapLists.isEmpty()) {
            return 0;
        }
        MapNode mapNode = mapLists.get(xNode.getX()).get(xNode.getY());
        if (mapNode != null) {
            switch (xNode.getDirection()) {
                case "top":
                    return mapNode.getTop();
                case "bottom":
                    return mapNode.getBottom();
                case "left":
                    return mapNode.getLeft();
                case "right":
                    return mapNode.getRight();
            }
        }
        return 0;
    }
@@ -291,9 +393,9 @@
     * 根据原始节点结果,计算总行走距离
     */
    public Integer getOriginPathAllDistance(List<NavigateNode> path) {
        ArrayList<ArrayList<NavigateNode>> sectionPath = getSectionPath(path);
        List<List<NavigateNode>> sectionPath = getSectionPath(path);
        Integer allDistance = 0;
        for (ArrayList<NavigateNode> navigateNodes : sectionPath) {
        for (List<NavigateNode> navigateNodes : sectionPath) {
            Integer distance = getCurrentPathAllDistance(navigateNodes);
            allDistance += distance;
        }
@@ -346,8 +448,7 @@
     * 检测路径是否可用(可走)
     */
    public boolean checkPathIsAvailable(List<NavigateNode> path, Integer shuttleNo, Integer lev) {
        NavigateSolution solution = new NavigateSolution(NavigationMapType.DFX.id, lev, null, Utils.getShuttlePoints(shuttleNo, lev));//获取无白名单地图(该地图包含小车坐标)
        int[][] map = solution.map;
        int[][] map = navigateMapData.getDataFromRedis(lev, NavigationMapType.getDfxWithDevice(), null, Utils.getShuttlePoints(shuttleNo, lev));
        for (NavigateNode node : path) {
            int value = map[node.getX()][node.getY()];
            if (value != MapNodeType.NORMAL_PATH.id && value != MapNodeType.MAIN_PATH.id && value != MapNodeType.CHARGE.id && value != MapNodeType.CONVEYOR_CAR_GO.id) {//母轨道3、子轨道0、充电桩5、小车可走输送站
@@ -419,6 +520,17 @@
        return 0D;
    }
    //检测库位路径是否可用(用于库位是否可移动检测)
    public boolean checkLocPathIsAvailable(String startLocNo, String endLocNo) {
        List<int[]> shuttlePoints = Utils.getShuttlePoints(0, Utils.getLev(startLocNo));
        //计算库位到提升机库位,路径是否可用
        List<NavigateNode> nodeList = this.calc(startLocNo, endLocNo, NavigationMapType.getMapTypes(NavigationMapType.DFX), shuttlePoints, null);
        if (nodeList == null) {
            return false;
        }
        return true;
    }
    public static void main(String[] args) {
//        //计算路径
//        List<NavigateNode> calc = calc("1000901", "1800201", NavigationMapType.NONE.id, null);