#
Junjie
8 天以前 2df6d2c5d13a2a7909e802c5f190afeeba70f111
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.zy.asrs.wcs.core.utils;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zy.asrs.wcs.core.domain.dto.RedisMapDto;
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.rcs.constant.DeviceRedisConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
@Component
public class NavigateMapUtils {
 
    @Autowired
    private NavigateMapData navigateMapData;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ObjectMapper objectMapper;
 
    /**
     * 写入路径节点数据到redis地图中
     * lock为true 禁用库位,lock为false恢复库位
     */
    public synchronized boolean writeNavigateNodeToRedisMap(Integer lev, Integer shuttleNo, List<NavigateNode> nodes, boolean lock) {
        try {
            if (nodes.isEmpty()) {
                return true;
            }
 
            navigateMapData.setLev(lev);
            Object o = redisUtil.get(DeviceRedisConstant.MAP + lev);
            if (o == null) {
                return false;
            }
 
            //获取小车节点
            List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, lev);
 
            RedisMapDto redisMap = JSON.parseObject(o.toString(), RedisMapDto.class);
            ArrayList arrayList = JSON.parseObject(redisMap.getData(), ArrayList.class);
            //带小车地图
            List<List<MapNode>> listsHasShuttle = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, shuttlePoints);//获取带小车地图数据
            List<List<MapNode>> lists = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//获取全部地图数据
 
            //检测节点是否为当前设备
            for (NavigateNode node : nodes) {
                List<MapNode> listX = listsHasShuttle.get(node.getX());
                MapNode mapNode = listX.get(node.getY());
                if (mapNode.getLockDeviceNo() == null) {
                    continue;
                }
 
                if (!mapNode.getLockDeviceNo().equals(shuttleNo)) {
                    return false;//路径所属权不是当前设备
                }
            }
 
            //检测路径是否被锁定
            if (lock) {
                for (NavigateNode node : nodes) {
                    List<MapNode> listX = listsHasShuttle.get(node.getX());
                    MapNode mapNode = listX.get(node.getY());
                    if (mapNode.getValue().equals(MapNodeType.LOCK.id)) {
                        return false;//路径被锁定过,禁止再次锁定
                    }
                    if (mapNode.getValue().equals(MapNodeType.CAR.id)) {
                        return false;//路径存在小车,禁止锁定
                    }
                }
            }
 
            //尝试锁定/解锁路径
            navigateMapData.setLev(nodes.get(0).getZ());
            List<List<MapNode>> realMap = navigateMapData.getJsonDataFromDict(-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(MapNodeType.LOCK.id);//禁用库位
                    mapNode.setLockDeviceNo(shuttleNo);
                } else {
                    //获取原始节点数据
                    List<MapNode> rows = realMap.get(node.getX());
                    MapNode col = rows.get(node.getY());
                    mapNode.setValue(col.getValue());//恢复库位
                    mapNode.setLockDeviceNo(null);
                }
 
                listX.set(node.getY(), mapNode);
                lists.set(node.getX(), listX);
            }
            redisMap.setData(JSON.toJSONString(lists));
            redisMap.setUpdateTime(new Date());
            //将数据库地图数据存入redis
            redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(redisMap, SerializerFeature.DisableCircularReferenceDetect));
 
            //保存路径锁节点
            saveLockPath(lev, nodes, lock);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
 
    //保存路径锁节点
    public void saveLockPath(Integer lev, List<NavigateNode> nodes, boolean lock) {
        Object o = redisUtil.get(DeviceRedisConstant.LOCK_PATH + lev);
        List<NavigateNode> navigateNodes = new ArrayList<>();
        if (o != null) {
            try {
                navigateNodes = objectMapper.readValue(o.toString(), new TypeReference<List<NavigateNode>>() {});
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
 
        String nodeStr = null;
        if (lock) {
            navigateNodes.addAll(nodes);
            try {
                nodeStr = objectMapper.writeValueAsString(navigateNodes);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            redisUtil.set(DeviceRedisConstant.LOCK_PATH + lev, nodeStr);
        }else {
            List<NavigateNode> tmp = new ArrayList<>();
            for (NavigateNode navigateNode : navigateNodes) {
                boolean flag = true;
                for (NavigateNode node : nodes) {
                    if (navigateNode.getX() == node.getX()
                            && navigateNode.getY() == node.getY()
                            && navigateNode.getZ() == node.getZ()) {
                        flag = false;
                        break;
                    }
                }
 
                if (flag) {
                    tmp.add(navigateNode);
                }
            }
 
            try {
                nodeStr = objectMapper.writeValueAsString(tmp);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            redisUtil.set(DeviceRedisConstant.LOCK_PATH + lev, nodeStr);
        }
    }
 
    //获取路径锁节点
    public List<NavigateNode> getLockPath(Integer lev) {
        Object obj = redisUtil.get(DeviceRedisConstant.LOCK_PATH + lev);
        List<NavigateNode> navigateNodes = new ArrayList<>();
        if (obj != null) {
            try {
                navigateNodes = objectMapper.readValue(obj.toString(), new TypeReference<List<NavigateNode>>() {});
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return navigateNodes;
    }
 
}