atriusmaps-node-sdk 3.3.898 → 3.3.900
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/nodesdk/nodeEntry.js +36 -58
- package/dist/cjs/package.json.js +8 -4
- package/dist/cjs/plugins/clientAPI/src/clientAPI.js +8 -6
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +50 -142
- package/dist/cjs/plugins/dynamicPois/src/processors.js +31 -53
- package/dist/cjs/plugins/flightStatus/src/flightDetailsMapper.js +47 -116
- package/dist/cjs/plugins/flightStatus/src/flightStatus.js +48 -82
- package/dist/cjs/plugins/flightStatus/src/utils.js +4 -14
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +77 -154
- package/dist/cjs/plugins/sdkServer/src/prepareSDKConfig.js +45 -76
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +70 -79
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +97 -147
- package/dist/cjs/plugins/searchService/src/flexsearchExports/lang.js +16 -190
- package/dist/cjs/plugins/searchService/src/flexsearchExports/simple.js +28 -35
- package/dist/cjs/plugins/searchService/src/poiSearch.js +10 -21
- package/dist/cjs/plugins/searchService/src/searchService.js +45 -147
- package/dist/cjs/plugins/searchService/src/searchTypeahead.js +17 -28
- package/dist/cjs/plugins/searchService/src/utils.js +9 -13
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +148 -304
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +47 -126
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +6 -73
- package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +7 -27
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +78 -259
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +26 -57
- package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +25 -25
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +50 -133
- package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +29 -29
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +53 -145
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +105 -349
- package/dist/cjs/src/app.js +53 -91
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +34 -43
- package/dist/cjs/src/configs/postproc-stateTracking.js +1 -19
- package/dist/cjs/src/controller.js +4 -26
- package/dist/cjs/src/debugTools.js +55 -94
- package/dist/cjs/src/env.js +8 -19
- package/dist/cjs/src/extModules/bustle.js +15 -71
- package/dist/cjs/src/extModules/flexapi/src/help.js +7 -22
- package/dist/cjs/src/extModules/flexapi/src/index.js +15 -29
- package/dist/cjs/src/extModules/flexapi/src/validate.js +45 -93
- package/dist/cjs/src/extModules/geohasher.js +13 -31
- package/dist/cjs/src/extModules/log.js +18 -29
- package/dist/cjs/src/historyManager.js +4 -6
- package/dist/cjs/src/utils/bounds.js +2 -4
- package/dist/cjs/src/utils/buildStructureLookup.js +7 -7
- package/dist/cjs/src/utils/configUtils.js +7 -43
- package/dist/cjs/src/utils/date.js +5 -17
- package/dist/cjs/src/utils/distance.js +2 -2
- package/dist/cjs/src/utils/dom.js +9 -24
- package/dist/cjs/src/utils/funcs.js +15 -30
- package/dist/cjs/src/utils/geodesy.js +24 -39
- package/dist/cjs/src/utils/geom.js +32 -148
- package/dist/cjs/src/utils/i18n.js +39 -70
- package/dist/cjs/src/utils/isInitialState.js +7 -13
- package/dist/cjs/src/utils/location.js +10 -29
- package/dist/cjs/src/utils/observable.js +4 -29
- package/dist/cjs/src/utils/rand.js +9 -80
- package/dist/cjs/utils/constants.js +1 -1
- package/dist/package.json.js +1 -1
- package/dist/plugins/sdkServer/src/prepareSDKConfig.js +1 -1
- package/dist/src/utils/buildStructureLookup.js +1 -1
- package/dist/src/utils/date.js +1 -1
- package/package.json +1 -1
|
@@ -7,164 +7,93 @@ var minPriorityQueue = require('./minPriorityQueue.js');
|
|
|
7
7
|
|
|
8
8
|
const DEFAULT_WALKING_SPEED_M_PER_MIN = 60;
|
|
9
9
|
const CLOSED_CHECKPOINT_EDGE_WEIGHT = 9999;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @typedef NavNode
|
|
13
|
-
* @property {number} ordinal
|
|
14
|
-
* @property {Array.<NavEdge>} edges
|
|
15
|
-
* @property {string} id
|
|
16
|
-
* @property {number} lat
|
|
17
|
-
* @property {number} lng
|
|
18
|
-
* @property {string} floorId
|
|
19
|
-
* @property {structureId} structureId
|
|
20
|
-
*
|
|
21
|
-
* @typedef NavEdge
|
|
22
|
-
* @property {string} dst - id of node at edge end
|
|
23
|
-
* @property {string} src - id of node at edge start
|
|
24
|
-
* @property {number} distance
|
|
25
|
-
* @property {string|undefined} o - id of security lane POI associated with this edge
|
|
26
|
-
* @property {CurvedPath|null} path - list of Bezier points if edge represents curve
|
|
27
|
-
* @property {boolean} isAccessible
|
|
28
|
-
* @property {boolean} isDriveway - true if edge points to POI, false if edge just connects other edges
|
|
29
|
-
* @property {number} transitTime
|
|
30
|
-
* @property {string} type
|
|
31
|
-
* @property {number} weight - value used by Dijkstra algorithm (usually edge time or distance)
|
|
32
|
-
*
|
|
33
|
-
* @param {RawNavGraph} data
|
|
34
|
-
* @param {function} floorIdToOrdinal
|
|
35
|
-
* @param {function} floorIdToStructureId
|
|
36
|
-
* @param {Array.<SecurityLane>} securityLanesMap - list of security lanes
|
|
37
|
-
* @return {Object}
|
|
38
|
-
*/
|
|
39
|
-
// todo remove dead commented code
|
|
40
10
|
function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLanesMap) {
|
|
41
11
|
const nodes = {};
|
|
42
12
|
const geoDb = {};
|
|
43
|
-
const nodesToAvoid = new Set();
|
|
13
|
+
const nodesToAvoid = /* @__PURE__ */ new Set();
|
|
44
14
|
let securityWaitTimes = {};
|
|
45
|
-
|
|
46
|
-
data.nodes.forEach(nodeData => {
|
|
15
|
+
data.nodes.forEach((nodeData) => {
|
|
47
16
|
const ordinal = floorIdToOrdinal(nodeData.floorId);
|
|
48
17
|
const structureId = floorIdToStructureId(nodeData.floorId);
|
|
49
18
|
const node = {
|
|
50
|
-
...R.pick([
|
|
19
|
+
...R.pick(["id", "lat", "lng", "floorId"], nodeData),
|
|
51
20
|
edges: [],
|
|
52
21
|
ordinal,
|
|
53
|
-
structureId
|
|
22
|
+
structureId
|
|
54
23
|
};
|
|
55
24
|
addNode(node);
|
|
56
25
|
});
|
|
57
|
-
|
|
58
|
-
data.edges.forEach(ed => nodes[ed.s].edges.push(createEdge(ed, nodes)));
|
|
59
|
-
|
|
26
|
+
data.edges.forEach((ed) => nodes[ed.s].edges.push(createEdge(ed, nodes)));
|
|
60
27
|
function addNode(node) {
|
|
61
|
-
const largeGeo = node.floorId +
|
|
62
|
-
const mediumGeo = node.floorId +
|
|
63
|
-
|
|
28
|
+
const largeGeo = node.floorId + ":" + geohasher.encode(node.lat, node.lng).substr(0, 7);
|
|
29
|
+
const mediumGeo = node.floorId + ":" + geohasher.encode(node.lat, node.lng).substr(0, 8);
|
|
64
30
|
if (!geoDb[largeGeo]) {
|
|
65
31
|
geoDb[largeGeo] = [];
|
|
66
32
|
}
|
|
67
|
-
|
|
68
33
|
geoDb[largeGeo].push(node);
|
|
69
|
-
|
|
70
34
|
if (!geoDb[mediumGeo]) {
|
|
71
35
|
geoDb[mediumGeo] = [];
|
|
72
36
|
}
|
|
73
|
-
|
|
74
37
|
geoDb[mediumGeo].push(node);
|
|
75
|
-
|
|
76
38
|
nodes[node.id] = node;
|
|
77
39
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const type = getEdgeType(data);
|
|
40
|
+
function createEdge(data2, nodes2) {
|
|
41
|
+
const type = getEdgeType(data2);
|
|
81
42
|
const typeLower = type.toLowerCase();
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
end: { lat: point.e[0], lng: point.e[1] },
|
|
95
|
-
};
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const path = data.p ? buildCurvedPath(data.p) : null;
|
|
99
|
-
|
|
43
|
+
const isAccessible = typeLower !== "escalator" && typeLower !== "stairs";
|
|
44
|
+
const distance = distanceBetweenNodes(data2.s, data2.d, nodes2);
|
|
45
|
+
const transitTime = data2.l || distance / DEFAULT_WALKING_SPEED_M_PER_MIN;
|
|
46
|
+
const buildCurvedPath = (points) => points.map((point) => {
|
|
47
|
+
return {
|
|
48
|
+
start: { lat: point.s[0], lng: point.s[1] },
|
|
49
|
+
out: { lat: point.o[0], lng: point.o[1] },
|
|
50
|
+
in: { lat: point.i[0], lng: point.i[1] },
|
|
51
|
+
end: { lat: point.e[0], lng: point.e[1] }
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
const path = data2.p ? buildCurvedPath(data2.p) : null;
|
|
100
55
|
return {
|
|
101
56
|
distance,
|
|
102
|
-
dst:
|
|
103
|
-
o:
|
|
57
|
+
dst: data2.d,
|
|
58
|
+
o: data2.o,
|
|
104
59
|
isAccessible,
|
|
105
|
-
isDriveway: !R.isNil(
|
|
106
|
-
src:
|
|
60
|
+
isDriveway: !R.isNil(data2.h) && !data2.h,
|
|
61
|
+
src: data2.s,
|
|
107
62
|
transitTime,
|
|
108
63
|
type,
|
|
109
64
|
path,
|
|
110
|
-
weight: transitTime
|
|
65
|
+
weight: transitTime
|
|
111
66
|
};
|
|
112
67
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return 'Security Checkpoint';
|
|
68
|
+
function getEdgeType(data2) {
|
|
69
|
+
if (data2.x) {
|
|
70
|
+
return "Security Checkpoint";
|
|
117
71
|
}
|
|
118
|
-
if (
|
|
119
|
-
return
|
|
72
|
+
if (data2.t === "") {
|
|
73
|
+
return "Ground";
|
|
120
74
|
}
|
|
121
|
-
return
|
|
75
|
+
return data2.t;
|
|
122
76
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{
|
|
127
|
-
throw Error('Endpoint specified in findRoute without floorId nor an ordinal');
|
|
77
|
+
const findClosestNode = (endpoint) => {
|
|
78
|
+
if (endpoint.floorId === void 0 && endpoint.ordinal === void 0) {
|
|
79
|
+
throw Error("Endpoint specified in findRoute without floorId nor an ordinal");
|
|
128
80
|
}
|
|
129
|
-
const lat = endpoint.lat || endpoint.latitude;
|
|
130
|
-
const lng = endpoint.lng || endpoint.longitude;
|
|
131
|
-
return endpoint.floorId
|
|
132
|
-
? findClosestNodeByFloor(endpoint.floorId, lat, lng, geoDb, nodes)
|
|
133
|
-
: findClosestNodeByOrdinal(endpoint.ordinal, lat, lng, nodes);
|
|
81
|
+
const lat = endpoint.lat || endpoint.latitude;
|
|
82
|
+
const lng = endpoint.lng || endpoint.longitude;
|
|
83
|
+
return endpoint.floorId ? findClosestNodeByFloor(endpoint.floorId, lat, lng, geoDb, nodes) : findClosestNodeByOrdinal(endpoint.ordinal, lat, lng, nodes);
|
|
134
84
|
};
|
|
135
|
-
|
|
136
|
-
function findShortestPathEntry(start, end, nodes, options = {}) {
|
|
85
|
+
function findShortestPathEntry(start, end, nodes2, options = {}) {
|
|
137
86
|
const startNode = findClosestNode(start);
|
|
138
87
|
const endNode = findClosestNode(end);
|
|
139
|
-
|
|
140
|
-
// This code section does improve performance by about 10-20%, but comes at a cost
|
|
141
|
-
// of making the caching unusable in some cases
|
|
142
|
-
// if (start.structureId === end.structureId) {
|
|
143
|
-
// options.minOrd = Math.min(start.ordinal, end.ordinal)
|
|
144
|
-
// options.maxOrd = Math.max(start.ordinal, end.ordinal)
|
|
145
|
-
// options.structureId = start.structureId
|
|
146
|
-
// }
|
|
147
|
-
return findShortestPath(startNode, endNode, nodes, nodesToAvoid, securityWaitTimes, securityLanesMap, options);
|
|
88
|
+
return findShortestPath(startNode, endNode, nodes2, nodesToAvoid, securityWaitTimes, securityLanesMap, options);
|
|
148
89
|
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
*
|
|
152
|
-
* @param {Array.<string>} nodes - Array of nodes to avoid
|
|
153
|
-
*/
|
|
154
|
-
function updateNodesToAvoid(nodes) {
|
|
155
|
-
// We want to replace entire list when we get new nodes, not just add
|
|
90
|
+
function updateNodesToAvoid(nodes2) {
|
|
156
91
|
nodesToAvoid.clear();
|
|
157
|
-
|
|
92
|
+
nodes2.forEach((n) => nodesToAvoid.add(n));
|
|
158
93
|
}
|
|
159
|
-
/**
|
|
160
|
-
* @param {Endpoint} start - start endpoint
|
|
161
|
-
* @param {Array.<Endpoint>} destArray - list of destinations
|
|
162
|
-
* @param {RouteOptions} options extra options (such as requireAccessibility)
|
|
163
|
-
* @returns {Array.<Array.<NavNode>>} array of routes corresponding to destinations specified
|
|
164
|
-
*/
|
|
165
94
|
function findAllShortestPaths(start, destArray, options) {
|
|
166
95
|
const startNode = findClosestNode(start);
|
|
167
|
-
const destNodeArray = destArray.map(dest => findClosestNode(dest));
|
|
96
|
+
const destNodeArray = destArray.map((dest) => findClosestNode(dest));
|
|
168
97
|
if (!startNode || !destNodeArray.length) {
|
|
169
98
|
return [];
|
|
170
99
|
}
|
|
@@ -175,64 +104,37 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
|
|
|
175
104
|
nodesToAvoid,
|
|
176
105
|
securityWaitTimes,
|
|
177
106
|
securityLanesMap,
|
|
178
|
-
options
|
|
107
|
+
options
|
|
179
108
|
);
|
|
180
109
|
}
|
|
181
|
-
|
|
182
110
|
function updateWithSecurityWaitTime(waitTimesData) {
|
|
183
|
-
securityWaitTimes = R.map(R.omit([
|
|
111
|
+
securityWaitTimes = R.map(R.omit(["lastUpdated"]), waitTimesData);
|
|
184
112
|
clearCache();
|
|
185
113
|
}
|
|
186
|
-
|
|
187
114
|
return {
|
|
188
115
|
_nodes: nodes,
|
|
189
116
|
_geoDb: geoDb,
|
|
190
117
|
_nodesToAvoid: nodesToAvoid,
|
|
191
|
-
addNodesToAvoid:
|
|
118
|
+
addNodesToAvoid: (nodes2) => updateNodesToAvoid(nodes2),
|
|
192
119
|
findClosestNode: (floorId, lat, lng) => findClosestNodeByFloor(floorId, lat, lng, geoDb, nodes),
|
|
193
120
|
findShortestPath: (start, end, options) => findShortestPathEntry(start, end, nodes, options),
|
|
194
121
|
findAllShortestPaths,
|
|
195
|
-
floorIdToOrdinal,
|
|
196
|
-
|
|
122
|
+
floorIdToOrdinal,
|
|
123
|
+
// todo lets get rid of this...
|
|
124
|
+
floorIdToStructureId,
|
|
125
|
+
// todo lets get rid of this...,
|
|
197
126
|
updateWithSecurityWaitTime,
|
|
198
|
-
clearCache
|
|
127
|
+
clearCache
|
|
199
128
|
};
|
|
200
129
|
}
|
|
201
|
-
|
|
202
130
|
function distanceBetweenNodes(n1, n2, nodes) {
|
|
203
131
|
const node1 = nodes[n1];
|
|
204
132
|
const node2 = nodes[n2];
|
|
205
133
|
const distance = geodesy.distance(node1.lat, node1.lng, node2.lat, node2.lng);
|
|
206
134
|
return distance;
|
|
207
135
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
* @param {Object.<Node>} start - a node in the navGraph to start on
|
|
211
|
-
* @param {Array.<Node>} destinations - array of nodes to find path to
|
|
212
|
-
* @param {Object.<string, NavNode>} nodes - dictionary of nodes by id
|
|
213
|
-
* @param {Set.<string>} nodesToAvoid - set of nodes to avoid
|
|
214
|
-
* @param {Object.<string, SecurityWaitTime>} securityWaitTimes - map of POI id to security wait time
|
|
215
|
-
* @param {Object.<string, SecurityLane>} securityLanesMap - map of POI id to security lane
|
|
216
|
-
* @param {RouteOptions} [options={}] extra options (such as requireAccessibility)
|
|
217
|
-
* @returns {Array.<Array.<Node>>} list of shortest path to each destination
|
|
218
|
-
*/
|
|
219
|
-
function findAllShortestPathsImpl(
|
|
220
|
-
start,
|
|
221
|
-
destinations,
|
|
222
|
-
nodes,
|
|
223
|
-
nodesToAvoid,
|
|
224
|
-
securityWaitTimes = {},
|
|
225
|
-
securityLanesMap = {},
|
|
226
|
-
options = {},
|
|
227
|
-
) {
|
|
228
|
-
// const previous = findPaths(start, start, nodes, options)
|
|
229
|
-
|
|
230
|
-
// const backtrackPath = node => buildBacktrackPath(nodes, previous, node)
|
|
231
|
-
// const poiNodeTuples = Array.from(destinations.entries())
|
|
232
|
-
|
|
233
|
-
// const poiPathTuples = poiNodeTuples.map(([poi, node]) => [poi, backtrackPath(node)])
|
|
234
|
-
// return new Map(poiPathTuples)
|
|
235
|
-
return destinations.map(d => {
|
|
136
|
+
function findAllShortestPathsImpl(start, destinations, nodes, nodesToAvoid, securityWaitTimes = {}, securityLanesMap = {}, options = {}) {
|
|
137
|
+
return destinations.map((d) => {
|
|
236
138
|
try {
|
|
237
139
|
return findShortestPath(start, d, nodes, nodesToAvoid, securityWaitTimes, securityLanesMap, options);
|
|
238
140
|
} catch {
|
|
@@ -240,9 +142,7 @@ function findAllShortestPathsImpl(
|
|
|
240
142
|
}
|
|
241
143
|
});
|
|
242
144
|
}
|
|
243
|
-
|
|
244
145
|
let cost, prev, visited, visitQueue, lastStartId, lastOptionsStr;
|
|
245
|
-
|
|
246
146
|
const clearCache = () => {
|
|
247
147
|
cost = {};
|
|
248
148
|
prev = {};
|
|
@@ -251,66 +151,29 @@ const clearCache = () => {
|
|
|
251
151
|
lastStartId = null;
|
|
252
152
|
lastOptionsStr = {};
|
|
253
153
|
};
|
|
254
|
-
|
|
255
|
-
// This is a temporary name during a "probation" period - then I will
|
|
256
|
-
// ditch findShortestPath and rewrite findAllShortestPaths and ditch
|
|
257
|
-
// backtrackPath, etc.
|
|
258
|
-
// NOTE: export just for testing
|
|
259
|
-
/**
|
|
260
|
-
* @param {Object<Node>} start a node in the navGraph to start on
|
|
261
|
-
* @param {Object<Node>} end a node in the navGraph to find path to
|
|
262
|
-
* @param {Object.<string, Node>} nodes dictionary of nodes by id
|
|
263
|
-
* @param {Set.<string>} nodesToAvoid - set of nodes to avoid
|
|
264
|
-
* @param {Object.<string, SecurityWaitTime>} securityWaitTimes - map of POI id to security wait time
|
|
265
|
-
* @param {Object.<string, SecurityLane>} securityLanesMap - map of POI id to security lane
|
|
266
|
-
* @param {RouteOptions} options={} extra options (such as requireAccessibility)
|
|
267
|
-
* @returns {Array.<Node>} an array of nodes that represent the shortest route from start to end. null if no route exists.
|
|
268
|
-
*/
|
|
269
|
-
function findShortestPath(
|
|
270
|
-
start,
|
|
271
|
-
end,
|
|
272
|
-
nodes,
|
|
273
|
-
nodesToAvoid,
|
|
274
|
-
securityWaitTimes = {},
|
|
275
|
-
securityLanesMap = {},
|
|
276
|
-
options = {},
|
|
277
|
-
) {
|
|
154
|
+
function findShortestPath(start, end, nodes, nodesToAvoid, securityWaitTimes = {}, securityLanesMap = {}, options = {}) {
|
|
278
155
|
if (start.id !== lastStartId || lastOptionsStr !== JSON.stringify(options)) {
|
|
279
156
|
clearCache();
|
|
280
157
|
visitQueue.offerWithPriority(start.id, 0);
|
|
281
158
|
cost[start.id] = 0;
|
|
282
159
|
visited[start.id] = true;
|
|
283
|
-
|
|
284
160
|
lastStartId = start.id;
|
|
285
161
|
lastOptionsStr = JSON.stringify(options);
|
|
286
162
|
}
|
|
287
|
-
|
|
288
|
-
// continue crawling paths - but stop once we found destination
|
|
289
163
|
while (!visitQueue.isEmpty() && !visited[end.id]) {
|
|
290
|
-
const
|
|
291
|
-
const ccost = cost[
|
|
292
|
-
for (let ei = 0; ei <
|
|
293
|
-
const e =
|
|
294
|
-
|
|
164
|
+
const node2 = nodes[visitQueue.poll()];
|
|
165
|
+
const ccost = cost[node2.id];
|
|
166
|
+
for (let ei = 0; ei < node2.edges.length; ei++) {
|
|
167
|
+
const e = node2.edges[ei];
|
|
295
168
|
if (nodesToAvoid.size > 0 && nodesToAvoid.has(e.dst)) {
|
|
296
169
|
continue;
|
|
297
170
|
}
|
|
298
171
|
if (visited[e.dst]) {
|
|
299
172
|
continue;
|
|
300
173
|
}
|
|
301
|
-
|
|
302
174
|
if (options.requiresAccessibility && !e.isAccessible) {
|
|
303
|
-
// ignore not accessible edges if we're looking for an accessible route
|
|
304
175
|
continue;
|
|
305
176
|
}
|
|
306
|
-
|
|
307
|
-
// This code section does improve performance by about 10-20%, but comes at a cost
|
|
308
|
-
// of making the caching unusable in some cases
|
|
309
|
-
// if ((options.minOrd !== undefined && nodes[e.dst].ordinal < options.minOrd) ||
|
|
310
|
-
// (options.maxOrd !== undefined && nodes[e.dst].ordinal > options.maxOrd) ||
|
|
311
|
-
// (options.structureId !== undefined && nodes[e.dst].structureId !== options.structureId))
|
|
312
|
-
// continue
|
|
313
|
-
|
|
314
177
|
let weight = e.weight;
|
|
315
178
|
if (e.o && securityWaitTimes[e.o]) {
|
|
316
179
|
const dynamicData = securityWaitTimes[e.o];
|
|
@@ -322,37 +185,29 @@ function findShortestPath(
|
|
|
322
185
|
}
|
|
323
186
|
e.securityWaitTimes = dynamicData;
|
|
324
187
|
}
|
|
325
|
-
|
|
326
188
|
if (e.o && securityLanesMap[e.o]) {
|
|
327
189
|
e.securityLane = securityLanesMap[e.o];
|
|
328
190
|
const { type, id } = securityLanesMap[e.o];
|
|
329
|
-
const securityLanesIds = R.path([
|
|
191
|
+
const securityLanesIds = R.path(["selectedSecurityLanes", type], options);
|
|
330
192
|
if (securityLanesIds && !securityLanesIds.includes(id)) {
|
|
331
193
|
continue;
|
|
332
194
|
}
|
|
333
195
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
prev[e.dst] = node;
|
|
196
|
+
if (cost[e.dst] === void 0) {
|
|
197
|
+
prev[e.dst] = node2;
|
|
337
198
|
cost[e.dst] = ccost + weight;
|
|
338
|
-
visitQueue.offerWithPriority(e.dst, ccost + weight);
|
|
199
|
+
visitQueue.offerWithPriority(e.dst, ccost + weight);
|
|
339
200
|
} else if (cost[e.dst] > ccost + weight) {
|
|
340
|
-
// is this a shorter path? Relaxation...
|
|
341
|
-
// if so, update the cost and parent
|
|
342
201
|
cost[e.dst] = ccost + weight;
|
|
343
|
-
prev[e.dst] =
|
|
202
|
+
prev[e.dst] = node2;
|
|
344
203
|
visitQueue.raisePriority(e.dst, ccost + weight);
|
|
345
204
|
}
|
|
346
205
|
}
|
|
347
|
-
visited[
|
|
206
|
+
visited[node2.id] = true;
|
|
348
207
|
}
|
|
349
|
-
|
|
350
|
-
if (!visited[end.id]) // if we never found our endpoint, it was inaccessible
|
|
351
|
-
{
|
|
208
|
+
if (!visited[end.id]) {
|
|
352
209
|
return null;
|
|
353
210
|
}
|
|
354
|
-
|
|
355
|
-
// build the path and return it
|
|
356
211
|
const path = [];
|
|
357
212
|
let node = end;
|
|
358
213
|
while (node) {
|
|
@@ -361,21 +216,18 @@ function findShortestPath(
|
|
|
361
216
|
}
|
|
362
217
|
return path.reverse();
|
|
363
218
|
}
|
|
364
|
-
|
|
365
219
|
function geohashSearch(floorId, geohash, geoDb, size) {
|
|
366
220
|
const geohashPrefix = geohash.substr(0, size);
|
|
367
|
-
|
|
368
221
|
const searchGeos = [];
|
|
369
|
-
searchGeos.push(floorId +
|
|
370
|
-
searchGeos.push(floorId +
|
|
371
|
-
searchGeos.push(floorId +
|
|
372
|
-
searchGeos.push(floorId +
|
|
373
|
-
searchGeos.push(floorId +
|
|
374
|
-
searchGeos.push(floorId +
|
|
375
|
-
searchGeos.push(floorId +
|
|
376
|
-
searchGeos.push(floorId +
|
|
377
|
-
searchGeos.push(floorId +
|
|
378
|
-
|
|
222
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohasher.calculateAdjacent(geohashPrefix, "top"), "left"));
|
|
223
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohashPrefix, "top"));
|
|
224
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohasher.calculateAdjacent(geohashPrefix, "top"), "right"));
|
|
225
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohashPrefix, "left"));
|
|
226
|
+
searchGeos.push(floorId + ":" + geohashPrefix);
|
|
227
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohashPrefix, "right"));
|
|
228
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohasher.calculateAdjacent(geohashPrefix, "bottom"), "left"));
|
|
229
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohashPrefix, "bottom"));
|
|
230
|
+
searchGeos.push(floorId + ":" + geohasher.calculateAdjacent(geohasher.calculateAdjacent(geohashPrefix, "bottom"), "right"));
|
|
379
231
|
const nodes = [];
|
|
380
232
|
for (let i = 0; i < searchGeos.length; i++) {
|
|
381
233
|
const nodesFound = geoDb[searchGeos[i]];
|
|
@@ -385,81 +237,49 @@ function geohashSearch(floorId, geohash, geoDb, size) {
|
|
|
385
237
|
}
|
|
386
238
|
}
|
|
387
239
|
}
|
|
388
|
-
|
|
389
240
|
return nodes;
|
|
390
241
|
}
|
|
391
|
-
|
|
392
242
|
function findNodesByGeohash(floorId, geohash, geoDb) {
|
|
393
243
|
let foundNodes = geohashSearch(floorId, geohash, geoDb, 8);
|
|
394
244
|
if (foundNodes.length > 0) {
|
|
395
245
|
return foundNodes;
|
|
396
246
|
}
|
|
397
|
-
|
|
398
|
-
// broaden our search a bit and try again...
|
|
399
247
|
foundNodes = geohashSearch(floorId, geohash, geoDb, 7);
|
|
400
248
|
if (foundNodes.length > 0) {
|
|
401
249
|
return foundNodes;
|
|
402
250
|
}
|
|
403
|
-
|
|
404
|
-
// give up and let someone else try...
|
|
405
251
|
return null;
|
|
406
252
|
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* @param floorId
|
|
410
|
-
* @param lat
|
|
411
|
-
* @param lng
|
|
412
|
-
* @param geoDb
|
|
413
|
-
* @param {Object<string, NavNode>} nodes - dictionary of node id to node object
|
|
414
|
-
* @return {NavNode} - node that is on the same floor and closest to the lat,lng point
|
|
415
|
-
*/
|
|
416
253
|
function findClosestNodeByFloor(floorId, lat, lng, geoDb, nodes) {
|
|
417
|
-
const cnodes =
|
|
418
|
-
findNodesByGeohash(floorId, geohasher.encode(lat, lng), geoDb) || findClosestNodeByFloor2(floorId, lat, lng, nodes);
|
|
419
|
-
|
|
254
|
+
const cnodes = findNodesByGeohash(floorId, geohasher.encode(lat, lng), geoDb) || findClosestNodeByFloor2(floorId, lat, lng, nodes);
|
|
420
255
|
const nodeWithDistance = [];
|
|
421
256
|
for (let i = 0; i < cnodes.length; i++) {
|
|
422
|
-
// Attached distance to each node from the origin.
|
|
423
257
|
const distance = geodesy.distance(lat, lng, cnodes[i].lat, cnodes[i].lng);
|
|
424
258
|
nodeWithDistance.push([cnodes[i], distance]);
|
|
425
259
|
}
|
|
426
|
-
|
|
427
|
-
// Sort by distance.
|
|
428
|
-
nodeWithDistance.sort(function (a, b) {
|
|
260
|
+
nodeWithDistance.sort(function(a, b) {
|
|
429
261
|
return a[1] - b[1];
|
|
430
262
|
});
|
|
431
263
|
const nodesSortedByDistance = [];
|
|
432
264
|
for (let i = 0; i < nodeWithDistance.length; i++) {
|
|
433
265
|
nodesSortedByDistance.push(nodeWithDistance[i][0]);
|
|
434
266
|
}
|
|
435
|
-
|
|
436
267
|
return nodesSortedByDistance[0];
|
|
437
268
|
}
|
|
438
|
-
|
|
439
|
-
// A slightly slower alternative to findClosestNode (an experiment - its simpler, but slower)
|
|
440
269
|
function findClosestNodeByFloor2(floorId, lat, lng, nodes) {
|
|
441
|
-
const floorNodes = Object.values(nodes)
|
|
442
|
-
.filter(n => n.floorId === floorId)
|
|
443
|
-
.map(n => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
270
|
+
const floorNodes = Object.values(nodes).filter((n) => n.floorId === floorId).map((n) => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
444
271
|
if (!floorNodes.length) {
|
|
445
272
|
throw Error(`findClosestNodeByFloor2 found no nodes on floor ${floorId}`);
|
|
446
273
|
}
|
|
447
274
|
return selectShortest(floorNodes);
|
|
448
275
|
}
|
|
449
|
-
|
|
450
276
|
function findClosestNodeByOrdinal(ord, lat, lng, nodes) {
|
|
451
|
-
const ordNodes = Object.values(nodes)
|
|
452
|
-
.filter(n => n.ordinal === ord)
|
|
453
|
-
.map(n => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
277
|
+
const ordNodes = Object.values(nodes).filter((n) => n.ordinal === ord).map((n) => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
454
278
|
if (!ordNodes.length) {
|
|
455
279
|
throw Error(`findClosestNodeByOrdinal found no nodes on ordinal ${ord}`);
|
|
456
280
|
}
|
|
457
281
|
return selectShortest(ordNodes);
|
|
458
282
|
}
|
|
459
|
-
|
|
460
|
-
// companion to above function - it returns closest node
|
|
461
|
-
// ar is 2-dim array - ar[i][0] = node, ar[i][1] = distance
|
|
462
|
-
// TODO: use this approach in findClosestNode - no need to sort first!
|
|
463
283
|
function selectShortest(ar) {
|
|
464
284
|
let shortest = ar[0];
|
|
465
285
|
for (let i = 1; i < ar.length; i++) {
|
|
@@ -467,7 +287,6 @@ function selectShortest(ar) {
|
|
|
467
287
|
shortest = ar[i];
|
|
468
288
|
}
|
|
469
289
|
}
|
|
470
|
-
|
|
471
290
|
return shortest[0];
|
|
472
291
|
}
|
|
473
292
|
|
|
@@ -21,101 +21,70 @@ function _interopNamespaceDefault(e) {
|
|
|
21
21
|
|
|
22
22
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
* Visits all nodes (breadth-first) from the nodes2visit
|
|
26
|
-
* array, adding them to vnodes and adding their connected
|
|
27
|
-
* nodes to nodes2visit - until nodes2visit is empty.
|
|
28
|
-
* Nothing is returned - but the vnodes array will have been
|
|
29
|
-
* altered.
|
|
30
|
-
* @param {Object.<id:node>} nodes - the node pool you wish to scan
|
|
31
|
-
* @param {Node} startingNode - which node to start the scan
|
|
32
|
-
*/
|
|
33
24
|
function visitAll(nodes, startingNode) {
|
|
34
|
-
// initialize nodes2visit with the specified node to start
|
|
35
25
|
const nodes2visit = [startingNode];
|
|
36
|
-
const vnodes = new Set();
|
|
37
|
-
|
|
26
|
+
const vnodes = /* @__PURE__ */ new Set();
|
|
38
27
|
while (nodes2visit.length) {
|
|
39
|
-
const node = nodes2visit.splice(0, 1)[0];
|
|
28
|
+
const node = nodes2visit.splice(0, 1)[0];
|
|
40
29
|
if (node && !vnodes.has(node)) {
|
|
41
30
|
vnodes.add(node);
|
|
42
|
-
node.edges.forEach(edge => {
|
|
31
|
+
node.edges.forEach((edge) => {
|
|
43
32
|
if (!vnodes.has(nodes[edge.dst])) {
|
|
44
33
|
nodes2visit.push(nodes[edge.dst]);
|
|
45
34
|
}
|
|
46
35
|
});
|
|
47
36
|
}
|
|
48
37
|
}
|
|
49
|
-
|
|
50
38
|
return vnodes;
|
|
51
39
|
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @param {Object.<id:node>} nodes - the node pool you wish to scan
|
|
55
|
-
* @param {Node} [startingNode] - which node to start the scan (default: "first" node)
|
|
56
|
-
* @returns two arrays of nodes in an object, { orphaned, connected }
|
|
57
|
-
*/
|
|
58
40
|
function orphanTest(nodes, startingNode) {
|
|
59
|
-
const nodesArray = Object.values(nodes);
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const onodes = nodesArray.filter(n => !vnodes.has(n));
|
|
63
|
-
|
|
41
|
+
const nodesArray = Object.values(nodes);
|
|
42
|
+
const vnodes = visitAll(nodes, startingNode || nodesArray[0]);
|
|
43
|
+
const onodes = nodesArray.filter((n) => !vnodes.has(n));
|
|
64
44
|
console.log(`${onodes.length} Orphaned nodes found from ${nodesArray.length} total`);
|
|
65
|
-
|
|
66
45
|
return {
|
|
67
46
|
orphaned: onodes,
|
|
68
|
-
orphanedByFloor: R__namespace.groupBy(R__namespace.prop(
|
|
69
|
-
connected: Array.from(vnodes)
|
|
47
|
+
orphanedByFloor: R__namespace.groupBy(R__namespace.prop("floorId"), onodes),
|
|
48
|
+
connected: Array.from(vnodes)
|
|
70
49
|
};
|
|
71
50
|
}
|
|
72
|
-
|
|
73
|
-
const enrichDebugNavGraph = nodes => ({
|
|
51
|
+
const enrichDebugNavGraph = (nodes) => ({
|
|
74
52
|
nodes: toOrphanedNodesArray(nodes),
|
|
75
|
-
edges: getNavEdgeFeatures(nodes)
|
|
53
|
+
edges: getNavEdgeFeatures(nodes)
|
|
76
54
|
});
|
|
77
|
-
|
|
78
|
-
const transformNodes = isOrphaned => R__namespace.map(R__namespace.pipe(R__namespace.assoc('isOrphaned', isOrphaned), R__namespace.dissoc('edges')));
|
|
79
|
-
|
|
55
|
+
const transformNodes = (isOrphaned) => R__namespace.map(R__namespace.pipe(R__namespace.assoc("isOrphaned", isOrphaned), R__namespace.dissoc("edges")));
|
|
80
56
|
const toOrphanedNodesArray = R__namespace.pipe(
|
|
81
57
|
orphanTest,
|
|
82
|
-
R__namespace.pick([
|
|
58
|
+
R__namespace.pick(["connected", "orphaned"]),
|
|
83
59
|
R__namespace.evolve({
|
|
84
60
|
connected: transformNodes(false),
|
|
85
|
-
orphaned: transformNodes(true)
|
|
61
|
+
orphaned: transformNodes(true)
|
|
86
62
|
}),
|
|
87
63
|
R__namespace.values,
|
|
88
|
-
R__namespace.flatten
|
|
64
|
+
R__namespace.flatten
|
|
89
65
|
);
|
|
90
|
-
|
|
91
|
-
const getNavEdgeFeatures = nodes =>
|
|
92
|
-
Object.values(nodes)
|
|
93
|
-
.flatMap(node => node.edges)
|
|
94
|
-
.map(edge => mapEdge(edge, nodes));
|
|
95
|
-
|
|
66
|
+
const getNavEdgeFeatures = (nodes) => Object.values(nodes).flatMap((node) => node.edges).map((edge) => mapEdge(edge, nodes));
|
|
96
67
|
const mapEdge = ({ src, dst, type, isDriveway }, nodeMap) => ({
|
|
97
68
|
startCoordinates: [nodeMap[src].lng, nodeMap[src].lat],
|
|
98
69
|
endCoordinates: [nodeMap[dst].lng, nodeMap[dst].lat],
|
|
99
70
|
isDriveway,
|
|
100
71
|
ordinal: nodeMap[src].ordinal,
|
|
101
72
|
category: getEdgeCategory(type),
|
|
102
|
-
defaultStrokeColor: getStrokeColorForMissingCategory(type)
|
|
73
|
+
defaultStrokeColor: getStrokeColorForMissingCategory(type)
|
|
103
74
|
});
|
|
104
|
-
|
|
105
75
|
const getStrokeColorForMissingCategory = R__namespace.cond([
|
|
106
|
-
[R__namespace.equals(
|
|
107
|
-
[R__namespace.equals(
|
|
108
|
-
[R__namespace.equals(
|
|
109
|
-
[R__namespace.equals(
|
|
110
|
-
[R__namespace.T, R__namespace.always(
|
|
76
|
+
[R__namespace.equals("Stairs"), R__namespace.always("#EFBC9B")],
|
|
77
|
+
[R__namespace.equals("Elevator"), R__namespace.always("#A491D3")],
|
|
78
|
+
[R__namespace.equals("Escalator"), R__namespace.always("#563F1B")],
|
|
79
|
+
[R__namespace.equals("Ramp"), R__namespace.always("#DBD053")],
|
|
80
|
+
[R__namespace.T, R__namespace.always("#FF0000")]
|
|
111
81
|
]);
|
|
112
|
-
|
|
113
82
|
const getEdgeCategory = R__namespace.cond([
|
|
114
|
-
[R__namespace.equals(
|
|
115
|
-
[R__namespace.equals(
|
|
116
|
-
[R__namespace.equals(
|
|
117
|
-
[R__namespace.equals(
|
|
118
|
-
[R__namespace.T, R__namespace.always(
|
|
83
|
+
[R__namespace.equals("Train"), R__namespace.always("nav.train")],
|
|
84
|
+
[R__namespace.equals("Bus"), R__namespace.always("nav.transit")],
|
|
85
|
+
[R__namespace.equals("Security Checkpoint"), R__namespace.always("nav.secure")],
|
|
86
|
+
[R__namespace.equals("Ground"), R__namespace.always("nav.primary")],
|
|
87
|
+
[R__namespace.T, R__namespace.always("")]
|
|
119
88
|
]);
|
|
120
89
|
|
|
121
90
|
exports.enrichDebugNavGraph = enrichDebugNavGraph;
|