atriusmaps-node-sdk 3.3.196 → 3.3.225
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/_virtual/_empty_module_placeholder.js +2 -2
- package/dist/cjs/deploy/prepareSDKConfig.js +152 -2
- package/dist/cjs/nodesdk/nodeEntry.js +109 -0
- package/dist/cjs/package.json.js +190 -14
- package/dist/cjs/plugins/clientAPI/src/clientAPI.js +11 -2
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +218 -21
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +292 -21
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +99 -20
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +219 -2
- package/dist/cjs/plugins/sdkServer/src/util.js +16 -3
- package/dist/cjs/plugins/searchService/src/poiSearch.js +57 -19
- package/dist/cjs/plugins/searchService/src/searchService.js +246 -21
- package/dist/cjs/plugins/searchService/src/searchTypeahead.js +60 -3
- package/dist/cjs/plugins/searchService/src/utils.js +23 -4
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +472 -21
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +191 -23
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +147 -19
- package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +88 -2
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +393 -5
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +110 -20
- package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +28 -2
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +257 -19
- package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +29 -2
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +238 -3
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +597 -22
- package/dist/cjs/src/app.js +191 -25
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +58 -2
- package/dist/cjs/src/configs/postproc-stateTracking.js +53 -19
- package/dist/cjs/src/controller.js +43 -4
- package/dist/cjs/src/debugTools.js +128 -23
- package/dist/cjs/src/env.js +17 -2
- package/dist/cjs/src/extModules/bustle.js +128 -4
- package/dist/cjs/src/extModules/flexapi/src/help.js +23 -4
- package/dist/cjs/src/extModules/flexapi/src/index.js +65 -4
- package/dist/cjs/src/extModules/flexapi/src/validate.js +133 -5
- package/dist/cjs/src/extModules/geohasher.js +90 -3
- package/dist/cjs/src/extModules/log.js +69 -2
- package/dist/cjs/src/historyManager.js +29 -2
- package/dist/cjs/src/utils/bounds.js +22 -4
- package/dist/cjs/src/utils/buildStructureLookup.js +31 -19
- package/dist/cjs/src/utils/configUtils.js +71 -3
- package/dist/cjs/src/utils/dom.js +48 -5
- package/dist/cjs/src/utils/funcs.js +30 -3
- package/dist/cjs/src/utils/geodesy.js +35 -3
- package/dist/cjs/src/utils/geom.js +209 -27
- package/dist/cjs/src/utils/i18n.js +69 -5
- package/dist/cjs/src/utils/observable.js +73 -2
- package/dist/cjs/src/utils/rand.js +82 -3
- package/dist/nodesdk/nodeEntry.js +1 -0
- package/dist/package.json.js +1 -0
- package/dist/plugins/searchService/src/searchService.js +1 -0
- package/dist/plugins/venueDataLoader/src/venueDataLoader.js +1 -0
- package/dist/plugins/venueDataLoader/src/venueLoadingUtils.js +1 -0
- package/dist/src/app.js +1 -0
- package/package.json +13 -9
- package/.yarnrc.yml +0 -1
- package/config/rollup.config.cjs.js +0 -31
- package/dist/cjs/deploy/nodeEntry.js +0 -20
- package/dist/cjs/src/auth/Auth.js +0 -23
- package/lib/deploy/nodeEntry.js +0 -1
- package/lib/package.json.js +0 -1
- package/lib/plugins/searchService/src/searchService.js +0 -1
- package/lib/plugins/venueDataLoader/src/venueDataLoader.js +0 -1
- package/lib/plugins/venueDataLoader/src/venueLoadingUtils.js +0 -1
- package/lib/src/app.js +0 -1
- package/lib/src/configs/sdkHeadless.json +0 -28
- /package/{lib → dist}/_virtual/_empty_module_placeholder.js +0 -0
- /package/{lib → dist}/deploy/prepareSDKConfig.js +0 -0
- /package/{lib → dist}/plugins/clientAPI/src/clientAPI.js +0 -0
- /package/{lib → dist}/plugins/dynamicPois/src/dynamicPois.js +0 -0
- /package/{lib → dist}/plugins/poiDataManager/src/poiDataManager.js +0 -0
- /package/{lib → dist}/plugins/sdkServer/src/sdkHeadless.js +0 -0
- /package/{lib → dist}/plugins/sdkServer/src/sdkServer.js +0 -0
- /package/{lib → dist}/plugins/sdkServer/src/util.js +0 -0
- /package/{lib → dist}/plugins/searchService/src/poiSearch.js +0 -0
- /package/{lib → dist}/plugins/searchService/src/searchTypeahead.js +0 -0
- /package/{lib → dist}/plugins/searchService/src/utils.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/findRoute.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/minPriorityQueue.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/navGraph.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/navGraphDebug.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/segmentBadges.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/segmentBuilder.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/segmentCategories.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/stepBuilder.js +0 -0
- /package/{lib → dist}/plugins/wayfinder/src/wayfinder.js +0 -0
- /package/{lib → dist}/src/configs/postproc-mol-url-parms.js +0 -0
- /package/{lib → dist}/src/configs/postproc-stateTracking.js +0 -0
- /package/{lib → dist}/src/configs/sdkHeadless.json.js +0 -0
- /package/{lib → dist}/src/controller.js +0 -0
- /package/{lib → dist}/src/debugTools.js +0 -0
- /package/{lib → dist}/src/env.js +0 -0
- /package/{lib → dist}/src/extModules/bustle.js +0 -0
- /package/{lib → dist}/src/extModules/flexapi/src/help.js +0 -0
- /package/{lib → dist}/src/extModules/flexapi/src/index.js +0 -0
- /package/{lib → dist}/src/extModules/flexapi/src/validate.js +0 -0
- /package/{lib → dist}/src/extModules/geohasher.js +0 -0
- /package/{lib → dist}/src/extModules/log.js +0 -0
- /package/{lib → dist}/src/historyManager.js +0 -0
- /package/{lib → dist}/src/utils/bounds.js +0 -0
- /package/{lib → dist}/src/utils/buildStructureLookup.js +0 -0
- /package/{lib → dist}/src/utils/configUtils.js +0 -0
- /package/{lib → dist}/src/utils/dom.js +0 -0
- /package/{lib → dist}/src/utils/funcs.js +0 -0
- /package/{lib → dist}/src/utils/geodesy.js +0 -0
- /package/{lib → dist}/src/utils/geom.js +0 -0
- /package/{lib → dist}/src/utils/i18n.js +0 -0
- /package/{lib → dist}/src/utils/observable.js +0 -0
- /package/{lib → dist}/src/utils/rand.js +0 -0
|
@@ -2,34 +2,202 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var R = require('ramda');
|
|
6
6
|
var bounds = require('../../../src/utils/bounds.js');
|
|
7
7
|
var configUtils = require('../../../src/utils/configUtils.js');
|
|
8
8
|
|
|
9
9
|
function _interopNamespace(e) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n["default"] = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var R__namespace = /*#__PURE__*/_interopNamespace(R);
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const fetchURL = async (token, url) => {
|
|
30
|
+
if (token) {
|
|
31
|
+
return fetch(url, {
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: token
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
} else
|
|
37
|
+
return fetch(url)
|
|
38
|
+
};
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
const createFetchJson = (token) => url => fetchURL(token, url).then(response => response.json());
|
|
41
|
+
const createFetchText = (token) => url => fetchURL(token, url).then(response => response.text());
|
|
42
|
+
|
|
43
|
+
const baseContentUrl = (contentStage) => `https://api.content.locuslabs.com/${contentStage}`;
|
|
44
|
+
|
|
45
|
+
const remapContentUrl = (url, category, contentStage, accountId, venueId, key) => {
|
|
46
|
+
if (key === 'theme' || key === 'style') {
|
|
47
|
+
return `${baseContentUrl(contentStage)}/${category}/${key}/${venueId}/${accountId}/${key}.json`
|
|
48
|
+
}
|
|
49
|
+
return url.replace(/https:\/\/content.locuslabs.com/gi, baseContentUrl(contentStage))
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const remapEachURLForContentStage = (category, files, contentStage, accountId, venueId) =>
|
|
53
|
+
R__namespace.mapObjIndexed((file, key) => remapContentUrl(file, category, contentStage, accountId, venueId, key), files);
|
|
54
|
+
|
|
55
|
+
const getContentStage = (vconfig) => {
|
|
56
|
+
const stage = vconfig.deepLinkProps ? vconfig.deepLinkProps.contentStage : null;
|
|
57
|
+
return stage === 'alpha' || stage === 'beta' || stage === 'prod' ? stage : null
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const getVenueDataFromUrls = async (vconfig, fetchJson, languagesToTry) => {
|
|
61
|
+
const stages = {
|
|
62
|
+
alpha: 'alpha-a.locuslabs.com',
|
|
63
|
+
beta: 'beta-a.locuslabs.com',
|
|
64
|
+
gamma: 'gamma-a.locuslabs.com',
|
|
65
|
+
prod: 'a.locuslabs.com'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const { assetStage, accountId, formatVersion } = vconfig;
|
|
69
|
+
let { venueId } = vconfig;
|
|
70
|
+
const stageUrl = stages[assetStage] || stages.prod;
|
|
71
|
+
const accountUrl = `https://${stageUrl}/accounts/${accountId}`;
|
|
72
|
+
const assetFormat = formatVersion || 'v5';
|
|
73
|
+
|
|
74
|
+
// Load the v5.json resource
|
|
75
|
+
const venueList = (vconfig.dataFetch && configUtils.global[vconfig.dataFetch] && configUtils.global[vconfig.dataFetch].getFiles)
|
|
76
|
+
? await configUtils.global[vconfig.dataFetch].getFiles(vconfig)
|
|
77
|
+
: await fetchJson(`${accountUrl}/${assetFormat}.json`);
|
|
78
|
+
|
|
79
|
+
// Reassign venue id to venueId+langauge preference if that venue in that language is avaialbe to us in the v5 json
|
|
80
|
+
if (languagesToTry.length > 0) {
|
|
81
|
+
const convertedLangsToTry = languagesToTry.map(lang => lang.slice(0, 2)); // Browser langs can look like this [fr', 'fr-FR', 'ar', 'en-US', 'en'] so we need to process them so they match our lang codes which are just 2 digits
|
|
82
|
+
for (let i = 0; i < convertedLangsToTry.length; i += 1) {
|
|
83
|
+
if (venueList[`${venueId}${convertedLangsToTry[i]}`]) {
|
|
84
|
+
venueId = `${venueId}${convertedLangsToTry[i]}`;
|
|
85
|
+
vconfig.venueId = `${venueId}`;
|
|
86
|
+
break
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!venueList[venueId])
|
|
92
|
+
throw Error(`Attempt to access venue ${venueId} which is not within venue list: ${Object.keys(venueList)}`)
|
|
93
|
+
const files = venueList[venueId].files; // mapping of asset "types" (spritesheet, style, badges, etc) to their URL
|
|
94
|
+
const fetchedData = (vconfig.dataFetch && configUtils.global[vconfig.dataFetch] && configUtils.global[vconfig.dataFetch].getVenueData)
|
|
95
|
+
? await configUtils.global[vconfig.dataFetch].getVenueData(vconfig)
|
|
96
|
+
: await fetchJson(files.venueData);
|
|
97
|
+
|
|
98
|
+
const venueData = fetchedData[venueId];
|
|
99
|
+
|
|
100
|
+
// For tilemaps, we need to embellish the venue data with structure
|
|
101
|
+
if (venueData.tileServerAuthInfo)
|
|
102
|
+
embellishTilemapVenueData(venueData);
|
|
103
|
+
|
|
104
|
+
venueData.venueList = venueList;
|
|
105
|
+
const contentStage = getContentStage(vconfig);
|
|
106
|
+
venueData.files = contentStage // if a contentStage is defined, remap content URLs (see docs/Content-And-Asset-Loading/contentStaging.md)
|
|
107
|
+
? remapEachURLForContentStage(venueData.category, files, contentStage, accountId, venueId)
|
|
108
|
+
: files;
|
|
109
|
+
|
|
110
|
+
return venueData
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const buildStructures = (venueData) => {
|
|
114
|
+
const { structureOrder, structures } = venueData;
|
|
115
|
+
return structureOrder.map(structureId => {
|
|
116
|
+
const structure = structures[structureId];
|
|
117
|
+
// Was going to use this for selecting floors - but it seems floor bounds are incorrect? (was testing LAX/lax-msc-2 for example)
|
|
118
|
+
// Object.values(structure.levels).forEach(level => (level.bounds = findBoundsOfCoordinates(level.boundsPolygon)))
|
|
119
|
+
const bounds$1 = bounds.findBoundsOfCoordinates(structure.boundsPolygon);
|
|
120
|
+
return { ...structure, bounds: bounds$1 }
|
|
121
|
+
})
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
function embellishTilemapVenueData (venueData) {
|
|
125
|
+
const additionalFields = {
|
|
126
|
+
defaultOrdinal: 0, // this and below override the venue data
|
|
127
|
+
defaultStructureId: 'singleBuilding',
|
|
128
|
+
formatVersion: 'v5',
|
|
129
|
+
// Note: this structures object does not represent the "buildingsAndLevels" as
|
|
130
|
+
// managed within this app. This is a mock structure for the purposes of rendering
|
|
131
|
+
// a tiled map. It is always a single building, single floor. If user switches
|
|
132
|
+
// buildings or floors, it unmounts this map and remounts a new map with that building/floor
|
|
133
|
+
structures: {
|
|
134
|
+
singleBuilding: {
|
|
135
|
+
name: 'singleBuilding',
|
|
136
|
+
boundsPolygon: [],
|
|
137
|
+
defaultLevelId: 'singleLevel',
|
|
138
|
+
id: 'singleBuilding',
|
|
139
|
+
levels: {
|
|
140
|
+
singleLevel: {
|
|
141
|
+
boundsPolygon: [],
|
|
142
|
+
clfloor: 0,
|
|
143
|
+
details: '',
|
|
144
|
+
id: 'singleLevel',
|
|
145
|
+
name: 'singleLevel',
|
|
146
|
+
ordinal: 0
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
structureOrder: [
|
|
152
|
+
'singleBuilding'
|
|
153
|
+
]
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
for (const key in additionalFields)
|
|
157
|
+
venueData[key] = additionalFields[key];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const between = (val, lim1, lim2) => val > lim1 ? val <= lim2 : val => lim2;
|
|
161
|
+
|
|
162
|
+
// exchanges the first and second items in an array, preserving the rest of the array untouched
|
|
163
|
+
// i.e. [1,2,3,4,5] => [2,1,3,4,5]
|
|
164
|
+
const swapFirstTwoItems = ([c1, c2, ...c3]) => [c2, c1, ...c3];
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Since coordinates are often expressed as [lat, lng] but required by GeoJSON to be [lng, lat],
|
|
168
|
+
* this function will take a list of coordinate pairs and ensure they are in the required format
|
|
169
|
+
* by comparing to the venue bounds.
|
|
170
|
+
*
|
|
171
|
+
* @param {array.array.float} coords list of coordinate pairs, such as [[36.3,-115.85], [36.5, -115.34]]
|
|
172
|
+
* @param {object} venueBounds contains props {ne, sw} which each are objects containing {lat,lng} properties
|
|
173
|
+
* @returns {array.array.float} with [lng,lat,...] for each item
|
|
174
|
+
*/
|
|
175
|
+
const normalizeCoords = (coords, venueBounds) => {
|
|
176
|
+
if (!coords || !Array.isArray(coords) || coords.length < 1)
|
|
177
|
+
return coords
|
|
178
|
+
|
|
179
|
+
if (between(coords[0][0], venueBounds.ne.lng, venueBounds.sw.lng)) // looks like a lat - so already in proper order
|
|
180
|
+
return coords
|
|
181
|
+
|
|
182
|
+
// wrong order, so swtich em
|
|
183
|
+
return coords.map(swapFirstTwoItems)
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// If config.useDynamicUrlParams is true, allow changing even security-related parameters in
|
|
187
|
+
// the URL - else, only allow the changing of "end-user-changable" parameters, such as vid
|
|
188
|
+
// export function updateConfigWithUrlParams (config) {
|
|
189
|
+
// const dlp = config.deepLinkProps
|
|
190
|
+
// if (dlp) {
|
|
191
|
+
// const venueId = dlp.vid ? dlp.vid : config.venueId
|
|
192
|
+
// const assetStage = config.useDynamicUrlParams && dlp.stage ? dlp.stage : config.assetStage
|
|
193
|
+
// const accountId = assetStage === 'alpha' ? 'A1VPTJKREFJWX5' : config.accountId
|
|
194
|
+
// return { ...config, venueId, assetStage, accountId }
|
|
195
|
+
// }
|
|
196
|
+
// return config
|
|
197
|
+
// }
|
|
198
|
+
|
|
199
|
+
exports.buildStructures = buildStructures;
|
|
200
|
+
exports.createFetchJson = createFetchJson;
|
|
201
|
+
exports.createFetchText = createFetchText;
|
|
202
|
+
exports.getVenueDataFromUrls = getVenueDataFromUrls;
|
|
203
|
+
exports.normalizeCoords = normalizeCoords;
|
|
@@ -2,29 +2,157 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var R = require('ramda');
|
|
6
6
|
var wayfinder = require('./wayfinder.js');
|
|
7
7
|
|
|
8
8
|
function _interopNamespace(e) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
if (e && e.__esModule) return e;
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n["default"] = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
var
|
|
26
|
+
var R__namespace = /*#__PURE__*/_interopNamespace(R);
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const getEdgeTo = dst => node => R__namespace.find(e => e.dst === dst, node.edges);
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Returns the shortest route (or path) from start to end.
|
|
32
|
+
* @param {Object} start must include {floorId, lat, lng}
|
|
33
|
+
* @param {Object} end must include {floorId, lat, lng}
|
|
34
|
+
* @param {Object} options optional settings for choosing route
|
|
35
|
+
* @param {boolean} options.requiresAccessibility if true, only accessible routes are returned (no stairs or escalators)
|
|
36
|
+
* @returns {[nodes]} array of NavGraph nodes OR null if no route exists
|
|
37
|
+
* @throws if start or end is not defined
|
|
38
|
+
*/
|
|
39
|
+
const calculateRoute = (graph, start, end, options) => {
|
|
40
|
+
if (!start || !end)
|
|
41
|
+
throw Error('bad calculate Route request!')
|
|
42
|
+
return graph.findShortestPath(start, end, options)
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @typedef Waypoint
|
|
47
|
+
* @property {FullPosition} position
|
|
48
|
+
* @property {number} distance
|
|
49
|
+
* @property {number} eta
|
|
50
|
+
* @property {boolean} isSecurityCheckpoint
|
|
51
|
+
* @property {boolean} isPortal
|
|
52
|
+
* @property {string} portalType
|
|
53
|
+
* @property {number} levelDifference
|
|
54
|
+
* @property {boolean} isDestination
|
|
55
|
+
* @property {SecurityWaitTime|null} securityWaitTimes
|
|
56
|
+
* @property {SecurityLane|null} securityLane
|
|
57
|
+
* @property {CurvedPath|null} curvedPathForward
|
|
58
|
+
*
|
|
59
|
+
* @typedef SecurityLane
|
|
60
|
+
* @property {string} id
|
|
61
|
+
* @property {string} type
|
|
62
|
+
*
|
|
63
|
+
* @typedef FullPosition
|
|
64
|
+
* @property {string} floorId
|
|
65
|
+
* @property {string} lat
|
|
66
|
+
* @property {number} lng
|
|
67
|
+
* @property {number} ordinal
|
|
68
|
+
* @property {string} structureId
|
|
69
|
+
*
|
|
70
|
+
* @typedef {Array.<CurvedPoint>} CurvedPath
|
|
71
|
+
*
|
|
72
|
+
* @typedef CurvedPoint
|
|
73
|
+
* @property {ObjCoordinate} end
|
|
74
|
+
* @property {ObjCoordinate} in
|
|
75
|
+
* @property {ObjCoordinate} out
|
|
76
|
+
* @property {ObjCoordinate} start
|
|
77
|
+
*
|
|
78
|
+
* @typedef {{lng: number, lat: number}} ObjCoordinate
|
|
79
|
+
*
|
|
80
|
+
* Returns the shortest route (or path) from start to end.
|
|
81
|
+
* @param graph
|
|
82
|
+
* @param {Endpoint} start
|
|
83
|
+
* @param {Endpoint} destination
|
|
84
|
+
* @param {RouteOptions} options
|
|
85
|
+
* @return {{waypoints: Array.<Waypoint>}|null}
|
|
86
|
+
*/
|
|
87
|
+
// todo refactor
|
|
88
|
+
const findRoute = (graph, start, destination, options = {}) => {
|
|
89
|
+
const waypoints = [];
|
|
90
|
+
const queues = [];
|
|
91
|
+
|
|
92
|
+
let hasSecurity = false;
|
|
93
|
+
let hasImmigration = false;
|
|
94
|
+
|
|
95
|
+
const routeNodes = calculateRoute(graph, start, destination, options);
|
|
96
|
+
|
|
97
|
+
if (routeNodes === null)
|
|
98
|
+
return null
|
|
99
|
+
|
|
100
|
+
let previousRouteNode = null;
|
|
101
|
+
for (let i = 0; i < routeNodes.length; i++) {
|
|
102
|
+
const waypoint = {
|
|
103
|
+
distance: 0,
|
|
104
|
+
eta: 0
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (previousRouteNode) {
|
|
108
|
+
const edgeUsed = getEdgeTo(routeNodes[i].id)(previousRouteNode);
|
|
109
|
+
if (edgeUsed != null) {
|
|
110
|
+
waypoint.distance = edgeUsed.distance;
|
|
111
|
+
waypoint.eta = edgeUsed.transitTime;
|
|
112
|
+
|
|
113
|
+
if (edgeUsed.type !== 'Ground') {
|
|
114
|
+
waypoint.portalType = edgeUsed.type;
|
|
115
|
+
waypoint.isPortal = true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (edgeUsed.o)
|
|
119
|
+
waypoint.poiId = edgeUsed.o;
|
|
120
|
+
|
|
121
|
+
if (edgeUsed.path)
|
|
122
|
+
waypoint.curvedPathForward = edgeUsed.path;
|
|
123
|
+
if (edgeUsed.securityWaitTimes) {
|
|
124
|
+
waypoint.securityWaitTimes = edgeUsed.securityWaitTimes;
|
|
125
|
+
waypoint.eta = waypoint.securityWaitTimes.queueTime;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (edgeUsed.securityLane) {
|
|
129
|
+
waypoint.securityLane = edgeUsed.securityLane;
|
|
130
|
+
waypoint.isSecurityCheckpoint = true;
|
|
131
|
+
if (edgeUsed.securityLane.type === wayfinder.SecurityLaneType.SECURITY)
|
|
132
|
+
hasSecurity = true;
|
|
133
|
+
if (edgeUsed.securityLane.type === wayfinder.SecurityLaneType.IMMIGRATION)
|
|
134
|
+
hasImmigration = true;
|
|
135
|
+
if (edgeUsed.o)
|
|
136
|
+
queues.push(edgeUsed.o);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
waypoint.levelDifference = previousRouteNode ? routeNodes[i].ordinal - previousRouteNode.ordinal : 0;
|
|
142
|
+
waypoint.position = R__namespace.omit(['edges', 'id'], { ...routeNodes[i] });
|
|
143
|
+
|
|
144
|
+
waypoints.push(waypoint);
|
|
145
|
+
|
|
146
|
+
previousRouteNode = routeNodes[i];
|
|
147
|
+
}
|
|
148
|
+
R__namespace.last(waypoints).isDestination = true;
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
waypoints,
|
|
152
|
+
queues,
|
|
153
|
+
hasSecurity,
|
|
154
|
+
hasImmigration
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
exports.findRoute = findRoute;
|
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class MinPriorityQueue {
|
|
4
|
+
constructor () {
|
|
5
|
+
this.heap = [null]; // array representation of binary heap
|
|
6
|
+
this.heapMap = {};
|
|
7
|
+
}
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
offerWithPriority (node, priority) {
|
|
10
|
+
const index = this.heap.push([node, priority]) - 1;
|
|
11
|
+
|
|
12
|
+
this.heapMap[node] = index;
|
|
13
|
+
this.bubble(index);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
raisePriority (node, priority) {
|
|
17
|
+
const index = this.heapMap[node];
|
|
18
|
+
this.heap[index][1] = priority;
|
|
19
|
+
|
|
20
|
+
this.bubble(index);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
poll () {
|
|
24
|
+
if (this.heap.length === 1) {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
if (this.heap.length === 2) {
|
|
28
|
+
const value = this.heap.pop()[0];
|
|
29
|
+
delete this.heapMap[value];
|
|
30
|
+
return value
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const value = this.heap[1][0];
|
|
34
|
+
delete this.heapMap[value];
|
|
35
|
+
|
|
36
|
+
this.heap[1] = this.heap.pop();
|
|
37
|
+
this.heapMap[this.heap[1][0]] = 1;
|
|
38
|
+
|
|
39
|
+
this.sink(1);
|
|
40
|
+
|
|
41
|
+
return value
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
isEmpty () {
|
|
45
|
+
return this.heap.length === 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
bubble (i) {
|
|
49
|
+
while (i > 1) {
|
|
50
|
+
const parentIndex = i >> 1; // floor(i/2)
|
|
51
|
+
|
|
52
|
+
if (!this.isHigherPriority(i, parentIndex)) {
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.swap(i, parentIndex);
|
|
57
|
+
i = parentIndex;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
sink (i) {
|
|
62
|
+
while (i * 2 < this.heap.length) {
|
|
63
|
+
const isRightChildHigherPriority = (this.heap[i * 2 + 1] === undefined)
|
|
64
|
+
? false
|
|
65
|
+
: this.isHigherPriority(i * 2 + 1, i * 2); // i*2 +1 might be null
|
|
66
|
+
const childIndex = isRightChildHigherPriority ? i * 2 + 1 : i * 2;
|
|
67
|
+
|
|
68
|
+
if (this.isHigherPriority(i, childIndex)) {
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.swap(i, childIndex);
|
|
73
|
+
i = childIndex;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
swap (i, j) {
|
|
78
|
+
this.heapMap[this.heap[i][0]] = j;
|
|
79
|
+
this.heapMap[this.heap[j][0]] = i;
|
|
80
|
+
|
|
81
|
+
const temp = this.heap[i];
|
|
82
|
+
this.heap[i] = this.heap[j];
|
|
83
|
+
this.heap[j] = temp;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
isHigherPriority (i, j) {
|
|
87
|
+
return this.heap[i][1] < this.heap[j][1] // lower score -> higher priority
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = MinPriorityQueue;
|