| | |
| | | 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.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*算法地图获取类 |
| | |
| | | |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private DictService dictService; |
| | | |
| | | private Integer lev;//地图楼层 |
| | | |
| | |
| | | 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")); |
| | | 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(-1); |
| | | 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(-1); |
| | | 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) { |
| | | RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); |
| | |
| | | //过滤数据 |
| | | //获取当前楼层库位数据 |
| | | List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getLev, lev)); |
| | | .eq(Loc::getLev, lev) |
| | | .orderByAsc(Loc::getRow, Loc::getBay)); |
| | | for (Loc loc : locs) { |
| | | Integer row = loc.getRow(); |
| | | Integer bay = loc.getBay(); |
| | |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.setLev(nodes.get(0).getZ()); |
| | | List<List<MapNode>> realMap = this.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; |
| | | } |
| | | |
| | | } |