atriusmaps-node-sdk 3.3.898 → 3.3.899
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
|
@@ -29,324 +29,171 @@ function _interopNamespaceDefault(e) {
|
|
|
29
29
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
30
30
|
|
|
31
31
|
const DEFAULT_WALKING_SPEED_M_PER_MIN = 60;
|
|
32
|
-
|
|
33
|
-
const getEdgeTo = dst => node => R__namespace.find(e => e.dst === dst, node.edges);
|
|
34
|
-
|
|
35
|
-
// todo may be not needed
|
|
32
|
+
const getEdgeTo = (dst) => (node) => R__namespace.find((e) => e.dst === dst, node.edges);
|
|
36
33
|
const SecurityLaneType = {
|
|
37
|
-
SECURITY:
|
|
38
|
-
IMMIGRATION:
|
|
34
|
+
SECURITY: "SecurityLane",
|
|
35
|
+
IMMIGRATION: "ImmigrationLane"
|
|
39
36
|
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @typedef {Object} Endpoint
|
|
43
|
-
* @property {number} lat - latitude
|
|
44
|
-
* @property {number} lng - longitude
|
|
45
|
-
* @property {string} title
|
|
46
|
-
* @property {string} [floorId] - usually present
|
|
47
|
-
* @property {number} [ordinal] - optional
|
|
48
|
-
*
|
|
49
|
-
* @typedef SecurityLaneIdsMap
|
|
50
|
-
* @property {string[]} SecurityLane - list of ids of security lanes
|
|
51
|
-
* @property {string[]} ImmigrationLane - list of ids of immigration lanes
|
|
52
|
-
*
|
|
53
|
-
* @typedef Route
|
|
54
|
-
* @property {Step[]} steps - list of navigation steps
|
|
55
|
-
* @property {Segment[]} segments - list of navigation line segments
|
|
56
|
-
* @property {number} time - total route time
|
|
57
|
-
* @property {number} distance - total route distance
|
|
58
|
-
*
|
|
59
|
-
* @typedef RouteOptions
|
|
60
|
-
* @property {SecurityLaneIdsMap} selectedSecurityLanes - map of selected lane ids by type
|
|
61
|
-
* @property {boolean} requiresAccessibility - true if route should be accessible
|
|
62
|
-
* @property {boolean} compareFindPaths - indicate whether to calculate path using 2 methods and then compare their performance
|
|
63
|
-
*
|
|
64
|
-
* @typedef SecurityWaitTime
|
|
65
|
-
* @property {number} queueTime
|
|
66
|
-
* @property {boolean} timeIsReal
|
|
67
|
-
* @property {boolean} isTemporarilyClosed
|
|
68
|
-
*
|
|
69
|
-
* @typedef {Array<number>} Coordinate - pair of lng and lat
|
|
70
|
-
*
|
|
71
|
-
*/
|
|
72
37
|
function create(app, config) {
|
|
73
|
-
const log = app.log.sublog(
|
|
38
|
+
const log = app.log.sublog("wayfinder");
|
|
74
39
|
const init = async () => {
|
|
75
|
-
app.bus.send(
|
|
40
|
+
app.bus.send("venueData/loadNavGraph");
|
|
76
41
|
};
|
|
77
|
-
|
|
78
42
|
let graphLoadedProm = new Zousan();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* Returns nav graph object for testing purposes.
|
|
82
|
-
* Result includes nav nodes, edges, functions to update dynamic data and calculate shortest paths
|
|
83
|
-
*
|
|
84
|
-
* @returns {Object}
|
|
85
|
-
*/
|
|
86
|
-
app.bus.on('wayfinder/_getNavGraph', () => graphLoadedProm);
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @typedef RawNavGraph
|
|
90
|
-
* @property Array.<RawNavEdge> edges
|
|
91
|
-
* @property Array.<RawNavNode> nodes
|
|
92
|
-
*
|
|
93
|
-
* @typedef RawNavEdge
|
|
94
|
-
* @property {string} s - id of start node
|
|
95
|
-
* @property {string} d - id of destination node
|
|
96
|
-
* @property {number} l - custom transit time
|
|
97
|
-
* @property {boolean} h - is edge a driveway
|
|
98
|
-
* @property {string} t - edge type
|
|
99
|
-
* @property {Array.<{ s, o, i, e }>|null} p - list of Bezier points
|
|
100
|
-
*
|
|
101
|
-
* @typedef RawNavNode
|
|
102
|
-
* @property {string} id
|
|
103
|
-
* @property {string} floorId
|
|
104
|
-
* @property {number} lat
|
|
105
|
-
* @property {number} lng
|
|
106
|
-
*
|
|
107
|
-
* Transforms raw nav graph data and list of structures
|
|
108
|
-
* to nav graph object with functions to build shortest paths
|
|
109
|
-
*
|
|
110
|
-
* @param {RawNavGraph} navGraphData
|
|
111
|
-
* @param {Array.<Structure>} structures
|
|
112
|
-
*/
|
|
113
|
-
app.bus.on('venueData/navGraphLoaded', async ({ navGraphData, structures }) => {
|
|
43
|
+
app.bus.on("wayfinder/_getNavGraph", () => graphLoadedProm);
|
|
44
|
+
app.bus.on("venueData/navGraphLoaded", async ({ navGraphData, structures }) => {
|
|
114
45
|
const structureLookup = buildStructureLookup.buildStructuresLookup(structures);
|
|
115
46
|
const securityLanesMap = await prepareSecurityLanes();
|
|
116
47
|
const graph = navGraph.createNavGraph(
|
|
117
48
|
navGraphData,
|
|
118
49
|
structureLookup.floorIdToOrdinal,
|
|
119
50
|
structureLookup.floorIdToStructureId,
|
|
120
|
-
securityLanesMap
|
|
51
|
+
securityLanesMap
|
|
121
52
|
);
|
|
122
53
|
graphLoadedProm.resolve(graph);
|
|
123
54
|
});
|
|
124
|
-
|
|
125
|
-
app.bus.on('poi/setDynamicRouting', async ({ idValuesMap }) => {
|
|
55
|
+
app.bus.on("poi/setDynamicRouting", async ({ idValuesMap }) => {
|
|
126
56
|
const graph = await graphLoadedProm;
|
|
127
57
|
const poisToAvoid = Object.values(idValuesMap);
|
|
128
|
-
const nodesToAvoid = poisToAvoid
|
|
129
|
-
.
|
|
130
|
-
|
|
131
|
-
)
|
|
132
|
-
.map(poi => graph.findClosestNode(poi.position.floorId, poi.position.latitude, poi.position.longitude).id);
|
|
58
|
+
const nodesToAvoid = poisToAvoid.filter(
|
|
59
|
+
(poi) => poi.position && poi.position.floorId !== void 0 && poi.position.latitude && poi.position.longitude
|
|
60
|
+
).map((poi) => graph.findClosestNode(poi.position.floorId, poi.position.latitude, poi.position.longitude).id);
|
|
133
61
|
graph.addNodesToAvoid(nodesToAvoid);
|
|
134
62
|
});
|
|
135
|
-
|
|
136
63
|
const prepareSecurityLanes = async () => {
|
|
137
|
-
const securityPois = await app.bus.get(
|
|
138
|
-
categoryId:
|
|
64
|
+
const securityPois = await app.bus.get("poi/getByCategoryId", {
|
|
65
|
+
categoryId: "security"
|
|
139
66
|
});
|
|
140
67
|
return R__namespace.pipe(R__namespace.map(getSecurityLane), R__namespace.filter(R__namespace.identity))(securityPois);
|
|
141
68
|
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
id: R__namespace.path(['queue', 'queueSubtype'], poi),
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Returns a shortest path from user physical location to provided destination
|
|
151
|
-
* and triggers rendering navigation line on the map
|
|
152
|
-
*
|
|
153
|
-
* @param {Endpoint} toEndpoint
|
|
154
|
-
* @param {Boolean} requiresAccessibility
|
|
155
|
-
* @param {SecurityLaneIdsMap} selectedSecurityLanes
|
|
156
|
-
* @returns {Route}
|
|
157
|
-
*/
|
|
69
|
+
const getSecurityLane = (poi) => poi.queue && {
|
|
70
|
+
type: R__namespace.path(["queue", "queueType"], poi),
|
|
71
|
+
id: R__namespace.path(["queue", "queueSubtype"], poi)
|
|
72
|
+
};
|
|
158
73
|
app.bus.on(
|
|
159
|
-
|
|
74
|
+
"wayfinder/showNavLineFromPhysicalLocation",
|
|
160
75
|
async ({ toEndpoint, selectedSecurityLanes = null, requiresAccessibility }) => {
|
|
161
|
-
const physicalLocation = await app.bus.getFirst(
|
|
76
|
+
const physicalLocation = await app.bus.getFirst("user/getPhysicalLocation");
|
|
162
77
|
return navigateFromTo(physicalLocation, toEndpoint, {
|
|
163
78
|
selectedSecurityLanes,
|
|
164
79
|
requiresAccessibility,
|
|
165
|
-
primary: true
|
|
80
|
+
primary: true
|
|
166
81
|
});
|
|
167
|
-
}
|
|
82
|
+
}
|
|
168
83
|
);
|
|
169
|
-
|
|
170
84
|
async function navigateFromTo(fromEndpoint, toEndpoint, options) {
|
|
171
85
|
const route = await getRoute({ fromEndpoint, toEndpoint, options });
|
|
172
86
|
if (route) {
|
|
173
87
|
const { segments } = route;
|
|
174
88
|
if (options.primary) {
|
|
175
|
-
app.bus.send(
|
|
89
|
+
app.bus.send("map/resetNavlineFeatures");
|
|
176
90
|
}
|
|
177
|
-
app.bus.send(
|
|
91
|
+
app.bus.send("map/showNavlineFeatures", {
|
|
178
92
|
segments,
|
|
179
|
-
category: options.primary ?
|
|
93
|
+
category: options.primary ? "primary" : "alternative"
|
|
180
94
|
});
|
|
181
95
|
}
|
|
182
|
-
|
|
183
96
|
return route;
|
|
184
97
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* @busEvent wayfinder/getNavigationEndpoint
|
|
197
|
-
*
|
|
198
|
-
* Returns an object of the Endoint type.
|
|
199
|
-
* wayfinding uses this structure to find the closest node
|
|
200
|
-
* for shortestPath calculations, etc.
|
|
201
|
-
* @param {Object} p - can be a POI (or similar) or a string with lat,lng[,floorId[,name]] or location defined as { latitutde, longitude [, floorId] [, title] }
|
|
202
|
-
* @returns {Endpoint} navigational endpoint
|
|
203
|
-
*/
|
|
98
|
+
const poiIdToNavigationEndpoint = (id, floorIdToOrdinal) => app.bus.get("poi/getById", { id }).then((poi) => {
|
|
99
|
+
if (poi && poi.position) {
|
|
100
|
+
return poiToNavigationEndpoint(poi, floorIdToOrdinal);
|
|
101
|
+
} else {
|
|
102
|
+
throw Error("Unknown POI ID " + id);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
204
105
|
async function getNavigationEndpoint(p) {
|
|
205
|
-
return graphLoadedProm.then(graph => {
|
|
106
|
+
return graphLoadedProm.then((graph) => {
|
|
206
107
|
if (!p) {
|
|
207
|
-
throw Error(
|
|
108
|
+
throw Error("wayfinder: Invalid endpoint definition", p);
|
|
208
109
|
}
|
|
209
|
-
|
|
210
|
-
if (typeof p === 'number') {
|
|
110
|
+
if (typeof p === "number") {
|
|
211
111
|
return poiIdToNavigationEndpoint(p, graph.floorIdToOrdinal);
|
|
212
112
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (p.match(/^\d+$/)) // single integer - assume its poi id
|
|
216
|
-
{
|
|
113
|
+
if (typeof p === "string") {
|
|
114
|
+
if (p.match(/^\d+$/)) {
|
|
217
115
|
return poiIdToNavigationEndpoint(parseInt(p), graph.floorIdToOrdinal);
|
|
218
116
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
// lat,lng,floorId,desc format
|
|
222
|
-
const [lat, lng, floorId, initialTitle] = p.split(',');
|
|
117
|
+
if (p.indexOf(",") > 0) {
|
|
118
|
+
const [lat, lng, floorId, initialTitle] = p.split(",");
|
|
223
119
|
if (!graph.floorIdToStructureId(floorId)) {
|
|
224
|
-
throw Error(
|
|
120
|
+
throw Error("Unknown floorId in endpoint: " + floorId);
|
|
225
121
|
}
|
|
226
122
|
let title = initialTitle;
|
|
227
123
|
if (!title) {
|
|
228
|
-
title =
|
|
124
|
+
title = "Starting Point";
|
|
229
125
|
}
|
|
230
|
-
|
|
231
126
|
return {
|
|
232
127
|
lat: parseFloat(lat),
|
|
233
128
|
lng: parseFloat(lng),
|
|
234
129
|
ordinal: graph.floorIdToOrdinal(floorId),
|
|
235
130
|
floorId,
|
|
236
|
-
title
|
|
131
|
+
title
|
|
237
132
|
};
|
|
238
133
|
}
|
|
239
134
|
}
|
|
240
|
-
|
|
241
135
|
if (isEndpoint(p)) {
|
|
242
136
|
return p;
|
|
243
137
|
}
|
|
244
|
-
|
|
245
138
|
if (p.latitude) {
|
|
246
139
|
return {
|
|
247
140
|
lat: p.latitude,
|
|
248
141
|
lng: p.longitude,
|
|
249
142
|
floorId: p.floorId,
|
|
250
143
|
ordinal: graph.floorIdToOrdinal(p.floorId),
|
|
251
|
-
title: p.title
|
|
144
|
+
title: p.title
|
|
252
145
|
};
|
|
253
146
|
}
|
|
254
|
-
|
|
255
|
-
if (p.position && p.name) // looks like a POI or some other
|
|
256
|
-
{
|
|
147
|
+
if (p.position && p.name) {
|
|
257
148
|
return poiToNavigationEndpoint(p, graph.floorIdToOrdinal);
|
|
258
149
|
}
|
|
259
|
-
|
|
260
|
-
throw Error('Invalid start or end point: ' + p);
|
|
150
|
+
throw Error("Invalid start or end point: " + p);
|
|
261
151
|
});
|
|
262
152
|
}
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
const isEndpoint = R__namespace.pipe(R__namespace.pick(endpointProps), R__namespace.keys, R__namespace.propEq(endpointProps.length, 'length'), Boolean);
|
|
266
|
-
|
|
153
|
+
const endpointProps = ["lat", "lng", "floorId", "ordinal"];
|
|
154
|
+
const isEndpoint = R__namespace.pipe(R__namespace.pick(endpointProps), R__namespace.keys, R__namespace.propEq(endpointProps.length, "length"), Boolean);
|
|
267
155
|
const poiToNavigationEndpoint = (poi, floorIdToOrdinal) => ({
|
|
268
156
|
lat: poi.position.latitude,
|
|
269
157
|
lng: poi.position.longitude,
|
|
270
158
|
floorId: poi.position.floorId,
|
|
271
159
|
ordinal: floorIdToOrdinal(poi.position.floorId),
|
|
272
|
-
title: poi.name
|
|
160
|
+
title: poi.name
|
|
273
161
|
});
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
* @return {Endpoint} - navigation endpoint
|
|
279
|
-
*/
|
|
280
|
-
app.bus.on('wayfinder/getNavigationEndpoint', ({ ep }) => getNavigationEndpoint(ep));
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* @typedef PathSecurityInfo
|
|
284
|
-
* @property {boolean} routeExists
|
|
285
|
-
* @property {boolean} [hasSecurity]
|
|
286
|
-
* @property {boolean} [hasImmigration]
|
|
287
|
-
*
|
|
288
|
-
* Checks if there is a path between 2 endpoints which satisfies passed options
|
|
289
|
-
* and if this path includes security and immigration lanes
|
|
290
|
-
*
|
|
291
|
-
* @param {Endpoint} fromEndpoint
|
|
292
|
-
* @param {Endpoint} toEndpoint
|
|
293
|
-
* @param {RouteOptions} options
|
|
294
|
-
* @returns {PathSecurityInfo}
|
|
295
|
-
*/
|
|
296
|
-
app.bus.on('wayfinder/checkIfPathHasSecurity', ({ fromEndpoint, toEndpoint, options = {} }) =>
|
|
297
|
-
graphLoadedProm.then(graph => {
|
|
162
|
+
app.bus.on("wayfinder/getNavigationEndpoint", ({ ep }) => getNavigationEndpoint(ep));
|
|
163
|
+
app.bus.on(
|
|
164
|
+
"wayfinder/checkIfPathHasSecurity",
|
|
165
|
+
({ fromEndpoint, toEndpoint, options = {} }) => graphLoadedProm.then((graph) => {
|
|
298
166
|
options.compareFindPaths = config.compareFindPaths;
|
|
299
167
|
const route = findRoute.findRoute(graph, fromEndpoint, toEndpoint, options);
|
|
300
|
-
|
|
301
168
|
if (!route) {
|
|
302
169
|
return { routeExists: false };
|
|
303
170
|
}
|
|
304
|
-
|
|
305
171
|
const queues = route.waypoints.filter(
|
|
306
|
-
node =>
|
|
307
|
-
R__namespace.pathEq(SecurityLaneType.SECURITY, ['securityLane', 'type'], node) ||
|
|
308
|
-
R__namespace.pathEq(SecurityLaneType.IMMIGRATION, ['securityLane', 'type'], node),
|
|
172
|
+
(node) => R__namespace.pathEq(SecurityLaneType.SECURITY, ["securityLane", "type"], node) || R__namespace.pathEq(SecurityLaneType.IMMIGRATION, ["securityLane", "type"], node)
|
|
309
173
|
);
|
|
310
|
-
const containsSecurityLaneType = type => Boolean(route.waypoints.find(R__namespace.pathEq(type, [
|
|
174
|
+
const containsSecurityLaneType = (type) => Boolean(route.waypoints.find(R__namespace.pathEq(type, ["securityLane", "type"])));
|
|
311
175
|
return {
|
|
312
176
|
routeExists: true,
|
|
313
177
|
queues,
|
|
314
178
|
hasSecurity: containsSecurityLaneType(SecurityLaneType.SECURITY),
|
|
315
|
-
hasImmigration: containsSecurityLaneType(SecurityLaneType.IMMIGRATION)
|
|
179
|
+
hasImmigration: containsSecurityLaneType(SecurityLaneType.IMMIGRATION)
|
|
316
180
|
};
|
|
317
|
-
})
|
|
181
|
+
})
|
|
318
182
|
);
|
|
319
|
-
|
|
320
|
-
app.bus.on('wayfinder/getRoute', getRoute);
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* @busEvent wayfinder/getRoute
|
|
324
|
-
*
|
|
325
|
-
* Builds the shortest path between 2 endpoints which satisfies passed options
|
|
326
|
-
*
|
|
327
|
-
* @param {RouteOptions} options
|
|
328
|
-
* @param {Endpoint} fromEndpoint
|
|
329
|
-
* @param {Endpoint} toEndpoint
|
|
330
|
-
*
|
|
331
|
-
* @return {(Route|null)} route - route or null if no route available
|
|
332
|
-
*/
|
|
183
|
+
app.bus.on("wayfinder/getRoute", getRoute);
|
|
333
184
|
async function getRoute({ fromEndpoint, toEndpoint, options = {} }) {
|
|
334
|
-
const rawPois =
|
|
335
|
-
// Extract the POI objects (assuming rawPois is an array with one object)
|
|
185
|
+
const rawPois = await app.bus.get("poi/getAll") || {};
|
|
336
186
|
const allPois = Array.isArray(rawPois) ? rawPois[0] : rawPois;
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
const currentUnits = (await app.bus.getFirst('directions/getPreferredUnits')) || 'meters'; // can be 'meters' or 'yards'
|
|
341
|
-
|
|
342
|
-
return graphLoadedProm.then(async graph => {
|
|
187
|
+
const securityPois = Object.values(allPois).filter((poi) => poi.category && poi.category.startsWith("security"));
|
|
188
|
+
const currentUnits = await app.bus.getFirst("directions/getPreferredUnits") || "meters";
|
|
189
|
+
return graphLoadedProm.then(async (graph) => {
|
|
343
190
|
options.compareFindPaths = config.compareFindPaths;
|
|
344
191
|
const route = findRoute.findRoute(graph, fromEndpoint, toEndpoint, options);
|
|
345
192
|
if (!route) {
|
|
346
193
|
return null;
|
|
347
194
|
}
|
|
348
|
-
const floorIdToNameMap = await app.bus.get(
|
|
349
|
-
const queueTypes = await app.bus.get(
|
|
195
|
+
const floorIdToNameMap = await app.bus.get("venueData/getFloorIdToNameMap");
|
|
196
|
+
const queueTypes = await app.bus.get("venueData/getQueueTypes");
|
|
350
197
|
const translate = app.gt();
|
|
351
198
|
const isAccessible = options.requiresAccessibility;
|
|
352
199
|
const { steps, segments } = segmentBuilder.buildSegments(
|
|
@@ -358,130 +205,88 @@ function create(app, config) {
|
|
|
358
205
|
queueTypes,
|
|
359
206
|
isAccessible,
|
|
360
207
|
securityPois,
|
|
361
|
-
currentUnits
|
|
208
|
+
currentUnits
|
|
362
209
|
);
|
|
363
|
-
|
|
364
|
-
log.info('route', route);
|
|
210
|
+
log.info("route", route);
|
|
365
211
|
const time = Math.round(route.waypoints.reduce((total, { eta }) => total + eta, 0));
|
|
366
|
-
const distance = Math.round(route.waypoints.reduce((total, { distance }) => total +
|
|
367
|
-
|
|
212
|
+
const distance = Math.round(route.waypoints.reduce((total, { distance: distance2 }) => total + distance2, 0));
|
|
368
213
|
return { ...route, segments, steps, time, distance };
|
|
369
214
|
});
|
|
370
215
|
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Calculates transit time and distance of shortest path from each POI to start location which satisfies passed options
|
|
374
|
-
* and returns list of copies of POI with these new properties
|
|
375
|
-
*
|
|
376
|
-
* @param {Endpoint} startLocation
|
|
377
|
-
* @param {RouteOptions} options
|
|
378
|
-
* @param pois: array of pois
|
|
379
|
-
* @returns Array.<Object> - list of POIs
|
|
380
|
-
*/
|
|
381
|
-
app.bus.on('wayfinder/addPathTimeMultiple', async ({ pois, startLocation, options = {} }) => {
|
|
216
|
+
app.bus.on("wayfinder/addPathTimeMultiple", async ({ pois, startLocation, options = {} }) => {
|
|
382
217
|
if (!startLocation) {
|
|
383
218
|
return pois;
|
|
384
219
|
}
|
|
385
|
-
return graphLoadedProm.then(graph => addPathTimeMultiple(graph, options, pois, startLocation));
|
|
220
|
+
return graphLoadedProm.then((graph) => addPathTimeMultiple(graph, options, pois, startLocation));
|
|
386
221
|
});
|
|
387
|
-
|
|
388
222
|
function addPathTimeMultiple(graph, options, pois, start) {
|
|
389
223
|
try {
|
|
390
224
|
const poisList = R__namespace.clone(pois);
|
|
391
|
-
const poiLocations = poisList.map(poi => poiToNavigationEndpoint(poi, graph.floorIdToOrdinal));
|
|
392
|
-
|
|
225
|
+
const poiLocations = poisList.map((poi) => poiToNavigationEndpoint(poi, graph.floorIdToOrdinal));
|
|
393
226
|
const paths = graph.findAllShortestPaths(start, poiLocations, options);
|
|
394
|
-
const poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, paths[i], start,
|
|
395
|
-
|
|
227
|
+
const poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, paths[i], start, "start"));
|
|
396
228
|
return filterAndSort(poisWithPathProps);
|
|
397
229
|
} catch (e) {
|
|
398
230
|
log.error(e);
|
|
399
231
|
return pois;
|
|
400
232
|
}
|
|
401
233
|
}
|
|
402
|
-
|
|
403
234
|
function resolveAndAddPathProps(poi, path, endpoint, endpointType) {
|
|
404
235
|
let updatedPoi = R__namespace.clone(poi);
|
|
405
236
|
updatedPoi = addEndpointInformation(updatedPoi, endpoint, endpointType);
|
|
406
|
-
|
|
407
237
|
if (path && path.length) {
|
|
408
238
|
return {
|
|
409
239
|
...updatedPoi,
|
|
410
|
-
transitTime: calculateTotalPathProperty(path,
|
|
411
|
-
distance: calculateTotalPathProperty(path,
|
|
240
|
+
transitTime: calculateTotalPathProperty(path, "transitTime"),
|
|
241
|
+
distance: calculateTotalPathProperty(path, "distance")
|
|
412
242
|
};
|
|
413
243
|
} else {
|
|
414
|
-
updatedPoi.distance =
|
|
415
|
-
endpointType === 'start' ? getGeoDistance(updatedPoi, endpoint) : getGeoDistance(endpoint, updatedPoi);
|
|
244
|
+
updatedPoi.distance = endpointType === "start" ? getGeoDistance(updatedPoi, endpoint) : getGeoDistance(endpoint, updatedPoi);
|
|
416
245
|
updatedPoi.transitTime = getTransitTime(updatedPoi.distance);
|
|
417
246
|
return updatedPoi;
|
|
418
247
|
}
|
|
419
248
|
}
|
|
420
|
-
|
|
421
249
|
function calculateTotalPathProperty(path, propertyName) {
|
|
422
|
-
return R__namespace.aperture(2, path)
|
|
423
|
-
.map(([from, to]) => getEdgeTo(to.id)(from))
|
|
424
|
-
.map(R__namespace.prop(propertyName))
|
|
425
|
-
.reduce((totalTime, edgeTime) => totalTime + edgeTime, 0);
|
|
250
|
+
return R__namespace.aperture(2, path).map(([from, to]) => getEdgeTo(to.id)(from)).map(R__namespace.prop(propertyName)).reduce((totalTime, edgeTime) => totalTime + edgeTime, 0);
|
|
426
251
|
}
|
|
427
|
-
|
|
428
252
|
function addEndpointInformation(poi, endpoint, endpointType) {
|
|
429
253
|
return {
|
|
430
254
|
...poi,
|
|
431
|
-
[endpointType +
|
|
255
|
+
[endpointType + "Information"]: {
|
|
432
256
|
lat: endpoint?.lat || endpoint?.position?.latitude,
|
|
433
257
|
lng: endpoint?.lng || endpoint?.position?.longitude,
|
|
434
|
-
floorId: endpoint?.floorId || endpoint?.position?.floorId
|
|
435
|
-
}
|
|
258
|
+
floorId: endpoint?.floorId || endpoint?.position?.floorId
|
|
259
|
+
}
|
|
436
260
|
};
|
|
437
261
|
}
|
|
438
|
-
|
|
439
262
|
function getGeoDistance(endLocation, startLocation) {
|
|
440
263
|
return geodesy.distance(
|
|
441
264
|
startLocation?.lat || startLocation?.position?.latitude,
|
|
442
265
|
startLocation?.lng || startLocation?.position?.longitude,
|
|
443
266
|
endLocation?.lat || endLocation?.position?.latitude,
|
|
444
|
-
endLocation?.lng || endLocation?.position?.longitude
|
|
267
|
+
endLocation?.lng || endLocation?.position?.longitude
|
|
445
268
|
);
|
|
446
269
|
}
|
|
447
|
-
|
|
448
270
|
function getTransitTime(distance) {
|
|
449
271
|
return distance / DEFAULT_WALKING_SPEED_M_PER_MIN;
|
|
450
272
|
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Calculates transit time and distance of shortest path from the start location to each POI
|
|
454
|
-
* and calculates transit time and distance of shortest path from each POI to end location,
|
|
455
|
-
* where both calculates must satisfy the passed options,
|
|
456
|
-
* then adds the transit times and distances to create a total for each POI
|
|
457
|
-
* and returns list of copies of POI with these new properties
|
|
458
|
-
*
|
|
459
|
-
* @param {Poi} startLocation
|
|
460
|
-
* @param {Poi} endLocation
|
|
461
|
-
* @param {Endpoint} currentLocation
|
|
462
|
-
* @param {RouteOptions} options
|
|
463
|
-
* @param pois: array of pois
|
|
464
|
-
* @returns Array.<Object> - list of POIs
|
|
465
|
-
*/
|
|
466
273
|
app.bus.on(
|
|
467
|
-
|
|
274
|
+
"wayfinder/multipointAddPathTimeMultiple",
|
|
468
275
|
async ({ pois, startLocation, endLocation, currentLocation, options = {} }) => {
|
|
469
276
|
if (!startLocation && !endLocation && !currentLocation) {
|
|
470
277
|
return pois;
|
|
471
278
|
}
|
|
472
|
-
return graphLoadedProm.then(
|
|
473
|
-
multipointAddPathTimeMultiple(graph, options, pois, startLocation, endLocation, currentLocation)
|
|
279
|
+
return graphLoadedProm.then(
|
|
280
|
+
(graph) => multipointAddPathTimeMultiple(graph, options, pois, startLocation, endLocation, currentLocation)
|
|
474
281
|
);
|
|
475
|
-
}
|
|
282
|
+
}
|
|
476
283
|
);
|
|
477
|
-
|
|
478
284
|
function multipointAddPathTimeMultiple(graph, options, pois, startPoi, endPoi, currentLocation) {
|
|
479
285
|
try {
|
|
480
286
|
const start = startPoi ? poiToNavigationEndpoint(startPoi, graph.floorIdToOrdinal) : currentLocation;
|
|
481
287
|
const end = endPoi ? poiToNavigationEndpoint(endPoi, graph.floorIdToOrdinal) : null;
|
|
482
288
|
const poisList = R__namespace.clone(pois);
|
|
483
|
-
const poiLocations = poisList.map(poi => poiToNavigationEndpoint(poi, graph.floorIdToOrdinal));
|
|
484
|
-
|
|
289
|
+
const poiLocations = poisList.map((poi) => poiToNavigationEndpoint(poi, graph.floorIdToOrdinal));
|
|
485
290
|
let pathsPrimary, pathsSecondary;
|
|
486
291
|
if (start) {
|
|
487
292
|
pathsPrimary = graph.findAllShortestPaths(start, poiLocations, options);
|
|
@@ -489,46 +294,37 @@ function create(app, config) {
|
|
|
489
294
|
if (end) {
|
|
490
295
|
pathsSecondary = getAllSecondaryPaths(graph, poiLocations, end, options);
|
|
491
296
|
}
|
|
492
|
-
|
|
493
297
|
let poisWithPathProps;
|
|
494
298
|
if (start && end) {
|
|
495
|
-
poisWithPathProps = poisList.map(
|
|
496
|
-
resolveAndAddMultipointPathProps(poi, pathsPrimary[i], pathsSecondary[i], start, end)
|
|
299
|
+
poisWithPathProps = poisList.map(
|
|
300
|
+
(poi, i) => resolveAndAddMultipointPathProps(poi, pathsPrimary[i], pathsSecondary[i], start, end)
|
|
497
301
|
);
|
|
498
302
|
} else if (start) {
|
|
499
|
-
poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, pathsPrimary[i], start,
|
|
303
|
+
poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, pathsPrimary[i], start, "start"));
|
|
500
304
|
} else {
|
|
501
|
-
poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, pathsSecondary[i], end,
|
|
305
|
+
poisWithPathProps = poisList.map((poi, i) => resolveAndAddPathProps(poi, pathsSecondary[i], end, "end"));
|
|
502
306
|
}
|
|
503
|
-
|
|
504
307
|
return filterAndSort(poisWithPathProps);
|
|
505
308
|
} catch (e) {
|
|
506
309
|
log.error(e);
|
|
507
310
|
return pois;
|
|
508
311
|
}
|
|
509
312
|
}
|
|
510
|
-
|
|
511
313
|
function filterAndSort(pois) {
|
|
512
|
-
const poisWithPathProps = pois.filter(poi => poi !== null);
|
|
513
|
-
return R__namespace.sortBy(R__namespace.propOr(Infinity,
|
|
314
|
+
const poisWithPathProps = pois.filter((poi) => poi !== null);
|
|
315
|
+
return R__namespace.sortBy(R__namespace.propOr(Infinity, "transitTime"), poisWithPathProps);
|
|
514
316
|
}
|
|
515
|
-
|
|
516
317
|
function resolveAndAddMultipointPathProps(poi, pathPrimary, pathSecondary, startLocation, endLocation) {
|
|
517
318
|
const distancePrimary = resolvePathDistance(pathPrimary, startLocation, poi);
|
|
518
319
|
const distanceSecondary = resolvePathDistance(pathSecondary, poi, endLocation);
|
|
519
|
-
|
|
520
320
|
if (!distancePrimary || !distanceSecondary) {
|
|
521
321
|
return null;
|
|
522
|
-
}
|
|
523
|
-
|
|
322
|
+
}
|
|
524
323
|
const timePrimary = resolvePathTime(pathPrimary, distancePrimary);
|
|
525
324
|
const timeSecondary = resolvePathTime(pathSecondary, distanceSecondary);
|
|
526
|
-
|
|
527
|
-
// create deep copy of poi and add information on the start and end locations
|
|
528
325
|
let updatedPoi = R__namespace.clone(poi);
|
|
529
|
-
updatedPoi = addEndpointInformation(updatedPoi, startLocation,
|
|
530
|
-
updatedPoi = addEndpointInformation(updatedPoi, endLocation,
|
|
531
|
-
|
|
326
|
+
updatedPoi = addEndpointInformation(updatedPoi, startLocation, "start");
|
|
327
|
+
updatedPoi = addEndpointInformation(updatedPoi, endLocation, "end");
|
|
532
328
|
return {
|
|
533
329
|
...updatedPoi,
|
|
534
330
|
transitTime: timePrimary + timeSecondary,
|
|
@@ -536,16 +332,15 @@ function create(app, config) {
|
|
|
536
332
|
startInformation: {
|
|
537
333
|
...updatedPoi.startInformation,
|
|
538
334
|
transitTime: timePrimary,
|
|
539
|
-
distance: distancePrimary
|
|
335
|
+
distance: distancePrimary
|
|
540
336
|
},
|
|
541
337
|
endInformation: {
|
|
542
338
|
...updatedPoi.endInformation,
|
|
543
339
|
transitTime: timeSecondary,
|
|
544
|
-
distance: distanceSecondary
|
|
545
|
-
}
|
|
340
|
+
distance: distanceSecondary
|
|
341
|
+
}
|
|
546
342
|
};
|
|
547
343
|
}
|
|
548
|
-
|
|
549
344
|
function getAllSecondaryPaths(graph, poiLocations, endLocation, options) {
|
|
550
345
|
const pathsSecondary = [];
|
|
551
346
|
for (const pointAsStart of poiLocations) {
|
|
@@ -553,68 +348,29 @@ function create(app, config) {
|
|
|
553
348
|
}
|
|
554
349
|
return pathsSecondary;
|
|
555
350
|
}
|
|
556
|
-
|
|
557
351
|
function resolvePathTime(path, distance) {
|
|
558
|
-
return path && path.length ? calculateTotalPathProperty(path,
|
|
352
|
+
return path && path.length ? calculateTotalPathProperty(path, "transitTime") : getTransitTime(distance);
|
|
559
353
|
}
|
|
560
|
-
|
|
561
354
|
function resolvePathDistance(path, startLocation, endLocation) {
|
|
562
|
-
return path && path.length
|
|
563
|
-
? calculateTotalPathProperty(path, 'distance')
|
|
564
|
-
: getGeoDistance(endLocation, startLocation);
|
|
355
|
+
return path && path.length ? calculateTotalPathProperty(path, "distance") : getGeoDistance(endLocation, startLocation);
|
|
565
356
|
}
|
|
566
|
-
|
|
567
|
-
/**
|
|
568
|
-
* Resets plugin state
|
|
569
|
-
*/
|
|
570
|
-
app.bus.on('venueData/loadNewVenue', () => {
|
|
357
|
+
app.bus.on("venueData/loadNewVenue", () => {
|
|
571
358
|
graphLoadedProm = new Zousan();
|
|
572
359
|
init();
|
|
573
360
|
});
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
* Updates nav graph dynamic data if security data is passed
|
|
577
|
-
*
|
|
578
|
-
* @param {string} plugin - type of dynamic data
|
|
579
|
-
* @param {Object<string, SecurityWaitTime|Object>} - dictionary of POI id to dynamic data object
|
|
580
|
-
*/
|
|
581
|
-
app.bus.on('poi/setDynamicData', ({ plugin, idValuesMap }) => {
|
|
582
|
-
if (plugin !== 'security') {
|
|
361
|
+
app.bus.on("poi/setDynamicData", ({ plugin, idValuesMap }) => {
|
|
362
|
+
if (plugin !== "security") {
|
|
583
363
|
return;
|
|
584
364
|
}
|
|
585
|
-
graphLoadedProm.then(graph => graph.updateWithSecurityWaitTime(idValuesMap));
|
|
365
|
+
graphLoadedProm.then((graph) => graph.updateWithSecurityWaitTime(idValuesMap));
|
|
586
366
|
});
|
|
587
|
-
|
|
588
|
-
/**
|
|
589
|
-
* Returns a list of edges and nodes in a format convenient to display them on the map
|
|
590
|
-
*
|
|
591
|
-
* @typedef DebugNode
|
|
592
|
-
* @property {string} floorId
|
|
593
|
-
* @property {string} id
|
|
594
|
-
* @property {boolean} isOrphaned
|
|
595
|
-
* @property {number} lat
|
|
596
|
-
* @property {number} lng
|
|
597
|
-
* @property {number} ordinal
|
|
598
|
-
* @property {string} structureId
|
|
599
|
-
*
|
|
600
|
-
* @typedef DebugEdge
|
|
601
|
-
* @property {Coordinate} startCoordinates
|
|
602
|
-
* @property {Coordinate} endCoordinates
|
|
603
|
-
* @property {boolean} isDriveway
|
|
604
|
-
* @property {number} ordinal
|
|
605
|
-
* @property {string} category
|
|
606
|
-
* @property {string} defaultStrokeColor
|
|
607
|
-
*
|
|
608
|
-
* @returns {{nodes: DebugNode[], edges: DebugEdge[]}} debug nav graph
|
|
609
|
-
*/
|
|
610
|
-
app.bus.on('wayfinder/getNavGraphFeatures', () => graphLoadedProm.then(({ _nodes }) => navGraphDebug.enrichDebugNavGraph(_nodes)));
|
|
611
|
-
|
|
367
|
+
app.bus.on("wayfinder/getNavGraphFeatures", () => graphLoadedProm.then(({ _nodes }) => navGraphDebug.enrichDebugNavGraph(_nodes)));
|
|
612
368
|
return {
|
|
613
369
|
init,
|
|
614
370
|
internal: {
|
|
615
|
-
resolveNavGraph: graph => graphLoadedProm.resolve(graph),
|
|
616
|
-
prepareSecurityLanes
|
|
617
|
-
}
|
|
371
|
+
resolveNavGraph: (graph) => graphLoadedProm.resolve(graph),
|
|
372
|
+
prepareSecurityLanes
|
|
373
|
+
}
|
|
618
374
|
};
|
|
619
375
|
}
|
|
620
376
|
|