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
|
@@ -27,98 +27,65 @@ const fetchURL = async (token, url) => {
|
|
|
27
27
|
return fetch(url);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const baseContentUrl = contentStage => `https://api.content.locuslabs.com/${contentStage}`;
|
|
35
|
-
|
|
30
|
+
const createFetchJson = (token) => (url) => fetchURL(token, url).then((response) => response.json());
|
|
31
|
+
const createFetchText = (token) => (url) => fetchURL(token, url).then((response) => response.text());
|
|
32
|
+
const baseContentUrl = (contentStage) => `https://api.content.locuslabs.com/${contentStage}`;
|
|
36
33
|
const remapContentUrl = (url, category, contentStage, accountId, venueId, key) => {
|
|
37
|
-
if (key ===
|
|
34
|
+
if (key === "theme" || key === "style") {
|
|
38
35
|
return `${baseContentUrl(contentStage)}/${category}/${key}/${venueId}/${accountId}/${key}.json`;
|
|
39
36
|
}
|
|
40
37
|
return url.replace(/https:\/\/content.locuslabs.com/gi, baseContentUrl(contentStage));
|
|
41
38
|
};
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
R__namespace.mapObjIndexed((file, key) => remapContentUrl(file, category, contentStage, accountId, venueId, key), files);
|
|
45
|
-
|
|
46
|
-
const getContentStage = vconfig => {
|
|
39
|
+
const remapEachURLForContentStage = (category, files, contentStage, accountId, venueId) => R__namespace.mapObjIndexed((file, key) => remapContentUrl(file, category, contentStage, accountId, venueId, key), files);
|
|
40
|
+
const getContentStage = (vconfig) => {
|
|
47
41
|
const stage = vconfig.deepLinkProps ? vconfig.deepLinkProps.contentStage : null;
|
|
48
|
-
return stage ===
|
|
42
|
+
return stage === "alpha" || stage === "beta" || stage === "prod" ? stage : null;
|
|
49
43
|
};
|
|
50
|
-
|
|
51
|
-
// Groups of locale tags that refer to the same language variant and should match each other
|
|
52
|
-
// when no exact match is available. zh-CN/zh-SG use simplified script; zh-TW/zh-HK/zh-MO use traditional.
|
|
53
44
|
const LOCALE_ALIAS_GROUPS = [
|
|
54
|
-
[
|
|
55
|
-
[
|
|
45
|
+
["zh-CN", "zh-SG", "zh-Hans"],
|
|
46
|
+
["zh-TW", "zh-HK", "zh-MO", "zh-Hant"]
|
|
56
47
|
];
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
return group ? group.filter(l => l !== locale) : [];
|
|
48
|
+
const getLocaleAliases = (locale) => {
|
|
49
|
+
const group = LOCALE_ALIAS_GROUPS.find((g) => g.includes(locale));
|
|
50
|
+
return group ? group.filter((l) => l !== locale) : [];
|
|
61
51
|
};
|
|
62
|
-
|
|
63
|
-
// Three tiers of locale match, from most to least specific. Returned as predicates
|
|
64
|
-
// so the resolver below can walk all venues at each tier before falling to the next.
|
|
65
|
-
// 1. Exact full-tag match (e.g. "zh-Hans" === "zh-Hans")
|
|
66
|
-
// 2. Known aliases (e.g. browser "zh-CN" matches venue "zh-Hans")
|
|
67
|
-
// 3. Two-char language-subtag prefix on both sides (e.g. "fr-FR" vs "fr_CA" both reduce to "fr")
|
|
68
|
-
const getLocaleMatchTiers = browserLang => {
|
|
52
|
+
const getLocaleMatchTiers = (browserLang) => {
|
|
69
53
|
const aliases = getLocaleAliases(browserLang);
|
|
70
54
|
const prefix = browserLang.slice(0, 2);
|
|
71
55
|
return [
|
|
72
|
-
locale => locale === browserLang,
|
|
73
|
-
locale => aliases.includes(locale),
|
|
74
|
-
locale => locale.slice(0, 2) === prefix
|
|
56
|
+
(locale) => locale === browserLang,
|
|
57
|
+
(locale) => aliases.includes(locale),
|
|
58
|
+
(locale) => locale.slice(0, 2) === prefix
|
|
75
59
|
];
|
|
76
60
|
};
|
|
77
|
-
|
|
78
|
-
// Resolve a browser locale to a venue. Within each tier, prefer `currentVenue` over
|
|
79
|
-
// other siblings when both would match — this keeps the caller on their intended venue
|
|
80
|
-
// when it satisfies the preference, and prevents a lower-tier match (e.g. "en" prefix)
|
|
81
|
-
// from yanking a user off an exactly-matching region sibling.
|
|
82
61
|
const findVenueForLocale = (venues, browserLang, currentVenue = null) => {
|
|
83
62
|
for (const matches of getLocaleMatchTiers(browserLang)) {
|
|
84
63
|
if (currentVenue && matches(currentVenue.locale)) {
|
|
85
64
|
return currentVenue;
|
|
86
65
|
}
|
|
87
|
-
const venue = venues.find(v => matches(v.locale));
|
|
66
|
+
const venue = venues.find((v) => matches(v.locale));
|
|
88
67
|
if (venue) {
|
|
89
68
|
return venue;
|
|
90
69
|
}
|
|
91
70
|
}
|
|
92
71
|
return null;
|
|
93
72
|
};
|
|
94
|
-
|
|
95
73
|
const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => {
|
|
96
74
|
const stages = {
|
|
97
|
-
alpha:
|
|
98
|
-
beta:
|
|
99
|
-
gamma:
|
|
100
|
-
prod:
|
|
75
|
+
alpha: "alpha-a.locuslabs.com",
|
|
76
|
+
beta: "beta-a.locuslabs.com",
|
|
77
|
+
gamma: "gamma-a.locuslabs.com",
|
|
78
|
+
prod: "a.locuslabs.com"
|
|
101
79
|
};
|
|
102
|
-
|
|
103
80
|
const { assetStage, accountId, formatVersion } = vconfig;
|
|
104
81
|
let { venueId } = vconfig;
|
|
105
82
|
const stageUrl = stages[assetStage] || stages.prod;
|
|
106
83
|
const accountUrl = `https://${stageUrl}/accounts/${accountId}`;
|
|
107
|
-
const assetFormat = formatVersion ||
|
|
108
|
-
|
|
109
|
-
// Load the v5.json resource
|
|
110
|
-
const venueList =
|
|
111
|
-
vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getFiles
|
|
112
|
-
? await globalThis[vconfig.dataFetch].getFiles(vconfig)
|
|
113
|
-
: await fetchJson(`${accountUrl}/${assetFormat}.json`);
|
|
114
|
-
|
|
115
|
-
// Reassign venue id to venueId+language preference if that venue in that language is available to us in the venue list.
|
|
116
|
-
// Only attempt language resolution when the venue has a venueCode (indicating language siblings may exist).
|
|
117
|
-
// Venues without a venueCode (e.g. custom tiled maps provided via dataFetch) skip resolution entirely.
|
|
84
|
+
const assetFormat = formatVersion || "v5";
|
|
85
|
+
const venueList = vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getFiles ? await globalThis[vconfig.dataFetch].getFiles(vconfig) : await fetchJson(`${accountUrl}/${assetFormat}.json`);
|
|
118
86
|
const venueCode = venueList[venueId] ? venueList[venueId].venueCode : null;
|
|
119
|
-
|
|
120
87
|
if (venueCode) {
|
|
121
|
-
const venuesWithSameVenueCode = Object.values(venueList).filter(v => v.venueCode === venueCode);
|
|
88
|
+
const venuesWithSameVenueCode = Object.values(venueList).filter((v) => v.venueCode === venueCode);
|
|
122
89
|
const currentVenue = venueList[venueId];
|
|
123
90
|
for (const browserLang of languagesToTry) {
|
|
124
91
|
const venue = findVenueForLocale(venuesWithSameVenueCode, browserLang, currentVenue);
|
|
@@ -129,121 +96,75 @@ const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => {
|
|
|
129
96
|
}
|
|
130
97
|
}
|
|
131
98
|
}
|
|
132
|
-
|
|
133
99
|
if (!venueList[venueId]) {
|
|
134
100
|
throw Error(`Attempt to access venue ${venueId} which is not within venue list: ${Object.keys(venueList)}`);
|
|
135
101
|
}
|
|
136
|
-
const files = venueList[venueId].files;
|
|
137
|
-
const fetchedData =
|
|
138
|
-
vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getVenueData
|
|
139
|
-
? await globalThis[vconfig.dataFetch].getVenueData(vconfig)
|
|
140
|
-
: await fetchJson(files.venueData);
|
|
141
|
-
|
|
102
|
+
const files = venueList[venueId].files;
|
|
103
|
+
const fetchedData = vconfig.dataFetch && globalThis[vconfig.dataFetch] && globalThis[vconfig.dataFetch].getVenueData ? await globalThis[vconfig.dataFetch].getVenueData(vconfig) : await fetchJson(files.venueData);
|
|
142
104
|
const venueData = fetchedData[venueId];
|
|
143
|
-
|
|
144
|
-
// For tilemaps, we need to embellish the venue data with structure
|
|
145
105
|
if (venueData.tileServerAuthInfo) {
|
|
146
106
|
embellishTilemapVenueData(venueData);
|
|
147
107
|
}
|
|
148
|
-
|
|
149
108
|
venueData.venueList = venueList;
|
|
150
109
|
const contentStage = getContentStage(vconfig);
|
|
151
|
-
venueData.files = contentStage
|
|
152
|
-
? remapEachURLForContentStage(venueData.category, files, contentStage, accountId, venueId)
|
|
153
|
-
: files;
|
|
154
|
-
|
|
110
|
+
venueData.files = contentStage ? remapEachURLForContentStage(venueData.category, files, contentStage, accountId, venueId) : files;
|
|
155
111
|
return venueData;
|
|
156
112
|
};
|
|
157
|
-
|
|
158
|
-
const buildStructures = venueData => {
|
|
113
|
+
const buildStructures = (venueData) => {
|
|
159
114
|
const { structureOrder, structures } = venueData;
|
|
160
|
-
return structureOrder.map(structureId => {
|
|
115
|
+
return structureOrder.map((structureId) => {
|
|
161
116
|
const structure = structures[structureId];
|
|
162
|
-
|
|
163
|
-
Object.values(structure.levels).forEach(level => (level.bounds = bounds.findBoundsOfCoordinates(level.boundsPolygon)));
|
|
117
|
+
Object.values(structure.levels).forEach((level) => level.bounds = bounds.findBoundsOfCoordinates(level.boundsPolygon));
|
|
164
118
|
const bounds$1 = bounds.findBoundsOfCoordinates(structure.boundsPolygon);
|
|
165
119
|
return { ...structure, bounds: bounds$1 };
|
|
166
120
|
});
|
|
167
121
|
};
|
|
168
|
-
|
|
169
122
|
function embellishTilemapVenueData(venueData) {
|
|
170
123
|
const additionalFields = {
|
|
171
|
-
defaultOrdinal: 0,
|
|
172
|
-
|
|
173
|
-
|
|
124
|
+
defaultOrdinal: 0,
|
|
125
|
+
// this and below override the venue data
|
|
126
|
+
defaultStructureId: "singleBuilding",
|
|
127
|
+
formatVersion: "v5",
|
|
174
128
|
// Note: this structures object does not represent the "buildingsAndLevels" as
|
|
175
129
|
// managed within this app. This is a mock structure for the purposes of rendering
|
|
176
130
|
// a tiled map. It is always a single building, single floor. If user switches
|
|
177
131
|
// buildings or floors, it unmounts this map and remounts a new map with that building/floor
|
|
178
132
|
structures: {
|
|
179
133
|
singleBuilding: {
|
|
180
|
-
name:
|
|
134
|
+
name: "singleBuilding",
|
|
181
135
|
boundsPolygon: [],
|
|
182
|
-
defaultLevelId:
|
|
183
|
-
id:
|
|
136
|
+
defaultLevelId: "singleLevel",
|
|
137
|
+
id: "singleBuilding",
|
|
184
138
|
levels: {
|
|
185
139
|
singleLevel: {
|
|
186
140
|
boundsPolygon: [],
|
|
187
141
|
clfloor: 0,
|
|
188
|
-
details:
|
|
189
|
-
id:
|
|
190
|
-
name:
|
|
191
|
-
ordinal: 0
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
142
|
+
details: "",
|
|
143
|
+
id: "singleLevel",
|
|
144
|
+
name: "singleLevel",
|
|
145
|
+
ordinal: 0
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
195
149
|
},
|
|
196
|
-
structureOrder: [
|
|
150
|
+
structureOrder: ["singleBuilding"]
|
|
197
151
|
};
|
|
198
|
-
|
|
199
152
|
for (const key in additionalFields) {
|
|
200
153
|
venueData[key] = additionalFields[key];
|
|
201
154
|
}
|
|
202
155
|
}
|
|
203
|
-
|
|
204
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
205
|
-
const between = (val, lim1, lim2) => (val > lim1 ? val <= lim2 : val => lim2);
|
|
206
|
-
|
|
207
|
-
// exchanges the first and second items in an array, preserving the rest of the array untouched
|
|
208
|
-
// i.e. [1,2,3,4,5] => [2,1,3,4,5]
|
|
156
|
+
const between = (val, lim1, lim2) => val > lim1 ? val <= lim2 : (val2) => lim2;
|
|
209
157
|
const swapFirstTwoItems = ([c1, c2, ...c3]) => [c2, c1, ...c3];
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Since coordinates are often expressed as [lat, lng] but required by GeoJSON to be [lng, lat],
|
|
213
|
-
* this function will take a list of coordinate pairs and ensure they are in the required format
|
|
214
|
-
* by comparing to the venue bounds.
|
|
215
|
-
*
|
|
216
|
-
* @param {array.array.float} coords list of coordinate pairs, such as [[36.3,-115.85], [36.5, -115.34]]
|
|
217
|
-
* @param {object} venueBounds contains props {ne, sw} which each are objects containing {lat,lng} properties
|
|
218
|
-
* @returns {array.array.float} with [lng,lat,...] for each item
|
|
219
|
-
*/
|
|
220
158
|
const normalizeCoords = (coords, venueBounds) => {
|
|
221
159
|
if (!coords || !Array.isArray(coords) || coords.length < 1) {
|
|
222
160
|
return coords;
|
|
223
161
|
}
|
|
224
|
-
|
|
225
|
-
if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng)) // looks like a lat - so already in proper order
|
|
226
|
-
{
|
|
162
|
+
if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng)) {
|
|
227
163
|
return coords;
|
|
228
164
|
}
|
|
229
|
-
|
|
230
|
-
// wrong order, so swtich em
|
|
231
165
|
return coords.map(swapFirstTwoItems);
|
|
232
166
|
};
|
|
233
167
|
|
|
234
|
-
// If config.useDynamicUrlParams is true, allow changing even security-related parameters in
|
|
235
|
-
// the URL - else, only allow the changing of "end-user-changable" parameters, such as vid
|
|
236
|
-
// export function updateConfigWithUrlParams (config) {
|
|
237
|
-
// const dlp = config.deepLinkProps
|
|
238
|
-
// if (dlp) {
|
|
239
|
-
// const venueId = dlp.vid ? dlp.vid : config.venueId
|
|
240
|
-
// const assetStage = config.useDynamicUrlParams && dlp.stage ? dlp.stage : config.assetStage
|
|
241
|
-
// const accountId = assetStage === 'alpha' ? 'A1VPTJKREFJWX5' : config.accountId
|
|
242
|
-
// return { ...config, venueId, assetStage, accountId }
|
|
243
|
-
// }
|
|
244
|
-
// return config
|
|
245
|
-
// }
|
|
246
|
-
|
|
247
168
|
exports.buildStructures = buildStructures;
|
|
248
169
|
exports.createFetchJson = createFetchJson;
|
|
249
170
|
exports.createFetchText = createFetchText;
|
|
@@ -22,102 +22,40 @@ function _interopNamespaceDefault(e) {
|
|
|
22
22
|
|
|
23
23
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
24
24
|
|
|
25
|
-
const getEdgeTo = dst => node => R__namespace.find(e => e.dst === dst, node.edges);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Returns the shortest route (or path) from start to end.
|
|
29
|
-
* @param {Object} start must include {floorId, lat, lng}
|
|
30
|
-
* @param {Object} end must include {floorId, lat, lng}
|
|
31
|
-
* @param {Object} options optional settings for choosing route
|
|
32
|
-
* @param {boolean} options.requiresAccessibility if true, only accessible routes are returned (no stairs or escalators)
|
|
33
|
-
* @returns {[nodes]} array of NavGraph nodes OR null if no route exists
|
|
34
|
-
* @throws if start or end is not defined
|
|
35
|
-
*/
|
|
25
|
+
const getEdgeTo = (dst) => (node) => R__namespace.find((e) => e.dst === dst, node.edges);
|
|
36
26
|
const calculateRoute = (graph, start, end, options) => {
|
|
37
27
|
if (!start || !end) {
|
|
38
|
-
throw Error(
|
|
28
|
+
throw Error("bad calculate Route request!");
|
|
39
29
|
}
|
|
40
30
|
return graph.findShortestPath(start, end, options);
|
|
41
31
|
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @typedef Waypoint
|
|
45
|
-
* @property {FullPosition} position
|
|
46
|
-
* @property {number} distance
|
|
47
|
-
* @property {number} eta
|
|
48
|
-
* @property {boolean} isSecurityCheckpoint
|
|
49
|
-
* @property {boolean} isPortal
|
|
50
|
-
* @property {string} portalType
|
|
51
|
-
* @property {number} levelDifference
|
|
52
|
-
* @property {boolean} isDestination
|
|
53
|
-
* @property {SecurityWaitTime|null} securityWaitTimes
|
|
54
|
-
* @property {SecurityLane|null} securityLane
|
|
55
|
-
* @property {CurvedPath|null} curvedPathForward
|
|
56
|
-
*
|
|
57
|
-
* @typedef SecurityLane
|
|
58
|
-
* @property {string} id
|
|
59
|
-
* @property {string} type
|
|
60
|
-
*
|
|
61
|
-
* @typedef FullPosition
|
|
62
|
-
* @property {string} floorId
|
|
63
|
-
* @property {string} lat
|
|
64
|
-
* @property {number} lng
|
|
65
|
-
* @property {number} ordinal
|
|
66
|
-
* @property {string} structureId
|
|
67
|
-
*
|
|
68
|
-
* @typedef {Array.<CurvedPoint>} CurvedPath
|
|
69
|
-
*
|
|
70
|
-
* @typedef CurvedPoint
|
|
71
|
-
* @property {ObjCoordinate} end
|
|
72
|
-
* @property {ObjCoordinate} in
|
|
73
|
-
* @property {ObjCoordinate} out
|
|
74
|
-
* @property {ObjCoordinate} start
|
|
75
|
-
*
|
|
76
|
-
* @typedef {{lng: number, lat: number}} ObjCoordinate
|
|
77
|
-
*
|
|
78
|
-
* Returns the shortest route (or path) from start to end.
|
|
79
|
-
* @param graph
|
|
80
|
-
* @param {Endpoint} start
|
|
81
|
-
* @param {Endpoint} destination
|
|
82
|
-
* @param {RouteOptions} options
|
|
83
|
-
* @return {{waypoints: Array.<Waypoint>}|null}
|
|
84
|
-
*/
|
|
85
|
-
// todo refactor
|
|
86
32
|
const findRoute = (graph, start, destination, options = {}) => {
|
|
87
33
|
const waypoints = [];
|
|
88
34
|
const queues = [];
|
|
89
|
-
|
|
90
35
|
let hasSecurity = false;
|
|
91
36
|
let hasImmigration = false;
|
|
92
|
-
|
|
93
37
|
const routeNodes = calculateRoute(graph, start, destination, options);
|
|
94
|
-
|
|
95
38
|
if (routeNodes === null) {
|
|
96
39
|
return null;
|
|
97
40
|
}
|
|
98
|
-
|
|
99
41
|
let previousRouteNode = null;
|
|
100
42
|
for (let i = 0; i < routeNodes.length; i++) {
|
|
101
43
|
const waypoint = {
|
|
102
44
|
distance: 0,
|
|
103
|
-
eta: 0
|
|
45
|
+
eta: 0
|
|
104
46
|
};
|
|
105
|
-
|
|
106
47
|
if (previousRouteNode) {
|
|
107
48
|
const edgeUsed = getEdgeTo(routeNodes[i].id)(previousRouteNode);
|
|
108
49
|
if (edgeUsed != null) {
|
|
109
50
|
waypoint.distance = edgeUsed.distance;
|
|
110
51
|
waypoint.eta = edgeUsed.transitTime;
|
|
111
|
-
|
|
112
|
-
if (edgeUsed.type !== 'Ground') {
|
|
52
|
+
if (edgeUsed.type !== "Ground") {
|
|
113
53
|
waypoint.portalType = edgeUsed.type;
|
|
114
54
|
waypoint.isPortal = true;
|
|
115
55
|
}
|
|
116
|
-
|
|
117
56
|
if (edgeUsed.o) {
|
|
118
57
|
waypoint.poiId = edgeUsed.o;
|
|
119
58
|
}
|
|
120
|
-
|
|
121
59
|
if (edgeUsed.path) {
|
|
122
60
|
waypoint.curvedPathForward = edgeUsed.path;
|
|
123
61
|
}
|
|
@@ -125,7 +63,6 @@ const findRoute = (graph, start, destination, options = {}) => {
|
|
|
125
63
|
waypoint.securityWaitTimes = edgeUsed.securityWaitTimes;
|
|
126
64
|
waypoint.eta = waypoint.securityWaitTimes.queueTime;
|
|
127
65
|
}
|
|
128
|
-
|
|
129
66
|
if (edgeUsed.securityLane) {
|
|
130
67
|
waypoint.securityLane = edgeUsed.securityLane;
|
|
131
68
|
waypoint.isSecurityCheckpoint = true;
|
|
@@ -141,21 +78,17 @@ const findRoute = (graph, start, destination, options = {}) => {
|
|
|
141
78
|
}
|
|
142
79
|
}
|
|
143
80
|
}
|
|
144
|
-
|
|
145
81
|
waypoint.levelDifference = previousRouteNode ? routeNodes[i].ordinal - previousRouteNode.ordinal : 0;
|
|
146
|
-
waypoint.position = R__namespace.omit([
|
|
147
|
-
|
|
82
|
+
waypoint.position = R__namespace.omit(["edges", "id"], { ...routeNodes[i] });
|
|
148
83
|
waypoints.push(waypoint);
|
|
149
|
-
|
|
150
84
|
previousRouteNode = routeNodes[i];
|
|
151
85
|
}
|
|
152
86
|
R__namespace.last(waypoints).isDestination = true;
|
|
153
|
-
|
|
154
87
|
return {
|
|
155
88
|
waypoints,
|
|
156
89
|
queues,
|
|
157
90
|
hasSecurity,
|
|
158
|
-
hasImmigration
|
|
91
|
+
hasImmigration
|
|
159
92
|
};
|
|
160
93
|
};
|
|
161
94
|
|
|
@@ -2,88 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
class MinPriorityQueue {
|
|
4
4
|
constructor() {
|
|
5
|
-
this.heap = [null];
|
|
5
|
+
this.heap = [null];
|
|
6
6
|
this.heapMap = {};
|
|
7
7
|
}
|
|
8
|
-
|
|
9
8
|
offerWithPriority(node, priority) {
|
|
10
9
|
const index = this.heap.push([node, priority]) - 1;
|
|
11
|
-
|
|
12
10
|
this.heapMap[node] = index;
|
|
13
11
|
this.bubble(index);
|
|
14
12
|
}
|
|
15
|
-
|
|
16
13
|
raisePriority(node, priority) {
|
|
17
14
|
const index = this.heapMap[node];
|
|
18
15
|
this.heap[index][1] = priority;
|
|
19
|
-
|
|
20
16
|
this.bubble(index);
|
|
21
17
|
}
|
|
22
|
-
|
|
23
18
|
poll() {
|
|
24
19
|
if (this.heap.length === 1) {
|
|
25
20
|
return null;
|
|
26
21
|
}
|
|
27
22
|
if (this.heap.length === 2) {
|
|
28
|
-
const
|
|
29
|
-
delete this.heapMap[
|
|
30
|
-
return
|
|
23
|
+
const value2 = this.heap.pop()[0];
|
|
24
|
+
delete this.heapMap[value2];
|
|
25
|
+
return value2;
|
|
31
26
|
}
|
|
32
|
-
|
|
33
27
|
const value = this.heap[1][0];
|
|
34
28
|
delete this.heapMap[value];
|
|
35
|
-
|
|
36
29
|
this.heap[1] = this.heap.pop();
|
|
37
30
|
this.heapMap[this.heap[1][0]] = 1;
|
|
38
|
-
|
|
39
31
|
this.sink(1);
|
|
40
|
-
|
|
41
32
|
return value;
|
|
42
33
|
}
|
|
43
|
-
|
|
44
34
|
isEmpty() {
|
|
45
35
|
return this.heap.length === 1;
|
|
46
36
|
}
|
|
47
|
-
|
|
48
37
|
bubble(i) {
|
|
49
38
|
while (i > 1) {
|
|
50
|
-
const parentIndex = i >> 1;
|
|
51
|
-
|
|
39
|
+
const parentIndex = i >> 1;
|
|
52
40
|
if (!this.isHigherPriority(i, parentIndex)) {
|
|
53
41
|
break;
|
|
54
42
|
}
|
|
55
|
-
|
|
56
43
|
this.swap(i, parentIndex);
|
|
57
44
|
i = parentIndex;
|
|
58
45
|
}
|
|
59
46
|
}
|
|
60
|
-
|
|
61
47
|
sink(i) {
|
|
62
48
|
while (i * 2 < this.heap.length) {
|
|
63
|
-
const isRightChildHigherPriority =
|
|
64
|
-
this.heap[i * 2 + 1] === undefined ? false : this.isHigherPriority(i * 2 + 1, i * 2); // i*2 +1 might be null
|
|
49
|
+
const isRightChildHigherPriority = this.heap[i * 2 + 1] === void 0 ? false : this.isHigherPriority(i * 2 + 1, i * 2);
|
|
65
50
|
const childIndex = isRightChildHigherPriority ? i * 2 + 1 : i * 2;
|
|
66
|
-
|
|
67
51
|
if (this.isHigherPriority(i, childIndex)) {
|
|
68
52
|
break;
|
|
69
53
|
}
|
|
70
|
-
|
|
71
54
|
this.swap(i, childIndex);
|
|
72
55
|
i = childIndex;
|
|
73
56
|
}
|
|
74
57
|
}
|
|
75
|
-
|
|
76
58
|
swap(i, j) {
|
|
77
59
|
this.heapMap[this.heap[i][0]] = j;
|
|
78
60
|
this.heapMap[this.heap[j][0]] = i;
|
|
79
|
-
|
|
80
61
|
const temp = this.heap[i];
|
|
81
62
|
this.heap[i] = this.heap[j];
|
|
82
63
|
this.heap[j] = temp;
|
|
83
64
|
}
|
|
84
|
-
|
|
85
65
|
isHigherPriority(i, j) {
|
|
86
|
-
return this.heap[i][1] < this.heap[j][1];
|
|
66
|
+
return this.heap[i][1] < this.heap[j][1];
|
|
87
67
|
}
|
|
88
68
|
}
|
|
89
69
|
|