#
Junjie
2024-10-16 f0b0f5d954d54840d62135a4a88db94797898967
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java
@@ -1,27 +1,36 @@
package com.zy.asrs.wcs.core.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.common.wms.entity.BasMap;
import com.zy.asrs.common.wms.entity.LocMast;
import com.zy.asrs.common.wms.service.LocMastService;
import com.zy.asrs.framework.common.SpringUtils;
import com.zy.asrs.wcs.core.domain.dto.RedisMapDto;
import com.zy.asrs.wcs.core.entity.Loc;
import com.zy.asrs.wcs.core.model.MapNode;
import com.zy.asrs.wcs.core.model.NavigateNode;
import com.zy.asrs.wcs.core.model.enums.MapNodeType;
import com.zy.asrs.wcs.core.model.enums.NavigationMapType;
import com.zy.asrs.wcs.core.service.LocService;
import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
import com.zy.asrs.wcs.system.entity.Dict;
import com.zy.asrs.wcs.system.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * A*算法地图获取类
 */
@Component
public class NavigateMapData {
    @Autowired
    private LocService locService;
    @Autowired
    private DictService dictService;
    private Integer lev;//地图楼层
@@ -38,49 +47,7 @@
    }
    public int[][] getData() {
        return getData(NavigationMapType.NONE.id, null, null);//默认读取无过滤的全部地图数据
    }
    public int[][] getData(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) {
        try {
            String mapFilename = "map_" + lev + ".json";
            String fileName = this.getClass().getClassLoader().getResource(mapFilename).getPath();//获取文件路径
            File file = new File(fileName);
            StringBuffer stringBuffer = new StringBuffer();
            if (file.isFile() && file.exists()) {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "GBK");
                BufferedReader br = new BufferedReader(isr);
                String lineTxt = null;
                while ((lineTxt = br.readLine()) != null) {
                    stringBuffer.append(lineTxt);
                }
                br.close();
                //解析json地图数据
                ArrayList arrayList = JSON.parseObject(stringBuffer.toString(), ArrayList.class);
                List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据
                int[][] map = new int[lists.size()][];
                int j = 0;
                for (List<MapNode> list : lists) {
                    int[] tmp = new int[list.size()];
                    int i = 0;
                    for (MapNode mapNode : list) {
                        //将数据添加进二维数组
                        tmp[i++] = mapNode.getValue();
                    }
                    //数据添加进一维数组
                    map[j++] = tmp;
                }
                return map;
            } else {
                System.out.println("文件不存在!");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return null;
        return getDataFromRedis(NavigationMapType.NONE.id, null, null);//默认读取无过滤的全部地图数据
    }
    /**
@@ -119,35 +86,177 @@
        return map;
    }
    //获取JSON格式数据-原始地图
    public List<List<MapNode>> getJsonDataFromDict(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) {
        List<List<MapNode>> arrayList = getMapFromDict(lev);
        return arrayList;
    }
    //从数据字典中解析指定楼层地图数据
    public List<List<MapNode>> getMapFromDict(Integer currentLev) {
        List<Dict> dicts = dictService.list(new LambdaQueryWrapper<Dict>()
                .like(Dict::getFlag, "map-" + currentLev)
                .eq(Dict::getStatus, 1));
        TreeMap<Integer, ArrayList<ArrayList<MapNode>>> levData = new TreeMap<>();
        for (Dict dict : dicts) {
            String[] split = dict.getFlag().split("-");
            int lev = Integer.parseInt(split[1]);
            TreeMap<Integer, List<JSONObject>> rows = new TreeMap<>();
            //排序Row
            JSONArray value = JSON.parseArray(dict.getValue());
            for (Object o : value) {
                JSONObject item = JSON.parseObject(o.toString());
                if (item.getString("type").equals("SHELF")) {
                    JSONObject property = JSON.parseObject(item.getString("property"));
                    Integer row1 = property.getInteger("row");
                    ArrayList<JSONObject> bays = new ArrayList<>();
                    if (rows.containsKey(row1)) {
                        bays.addAll(rows.get(row1));
                    }
                    bays.add(property);
                    rows.put(row1, bays);
                }
            }
            ArrayList<ArrayList<MapNode>> list = new ArrayList<>();
            //排序Bay
            for (Map.Entry<Integer, List<JSONObject>> entry : rows.entrySet()) {
                ArrayList<MapNode> nodes = new ArrayList<>();
                for (JSONObject object : entry.getValue()) {
                    MapNode mapNode = new MapNode();
                    mapNode.setValue(object.getInteger("shelfType"));
                    mapNode.setTop(object.getInteger("top"));
                    mapNode.setBottom(object.getInteger("bottom"));
                    mapNode.setLeft(object.getInteger("left"));
                    mapNode.setRight(object.getInteger("right"));
                    mapNode.setRow(object.getInteger("row"));
                    mapNode.setBay(object.getInteger("bay"));
                    mapNode.setNo(object.getString("row") + "-" + object.getString("bay"));
                    mapNode.setXBase(object.getInteger("refx"));
                    mapNode.setYBase(object.getInteger("refy"));
                    if(mapNode.getValue() == MapNodeType.CONVEYOR.id) {
                        //输送线,判断小车是否可走
                        if (object.containsKey("conveyorHasGo")) {
                            if(object.getBoolean("conveyorHasGo")) {
                                //小车可走
                                mapNode.setValue(MapNodeType.CONVEYOR_CAR_GO.id);
                            }
                        }
                    }
                    nodes.add(mapNode);
                }
                Collections.sort(nodes, new Comparator<MapNode>() {
                    @Override
                    public int compare(MapNode o1, MapNode o2) {
                        return Integer.compare(o1.getBay(), o2.getBay());
                    }
                });
                ArrayList<MapNode> sortNodes = new ArrayList<>();
                int defaultBay = 1;//默认从1列开始
                for (MapNode node : nodes) {
                    if (node.getBay() == defaultBay) {
                        defaultBay++;
                        sortNodes.add(node);
                        continue;
                    }
                    //存在空缺节点,自动补足
                    for (int i = defaultBay; i < node.getBay(); i++) {
                        MapNode mapNode = new MapNode();
                        mapNode.setValue(MapNodeType.DISABLE.id);
                        mapNode.setTop(1000);
                        mapNode.setBottom(1000);
                        mapNode.setLeft(1000);
                        mapNode.setRight(1000);
                        mapNode.setRow(node.getRow());
                        mapNode.setBay(i);
                        mapNode.setNo(node.getRow() + "-" + i);
                        mapNode.setXBase(0);
                        mapNode.setYBase(0);
                        sortNodes.add(mapNode);
                    }
                    defaultBay = node.getBay() + 1;
                    sortNodes.add(node);
                }
                list.add(sortNodes);
            }
            levData.put(lev, list);
        }
        for (Map.Entry<Integer, ArrayList<ArrayList<MapNode>>> entry : levData.entrySet()) {
            ArrayList<ArrayList<MapNode>> lists = entry.getValue();//获取地图
            MapNode mapNode = new MapNode();
            mapNode.setValue(MapNodeType.DISABLE.id);
            mapNode.setTop(1000);
            mapNode.setBottom(1000);
            mapNode.setLeft(1000);
            mapNode.setRight(1000);
            mapNode.setRow(0);
            mapNode.setBay(0);
            mapNode.setNo("0-0");
            mapNode.setXBase(0);
            mapNode.setYBase(0);
            //获取最长row
            int row = 0;
            //给每个row首尾增加-1节点
            for (ArrayList<MapNode> list : lists) {
                if (list.size() > row) {
                    row = list.size();
                }
                list.add(0, mapNode.clone());
                list.add(mapNode.clone());
            }
            ArrayList<MapNode> headNodes = new ArrayList<>();
            ArrayList<MapNode> footerNodes = new ArrayList<>();
            for (int i = 0; i < row+2; i++) {
                headNodes.add(mapNode.clone());
                footerNodes.add(mapNode.clone());
            }
            lists.add(0, headNodes);
            lists.add(footerNodes);
            Integer lev = entry.getKey();
            Date now = new Date();
            RedisMapDto map = new RedisMapDto();
            map.setData(JSON.toJSONString(lists));
            map.setCreateTime(now);
            map.setUpdateTime(now);
            map.setLev(lev);
            List<List<MapNode>> mapNodeList = new ArrayList<>();
            mapNodeList.addAll(lists);
            return mapNodeList;
        }
        return null;
    }
    //获取JSON格式数据
    public List<List<MapNode>> getJsonData(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) {
        try {
            String mapFilename = "map_" + lev + ".json";
            String fileName = this.getClass().getClassLoader().getResource(mapFilename).getPath();//获取文件路径
            File file = new File(fileName);
            StringBuffer stringBuffer = new StringBuffer();
            if (file.isFile() && file.exists()) {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "GBK");
                BufferedReader br = new BufferedReader(isr);
                String lineTxt = null;
                while ((lineTxt = br.readLine()) != null) {
                    stringBuffer.append(lineTxt);
                }
                br.close();
                //解析json地图数据
                ArrayList arrayList = JSON.parseObject(stringBuffer.toString(), ArrayList.class);
                List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据
                return lists;
            } else {
                System.out.println("文件不存在!");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
        Object o = redisUtil.get(DeviceRedisConstant.MAP + lev);
        if (o == null) {
            return null;
        }
        return null;
        BasMap basMap = JSON.parseObject(o.toString(), BasMap.class);
        ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class);
        List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据
        return lists;
    }
    /**
@@ -172,13 +281,14 @@
        }
        //过滤数据
        LocMastService locMastService = SpringUtils.getBean(LocMastService.class);
        //获取当前楼层库位数据
        List<LocMast> locMasts = locMastService.list(new LambdaQueryWrapper<LocMast>()
                .eq(LocMast::getLev1, lev));
        for (LocMast locMast : locMasts) {
            Integer row = locMast.getRow1();
            Integer bay = locMast.getBay1();
        List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>()
                .eq(Loc::getLev, lev)
                .eq(Loc::getStatus, 1)
                .orderByAsc(Loc::getRow, Loc::getBay));
        for (Loc loc : locs) {
            Integer row = loc.getRow();
            Integer bay = loc.getBay();
            boolean whiteFlag = false;//默认不存在白名单
            if (whitePoints != null) {
@@ -203,18 +313,16 @@
            } else if (mapType == NavigationMapType.DFX.id) {
                //车辆有货
                //读取对应库位数据,将DFX库位状态的节点置为-1(障碍物)
                if (locMast.getLocSts().equals("F")
                        || locMast.getLocSts().equals("D")
                        || locMast.getLocSts().equals("X")
                        || locMast.getLocSts().equals("R")
                        || locMast.getLocSts().equals("P")
                if (loc.getLocStsFlag().equals("F")
                        || loc.getLocStsFlag().equals("D")
                        || loc.getLocStsFlag().equals("X")
                ) {
                    mapNode.setValue(-1);//禁用节点
                    mapNode.setValue(MapNodeType.DISABLE.id);//禁用节点
                }
            } else if (mapType == NavigationMapType.NORMAL.id) {
                //过滤库位状态X
                if (locMast.getLocSts().equals("X")) {
                    mapNode.setValue(-1);//禁用节点
                if (loc.getLocStsFlag().equals("X")) {
                    mapNode.setValue(MapNodeType.DISABLE.id);//禁用节点
                }
            }
@@ -230,7 +338,7 @@
                int y = points[1];
                List<MapNode> list = lists.get(x);
                MapNode mapNode = list.get(y);
                mapNode.setValue(66);//设置为车辆代码66
                mapNode.setValue(MapNodeType.CAR.id);//设置为车辆代码66
                //更新list
                list.set(y, mapNode);
                lists.set(x, list);
@@ -238,61 +346,6 @@
        }
        return lists;
    }
    /**
     * 锁/解锁 路径节点
     * 写入路径节点数据到redis地图中
     * lock为true 禁用库位,lock为false恢复库位
     */
    public synchronized boolean writeNavigateNodeToRedisMap(List<NavigateNode> nodes, boolean lock) {
        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
        Object o = redisUtil.get("realtimeBasMap_" + lev);
        if (o == null) {
            return false;
        }
        BasMap basMap = JSON.parseObject(o.toString(), BasMap.class);
        ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class);
        List<List<MapNode>> lists = filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//获取全部地图数据
        // 防止重复锁路径
        if (lock) {
            for (NavigateNode node : nodes) {
                List<MapNode> listX = lists.get(node.getX());
                MapNode mapNode = listX.get(node.getY());
                if (mapNode.getValue() == -999) {
                    return false;
                }
            }
        }
        NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ());
        List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库)
        for (NavigateNode node : nodes) {
            if (node.getZ() != lev) {
                continue;
            }
            List<MapNode> listX = lists.get(node.getX());
            MapNode mapNode = listX.get(node.getY());
            if (lock) {
                mapNode.setValue(-999);//禁用库位
            }else {
                //获取原始节点数据
                List<MapNode> rows = realMap.get(node.getX());
                MapNode col = rows.get(node.getY());
                mapNode.setValue(col.getValue());//恢复库位
            }
            listX.set(node.getY(), mapNode);
            lists.set(node.getX(), listX);
        }
        basMap.setData(JSON.toJSONString(lists));
        basMap.setUpdateTime(new Date());
        //将数据库地图数据存入redis
        redisUtil.set("realtimeBasMap_" + lev, JSON.toJSONString(basMap));
        return true;
    }
}