atriusmaps-node-sdk 3.3.721 → 3.3.723
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/deploy/prepareSDKConfig.js +40 -14
- package/dist/cjs/nodesdk/nodeEntry.js +14 -5
- package/dist/cjs/package.json.js +1 -1
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +14 -7
- package/dist/cjs/plugins/dynamicPois/src/processors.js +3 -1
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +55 -21
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +6 -2
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +19 -8
- package/dist/cjs/plugins/searchService/src/poiSearch.js +3 -2
- package/dist/cjs/plugins/searchService/src/searchService.js +6 -2
- package/dist/cjs/plugins/searchService/src/utils.js +3 -1
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +53 -21
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +17 -7
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +21 -7
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +56 -20
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +3 -1
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +75 -33
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +15 -5
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +47 -18
- package/dist/cjs/src/app.js +21 -8
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +15 -6
- package/dist/cjs/src/configs/postproc-stateTracking.js +8 -3
- package/dist/cjs/src/debugTools.js +8 -3
- package/dist/cjs/src/env.js +2 -1
- package/dist/cjs/src/extModules/bustle.js +40 -16
- package/dist/cjs/src/extModules/flexapi/src/validate.js +42 -18
- package/dist/cjs/src/extModules/log.js +16 -6
- package/dist/cjs/src/historyManager.js +3 -1
- package/dist/cjs/src/utils/configUtils.js +21 -8
- package/dist/cjs/src/utils/dom.js +19 -10
- package/dist/cjs/src/utils/funcs.js +8 -3
- package/dist/cjs/src/utils/geom.js +15 -5
- package/dist/cjs/src/utils/isInitialState.js +7 -3
- package/dist/cjs/src/utils/location.js +17 -8
- package/dist/cjs/src/utils/observable.js +17 -6
- package/dist/cjs/src/utils/rand.js +6 -2
- package/dist/package.json.js +1 -1
- package/dist/plugins/wayfinder/src/navGraph.js +1 -1
- package/dist/plugins/wayfinder/src/stepBuilder.js +1 -1
- package/package.json +1 -1
|
@@ -62,8 +62,7 @@ async function create(app, config) {
|
|
|
62
62
|
vConfig.assetStage !== 'prod' &&
|
|
63
63
|
location.hostname !== 'localhost' &&
|
|
64
64
|
USE_AUTH_WHEN_NOT_PROD_STAGE
|
|
65
|
-
)
|
|
66
|
-
;
|
|
65
|
+
) ;
|
|
67
66
|
|
|
68
67
|
const fetchJson = venueLoadingUtils.createFetchJson();
|
|
69
68
|
const fetchText = venueLoadingUtils.createFetchText();
|
|
@@ -81,14 +80,19 @@ async function create(app, config) {
|
|
|
81
80
|
`https://content.locuslabs.com/${venueData.category}/${contentType}/${venueId}/${accountId}`;
|
|
82
81
|
venueData.fetchJson = fetchJson;
|
|
83
82
|
venueData.fetchText = fetchText;
|
|
84
|
-
if (app.config.debug && app.env.isBrowser)
|
|
83
|
+
if (app.config.debug && app.env.isBrowser) {
|
|
84
|
+
window._venueData = venueData;
|
|
85
|
+
}
|
|
85
86
|
|
|
86
|
-
if (venueData.queueTypes)
|
|
87
|
+
if (venueData.queueTypes) {
|
|
87
88
|
venueData.securityQueueTypes = (() => {
|
|
88
89
|
const secLane = venueData.queueTypes.find(qt => qt.id === 'SecurityLane');
|
|
89
|
-
if (secLane)
|
|
90
|
+
if (secLane) {
|
|
91
|
+
return secLane.subtypes.map(t => t.id);
|
|
92
|
+
}
|
|
90
93
|
return [];
|
|
91
94
|
})();
|
|
95
|
+
}
|
|
92
96
|
|
|
93
97
|
app.bus.send('venueData/venueDataLoaded', { venueData });
|
|
94
98
|
|
|
@@ -104,11 +108,15 @@ async function create(app, config) {
|
|
|
104
108
|
|
|
105
109
|
function notifyState(venueData) {
|
|
106
110
|
const state = { id: 'venueDataLoader' };
|
|
107
|
-
if (venueData.id !== config.venueId)
|
|
111
|
+
if (venueData.id !== config.venueId) {
|
|
112
|
+
state.vid = venueData.id;
|
|
113
|
+
}
|
|
108
114
|
|
|
109
115
|
state.lang = app.i18n().language;
|
|
110
116
|
|
|
111
|
-
if (venueData.assetStage !== 'prod')
|
|
117
|
+
if (venueData.assetStage !== 'prod') {
|
|
118
|
+
state.stage = venueData.assetStage;
|
|
119
|
+
}
|
|
112
120
|
app.bus.send('deepLinking/notifyState', state);
|
|
113
121
|
return venueData;
|
|
114
122
|
}
|
|
@@ -116,8 +124,12 @@ async function create(app, config) {
|
|
|
116
124
|
app.bus.on('debugTools/fileDrop', async ({ file, content }) => {
|
|
117
125
|
if (file.type === 'application/json') {
|
|
118
126
|
const jsonOb = JSON.parse(content);
|
|
119
|
-
if (jsonOb.basemap && jsonOb['basemap.venue'])
|
|
120
|
-
|
|
127
|
+
if (jsonOb.basemap && jsonOb['basemap.venue']) {
|
|
128
|
+
return replaceTheme(JSON.parse(content));
|
|
129
|
+
} // looks like a theme!
|
|
130
|
+
if (jsonOb.metadata && jsonOb.metadata['mapbox:type']) {
|
|
131
|
+
return replaceStyle(content);
|
|
132
|
+
} // looks like a style!
|
|
121
133
|
}
|
|
122
134
|
});
|
|
123
135
|
|
|
@@ -131,7 +143,9 @@ async function create(app, config) {
|
|
|
131
143
|
|
|
132
144
|
function poiMapNameXForm(poi) {
|
|
133
145
|
let name = poi.name;
|
|
134
|
-
if (!config.poiMapNameXForm)
|
|
146
|
+
if (!config.poiMapNameXForm) {
|
|
147
|
+
return name;
|
|
148
|
+
} // no transforms for me today, thanks
|
|
135
149
|
Object.keys(config.poiMapNameXForm)
|
|
136
150
|
.filter(c2 => withinCategory(poi.category, c2))
|
|
137
151
|
.forEach(c2 => {
|
|
@@ -156,10 +170,14 @@ async function create(app, config) {
|
|
|
156
170
|
.filter(f => f.properties.aiLayer === 'poi' && f.geometry.type === 'Point')
|
|
157
171
|
.forEach(f => {
|
|
158
172
|
const poi = pois[f.properties.id];
|
|
159
|
-
if (!poi)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
if (!poi) {
|
|
174
|
+
log.warn(`Unknown poi in style: ${f.properties.id}`);
|
|
175
|
+
} else {
|
|
176
|
+
if (poi.mapLabel) {
|
|
177
|
+
f.properties.text = poi.mapLabel;
|
|
178
|
+
} else if (config.copyPOINamesToMap !== false) {
|
|
179
|
+
f.properties.text = poiMapNameXForm(poi);
|
|
180
|
+
}
|
|
163
181
|
}
|
|
164
182
|
}),
|
|
165
183
|
);
|
|
@@ -340,7 +358,9 @@ async function create(app, config) {
|
|
|
340
358
|
app.bus.on('venueData/getFloorIdName', ({ floorId }) => {
|
|
341
359
|
return venueDataLoaded.then(async venueData => {
|
|
342
360
|
const structure = R__namespace.pipe(R__namespace.values, R__namespace.find(R__namespace.hasPath(['levels', floorId])))(venueData.structures);
|
|
343
|
-
if (!structure)
|
|
361
|
+
if (!structure) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
344
364
|
return {
|
|
345
365
|
structureId: structure.id,
|
|
346
366
|
structureName: structure.name,
|
|
@@ -422,7 +442,9 @@ async function create(app, config) {
|
|
|
422
442
|
function getTranslatedFloorId(floorId, venueData) {
|
|
423
443
|
const allFloorIds = getAllFloorIds(venueData);
|
|
424
444
|
|
|
425
|
-
if (allFloorIds.includes(floorId))
|
|
445
|
+
if (allFloorIds.includes(floorId)) {
|
|
446
|
+
return floorId;
|
|
447
|
+
} // already in this venue
|
|
426
448
|
|
|
427
449
|
const buildingLevel = floorId.split('-').slice(1).join('-'); // get the building-level part of the floorId
|
|
428
450
|
|
|
@@ -463,7 +485,9 @@ async function create(app, config) {
|
|
|
463
485
|
obj[id] = typesWithImages;
|
|
464
486
|
return obj;
|
|
465
487
|
}, {});
|
|
466
|
-
} else
|
|
488
|
+
} else {
|
|
489
|
+
return {};
|
|
490
|
+
}
|
|
467
491
|
});
|
|
468
492
|
});
|
|
469
493
|
|
|
@@ -472,13 +496,19 @@ async function create(app, config) {
|
|
|
472
496
|
venueDataLoaded = new Zousan();
|
|
473
497
|
mapDataLoaded = new Zousan();
|
|
474
498
|
}
|
|
475
|
-
if (venueData)
|
|
499
|
+
if (venueData) {
|
|
500
|
+
venueDataLoaded = Zousan.resolve(venueData);
|
|
501
|
+
}
|
|
476
502
|
|
|
477
503
|
await testRoutine();
|
|
478
504
|
|
|
479
505
|
let venueDataObj, mapDataObj;
|
|
480
|
-
if (venueDataLoaded.v)
|
|
481
|
-
|
|
506
|
+
if (venueDataLoaded.v) {
|
|
507
|
+
venueDataObj = await venueDataLoaded;
|
|
508
|
+
}
|
|
509
|
+
if (mapDataLoaded.v) {
|
|
510
|
+
mapDataObj = await mapDataLoaded;
|
|
511
|
+
}
|
|
482
512
|
return { venueDataObj, mapDataObj };
|
|
483
513
|
};
|
|
484
514
|
|
|
@@ -492,7 +522,9 @@ async function create(app, config) {
|
|
|
492
522
|
languagesToTry = typeof window === 'undefined' ? [] : navigator.languages; // grab languages to use for alternate maps from the browser's list of preffered languages
|
|
493
523
|
}
|
|
494
524
|
const deepLinkProps = config.deepLinkProps || {};
|
|
495
|
-
if (deepLinkProps.lang)
|
|
525
|
+
if (deepLinkProps.lang) {
|
|
526
|
+
languagesToTry.unshift(deepLinkProps.lang);
|
|
527
|
+
}
|
|
496
528
|
const venueId = deepLinkProps.vid || config.venueId;
|
|
497
529
|
const assetStage = config.useDynamicUrlParams && deepLinkProps.stage ? deepLinkProps.stage : config.assetStage;
|
|
498
530
|
const accountId = deepLinkProps.accountId || (assetStage === 'alpha' ? 'A1VPTJKREFJWX5' : config.accountId);
|
|
@@ -24,7 +24,9 @@ function _interopNamespaceDefault(e) {
|
|
|
24
24
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
25
25
|
|
|
26
26
|
const fetchURL = async (token, url) => {
|
|
27
|
-
|
|
27
|
+
{
|
|
28
|
+
return fetch(url);
|
|
29
|
+
}
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
const createFetchJson = token => url => fetchURL(token, url).then(response => response.json());
|
|
@@ -79,8 +81,9 @@ const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => {
|
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
if (!venueList[venueId])
|
|
84
|
+
if (!venueList[venueId]) {
|
|
83
85
|
throw Error(`Attempt to access venue ${venueId} which is not within venue list: ${Object.keys(venueList)}`);
|
|
86
|
+
}
|
|
84
87
|
const files = venueList[venueId].files; // mapping of asset "types" (spritesheet, style, badges, etc) to their URL
|
|
85
88
|
const fetchedData =
|
|
86
89
|
vconfig.dataFetch && configUtils.global[vconfig.dataFetch] && configUtils.global[vconfig.dataFetch].getVenueData
|
|
@@ -90,7 +93,9 @@ const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => {
|
|
|
90
93
|
const venueData = fetchedData[venueId];
|
|
91
94
|
|
|
92
95
|
// For tilemaps, we need to embellish the venue data with structure
|
|
93
|
-
if (venueData.tileServerAuthInfo)
|
|
96
|
+
if (venueData.tileServerAuthInfo) {
|
|
97
|
+
embellishTilemapVenueData(venueData);
|
|
98
|
+
}
|
|
94
99
|
|
|
95
100
|
venueData.venueList = venueList;
|
|
96
101
|
const contentStage = getContentStage(vconfig);
|
|
@@ -142,7 +147,9 @@ function embellishTilemapVenueData(venueData) {
|
|
|
142
147
|
structureOrder: ['singleBuilding'],
|
|
143
148
|
};
|
|
144
149
|
|
|
145
|
-
for (const key in additionalFields)
|
|
150
|
+
for (const key in additionalFields) {
|
|
151
|
+
venueData[key] = additionalFields[key];
|
|
152
|
+
}
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
const between = (val, lim1, lim2) => (val > lim1 ? val <= lim2 : val => lim2);
|
|
@@ -161,11 +168,14 @@ const swapFirstTwoItems = ([c1, c2, ...c3]) => [c2, c1, ...c3];
|
|
|
161
168
|
* @returns {array.array.float} with [lng,lat,...] for each item
|
|
162
169
|
*/
|
|
163
170
|
const normalizeCoords = (coords, venueBounds) => {
|
|
164
|
-
if (!coords || !Array.isArray(coords) || coords.length < 1)
|
|
171
|
+
if (!coords || !Array.isArray(coords) || coords.length < 1) {
|
|
172
|
+
return coords;
|
|
173
|
+
}
|
|
165
174
|
|
|
166
|
-
if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng))
|
|
167
|
-
|
|
175
|
+
if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng)) // looks like a lat - so already in proper order
|
|
176
|
+
{
|
|
168
177
|
return coords;
|
|
178
|
+
}
|
|
169
179
|
|
|
170
180
|
// wrong order, so swtich em
|
|
171
181
|
return coords.map(swapFirstTwoItems);
|
|
@@ -34,7 +34,9 @@ const getEdgeTo = dst => node => R__namespace.find(e => e.dst === dst, node.edge
|
|
|
34
34
|
* @throws if start or end is not defined
|
|
35
35
|
*/
|
|
36
36
|
const calculateRoute = (graph, start, end, options) => {
|
|
37
|
-
if (!start || !end)
|
|
37
|
+
if (!start || !end) {
|
|
38
|
+
throw Error('bad calculate Route request!');
|
|
39
|
+
}
|
|
38
40
|
return graph.findShortestPath(start, end, options);
|
|
39
41
|
};
|
|
40
42
|
|
|
@@ -90,7 +92,9 @@ const findRoute = (graph, start, destination, options = {}) => {
|
|
|
90
92
|
|
|
91
93
|
const routeNodes = calculateRoute(graph, start, destination, options);
|
|
92
94
|
|
|
93
|
-
if (routeNodes === null)
|
|
95
|
+
if (routeNodes === null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
94
98
|
|
|
95
99
|
let previousRouteNode = null;
|
|
96
100
|
for (let i = 0; i < routeNodes.length; i++) {
|
|
@@ -110,9 +114,13 @@ const findRoute = (graph, start, destination, options = {}) => {
|
|
|
110
114
|
waypoint.isPortal = true;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
if (edgeUsed.o)
|
|
117
|
+
if (edgeUsed.o) {
|
|
118
|
+
waypoint.poiId = edgeUsed.o;
|
|
119
|
+
}
|
|
114
120
|
|
|
115
|
-
if (edgeUsed.path)
|
|
121
|
+
if (edgeUsed.path) {
|
|
122
|
+
waypoint.curvedPathForward = edgeUsed.path;
|
|
123
|
+
}
|
|
116
124
|
if (edgeUsed.securityWaitTimes) {
|
|
117
125
|
waypoint.securityWaitTimes = edgeUsed.securityWaitTimes;
|
|
118
126
|
waypoint.eta = waypoint.securityWaitTimes.queueTime;
|
|
@@ -121,9 +129,15 @@ const findRoute = (graph, start, destination, options = {}) => {
|
|
|
121
129
|
if (edgeUsed.securityLane) {
|
|
122
130
|
waypoint.securityLane = edgeUsed.securityLane;
|
|
123
131
|
waypoint.isSecurityCheckpoint = true;
|
|
124
|
-
if (edgeUsed.securityLane.type === wayfinder.SecurityLaneType.SECURITY)
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
if (edgeUsed.securityLane.type === wayfinder.SecurityLaneType.SECURITY) {
|
|
133
|
+
hasSecurity = true;
|
|
134
|
+
}
|
|
135
|
+
if (edgeUsed.securityLane.type === wayfinder.SecurityLaneType.IMMIGRATION) {
|
|
136
|
+
hasImmigration = true;
|
|
137
|
+
}
|
|
138
|
+
if (edgeUsed.o) {
|
|
139
|
+
queues.push(edgeUsed.o);
|
|
140
|
+
}
|
|
127
141
|
}
|
|
128
142
|
}
|
|
129
143
|
}
|
|
@@ -61,11 +61,15 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
|
|
|
61
61
|
const largeGeo = node.floorId + ':' + geohasher.encode(node.lat, node.lng).substr(0, 7);
|
|
62
62
|
const mediumGeo = node.floorId + ':' + geohasher.encode(node.lat, node.lng).substr(0, 8);
|
|
63
63
|
|
|
64
|
-
if (!geoDb[largeGeo])
|
|
64
|
+
if (!geoDb[largeGeo]) {
|
|
65
|
+
geoDb[largeGeo] = [];
|
|
66
|
+
}
|
|
65
67
|
|
|
66
68
|
geoDb[largeGeo].push(node);
|
|
67
69
|
|
|
68
|
-
if (!geoDb[mediumGeo])
|
|
70
|
+
if (!geoDb[mediumGeo]) {
|
|
71
|
+
geoDb[mediumGeo] = [];
|
|
72
|
+
}
|
|
69
73
|
|
|
70
74
|
geoDb[mediumGeo].push(node);
|
|
71
75
|
|
|
@@ -108,15 +112,20 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
function getEdgeType(data) {
|
|
111
|
-
if (data.x)
|
|
112
|
-
|
|
115
|
+
if (data.x) {
|
|
116
|
+
return 'Security Checkpoint';
|
|
117
|
+
}
|
|
118
|
+
if (data.t === '') {
|
|
119
|
+
return 'Ground';
|
|
120
|
+
}
|
|
113
121
|
return data.t;
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
const findClosestNode = endpoint => {
|
|
117
|
-
if (endpoint.floorId === undefined && endpoint.ordinal === undefined)
|
|
118
|
-
|
|
125
|
+
if (endpoint.floorId === undefined && endpoint.ordinal === undefined) // one of these must be present
|
|
126
|
+
{
|
|
119
127
|
throw Error('Endpoint specified in findRoute without floorId nor an ordinal');
|
|
128
|
+
}
|
|
120
129
|
const lat = endpoint.lat || endpoint.latitude; // handle bluedot location
|
|
121
130
|
const lng = endpoint.lng || endpoint.longitude; // handle bluedot location
|
|
122
131
|
return endpoint.floorId
|
|
@@ -156,7 +165,9 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
|
|
|
156
165
|
function findAllShortestPaths(start, destArray, options) {
|
|
157
166
|
const startNode = findClosestNode(start);
|
|
158
167
|
const destNodeArray = destArray.map(dest => findClosestNode(dest));
|
|
159
|
-
if (!startNode || !destNodeArray.length)
|
|
168
|
+
if (!startNode || !destNodeArray.length) {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
160
171
|
return findAllShortestPathsImpl(
|
|
161
172
|
startNode,
|
|
162
173
|
destNodeArray,
|
|
@@ -284,7 +295,9 @@ function findShortestPath(
|
|
|
284
295
|
if (nodesToAvoid.size > 0 && nodesToAvoid.has(e.dst)) {
|
|
285
296
|
continue;
|
|
286
297
|
}
|
|
287
|
-
if (visited[e.dst])
|
|
298
|
+
if (visited[e.dst]) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
288
301
|
|
|
289
302
|
if (options.requiresAccessibility && !e.isAccessible) {
|
|
290
303
|
// ignore not accessible edges if we're looking for an accessible route
|
|
@@ -301,8 +314,12 @@ function findShortestPath(
|
|
|
301
314
|
let weight = e.weight;
|
|
302
315
|
if (e.o && securityWaitTimes[e.o]) {
|
|
303
316
|
const dynamicData = securityWaitTimes[e.o];
|
|
304
|
-
if (dynamicData.queueTime)
|
|
305
|
-
|
|
317
|
+
if (dynamicData.queueTime) {
|
|
318
|
+
weight = dynamicData.queueTime;
|
|
319
|
+
}
|
|
320
|
+
if (dynamicData.isTemporarilyClosed) {
|
|
321
|
+
weight = CLOSED_CHECKPOINT_EDGE_WEIGHT;
|
|
322
|
+
}
|
|
306
323
|
e.securityWaitTimes = dynamicData;
|
|
307
324
|
}
|
|
308
325
|
|
|
@@ -310,7 +327,9 @@ function findShortestPath(
|
|
|
310
327
|
e.securityLane = securityLanesMap[e.o];
|
|
311
328
|
const { type, id } = securityLanesMap[e.o];
|
|
312
329
|
const securityLanesIds = R.path(['selectedSecurityLanes', type], options);
|
|
313
|
-
if (securityLanesIds && !securityLanesIds.includes(id))
|
|
330
|
+
if (securityLanesIds && !securityLanesIds.includes(id)) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
314
333
|
}
|
|
315
334
|
|
|
316
335
|
if (cost[e.dst] === undefined) {
|
|
@@ -328,9 +347,10 @@ function findShortestPath(
|
|
|
328
347
|
visited[node.id] = true; // we have now been selected
|
|
329
348
|
}
|
|
330
349
|
|
|
331
|
-
if (!visited[end.id])
|
|
332
|
-
|
|
350
|
+
if (!visited[end.id]) // if we never found our endpoint, it was inaccessible
|
|
351
|
+
{
|
|
333
352
|
return null;
|
|
353
|
+
}
|
|
334
354
|
|
|
335
355
|
// build the path and return it
|
|
336
356
|
const path = [];
|
|
@@ -360,7 +380,9 @@ function geohashSearch(floorId, geohash, geoDb, size) {
|
|
|
360
380
|
for (let i = 0; i < searchGeos.length; i++) {
|
|
361
381
|
const nodesFound = geoDb[searchGeos[i]];
|
|
362
382
|
if (nodesFound) {
|
|
363
|
-
for (let j = 0; j < nodesFound.length; j++)
|
|
383
|
+
for (let j = 0; j < nodesFound.length; j++) {
|
|
384
|
+
nodes.push(nodesFound[j]);
|
|
385
|
+
}
|
|
364
386
|
}
|
|
365
387
|
}
|
|
366
388
|
|
|
@@ -369,11 +391,15 @@ function geohashSearch(floorId, geohash, geoDb, size) {
|
|
|
369
391
|
|
|
370
392
|
function findNodesByGeohash(floorId, geohash, geoDb, nodes) {
|
|
371
393
|
let foundNodes = geohashSearch(floorId, geohash, geoDb, 8);
|
|
372
|
-
if (foundNodes.length > 0)
|
|
394
|
+
if (foundNodes.length > 0) {
|
|
395
|
+
return foundNodes;
|
|
396
|
+
}
|
|
373
397
|
|
|
374
398
|
// broaden our search a bit and try again...
|
|
375
399
|
foundNodes = geohashSearch(floorId, geohash, geoDb, 7);
|
|
376
|
-
if (foundNodes.length > 0)
|
|
400
|
+
if (foundNodes.length > 0) {
|
|
401
|
+
return foundNodes;
|
|
402
|
+
}
|
|
377
403
|
|
|
378
404
|
// give up and let someone else try...
|
|
379
405
|
return null;
|
|
@@ -403,7 +429,9 @@ function findClosestNodeByFloor(floorId, lat, lng, geoDb, nodes) {
|
|
|
403
429
|
return a[1] - b[1];
|
|
404
430
|
});
|
|
405
431
|
const nodesSortedByDistance = [];
|
|
406
|
-
for (let i = 0; i < nodeWithDistance.length; i++)
|
|
432
|
+
for (let i = 0; i < nodeWithDistance.length; i++) {
|
|
433
|
+
nodesSortedByDistance.push(nodeWithDistance[i][0]);
|
|
434
|
+
}
|
|
407
435
|
|
|
408
436
|
return nodesSortedByDistance[0];
|
|
409
437
|
}
|
|
@@ -413,7 +441,9 @@ function findClosestNodeByFloor2(floorId, lat, lng, nodes) {
|
|
|
413
441
|
const floorNodes = Object.values(nodes)
|
|
414
442
|
.filter(n => n.floorId === floorId)
|
|
415
443
|
.map(n => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
416
|
-
if (!floorNodes.length)
|
|
444
|
+
if (!floorNodes.length) {
|
|
445
|
+
throw Error(`findClosestNodeByFloor2 found no nodes on floor ${floorId}`);
|
|
446
|
+
}
|
|
417
447
|
return selectShortest(floorNodes);
|
|
418
448
|
}
|
|
419
449
|
|
|
@@ -421,7 +451,9 @@ function findClosestNodeByOrdinal(ord, lat, lng, nodes) {
|
|
|
421
451
|
const ordNodes = Object.values(nodes)
|
|
422
452
|
.filter(n => n.ordinal === ord)
|
|
423
453
|
.map(n => [n, geodesy.distance(n.lat, n.lng, lat, lng)]);
|
|
424
|
-
if (!ordNodes.length)
|
|
454
|
+
if (!ordNodes.length) {
|
|
455
|
+
throw Error(`findClosestNodeByOrdinal found no nodes on ordinal ${ord}`);
|
|
456
|
+
}
|
|
425
457
|
return selectShortest(ordNodes);
|
|
426
458
|
}
|
|
427
459
|
|
|
@@ -430,7 +462,11 @@ function findClosestNodeByOrdinal(ord, lat, lng, nodes) {
|
|
|
430
462
|
// TODO: use this approach in findClosestNode - no need to sort first!
|
|
431
463
|
function selectShortest(ar) {
|
|
432
464
|
let shortest = ar[0];
|
|
433
|
-
for (let i = 1; i < ar.length; i++)
|
|
465
|
+
for (let i = 1; i < ar.length; i++) {
|
|
466
|
+
if (ar[i][1] < shortest[1]) {
|
|
467
|
+
shortest = ar[i];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
434
470
|
|
|
435
471
|
return shortest[0];
|
|
436
472
|
}
|
|
@@ -40,7 +40,9 @@ function visitAll(nodes, startingNode) {
|
|
|
40
40
|
if (node && !vnodes.has(node)) {
|
|
41
41
|
vnodes.add(node);
|
|
42
42
|
node.edges.forEach(edge => {
|
|
43
|
-
if (!vnodes.has(nodes[edge.dst]))
|
|
43
|
+
if (!vnodes.has(nodes[edge.dst])) {
|
|
44
|
+
nodes2visit.push(nodes[edge.dst]);
|
|
45
|
+
}
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -28,35 +28,61 @@ const setSegmentCategory = segments => {
|
|
|
28
28
|
// Set the category of each segment based on the type of the current segment or the type of the next segment in case we are walking
|
|
29
29
|
// to a portal or to a security checkpoint
|
|
30
30
|
segments.forEach((segment, index) => {
|
|
31
|
-
if (index === 0)
|
|
32
|
-
|
|
31
|
+
if (index === 0) {
|
|
32
|
+
segment.segmentCategory = segmentCategories.START;
|
|
33
|
+
} else if (segment.waypoints[segment.waypoints.length - 1].isDestination) {
|
|
33
34
|
segment.segmentCategory = segmentCategories.WALKING_TO_END;
|
|
34
|
-
else if (segment.type === 'Security Checkpoint')
|
|
35
|
-
|
|
36
|
-
else if (segment.type === '
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
} else if (segment.type === 'Security Checkpoint') {
|
|
36
|
+
segment.segmentCategory = segmentCategories.SECURITY_CHECKPOINT;
|
|
37
|
+
} else if (segment.type === 'Bus') {
|
|
38
|
+
segment.segmentCategory = segmentCategories.BUS;
|
|
39
|
+
} else if (segment.type === 'Train') {
|
|
40
|
+
segment.segmentCategory = segmentCategories.TRAIN;
|
|
41
|
+
} else if (segment.type === 'Stairs') {
|
|
42
|
+
if (segment.levelDifference > 0) {
|
|
43
|
+
segment.segmentCategory = segmentCategories.STAIRS_UP;
|
|
44
|
+
} else if (segment.levelDifference < 0) {
|
|
45
|
+
segment.segmentCategory = segmentCategories.STAIRS_DOWN;
|
|
46
|
+
} else {
|
|
47
|
+
segment.segmentCategory = segmentCategories.STAIRS;
|
|
48
|
+
}
|
|
41
49
|
} else if (segment.type === 'AccessibleStairs') {
|
|
42
|
-
if (segment.levelDifference > 0)
|
|
43
|
-
|
|
44
|
-
else segment.
|
|
50
|
+
if (segment.levelDifference > 0) {
|
|
51
|
+
segment.segmentCategory = segmentCategories.ACCESSIBLE_STAIRS_UP;
|
|
52
|
+
} else if (segment.levelDifference < 0) {
|
|
53
|
+
segment.segmentCategory = segmentCategories.ACCESSIBLE_STAIRS_DOWN;
|
|
54
|
+
} else {
|
|
55
|
+
segment.segmentCategory = segmentCategories.ACCESSIBLE_STAIRS;
|
|
56
|
+
}
|
|
45
57
|
} else if (segment.type === 'Elevator') {
|
|
46
|
-
if (segment.levelDifference > 0)
|
|
47
|
-
|
|
48
|
-
else segment.
|
|
58
|
+
if (segment.levelDifference > 0) {
|
|
59
|
+
segment.segmentCategory = segmentCategories.ELEVATOR_UP;
|
|
60
|
+
} else if (segment.levelDifference < 0) {
|
|
61
|
+
segment.segmentCategory = segmentCategories.ELEVATOR_DOWN;
|
|
62
|
+
} else {
|
|
63
|
+
segment.segmentCategory = segmentCategories.ELEVATOR;
|
|
64
|
+
}
|
|
49
65
|
} else if (segment.type === 'Escalator') {
|
|
50
|
-
if (segment.levelDifference > 0)
|
|
51
|
-
|
|
52
|
-
else segment.
|
|
66
|
+
if (segment.levelDifference > 0) {
|
|
67
|
+
segment.segmentCategory = segmentCategories.ESCALATOR_UP;
|
|
68
|
+
} else if (segment.levelDifference < 0) {
|
|
69
|
+
segment.segmentCategory = segmentCategories.ESCALATOR_DOWN;
|
|
70
|
+
} else {
|
|
71
|
+
segment.segmentCategory = segmentCategories.ESCALATOR;
|
|
72
|
+
}
|
|
53
73
|
} else if (segment.type === 'Ramp') {
|
|
54
|
-
if (segment.levelDifference > 0)
|
|
55
|
-
|
|
56
|
-
else segment.
|
|
57
|
-
|
|
74
|
+
if (segment.levelDifference > 0) {
|
|
75
|
+
segment.segmentCategory = segmentCategories.RAMP_UP;
|
|
76
|
+
} else if (segment.levelDifference < 0) {
|
|
77
|
+
segment.segmentCategory = segmentCategories.RAMP_DOWN;
|
|
78
|
+
} else {
|
|
79
|
+
segment.segmentCategory = segmentCategories.RAMP;
|
|
80
|
+
}
|
|
81
|
+
} else if (segments[index + 1].type === 'Security Checkpoint') {
|
|
58
82
|
segment.segmentCategory = segmentCategories.WALKING_TO_SECURITY_CHECKPOINT;
|
|
59
|
-
else if (segments[index + 1].type !== 'Walk')
|
|
83
|
+
} else if (segments[index + 1].type !== 'Walk') {
|
|
84
|
+
segment.segmentCategory = segmentCategories.WALKING_TO_PORTAL;
|
|
85
|
+
}
|
|
60
86
|
});
|
|
61
87
|
};
|
|
62
88
|
|
|
@@ -132,18 +158,26 @@ const createSegments = waypoints => {
|
|
|
132
158
|
segment.waypoints = segmentWaypoints;
|
|
133
159
|
|
|
134
160
|
if (waypoint.isPortal || lastWaypoint.isPortal) {
|
|
135
|
-
if (segmentWaypoints.length > 1)
|
|
161
|
+
if (segmentWaypoints.length > 1) {
|
|
162
|
+
segmentWaypoints.pop();
|
|
163
|
+
}
|
|
136
164
|
|
|
137
165
|
// if the portal is not train or bus, we only want it to be one point segment
|
|
138
166
|
if (
|
|
139
167
|
waypoint.isPortal &&
|
|
140
168
|
(waypoint.portalType.toLowerCase() === 'train' || waypoint.portalType.toLowerCase() === 'bus')
|
|
141
|
-
)
|
|
169
|
+
) {
|
|
142
170
|
segmentWaypoints = [segmentWaypoints[segmentWaypoints.length - 1], waypoint];
|
|
143
|
-
else
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
171
|
+
} else {
|
|
172
|
+
segmentWaypoints = [waypoint];
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
segmentWaypoints = [];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (lastWaypoint.poiId) {
|
|
179
|
+
segment.poiId = lastWaypoint.poiId;
|
|
180
|
+
}
|
|
147
181
|
segments.push(segment);
|
|
148
182
|
|
|
149
183
|
segment = { segmentCategory: undefined, waypoints: [] };
|
|
@@ -158,7 +192,9 @@ const createSegments = waypoints => {
|
|
|
158
192
|
|
|
159
193
|
segment.waypoints = segmentWaypoints;
|
|
160
194
|
|
|
161
|
-
if (segmentWaypoints.length === 0)
|
|
195
|
+
if (segmentWaypoints.length === 0) {
|
|
196
|
+
segment.waypoints = [lastWaypoint];
|
|
197
|
+
}
|
|
162
198
|
|
|
163
199
|
segments.push(segment);
|
|
164
200
|
|
|
@@ -222,9 +258,13 @@ const buildSegments = (
|
|
|
222
258
|
rawSegments = addCurveLineCoordinates(rawSegments);
|
|
223
259
|
|
|
224
260
|
// add start location (kiosk) as first coordinate to link it with the navline
|
|
225
|
-
if (fromEndpoint)
|
|
261
|
+
if (fromEndpoint) {
|
|
262
|
+
rawSegments[0].coordinates.unshift([fromEndpoint.lng, fromEndpoint.lat]);
|
|
263
|
+
}
|
|
226
264
|
|
|
227
|
-
if (toEndpoint)
|
|
265
|
+
if (toEndpoint) {
|
|
266
|
+
R__namespace.last(rawSegments).coordinates.push([toEndpoint.lng, toEndpoint.lat]);
|
|
267
|
+
}
|
|
228
268
|
|
|
229
269
|
const segments = rawSegments.map((segment, index) => {
|
|
230
270
|
const startWaypoint = R__namespace.last(segment.waypoints);
|
|
@@ -252,7 +292,9 @@ const buildSegments = (
|
|
|
252
292
|
}
|
|
253
293
|
cookedSegment.badges = badges;
|
|
254
294
|
cookedSegment.segmentType = getSegmentType(segment);
|
|
255
|
-
if (segment.poiId)
|
|
295
|
+
if (segment.poiId) {
|
|
296
|
+
cookedSegment.poiId = segment.poiId;
|
|
297
|
+
}
|
|
256
298
|
return cookedSegment;
|
|
257
299
|
});
|
|
258
300
|
|
|
@@ -107,14 +107,18 @@ function getSteps(
|
|
|
107
107
|
securityWaitTimes,
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
-
if (segment.poiId)
|
|
110
|
+
if (segment.poiId) {
|
|
111
|
+
step.poiId = segment.poiId;
|
|
112
|
+
}
|
|
111
113
|
|
|
112
114
|
return step;
|
|
113
115
|
});
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
function calculateSegmentEta(waypoints) {
|
|
117
|
-
if (waypoints.length === 1)
|
|
119
|
+
if (waypoints.length === 1) {
|
|
120
|
+
return waypoints[0].eta;
|
|
121
|
+
} // for stairs/elevator segments. should be removed once segment builder will be refactored to not append waypoint from previous semgnent
|
|
118
122
|
return waypoints
|
|
119
123
|
.map(R.prop('eta'))
|
|
120
124
|
.slice(1) // first waypoint is end of previous segment and is added only to connect segments for navline calculation
|
|
@@ -122,7 +126,9 @@ function calculateSegmentEta(waypoints) {
|
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
function calculateSegmentDistance(waypoints) {
|
|
125
|
-
if (waypoints.length === 1)
|
|
129
|
+
if (waypoints.length === 1) {
|
|
130
|
+
return waypoints[0].distance;
|
|
131
|
+
} // for stairs/elevator segments. should be removed once segment builder will be refactored to not append waypoint from previous semgnent
|
|
126
132
|
return waypoints
|
|
127
133
|
.map(waypoint => waypoint.distance)
|
|
128
134
|
.slice(1) // first waypoint is end of previous segment and is added only to connect segments for navline calculation
|
|
@@ -358,7 +364,9 @@ const checkIfAccessible = R.compose(R.not, R.includes(R.__, ['escalator', 'stair
|
|
|
358
364
|
|
|
359
365
|
const getSecurityLaneName = (queueTypes, waypoints) => {
|
|
360
366
|
const lane = findPropWaypoints('securityLane')(waypoints);
|
|
361
|
-
if (!lane)
|
|
367
|
+
if (!lane) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
362
370
|
const types = R.prop(lane.type, queueTypes);
|
|
363
371
|
const laneType = R.find(R.propEq(lane.id, 'id'), types);
|
|
364
372
|
return R.prop('displayText', laneType);
|
|
@@ -376,7 +384,9 @@ const findPropWaypoints = propName => R.compose(R.prop(propName), R.find(R.prop(
|
|
|
376
384
|
* @returns {string|null} - The name of the closest security POI, or null if none found.
|
|
377
385
|
*/
|
|
378
386
|
const getClosestSecurityPoiTitle = (waypoints, securityPois) => {
|
|
379
|
-
if (!waypoints || waypoints.length === 0)
|
|
387
|
+
if (!waypoints || waypoints.length === 0) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
380
390
|
|
|
381
391
|
const checkpointWaypoint = waypoints[0];
|
|
382
392
|
const { lat, lng, floorId } = checkpointWaypoint.position;
|