venue-js 1.6.0 → 1.7.0
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/data/index.d.mts +75 -20
- package/dist/data/index.d.ts +75 -20
- package/dist/data/index.js +575 -376
- package/dist/data/index.js.map +1 -1
- package/dist/data/index.mjs +554 -357
- package/dist/data/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +752 -553
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +707 -510
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -3
package/dist/data/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(data_exports, {
|
|
|
32
32
|
ALL_FEATURE_TYPES: () => ALL_FEATURE_TYPES,
|
|
33
33
|
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
34
34
|
GEOJSON_FEATURE_TYPES: () => GEOJSON_FEATURE_TYPES,
|
|
35
|
+
ID_PREFIX_TO_FEATURE_TYPE: () => ID_PREFIX_TO_FEATURE_TYPE,
|
|
35
36
|
IMDF_FEATURE_TYPES: () => IMDF_FEATURE_TYPES,
|
|
36
37
|
IMDF_UNIT_CATEGORIES: () => IMDF_UNIT_CATEGORIES,
|
|
37
38
|
NONIMDF_FEATURE_TYPES: () => NONIMDF_FEATURE_TYPES,
|
|
@@ -58,6 +59,7 @@ __export(data_exports, {
|
|
|
58
59
|
getDataClient: () => getDataClient,
|
|
59
60
|
getInstructionText: () => getInstructionText,
|
|
60
61
|
getNavigateClient: () => getNavigateClient,
|
|
62
|
+
getPointOnFeature: () => getPointOnFeature,
|
|
61
63
|
getSearchClient: () => getSearchClient,
|
|
62
64
|
getTurn: () => getTurn,
|
|
63
65
|
matchFilter: () => matchFilter,
|
|
@@ -178,6 +180,9 @@ var ALL_FEATURE_TYPES = [
|
|
|
178
180
|
"sponsored-content",
|
|
179
181
|
"element"
|
|
180
182
|
];
|
|
183
|
+
var ID_PREFIX_TO_FEATURE_TYPE = {
|
|
184
|
+
sponsored: "sponsored-content"
|
|
185
|
+
};
|
|
181
186
|
var defaultFeatureQueryOptionsMap = {
|
|
182
187
|
// IMDF
|
|
183
188
|
address: {},
|
|
@@ -241,20 +246,143 @@ function matchFilters(item, filters) {
|
|
|
241
246
|
}
|
|
242
247
|
|
|
243
248
|
// src/data/utils/findContaining.ts
|
|
244
|
-
var import_point_on_feature = __toESM(require("@turf/point-on-feature"));
|
|
245
249
|
var import_boolean_point_in_polygon = require("@turf/boolean-point-in-polygon");
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
250
|
+
var import_intersect = require("@turf/intersect");
|
|
251
|
+
|
|
252
|
+
// node_modules/@turf/helpers/dist/esm/index.js
|
|
253
|
+
var earthRadius = 63710088e-1;
|
|
254
|
+
var factors = {
|
|
255
|
+
centimeters: earthRadius * 100,
|
|
256
|
+
centimetres: earthRadius * 100,
|
|
257
|
+
degrees: 360 / (2 * Math.PI),
|
|
258
|
+
feet: earthRadius * 3.28084,
|
|
259
|
+
inches: earthRadius * 39.37,
|
|
260
|
+
kilometers: earthRadius / 1e3,
|
|
261
|
+
kilometres: earthRadius / 1e3,
|
|
262
|
+
meters: earthRadius,
|
|
263
|
+
metres: earthRadius,
|
|
264
|
+
miles: earthRadius / 1609.344,
|
|
265
|
+
millimeters: earthRadius * 1e3,
|
|
266
|
+
millimetres: earthRadius * 1e3,
|
|
267
|
+
nauticalmiles: earthRadius / 1852,
|
|
268
|
+
radians: 1,
|
|
269
|
+
yards: earthRadius * 1.0936
|
|
270
|
+
};
|
|
271
|
+
function feature(geom, properties, options = {}) {
|
|
272
|
+
const feat = { type: "Feature" };
|
|
273
|
+
if (options.id === 0 || options.id) {
|
|
274
|
+
feat.id = options.id;
|
|
275
|
+
}
|
|
276
|
+
if (options.bbox) {
|
|
277
|
+
feat.bbox = options.bbox;
|
|
278
|
+
}
|
|
279
|
+
feat.properties = properties || {};
|
|
280
|
+
feat.geometry = geom;
|
|
281
|
+
return feat;
|
|
282
|
+
}
|
|
283
|
+
function point(coordinates, properties, options = {}) {
|
|
284
|
+
if (!coordinates) {
|
|
285
|
+
throw new Error("coordinates is required");
|
|
286
|
+
}
|
|
287
|
+
if (!Array.isArray(coordinates)) {
|
|
288
|
+
throw new Error("coordinates must be an Array");
|
|
289
|
+
}
|
|
290
|
+
if (coordinates.length < 2) {
|
|
291
|
+
throw new Error("coordinates must be at least 2 numbers long");
|
|
292
|
+
}
|
|
293
|
+
if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
|
|
294
|
+
throw new Error("coordinates must contain numbers");
|
|
295
|
+
}
|
|
296
|
+
const geom = {
|
|
297
|
+
type: "Point",
|
|
298
|
+
coordinates
|
|
299
|
+
};
|
|
300
|
+
return feature(geom, properties, options);
|
|
301
|
+
}
|
|
302
|
+
function polygon(coordinates, properties, options = {}) {
|
|
303
|
+
for (const ring of coordinates) {
|
|
304
|
+
if (ring.length < 4) {
|
|
305
|
+
throw new Error(
|
|
306
|
+
"Each LinearRing of a Polygon must have 4 or more Positions."
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
if (ring[ring.length - 1].length !== ring[0].length) {
|
|
310
|
+
throw new Error("First and last Position are not equivalent.");
|
|
311
|
+
}
|
|
312
|
+
for (let j = 0; j < ring[ring.length - 1].length; j++) {
|
|
313
|
+
if (ring[ring.length - 1][j] !== ring[0][j]) {
|
|
314
|
+
throw new Error("First and last Position are not equivalent.");
|
|
254
315
|
}
|
|
255
316
|
}
|
|
317
|
+
}
|
|
318
|
+
const geom = {
|
|
319
|
+
type: "Polygon",
|
|
320
|
+
coordinates
|
|
321
|
+
};
|
|
322
|
+
return feature(geom, properties, options);
|
|
323
|
+
}
|
|
324
|
+
function lineString(coordinates, properties, options = {}) {
|
|
325
|
+
if (coordinates.length < 2) {
|
|
326
|
+
throw new Error("coordinates must be an array of two or more positions");
|
|
327
|
+
}
|
|
328
|
+
const geom = {
|
|
329
|
+
type: "LineString",
|
|
330
|
+
coordinates
|
|
331
|
+
};
|
|
332
|
+
return feature(geom, properties, options);
|
|
333
|
+
}
|
|
334
|
+
function featureCollection(features, options = {}) {
|
|
335
|
+
const fc = { type: "FeatureCollection" };
|
|
336
|
+
if (options.id) {
|
|
337
|
+
fc.id = options.id;
|
|
338
|
+
}
|
|
339
|
+
if (options.bbox) {
|
|
340
|
+
fc.bbox = options.bbox;
|
|
341
|
+
}
|
|
342
|
+
fc.features = features;
|
|
343
|
+
return fc;
|
|
344
|
+
}
|
|
345
|
+
function multiLineString(coordinates, properties, options = {}) {
|
|
346
|
+
const geom = {
|
|
347
|
+
type: "MultiLineString",
|
|
348
|
+
coordinates
|
|
349
|
+
};
|
|
350
|
+
return feature(geom, properties, options);
|
|
351
|
+
}
|
|
352
|
+
function isNumber(num) {
|
|
353
|
+
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
354
|
+
}
|
|
355
|
+
function isObject(input) {
|
|
356
|
+
return input !== null && typeof input === "object" && !Array.isArray(input);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// src/data/utils/findContaining.ts
|
|
360
|
+
var import_center = require("@turf/center");
|
|
361
|
+
var import_area = require("@turf/area");
|
|
362
|
+
var findContainingUnit = (poi, units) => {
|
|
363
|
+
const sameLevelUnits = units.filter(
|
|
364
|
+
(unit) => unit.properties.level_id === poi.properties.level_id
|
|
256
365
|
);
|
|
257
|
-
return
|
|
366
|
+
if (sameLevelUnits.length === 0) return null;
|
|
367
|
+
const hitAtCenter = sameLevelUnits.find((unit) => (0, import_boolean_point_in_polygon.booleanPointInPolygon)((0, import_center.center)(poi), unit));
|
|
368
|
+
if (hitAtCenter) return hitAtCenter;
|
|
369
|
+
let overlapCandidate = null;
|
|
370
|
+
let bestOverlapScore = 0;
|
|
371
|
+
for (const unit of sameLevelUnits) {
|
|
372
|
+
try {
|
|
373
|
+
const overlap = (0, import_intersect.intersect)(featureCollection([poi, unit]));
|
|
374
|
+
if (!overlap) continue;
|
|
375
|
+
const overlapArea = (0, import_area.area)(overlap);
|
|
376
|
+
if (overlapArea > bestOverlapScore) {
|
|
377
|
+
bestOverlapScore = overlapArea;
|
|
378
|
+
overlapCandidate = unit;
|
|
379
|
+
}
|
|
380
|
+
} catch (e) {
|
|
381
|
+
console.log(`Cannot compare POI (${poi.id}) with unit (${unit.id}):`, e.message);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (overlapCandidate && bestOverlapScore > 0) return overlapCandidate;
|
|
385
|
+
return null;
|
|
258
386
|
};
|
|
259
387
|
var findContainingUnitAtPoint = (point3, levelId, units) => {
|
|
260
388
|
const unit = units.find(
|
|
@@ -267,7 +395,17 @@ var findContainingUnitAtPoint = (point3, levelId, units) => {
|
|
|
267
395
|
}
|
|
268
396
|
}
|
|
269
397
|
);
|
|
270
|
-
return unit;
|
|
398
|
+
return unit ? unit : null;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// src/data/utils/getPointOnFeature.ts
|
|
402
|
+
var import_center2 = require("@turf/center");
|
|
403
|
+
var import_boolean_point_in_polygon2 = __toESM(require("@turf/boolean-point-in-polygon"));
|
|
404
|
+
var import_point_on_feature = __toESM(require("@turf/point-on-feature"));
|
|
405
|
+
var getPointOnFeature = (feature3) => {
|
|
406
|
+
const c = (0, import_center2.center)(feature3);
|
|
407
|
+
if ((0, import_boolean_point_in_polygon2.default)(c, feature3)) return c;
|
|
408
|
+
return (0, import_point_on_feature.default)(feature3);
|
|
271
409
|
};
|
|
272
410
|
|
|
273
411
|
// src/data/utils/trace.ts
|
|
@@ -435,8 +573,8 @@ var safeFetchFeature = async (featureType, params) => {
|
|
|
435
573
|
var import_query_core = require("@tanstack/query-core");
|
|
436
574
|
|
|
437
575
|
// src/data/populator/index.ts
|
|
438
|
-
var
|
|
439
|
-
var
|
|
576
|
+
var import_center3 = require("@turf/center");
|
|
577
|
+
var import_boolean_point_in_polygon3 = require("@turf/boolean-point-in-polygon");
|
|
440
578
|
var import_lodash3 = __toESM(require("lodash"));
|
|
441
579
|
var createPopulator = ({
|
|
442
580
|
internalFindById,
|
|
@@ -448,7 +586,29 @@ var createPopulator = ({
|
|
|
448
586
|
const populateFootprint = (footprint) => Promise.resolve(footprint);
|
|
449
587
|
const populateGeofence = (geofence) => Promise.resolve(geofence);
|
|
450
588
|
const populatePrivilege = (privilege) => Promise.resolve(privilege);
|
|
451
|
-
const populateEvent = (event) =>
|
|
589
|
+
const populateEvent = async (event) => {
|
|
590
|
+
const { feature_id, venue_id, local_category_ids = [] } = event.properties;
|
|
591
|
+
const venue = await internalFindById(venue_id);
|
|
592
|
+
const feature3 = await internalFindById(feature_id);
|
|
593
|
+
const localCategories = (await Promise.all(
|
|
594
|
+
local_category_ids.map((id) => internalFindById(id))
|
|
595
|
+
)).filter(Boolean);
|
|
596
|
+
const [parentCategories, subCategories] = import_lodash3.default.partition(
|
|
597
|
+
localCategories,
|
|
598
|
+
(cat) => cat?.properties.parent_id === null
|
|
599
|
+
);
|
|
600
|
+
return {
|
|
601
|
+
...event,
|
|
602
|
+
properties: {
|
|
603
|
+
...event.properties,
|
|
604
|
+
venue,
|
|
605
|
+
feature: feature3,
|
|
606
|
+
local_categories: localCategories,
|
|
607
|
+
local_parent_categories: parentCategories,
|
|
608
|
+
local_sub_categories: subCategories
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
};
|
|
452
612
|
const populatePromotion = async (promotion) => {
|
|
453
613
|
const { feature_id, venue_id, local_category_ids = [] } = promotion.properties;
|
|
454
614
|
const venue = await internalFindById(venue_id);
|
|
@@ -472,6 +632,16 @@ var createPopulator = ({
|
|
|
472
632
|
}
|
|
473
633
|
};
|
|
474
634
|
};
|
|
635
|
+
const populateSponsoredContent = async (sc) => {
|
|
636
|
+
const { venue_id, feature_id } = sc;
|
|
637
|
+
const venue = await internalFindById(venue_id);
|
|
638
|
+
const feature3 = feature_id ? await internalFindById(feature_id) : null;
|
|
639
|
+
return {
|
|
640
|
+
...sc,
|
|
641
|
+
venue,
|
|
642
|
+
feature: feature3
|
|
643
|
+
};
|
|
644
|
+
};
|
|
475
645
|
const populateAmenity = async (amenity) => {
|
|
476
646
|
const units = await Promise.all(
|
|
477
647
|
amenity.properties.unit_ids.map(internalFindById)
|
|
@@ -483,7 +653,7 @@ var createPopulator = ({
|
|
|
483
653
|
const ordinalKiosks = kiosks.filter(
|
|
484
654
|
(kiosk2) => kiosk2.properties.level_id === defaultLevel.id
|
|
485
655
|
);
|
|
486
|
-
const kiosk = ordinalKiosks.find((kiosk2) => (0,
|
|
656
|
+
const kiosk = ordinalKiosks.find((kiosk2) => (0, import_boolean_point_in_polygon3.booleanPointInPolygon)(amenity, kiosk2));
|
|
487
657
|
return {
|
|
488
658
|
...amenity,
|
|
489
659
|
properties: {
|
|
@@ -502,7 +672,7 @@ var createPopulator = ({
|
|
|
502
672
|
const venue = await internalFindById(unit.properties.venue_id);
|
|
503
673
|
const level = await internalFindById(unit.properties.level_id);
|
|
504
674
|
const sections = await internalFilterByType("section");
|
|
505
|
-
const section = sections.find((section2) => (0,
|
|
675
|
+
const section = sections.find((section2) => (0, import_boolean_point_in_polygon3.booleanPointInPolygon)(anchor, section2));
|
|
506
676
|
return {
|
|
507
677
|
...anchor,
|
|
508
678
|
properties: {
|
|
@@ -539,7 +709,7 @@ var createPopulator = ({
|
|
|
539
709
|
let section = null;
|
|
540
710
|
if (anchor) {
|
|
541
711
|
const sections = await internalFilterByType("section");
|
|
542
|
-
section = sections.find((section2) => (0,
|
|
712
|
+
section = sections.find((section2) => (0, import_boolean_point_in_polygon3.booleanPointInPolygon)(anchor, section2));
|
|
543
713
|
}
|
|
544
714
|
return {
|
|
545
715
|
...kiosk,
|
|
@@ -656,7 +826,7 @@ var createPopulator = ({
|
|
|
656
826
|
const level = await internalFindById(unit.properties.level_id);
|
|
657
827
|
const sections = await internalFilterByType("section");
|
|
658
828
|
try {
|
|
659
|
-
const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => (0,
|
|
829
|
+
const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => (0, import_boolean_point_in_polygon3.booleanPointInPolygon)((0, import_center3.center)(unit), section2)) : null;
|
|
660
830
|
return {
|
|
661
831
|
...unit,
|
|
662
832
|
properties: {
|
|
@@ -723,7 +893,8 @@ var createPopulator = ({
|
|
|
723
893
|
unit: populateUnit,
|
|
724
894
|
venue: populateVenue,
|
|
725
895
|
taxonomy: populateTaxonomy,
|
|
726
|
-
model3d: populateModel3D
|
|
896
|
+
model3d: populateModel3D,
|
|
897
|
+
"sponsored-content": populateSponsoredContent
|
|
727
898
|
};
|
|
728
899
|
};
|
|
729
900
|
|
|
@@ -732,25 +903,25 @@ var import_distance = require("@turf/distance");
|
|
|
732
903
|
var import_rhumb_bearing = require("@turf/rhumb-bearing");
|
|
733
904
|
|
|
734
905
|
// ../../node_modules/@turf/rhumb-destination/node_modules/@turf/helpers/dist/esm/index.js
|
|
735
|
-
var
|
|
736
|
-
var
|
|
737
|
-
centimeters:
|
|
738
|
-
centimetres:
|
|
906
|
+
var earthRadius2 = 63710088e-1;
|
|
907
|
+
var factors2 = {
|
|
908
|
+
centimeters: earthRadius2 * 100,
|
|
909
|
+
centimetres: earthRadius2 * 100,
|
|
739
910
|
degrees: 360 / (2 * Math.PI),
|
|
740
|
-
feet:
|
|
741
|
-
inches:
|
|
742
|
-
kilometers:
|
|
743
|
-
kilometres:
|
|
744
|
-
meters:
|
|
745
|
-
metres:
|
|
746
|
-
miles:
|
|
747
|
-
millimeters:
|
|
748
|
-
millimetres:
|
|
749
|
-
nauticalmiles:
|
|
911
|
+
feet: earthRadius2 * 3.28084,
|
|
912
|
+
inches: earthRadius2 * 39.37,
|
|
913
|
+
kilometers: earthRadius2 / 1e3,
|
|
914
|
+
kilometres: earthRadius2 / 1e3,
|
|
915
|
+
meters: earthRadius2,
|
|
916
|
+
metres: earthRadius2,
|
|
917
|
+
miles: earthRadius2 / 1609.344,
|
|
918
|
+
millimeters: earthRadius2 * 1e3,
|
|
919
|
+
millimetres: earthRadius2 * 1e3,
|
|
920
|
+
nauticalmiles: earthRadius2 / 1852,
|
|
750
921
|
radians: 1,
|
|
751
|
-
yards:
|
|
922
|
+
yards: earthRadius2 * 1.0936
|
|
752
923
|
};
|
|
753
|
-
function
|
|
924
|
+
function feature2(geom, properties, options = {}) {
|
|
754
925
|
const feat = { type: "Feature" };
|
|
755
926
|
if (options.id === 0 || options.id) {
|
|
756
927
|
feat.id = options.id;
|
|
@@ -762,7 +933,7 @@ function feature(geom, properties, options = {}) {
|
|
|
762
933
|
feat.geometry = geom;
|
|
763
934
|
return feat;
|
|
764
935
|
}
|
|
765
|
-
function
|
|
936
|
+
function point2(coordinates, properties, options = {}) {
|
|
766
937
|
if (!coordinates) {
|
|
767
938
|
throw new Error("coordinates is required");
|
|
768
939
|
}
|
|
@@ -772,28 +943,28 @@ function point(coordinates, properties, options = {}) {
|
|
|
772
943
|
if (coordinates.length < 2) {
|
|
773
944
|
throw new Error("coordinates must be at least 2 numbers long");
|
|
774
945
|
}
|
|
775
|
-
if (!
|
|
946
|
+
if (!isNumber2(coordinates[0]) || !isNumber2(coordinates[1])) {
|
|
776
947
|
throw new Error("coordinates must contain numbers");
|
|
777
948
|
}
|
|
778
949
|
const geom = {
|
|
779
950
|
type: "Point",
|
|
780
951
|
coordinates
|
|
781
952
|
};
|
|
782
|
-
return
|
|
953
|
+
return feature2(geom, properties, options);
|
|
783
954
|
}
|
|
784
955
|
function radiansToLength(radians, units = "kilometers") {
|
|
785
|
-
const factor =
|
|
956
|
+
const factor = factors2[units];
|
|
786
957
|
if (!factor) {
|
|
787
958
|
throw new Error(units + " units is invalid");
|
|
788
959
|
}
|
|
789
960
|
return radians * factor;
|
|
790
961
|
}
|
|
791
|
-
function lengthToRadians(
|
|
792
|
-
const factor =
|
|
962
|
+
function lengthToRadians(distance7, units = "kilometers") {
|
|
963
|
+
const factor = factors2[units];
|
|
793
964
|
if (!factor) {
|
|
794
965
|
throw new Error(units + " units is invalid");
|
|
795
966
|
}
|
|
796
|
-
return
|
|
967
|
+
return distance7 / factor;
|
|
797
968
|
}
|
|
798
969
|
function degreesToRadians(degrees) {
|
|
799
970
|
const normalisedDegrees = degrees % 360;
|
|
@@ -805,16 +976,16 @@ function convertLength(length, originalUnit = "kilometers", finalUnit = "kilomet
|
|
|
805
976
|
}
|
|
806
977
|
return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);
|
|
807
978
|
}
|
|
808
|
-
function
|
|
979
|
+
function isNumber2(num) {
|
|
809
980
|
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
810
981
|
}
|
|
811
982
|
|
|
812
983
|
// ../../node_modules/@turf/rhumb-destination/dist/esm/index.js
|
|
813
984
|
var import_invariant = require("@turf/invariant");
|
|
814
|
-
function rhumbDestination(origin,
|
|
815
|
-
const wasNegativeDistance =
|
|
985
|
+
function rhumbDestination(origin, distance7, bearing, options = {}) {
|
|
986
|
+
const wasNegativeDistance = distance7 < 0;
|
|
816
987
|
let distanceInMeters = convertLength(
|
|
817
|
-
Math.abs(
|
|
988
|
+
Math.abs(distance7),
|
|
818
989
|
options.units,
|
|
819
990
|
"meters"
|
|
820
991
|
);
|
|
@@ -826,11 +997,11 @@ function rhumbDestination(origin, distance6, bearing, options = {}) {
|
|
|
826
997
|
bearing
|
|
827
998
|
);
|
|
828
999
|
destination[0] += destination[0] - coords[0] > 180 ? -360 : coords[0] - destination[0] > 180 ? 360 : 0;
|
|
829
|
-
return
|
|
1000
|
+
return point2(destination, options.properties);
|
|
830
1001
|
}
|
|
831
|
-
function calculateRhumbDestination(origin,
|
|
832
|
-
radius = radius === void 0 ?
|
|
833
|
-
const delta =
|
|
1002
|
+
function calculateRhumbDestination(origin, distance7, bearing, radius) {
|
|
1003
|
+
radius = radius === void 0 ? earthRadius2 : Number(radius);
|
|
1004
|
+
const delta = distance7 / radius;
|
|
834
1005
|
const lambda1 = origin[0] * Math.PI / 180;
|
|
835
1006
|
const phi1 = degreesToRadians(origin[1]);
|
|
836
1007
|
const theta = degreesToRadians(bearing);
|
|
@@ -851,113 +1022,6 @@ function calculateRhumbDestination(origin, distance6, bearing, radius) {
|
|
|
851
1022
|
];
|
|
852
1023
|
}
|
|
853
1024
|
|
|
854
|
-
// node_modules/@turf/helpers/dist/esm/index.js
|
|
855
|
-
var earthRadius2 = 63710088e-1;
|
|
856
|
-
var factors2 = {
|
|
857
|
-
centimeters: earthRadius2 * 100,
|
|
858
|
-
centimetres: earthRadius2 * 100,
|
|
859
|
-
degrees: 360 / (2 * Math.PI),
|
|
860
|
-
feet: earthRadius2 * 3.28084,
|
|
861
|
-
inches: earthRadius2 * 39.37,
|
|
862
|
-
kilometers: earthRadius2 / 1e3,
|
|
863
|
-
kilometres: earthRadius2 / 1e3,
|
|
864
|
-
meters: earthRadius2,
|
|
865
|
-
metres: earthRadius2,
|
|
866
|
-
miles: earthRadius2 / 1609.344,
|
|
867
|
-
millimeters: earthRadius2 * 1e3,
|
|
868
|
-
millimetres: earthRadius2 * 1e3,
|
|
869
|
-
nauticalmiles: earthRadius2 / 1852,
|
|
870
|
-
radians: 1,
|
|
871
|
-
yards: earthRadius2 * 1.0936
|
|
872
|
-
};
|
|
873
|
-
function feature2(geom, properties, options = {}) {
|
|
874
|
-
const feat = { type: "Feature" };
|
|
875
|
-
if (options.id === 0 || options.id) {
|
|
876
|
-
feat.id = options.id;
|
|
877
|
-
}
|
|
878
|
-
if (options.bbox) {
|
|
879
|
-
feat.bbox = options.bbox;
|
|
880
|
-
}
|
|
881
|
-
feat.properties = properties || {};
|
|
882
|
-
feat.geometry = geom;
|
|
883
|
-
return feat;
|
|
884
|
-
}
|
|
885
|
-
function point2(coordinates, properties, options = {}) {
|
|
886
|
-
if (!coordinates) {
|
|
887
|
-
throw new Error("coordinates is required");
|
|
888
|
-
}
|
|
889
|
-
if (!Array.isArray(coordinates)) {
|
|
890
|
-
throw new Error("coordinates must be an Array");
|
|
891
|
-
}
|
|
892
|
-
if (coordinates.length < 2) {
|
|
893
|
-
throw new Error("coordinates must be at least 2 numbers long");
|
|
894
|
-
}
|
|
895
|
-
if (!isNumber2(coordinates[0]) || !isNumber2(coordinates[1])) {
|
|
896
|
-
throw new Error("coordinates must contain numbers");
|
|
897
|
-
}
|
|
898
|
-
const geom = {
|
|
899
|
-
type: "Point",
|
|
900
|
-
coordinates
|
|
901
|
-
};
|
|
902
|
-
return feature2(geom, properties, options);
|
|
903
|
-
}
|
|
904
|
-
function polygon(coordinates, properties, options = {}) {
|
|
905
|
-
for (const ring of coordinates) {
|
|
906
|
-
if (ring.length < 4) {
|
|
907
|
-
throw new Error(
|
|
908
|
-
"Each LinearRing of a Polygon must have 4 or more Positions."
|
|
909
|
-
);
|
|
910
|
-
}
|
|
911
|
-
if (ring[ring.length - 1].length !== ring[0].length) {
|
|
912
|
-
throw new Error("First and last Position are not equivalent.");
|
|
913
|
-
}
|
|
914
|
-
for (let j = 0; j < ring[ring.length - 1].length; j++) {
|
|
915
|
-
if (ring[ring.length - 1][j] !== ring[0][j]) {
|
|
916
|
-
throw new Error("First and last Position are not equivalent.");
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
const geom = {
|
|
921
|
-
type: "Polygon",
|
|
922
|
-
coordinates
|
|
923
|
-
};
|
|
924
|
-
return feature2(geom, properties, options);
|
|
925
|
-
}
|
|
926
|
-
function lineString(coordinates, properties, options = {}) {
|
|
927
|
-
if (coordinates.length < 2) {
|
|
928
|
-
throw new Error("coordinates must be an array of two or more positions");
|
|
929
|
-
}
|
|
930
|
-
const geom = {
|
|
931
|
-
type: "LineString",
|
|
932
|
-
coordinates
|
|
933
|
-
};
|
|
934
|
-
return feature2(geom, properties, options);
|
|
935
|
-
}
|
|
936
|
-
function featureCollection(features, options = {}) {
|
|
937
|
-
const fc = { type: "FeatureCollection" };
|
|
938
|
-
if (options.id) {
|
|
939
|
-
fc.id = options.id;
|
|
940
|
-
}
|
|
941
|
-
if (options.bbox) {
|
|
942
|
-
fc.bbox = options.bbox;
|
|
943
|
-
}
|
|
944
|
-
fc.features = features;
|
|
945
|
-
return fc;
|
|
946
|
-
}
|
|
947
|
-
function multiLineString(coordinates, properties, options = {}) {
|
|
948
|
-
const geom = {
|
|
949
|
-
type: "MultiLineString",
|
|
950
|
-
coordinates
|
|
951
|
-
};
|
|
952
|
-
return feature2(geom, properties, options);
|
|
953
|
-
}
|
|
954
|
-
function isNumber2(num) {
|
|
955
|
-
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
956
|
-
}
|
|
957
|
-
function isObject(input) {
|
|
958
|
-
return input !== null && typeof input === "object" && !Array.isArray(input);
|
|
959
|
-
}
|
|
960
|
-
|
|
961
1025
|
// src/data/navigate/services/landmark/utils/outerRingsToLine.ts
|
|
962
1026
|
var outerRingsToLine = (geom) => {
|
|
963
1027
|
if (geom.type === "Polygon") {
|
|
@@ -984,7 +1048,7 @@ var distanceToWall = (p, wallLines) => {
|
|
|
984
1048
|
};
|
|
985
1049
|
|
|
986
1050
|
// src/data/navigate/services/landmark/utils/toLandmark.ts
|
|
987
|
-
var
|
|
1051
|
+
var import_center4 = require("@turf/center");
|
|
988
1052
|
var occupantToLandmark = (occupant, findByIdSync) => {
|
|
989
1053
|
const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
|
|
990
1054
|
const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
|
|
@@ -994,7 +1058,7 @@ var occupantToLandmark = (occupant, findByIdSync) => {
|
|
|
994
1058
|
if (!level) return null;
|
|
995
1059
|
return {
|
|
996
1060
|
name: occupant.properties.name,
|
|
997
|
-
point: (0,
|
|
1061
|
+
point: (0, import_center4.center)(location.geometry).geometry.coordinates,
|
|
998
1062
|
boundary: outerRingsToLine(location.geometry),
|
|
999
1063
|
level_id: location.properties.level_id,
|
|
1000
1064
|
is_priority: occupant.properties.is_landmark,
|
|
@@ -1006,7 +1070,7 @@ var unitToLandmark = (unit, findByIdSync) => {
|
|
|
1006
1070
|
if (!level) return null;
|
|
1007
1071
|
return {
|
|
1008
1072
|
name: { en: unit.properties.category },
|
|
1009
|
-
point: (0,
|
|
1073
|
+
point: (0, import_center4.center)(unit.geometry).geometry.coordinates,
|
|
1010
1074
|
boundary: outerRingsToLine(unit.geometry),
|
|
1011
1075
|
level_id: unit.properties.level_id,
|
|
1012
1076
|
is_priority: false,
|
|
@@ -1018,7 +1082,7 @@ var openingToLandmark = (opening, findByIdSync) => {
|
|
|
1018
1082
|
if (!level) return null;
|
|
1019
1083
|
return {
|
|
1020
1084
|
name: opening.properties.name?.en ? opening.properties.name : { en: "Entrance / Exit" },
|
|
1021
|
-
point: (0,
|
|
1085
|
+
point: (0, import_center4.center)(opening.geometry).geometry.coordinates,
|
|
1022
1086
|
level_id: opening.properties.level_id,
|
|
1023
1087
|
is_priority: true,
|
|
1024
1088
|
ordinal: level.properties.ordinal
|
|
@@ -1029,7 +1093,7 @@ var amenityToLandmark = (amenity, findByIdSync) => {
|
|
|
1029
1093
|
if (!level) return null;
|
|
1030
1094
|
return {
|
|
1031
1095
|
name: amenity.properties.name ?? { en: amenity.properties.category, th: amenity.properties.category },
|
|
1032
|
-
point: (0,
|
|
1096
|
+
point: (0, import_center4.center)(amenity.geometry).geometry.coordinates,
|
|
1033
1097
|
level_id: amenity.properties.level_id,
|
|
1034
1098
|
is_priority: true,
|
|
1035
1099
|
ordinal: level.properties.ordinal
|
|
@@ -1082,7 +1146,7 @@ var createLandmarkService = (ctx) => {
|
|
|
1082
1146
|
|
|
1083
1147
|
// src/data/navigate/context/createNavigateContext.ts
|
|
1084
1148
|
var createFindByIdSync = (data) => {
|
|
1085
|
-
const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
|
|
1149
|
+
const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], sections = [], units } = data;
|
|
1086
1150
|
const featureById = /* @__PURE__ */ new Map();
|
|
1087
1151
|
const entries = [
|
|
1088
1152
|
...amenities,
|
|
@@ -1093,6 +1157,7 @@ var createFindByIdSync = (data) => {
|
|
|
1093
1157
|
...relationships,
|
|
1094
1158
|
...occupants,
|
|
1095
1159
|
...openings,
|
|
1160
|
+
...sections,
|
|
1096
1161
|
...units
|
|
1097
1162
|
];
|
|
1098
1163
|
for (const f of entries) featureById.set(f.id, f);
|
|
@@ -1113,17 +1178,17 @@ var createNavigateContext = (options) => {
|
|
|
1113
1178
|
};
|
|
1114
1179
|
|
|
1115
1180
|
// src/data/navigate/client.ts
|
|
1116
|
-
var
|
|
1181
|
+
var import_boolean_point_in_polygon5 = require("@turf/boolean-point-in-polygon");
|
|
1117
1182
|
|
|
1118
1183
|
// src/data/navigate/services/graph/prepare.ts
|
|
1119
|
-
var
|
|
1184
|
+
var import_lodash19 = __toESM(require("lodash"));
|
|
1120
1185
|
var import_node_dijkstra = __toESM(require("node-dijkstra"));
|
|
1121
|
-
var
|
|
1122
|
-
var
|
|
1186
|
+
var import_distance5 = require("@turf/distance");
|
|
1187
|
+
var import_center8 = require("@turf/center");
|
|
1123
1188
|
|
|
1124
1189
|
// src/data/navigate/services/graph/nodemap/createTraversalNodeMap.ts
|
|
1125
1190
|
var import_distance2 = require("@turf/distance");
|
|
1126
|
-
var
|
|
1191
|
+
var import_center5 = require("@turf/center");
|
|
1127
1192
|
var import_lodash4 = __toESM(require("lodash"));
|
|
1128
1193
|
|
|
1129
1194
|
// src/data/navigate/services/graph/constants.ts
|
|
@@ -1172,14 +1237,14 @@ var createTraversalNodeMap = (unitOpenings, options) => {
|
|
|
1172
1237
|
const opening = features[currentIndex];
|
|
1173
1238
|
const feature3 = features[j];
|
|
1174
1239
|
try {
|
|
1175
|
-
const
|
|
1176
|
-
(0,
|
|
1177
|
-
(0,
|
|
1240
|
+
const distance7 = (0, import_distance2.distance)(
|
|
1241
|
+
(0, import_center5.center)(opening.geometry),
|
|
1242
|
+
(0, import_center5.center)(feature3.geometry),
|
|
1178
1243
|
{ units: "meters" }
|
|
1179
1244
|
) + (distanceOptions?.baseDistance ?? 0);
|
|
1180
1245
|
if (opening.id === feature3.id) continue;
|
|
1181
|
-
import_lodash4.default.set(relationshipGraph, `${opening.id}.${feature3.id}`,
|
|
1182
|
-
import_lodash4.default.set(relationshipGraph, `${feature3.id}.${opening.id}`,
|
|
1246
|
+
import_lodash4.default.set(relationshipGraph, `${opening.id}.${feature3.id}`, distance7);
|
|
1247
|
+
import_lodash4.default.set(relationshipGraph, `${feature3.id}.${opening.id}`, distance7);
|
|
1183
1248
|
counter++;
|
|
1184
1249
|
} catch (error) {
|
|
1185
1250
|
continue;
|
|
@@ -1260,15 +1325,15 @@ var createElevatorNodeMap = (elevatorLikeRelationships, unitOpenings, options) =
|
|
|
1260
1325
|
const { opening: theOpening, level: theLevel } = theConnection;
|
|
1261
1326
|
if (theConnection.opening.id === otherConnection.opening.id) continue;
|
|
1262
1327
|
const { opening: otherOpening, level: otherLevel } = otherConnection;
|
|
1263
|
-
let
|
|
1328
|
+
let distance7 = baseDistance;
|
|
1264
1329
|
if (scaleDistanceByLevel && theLevel && otherLevel) {
|
|
1265
1330
|
const originOrdinal = theLevel.properties.ordinal;
|
|
1266
1331
|
const connectionOrdinal = otherLevel.properties.ordinal;
|
|
1267
1332
|
const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
|
|
1268
|
-
if (levelDifference > 0)
|
|
1333
|
+
if (levelDifference > 0) distance7 *= levelDifference;
|
|
1269
1334
|
}
|
|
1270
|
-
import_lodash5.default.set(elevatorNodeMap, `${theOpening.id}.${otherOpening.id}`,
|
|
1271
|
-
import_lodash5.default.set(elevatorNodeMap, `${otherOpening.id}.${theOpening.id}`,
|
|
1335
|
+
import_lodash5.default.set(elevatorNodeMap, `${theOpening.id}.${otherOpening.id}`, distance7);
|
|
1336
|
+
import_lodash5.default.set(elevatorNodeMap, `${otherOpening.id}.${theOpening.id}`, distance7);
|
|
1272
1337
|
counter++;
|
|
1273
1338
|
}
|
|
1274
1339
|
}
|
|
@@ -1328,28 +1393,35 @@ var createRampNodeMap = (relationships, options) => {
|
|
|
1328
1393
|
|
|
1329
1394
|
// src/data/navigate/services/graph/nodemap/createStairNodeMap.ts
|
|
1330
1395
|
var import_lodash9 = __toESM(require("lodash"));
|
|
1331
|
-
var createStairNodeMap = (
|
|
1396
|
+
var createStairNodeMap = (stairLikeRelationships, unitOpenings, options) => {
|
|
1332
1397
|
const t0 = performance.now();
|
|
1333
1398
|
const { levels = [], openings = [], units = [] } = options.data;
|
|
1334
1399
|
const { baseDistance, scaleDistanceByLevel } = getDistanceOptions(options.unitDistanceOptions, "stairs");
|
|
1335
1400
|
let elevatorNodeMap = {};
|
|
1336
1401
|
let counter = 0;
|
|
1337
|
-
for (const relationship of
|
|
1402
|
+
for (const relationship of stairLikeRelationships) {
|
|
1338
1403
|
try {
|
|
1339
1404
|
const {
|
|
1340
|
-
origin:
|
|
1405
|
+
origin: originTypeAndId,
|
|
1406
|
+
// opening
|
|
1341
1407
|
intermediary,
|
|
1342
|
-
|
|
1408
|
+
// units
|
|
1409
|
+
destination: destinationTypeAndId
|
|
1410
|
+
// opening
|
|
1343
1411
|
} = relationship.properties;
|
|
1344
|
-
const origin = openings.find((opening) => opening.id ===
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1412
|
+
const origin = openings.find((opening) => opening.id === originTypeAndId.id);
|
|
1413
|
+
let originOpeningAndLevels = [];
|
|
1414
|
+
if (origin) {
|
|
1415
|
+
const originLevel = levels.find((level) => level.id === origin?.properties.level_id);
|
|
1416
|
+
originOpeningAndLevels.push({ opening: origin, level: originLevel });
|
|
1417
|
+
}
|
|
1418
|
+
const destination = openings.find((opening) => opening.id === destinationTypeAndId.id);
|
|
1419
|
+
let destinationOpeningAndLevels = [];
|
|
1420
|
+
if (destination) {
|
|
1421
|
+
const destinationLevel = levels.find((level) => level.id === destination?.properties.level_id);
|
|
1422
|
+
destinationOpeningAndLevels.push({ opening: destination, level: destinationLevel });
|
|
1423
|
+
}
|
|
1424
|
+
const intermediaryOpeningAndLevels = (intermediary || []).map((unitTypeAndId) => {
|
|
1353
1425
|
const openings2 = unitOpenings[unitTypeAndId.id];
|
|
1354
1426
|
const unit = units.find((unit2) => unit2.id === unitTypeAndId.id);
|
|
1355
1427
|
if (!unit) return [];
|
|
@@ -1357,20 +1429,28 @@ var createStairNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
|
|
|
1357
1429
|
if (!level) return [];
|
|
1358
1430
|
return openings2.map((opening) => ({ opening, level }));
|
|
1359
1431
|
}).flat();
|
|
1360
|
-
const connections = [
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
const
|
|
1369
|
-
if (
|
|
1432
|
+
const connections = compact([
|
|
1433
|
+
...originOpeningAndLevels,
|
|
1434
|
+
...intermediaryOpeningAndLevels,
|
|
1435
|
+
...destinationOpeningAndLevels
|
|
1436
|
+
]);
|
|
1437
|
+
if (connections.length === 0) return elevatorNodeMap;
|
|
1438
|
+
for (const theConnection of connections) {
|
|
1439
|
+
for (const otherConnection of connections) {
|
|
1440
|
+
const { opening: theOpening, level: theLevel } = theConnection;
|
|
1441
|
+
if (theConnection.opening.id === otherConnection.opening.id) continue;
|
|
1442
|
+
const { opening: otherOpening, level: otherLevel } = otherConnection;
|
|
1443
|
+
let distance7 = baseDistance;
|
|
1444
|
+
if (scaleDistanceByLevel && theLevel && otherLevel) {
|
|
1445
|
+
const originOrdinal = theLevel.properties.ordinal;
|
|
1446
|
+
const connectionOrdinal = otherLevel.properties.ordinal;
|
|
1447
|
+
const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
|
|
1448
|
+
if (levelDifference > 0) distance7 *= levelDifference;
|
|
1449
|
+
}
|
|
1450
|
+
import_lodash9.default.set(elevatorNodeMap, `${theOpening.id}.${otherOpening.id}`, distance7);
|
|
1451
|
+
import_lodash9.default.set(elevatorNodeMap, `${otherOpening.id}.${theOpening.id}`, distance7);
|
|
1452
|
+
counter++;
|
|
1370
1453
|
}
|
|
1371
|
-
import_lodash9.default.set(elevatorNodeMap, `${origin.id}.${opening.id}`, distance6);
|
|
1372
|
-
import_lodash9.default.set(elevatorNodeMap, `${opening.id}.${origin.id}`, distance6);
|
|
1373
|
-
counter++;
|
|
1374
1454
|
}
|
|
1375
1455
|
} catch (err) {
|
|
1376
1456
|
console.warn(
|
|
@@ -1390,7 +1470,7 @@ var createStairNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
|
|
|
1390
1470
|
};
|
|
1391
1471
|
|
|
1392
1472
|
// src/data/navigate/services/graph/nodemap/createOccupantNodeMap.ts
|
|
1393
|
-
var
|
|
1473
|
+
var import_lodash11 = __toESM(require("lodash"));
|
|
1394
1474
|
var createOccupantNodeMap = (occupants) => {
|
|
1395
1475
|
const t0 = performance.now();
|
|
1396
1476
|
let nodeMap = {};
|
|
@@ -1400,13 +1480,13 @@ var createOccupantNodeMap = (occupants) => {
|
|
|
1400
1480
|
const occupantRoomIds = compact(!is_maintenance ? [unit_id, ...unit_ids] : [temp_unit_id]);
|
|
1401
1481
|
const occupantKioskIds = compact(!is_maintenance ? [kiosk_id, ...kiosk_ids] : [temp_kiosk_id]);
|
|
1402
1482
|
for (const roomId of occupantRoomIds) {
|
|
1403
|
-
|
|
1404
|
-
|
|
1483
|
+
import_lodash11.default.set(nodeMap, `${roomId}.${occupant.id}`, 1e-3);
|
|
1484
|
+
import_lodash11.default.set(nodeMap, `${occupant.id}.${roomId}`, 1e-3);
|
|
1405
1485
|
counter++;
|
|
1406
1486
|
}
|
|
1407
1487
|
for (const kioskId of occupantKioskIds) {
|
|
1408
|
-
|
|
1409
|
-
|
|
1488
|
+
import_lodash11.default.set(nodeMap, `${kioskId}.${occupant.id}`, 1e-3);
|
|
1489
|
+
import_lodash11.default.set(nodeMap, `${occupant.id}.${kioskId}`, 1e-3);
|
|
1410
1490
|
counter++;
|
|
1411
1491
|
}
|
|
1412
1492
|
});
|
|
@@ -1415,11 +1495,11 @@ var createOccupantNodeMap = (occupants) => {
|
|
|
1415
1495
|
return nodeMap;
|
|
1416
1496
|
};
|
|
1417
1497
|
|
|
1418
|
-
// src/data/navigate/services/graph/nodemap/
|
|
1419
|
-
var
|
|
1498
|
+
// src/data/navigate/services/graph/nodemap/createPoiToWalkwayOpeningNodeMap.ts
|
|
1499
|
+
var import_center6 = require("@turf/center");
|
|
1420
1500
|
var import_distance3 = require("@turf/distance");
|
|
1421
|
-
var
|
|
1422
|
-
var
|
|
1501
|
+
var import_lodash13 = __toESM(require("lodash"));
|
|
1502
|
+
var createPoiToWalkwayOpeningNodeMap = (features, getFeatureUnit, unitOpenings) => {
|
|
1423
1503
|
const t0 = performance.now();
|
|
1424
1504
|
let nodeMap = {};
|
|
1425
1505
|
let counter = 0;
|
|
@@ -1428,13 +1508,13 @@ var createPOINodeMap = (features, getFeatureUnit, unitOpenings) => {
|
|
|
1428
1508
|
const locatedOnUnitId = getFeatureUnit(feat);
|
|
1429
1509
|
if (locatedOnUnitId) {
|
|
1430
1510
|
const openings = unitOpenings[locatedOnUnitId] ?? [];
|
|
1431
|
-
const
|
|
1511
|
+
const center6 = (0, import_center6.center)(feat);
|
|
1432
1512
|
for (const opening of openings) {
|
|
1433
1513
|
try {
|
|
1434
|
-
const openingCenter = (0,
|
|
1435
|
-
const dis = (0, import_distance3.distance)(
|
|
1436
|
-
|
|
1437
|
-
|
|
1514
|
+
const openingCenter = (0, import_center6.center)(opening);
|
|
1515
|
+
const dis = (0, import_distance3.distance)(center6, openingCenter, { units: "meters" }) + BASE_POI_BASEDISTANCE;
|
|
1516
|
+
import_lodash13.default.set(nodeMap, `${opening.id}.${feat.id}`, dis);
|
|
1517
|
+
import_lodash13.default.set(nodeMap, `${feat.id}.${opening.id}`, dis);
|
|
1438
1518
|
counter++;
|
|
1439
1519
|
} catch (err) {
|
|
1440
1520
|
console.log(err, opening);
|
|
@@ -1452,6 +1532,35 @@ var createPOINodeMap = (features, getFeatureUnit, unitOpenings) => {
|
|
|
1452
1532
|
return nodeMap;
|
|
1453
1533
|
};
|
|
1454
1534
|
|
|
1535
|
+
// src/data/navigate/services/graph/nodemap/createWalkwayNodeMap.ts
|
|
1536
|
+
var import_lodash14 = __toESM(require("lodash"));
|
|
1537
|
+
var import_distance4 = require("@turf/distance");
|
|
1538
|
+
var import_center7 = require("@turf/center");
|
|
1539
|
+
var createWalkwayNodeMap = (poiOnWalkways) => {
|
|
1540
|
+
const t0 = performance.now();
|
|
1541
|
+
let nodeMap = {};
|
|
1542
|
+
let counter = 0;
|
|
1543
|
+
for (const [walkwayId, pois] of Object.entries(poiOnWalkways)) {
|
|
1544
|
+
if (pois.length > 1) {
|
|
1545
|
+
for (let i = 0; i < pois.length; i++) {
|
|
1546
|
+
const thisPoi = pois[i];
|
|
1547
|
+
for (let j = 0; j < pois.length; j++) {
|
|
1548
|
+
const thatPoi = pois[j];
|
|
1549
|
+
if (thisPoi.id !== thatPoi.id) {
|
|
1550
|
+
const dis = (0, import_distance4.distance)((0, import_center7.center)(thisPoi), (0, import_center7.center)(thatPoi), { units: "meters" });
|
|
1551
|
+
import_lodash14.default.set(nodeMap, `${thisPoi.id}.${thatPoi.id}`, dis);
|
|
1552
|
+
import_lodash14.default.set(nodeMap, `${thatPoi.id}.${thisPoi.id}`, dis);
|
|
1553
|
+
counter++;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
const t1 = performance.now();
|
|
1560
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} within same walkway relationships`, t1 - t0);
|
|
1561
|
+
return nodeMap;
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1455
1564
|
// src/data/navigate/services/graph/utils/mergeNodeMap.ts
|
|
1456
1565
|
var mergeNodeMap = (nodeMaps) => {
|
|
1457
1566
|
const out = {};
|
|
@@ -1467,7 +1576,7 @@ var mergeNodeMap = (nodeMaps) => {
|
|
|
1467
1576
|
};
|
|
1468
1577
|
|
|
1469
1578
|
// src/data/navigate/services/graph/utils/createUnitOpenings.ts
|
|
1470
|
-
var
|
|
1579
|
+
var import_lodash15 = require("lodash");
|
|
1471
1580
|
var createUnitOpenings = (relationships, units, openings) => {
|
|
1472
1581
|
const openingConnections = {};
|
|
1473
1582
|
const relationshipMap = /* @__PURE__ */ new Map();
|
|
@@ -1493,7 +1602,7 @@ var createUnitOpenings = (relationships, units, openings) => {
|
|
|
1493
1602
|
const relationshipIntermediary = relationshipIntermediaryTypeAndId.map(({ id }) => {
|
|
1494
1603
|
return openings.find((opening) => !!opening && opening.id === id);
|
|
1495
1604
|
});
|
|
1496
|
-
openingConnections[unitId] = (0,
|
|
1605
|
+
openingConnections[unitId] = (0, import_lodash15.uniqBy)(
|
|
1497
1606
|
[...openingConnections[unitId] || [], ...relationshipIntermediary],
|
|
1498
1607
|
"id"
|
|
1499
1608
|
);
|
|
@@ -1507,18 +1616,49 @@ var parseOrdinalCoordinate = (id) => {
|
|
|
1507
1616
|
};
|
|
1508
1617
|
|
|
1509
1618
|
// src/data/navigate/services/graph/utils/createUnitsKiosks.ts
|
|
1510
|
-
var
|
|
1619
|
+
var import_lodash17 = require("lodash");
|
|
1511
1620
|
var createUnitsKiosks = (units, kiosks) => {
|
|
1512
1621
|
const unitsWithKiosks = {};
|
|
1513
1622
|
kiosks.forEach((kiosk) => {
|
|
1514
1623
|
const unitId = findContainingUnit(kiosk, units)?.id;
|
|
1515
1624
|
if (!unitId) return;
|
|
1516
|
-
const prevValues = (0,
|
|
1517
|
-
(0,
|
|
1625
|
+
const prevValues = (0, import_lodash17.get)(unitsWithKiosks, unitId, []);
|
|
1626
|
+
(0, import_lodash17.set)(unitsWithKiosks, unitId, [...prevValues, kiosk]);
|
|
1518
1627
|
});
|
|
1519
1628
|
return unitsWithKiosks;
|
|
1520
1629
|
};
|
|
1521
1630
|
|
|
1631
|
+
// src/data/navigate/services/graph/utils/createUnitsAmenities.ts
|
|
1632
|
+
var import_lodash18 = require("lodash");
|
|
1633
|
+
var createUnitsAmenities = (units, amenities) => {
|
|
1634
|
+
const unitsWithAmenities = {};
|
|
1635
|
+
amenities.forEach((amenity) => {
|
|
1636
|
+
const unitId = findContainingUnit(amenity, units)?.id;
|
|
1637
|
+
if (!unitId) return;
|
|
1638
|
+
const prevValues = (0, import_lodash18.get)(unitsWithAmenities, unitId, []);
|
|
1639
|
+
(0, import_lodash18.set)(unitsWithAmenities, unitId, [...prevValues, amenity]);
|
|
1640
|
+
});
|
|
1641
|
+
return unitsWithAmenities;
|
|
1642
|
+
};
|
|
1643
|
+
|
|
1644
|
+
// src/data/navigate/constants.ts
|
|
1645
|
+
var WALKABLE_UNIT_CATEGORY = [
|
|
1646
|
+
"walkway",
|
|
1647
|
+
"parking",
|
|
1648
|
+
"room",
|
|
1649
|
+
"terrace",
|
|
1650
|
+
"unenclosedarea",
|
|
1651
|
+
"vegetation",
|
|
1652
|
+
"unspecified"
|
|
1653
|
+
];
|
|
1654
|
+
var VERTICAL_TRAVERSAL_CATEGORY = [
|
|
1655
|
+
"elevator",
|
|
1656
|
+
"escalator",
|
|
1657
|
+
"stairs",
|
|
1658
|
+
"stairs.emergencyexit",
|
|
1659
|
+
"ramp"
|
|
1660
|
+
];
|
|
1661
|
+
|
|
1522
1662
|
// src/data/navigate/services/graph/prepare.ts
|
|
1523
1663
|
var prepareGraph = (options) => {
|
|
1524
1664
|
const {
|
|
@@ -1529,7 +1669,8 @@ var prepareGraph = (options) => {
|
|
|
1529
1669
|
relationships = [],
|
|
1530
1670
|
openings = [],
|
|
1531
1671
|
units = [],
|
|
1532
|
-
kiosks = []
|
|
1672
|
+
kiosks = [],
|
|
1673
|
+
sections = []
|
|
1533
1674
|
}
|
|
1534
1675
|
} = options;
|
|
1535
1676
|
const {
|
|
@@ -1538,10 +1679,12 @@ var prepareGraph = (options) => {
|
|
|
1538
1679
|
ramp: rampRelationships = [],
|
|
1539
1680
|
elevator: elevatorRelationships = [],
|
|
1540
1681
|
stairs: stairsRelationships = []
|
|
1541
|
-
} =
|
|
1682
|
+
} = import_lodash19.default.groupBy(relationships, "properties.category");
|
|
1542
1683
|
const unitOpenings = createUnitOpenings(traversalRelationships, units, openings);
|
|
1543
|
-
const
|
|
1684
|
+
const walkableUnits = units.filter((unit) => WALKABLE_UNIT_CATEGORY.includes(unit.properties.category));
|
|
1685
|
+
const walkwayUnits = walkableUnits.filter((unit) => unit.properties.category === "walkway");
|
|
1544
1686
|
const unitKiosks = createUnitsKiosks(walkwayUnits, kiosks);
|
|
1687
|
+
const unitAmenities = createUnitsAmenities(walkwayUnits, amenities);
|
|
1545
1688
|
const traversalNodeMap = createTraversalNodeMap(unitOpenings, options);
|
|
1546
1689
|
const escalatorNodeMap = createEscalatorNodeMap(escalatorRelationships, options);
|
|
1547
1690
|
const rampNodeMap = createRampNodeMap(rampRelationships, options);
|
|
@@ -1555,10 +1698,26 @@ var prepareGraph = (options) => {
|
|
|
1555
1698
|
unitOpenings,
|
|
1556
1699
|
options
|
|
1557
1700
|
);
|
|
1558
|
-
const amenityNodeMap =
|
|
1559
|
-
const anchorsNodeMap =
|
|
1560
|
-
const
|
|
1561
|
-
|
|
1701
|
+
const amenityNodeMap = createPoiToWalkwayOpeningNodeMap(amenities, (amenity) => amenity?.properties?.unit_ids?.[0] || null, unitOpenings);
|
|
1702
|
+
const anchorsNodeMap = createPoiToWalkwayOpeningNodeMap(anchors, (anchor) => anchor?.properties?.unit_id, unitOpenings);
|
|
1703
|
+
const sectionNodeMap = createPoiToWalkwayOpeningNodeMap(
|
|
1704
|
+
sections,
|
|
1705
|
+
(section) => {
|
|
1706
|
+
const sectionLevelId = section?.properties?.level_id;
|
|
1707
|
+
const displayPoint = section?.properties?.display_point;
|
|
1708
|
+
const unit = findContainingUnitAtPoint(displayPoint, sectionLevelId, walkableUnits) || findContainingUnit(section, walkableUnits);
|
|
1709
|
+
if (!unit) {
|
|
1710
|
+
console.warn(`[venue-js] Section ${section.id} on level ${section?.properties?.level_id} has no walkable containing unit \u2014 section will be excluded from routing.`);
|
|
1711
|
+
return null;
|
|
1712
|
+
}
|
|
1713
|
+
return unit.id;
|
|
1714
|
+
},
|
|
1715
|
+
unitOpenings
|
|
1716
|
+
);
|
|
1717
|
+
const kioskNodeMap = createPoiToWalkwayOpeningNodeMap(kiosks, (kiosk) => findContainingUnit(kiosk, walkwayUnits)?.id || null, unitOpenings);
|
|
1718
|
+
const poiOnWalkways = import_lodash19.default.mergeWith({}, unitKiosks, unitAmenities, (objValue = [], srcValue = []) => objValue.concat(srcValue));
|
|
1719
|
+
const walkwayNodeMap = createWalkwayNodeMap(poiOnWalkways);
|
|
1720
|
+
const unitNodeMap = createPoiToWalkwayOpeningNodeMap(units, (unit) => unit.id, unitOpenings);
|
|
1562
1721
|
const occupantNodeMap = createOccupantNodeMap(occupants);
|
|
1563
1722
|
const defaultGraph = new import_node_dijkstra.default(mergeNodeMap([
|
|
1564
1723
|
traversalNodeMap,
|
|
@@ -1568,7 +1727,9 @@ var prepareGraph = (options) => {
|
|
|
1568
1727
|
stairNodeMap,
|
|
1569
1728
|
amenityNodeMap,
|
|
1570
1729
|
anchorsNodeMap,
|
|
1730
|
+
sectionNodeMap,
|
|
1571
1731
|
kioskNodeMap,
|
|
1732
|
+
walkwayNodeMap,
|
|
1572
1733
|
unitNodeMap,
|
|
1573
1734
|
occupantNodeMap
|
|
1574
1735
|
]));
|
|
@@ -1578,7 +1739,9 @@ var prepareGraph = (options) => {
|
|
|
1578
1739
|
elevatorNodeMap,
|
|
1579
1740
|
amenityNodeMap,
|
|
1580
1741
|
anchorsNodeMap,
|
|
1742
|
+
sectionNodeMap,
|
|
1581
1743
|
kioskNodeMap,
|
|
1744
|
+
walkwayNodeMap,
|
|
1582
1745
|
unitNodeMap,
|
|
1583
1746
|
occupantNodeMap
|
|
1584
1747
|
]));
|
|
@@ -1589,8 +1752,8 @@ var prepareGraph = (options) => {
|
|
|
1589
1752
|
const kiosks2 = unitKiosks[locatedOnUnit.id] ?? [];
|
|
1590
1753
|
const routingGraphs = [accessibleGraph, defaultGraph];
|
|
1591
1754
|
for (const opening of openings2) {
|
|
1592
|
-
const openingCenter = (0,
|
|
1593
|
-
const dis = (0,
|
|
1755
|
+
const openingCenter = (0, import_center8.center)(opening);
|
|
1756
|
+
const dis = (0, import_distance5.distance)([lng, lat], openingCenter, { units: "meters" });
|
|
1594
1757
|
for (const routingGraph of routingGraphs) {
|
|
1595
1758
|
const updatedCoordsNodeGraph = routingGraph?.graph?.get(params) ?? /* @__PURE__ */ new Map();
|
|
1596
1759
|
updatedCoordsNodeGraph.set(opening.id, dis);
|
|
@@ -1600,8 +1763,8 @@ var prepareGraph = (options) => {
|
|
|
1600
1763
|
}
|
|
1601
1764
|
}
|
|
1602
1765
|
for (const kiosk of kiosks2) {
|
|
1603
|
-
const kioskCenter = (0,
|
|
1604
|
-
const dis = (0,
|
|
1766
|
+
const kioskCenter = (0, import_center8.center)(kiosk);
|
|
1767
|
+
const dis = (0, import_distance5.distance)([lng, lat], kioskCenter, { units: "meters" });
|
|
1605
1768
|
for (const routingGraph of routingGraphs) {
|
|
1606
1769
|
const updatedCoordsNodeGraph = routingGraph?.graph?.get(params) ?? /* @__PURE__ */ new Map();
|
|
1607
1770
|
updatedCoordsNodeGraph.set(kiosk.id, dis);
|
|
@@ -1619,16 +1782,16 @@ var prepareGraph = (options) => {
|
|
|
1619
1782
|
var import_length = __toESM(require("@turf/length"));
|
|
1620
1783
|
var WALKING_SPEED = 1.4;
|
|
1621
1784
|
var calculatePathLength = (feature3) => (0, import_length.default)(feature3, { units: "kilometers" }) * 1e3;
|
|
1622
|
-
var calculateTravelingDuration = (
|
|
1623
|
-
const duration =
|
|
1785
|
+
var calculateTravelingDuration = (distance7) => {
|
|
1786
|
+
const duration = distance7 / WALKING_SPEED;
|
|
1624
1787
|
const minutes = Math.round(duration / 60);
|
|
1625
1788
|
return minutes > 0 ? minutes : 1;
|
|
1626
1789
|
};
|
|
1627
1790
|
var calculateTotalDistance = (steps = []) => {
|
|
1628
1791
|
return steps.reduce((acc, { path }) => acc + calculatePathLength(lineString(path)), 0);
|
|
1629
1792
|
};
|
|
1630
|
-
var calculateRoundedDistance = (
|
|
1631
|
-
return Math.round(
|
|
1793
|
+
var calculateRoundedDistance = (distance7) => {
|
|
1794
|
+
return Math.round(distance7 - distance7 % 25);
|
|
1632
1795
|
};
|
|
1633
1796
|
|
|
1634
1797
|
// src/data/navigate/type-guard.ts
|
|
@@ -1637,7 +1800,7 @@ function isCoordinateOrdinalString(id) {
|
|
|
1637
1800
|
}
|
|
1638
1801
|
|
|
1639
1802
|
// src/data/navigate/services/waypoint/createWaypointService.ts
|
|
1640
|
-
var
|
|
1803
|
+
var import_center9 = require("@turf/center");
|
|
1641
1804
|
|
|
1642
1805
|
// src/data/navigate/services/waypoint/extractEndWaypoint.ts
|
|
1643
1806
|
var import_point_on_feature2 = __toESM(require("@turf/point-on-feature"));
|
|
@@ -1648,6 +1811,7 @@ var isUnit = (id) => !!id && id.startsWith("unit-");
|
|
|
1648
1811
|
var isKiosk = (id) => !!id && id.startsWith("kiosk-");
|
|
1649
1812
|
var isOpening = (id) => !!id && id.startsWith("opening-");
|
|
1650
1813
|
var isAmenity = (id) => !!id && id.startsWith("amenity-");
|
|
1814
|
+
var isSection = (id) => !!id && id.startsWith("section-");
|
|
1651
1815
|
|
|
1652
1816
|
// src/data/navigate/services/waypoint/extractEndWaypoint.ts
|
|
1653
1817
|
var extractEndPoint = (path, ctx) => {
|
|
@@ -1720,6 +1884,22 @@ var extractEndPoint = (path, ctx) => {
|
|
|
1720
1884
|
path.slice(0, -1)
|
|
1721
1885
|
];
|
|
1722
1886
|
}
|
|
1887
|
+
if (isSection(a) && isOpening(b)) {
|
|
1888
|
+
const section = findByIdSync(a);
|
|
1889
|
+
const level = findByIdSync(section.properties.level_id);
|
|
1890
|
+
return [
|
|
1891
|
+
{
|
|
1892
|
+
id: a,
|
|
1893
|
+
type: "end",
|
|
1894
|
+
name: section.properties.name,
|
|
1895
|
+
point: (0, import_point_on_feature2.default)(section).geometry.coordinates,
|
|
1896
|
+
levelId: section.properties.level_id,
|
|
1897
|
+
ordinal: level.properties.ordinal,
|
|
1898
|
+
source: { type: "section", id: a }
|
|
1899
|
+
},
|
|
1900
|
+
path.slice(0, -1)
|
|
1901
|
+
];
|
|
1902
|
+
}
|
|
1723
1903
|
if (isUnit(a) && isOpening(b)) {
|
|
1724
1904
|
const unit = findByIdSync(a);
|
|
1725
1905
|
const opening = findByIdSync(b);
|
|
@@ -1846,6 +2026,22 @@ var extractStartPoint = (path, ctx) => {
|
|
|
1846
2026
|
path.slice(1)
|
|
1847
2027
|
];
|
|
1848
2028
|
}
|
|
2029
|
+
if (isSection(a) && isOpening(b)) {
|
|
2030
|
+
const section = findByIdSync(a);
|
|
2031
|
+
const level = findByIdSync(section.properties.level_id);
|
|
2032
|
+
return [
|
|
2033
|
+
{
|
|
2034
|
+
id: a,
|
|
2035
|
+
type: "start",
|
|
2036
|
+
name: section.properties.name,
|
|
2037
|
+
point: (0, import_point_on_feature3.default)(section).geometry.coordinates,
|
|
2038
|
+
levelId: section.properties.level_id,
|
|
2039
|
+
ordinal: level.properties.ordinal,
|
|
2040
|
+
source: { type: "section", id: a }
|
|
2041
|
+
},
|
|
2042
|
+
path.slice(1)
|
|
2043
|
+
];
|
|
2044
|
+
}
|
|
1849
2045
|
if (isUnit(a) && isOpening(b)) {
|
|
1850
2046
|
const unit = findByIdSync(a);
|
|
1851
2047
|
const opening = findByIdSync(b);
|
|
@@ -1907,7 +2103,7 @@ var createWaypointService = (ctx) => {
|
|
|
1907
2103
|
const waypoints = middlePoints.map((openingId) => {
|
|
1908
2104
|
const opening = findByIdSync(openingId);
|
|
1909
2105
|
const level = findByIdSync(opening.properties.level_id);
|
|
1910
|
-
const coordinates = (0,
|
|
2106
|
+
const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
|
|
1911
2107
|
return {
|
|
1912
2108
|
id: `${opening.properties.level_id}:${openingId}`,
|
|
1913
2109
|
type: "between",
|
|
@@ -1915,6 +2111,7 @@ var createWaypointService = (ctx) => {
|
|
|
1915
2111
|
name: null,
|
|
1916
2112
|
levelId: opening.properties.level_id,
|
|
1917
2113
|
ordinal: level.properties.ordinal,
|
|
2114
|
+
checkpoint: opening.properties.category === "pedestrian.principal",
|
|
1918
2115
|
source: { type: "opening", id: opening.id }
|
|
1919
2116
|
};
|
|
1920
2117
|
});
|
|
@@ -1924,53 +2121,12 @@ var createWaypointService = (ctx) => {
|
|
|
1924
2121
|
};
|
|
1925
2122
|
|
|
1926
2123
|
// src/data/navigate/services/instructions/createInstructionService.ts
|
|
1927
|
-
var
|
|
2124
|
+
var import_distance7 = require("@turf/distance");
|
|
1928
2125
|
var import_rhumb_bearing3 = require("@turf/rhumb-bearing");
|
|
1929
2126
|
|
|
1930
|
-
// src/data/navigate/constants.ts
|
|
1931
|
-
var OBSTACLE_FEATURE_TYPES = [
|
|
1932
|
-
"kiosk"
|
|
1933
|
-
/* , "fixture" */
|
|
1934
|
-
];
|
|
1935
|
-
var OBSTACLE_CATEGORIES = [
|
|
1936
|
-
"fixture.water",
|
|
1937
|
-
"fixture.stage",
|
|
1938
|
-
"nonpublic",
|
|
1939
|
-
"opentobelow",
|
|
1940
|
-
"elevator",
|
|
1941
|
-
"escalator",
|
|
1942
|
-
"stairs",
|
|
1943
|
-
"stairs.emergencyexit",
|
|
1944
|
-
"room",
|
|
1945
|
-
"unspecified",
|
|
1946
|
-
"structure",
|
|
1947
|
-
"brick",
|
|
1948
|
-
"concrete",
|
|
1949
|
-
"drywall",
|
|
1950
|
-
"glass",
|
|
1951
|
-
"wood",
|
|
1952
|
-
"column"
|
|
1953
|
-
];
|
|
1954
|
-
var WALKABLE_CATEGORY = [
|
|
1955
|
-
"walkway",
|
|
1956
|
-
"parking",
|
|
1957
|
-
"room",
|
|
1958
|
-
"terrace",
|
|
1959
|
-
"unenclosedarea",
|
|
1960
|
-
"vegetation",
|
|
1961
|
-
"unspecified"
|
|
1962
|
-
];
|
|
1963
|
-
var VERTICAL_TRAVERSAL_CATEGORY = [
|
|
1964
|
-
"elevator",
|
|
1965
|
-
"escalator",
|
|
1966
|
-
"stairs",
|
|
1967
|
-
"stairs.emergencyexit",
|
|
1968
|
-
"ramp"
|
|
1969
|
-
];
|
|
1970
|
-
|
|
1971
2127
|
// src/data/navigate/services/instructions/utils/outwardOpeningBearing.ts
|
|
1972
2128
|
var import_rhumb_bearing2 = require("@turf/rhumb-bearing");
|
|
1973
|
-
var
|
|
2129
|
+
var import_distance6 = require("@turf/distance");
|
|
1974
2130
|
var outwardOpeningBearing = (openingLine, nextPoint) => {
|
|
1975
2131
|
const [p1, p2] = openingLine.coordinates;
|
|
1976
2132
|
const openingBearing = (0, import_rhumb_bearing2.rhumbBearing)(p1, p2);
|
|
@@ -1986,7 +2142,7 @@ var outwardOpeningBearing = (openingLine, nextPoint) => {
|
|
|
1986
2142
|
let minDist = Infinity;
|
|
1987
2143
|
for (const b of candidates) {
|
|
1988
2144
|
const testPoint = rhumbDestination(openingMid, 0.5, b, { units: "meters" }).geometry.coordinates;
|
|
1989
|
-
const d = (0,
|
|
2145
|
+
const d = (0, import_distance6.distance)(nextPoint, testPoint, { units: "meters" });
|
|
1990
2146
|
if (d < minDist) {
|
|
1991
2147
|
minDist = d;
|
|
1992
2148
|
best = b;
|
|
@@ -2085,7 +2241,7 @@ var createInstructionService = (ctx) => {
|
|
|
2085
2241
|
if (turn === "straight") {
|
|
2086
2242
|
continue;
|
|
2087
2243
|
}
|
|
2088
|
-
const distanceFromPreviousPoint = (0,
|
|
2244
|
+
const distanceFromPreviousPoint = (0, import_distance7.distance)(prevPoint, thisPoint, { units: "meters" });
|
|
2089
2245
|
if (distanceFromPreviousPoint < 20 && prevInstruction && sameDirectionalTurn(prevInstruction.turn, turn)) {
|
|
2090
2246
|
const prevTurnSide = turnSide(prevInstruction.turn);
|
|
2091
2247
|
const extendedTurn = getTurn(prevInstruction.bearing.from, toBearing2, prevTurnSide);
|
|
@@ -2097,7 +2253,7 @@ var createInstructionService = (ctx) => {
|
|
|
2097
2253
|
prevInstruction.bearing.delta = angleDiff(prevInstruction.bearing.from, toBearing2);
|
|
2098
2254
|
prevInstruction.turn = extendedTurn;
|
|
2099
2255
|
} else {
|
|
2100
|
-
const distanceSinceLastTurn = (0,
|
|
2256
|
+
const distanceSinceLastTurn = (0, import_distance7.distance)(prevTurnPoint, thisPoint, { units: "meters" });
|
|
2101
2257
|
const landmark = landmarkService.findNearestLandmark(thisPoint, ordinal);
|
|
2102
2258
|
const afterTurnToward2 = landmarkService.findTowardLandmark(thisPoint, nextPoint, ordinal);
|
|
2103
2259
|
const instruction = {
|
|
@@ -2133,7 +2289,7 @@ var createInstructionService = (ctx) => {
|
|
|
2133
2289
|
};
|
|
2134
2290
|
|
|
2135
2291
|
// src/data/navigate/services/steps/createStepService.ts
|
|
2136
|
-
var
|
|
2292
|
+
var import_lodash22 = require("lodash");
|
|
2137
2293
|
|
|
2138
2294
|
// src/data/navigate/services/description/describe.ts
|
|
2139
2295
|
var t = (template, locale, options) => {
|
|
@@ -2149,11 +2305,17 @@ var describeVerticalStep = (fromLevel, toLevel, intermediary) => {
|
|
|
2149
2305
|
};
|
|
2150
2306
|
};
|
|
2151
2307
|
var describeHorizontalStep = (intermediary, toward, landmark) => {
|
|
2152
|
-
const
|
|
2308
|
+
const segments = [
|
|
2309
|
+
// fallback: skip "through" segment if intermediary is null/empty
|
|
2310
|
+
intermediary === "walkway" ? "along the walkway" : intermediary ? "through {{intermediary}}" : null,
|
|
2311
|
+
toward ? "toward {{toward}}" : null,
|
|
2312
|
+
!toward && landmark ? "near {{landmark}}" : null
|
|
2313
|
+
].filter(Boolean);
|
|
2314
|
+
const template = `Follow the path ${segments.join(" ")}`;
|
|
2153
2315
|
return {
|
|
2154
2316
|
text: t(template, "en", { intermediary, toward, landmark }),
|
|
2155
2317
|
template,
|
|
2156
|
-
options: { toward, landmark }
|
|
2318
|
+
options: { intermediary, toward, landmark }
|
|
2157
2319
|
};
|
|
2158
2320
|
};
|
|
2159
2321
|
var describeLastStep = () => {
|
|
@@ -2163,11 +2325,11 @@ var describeLastStep = () => {
|
|
|
2163
2325
|
};
|
|
2164
2326
|
|
|
2165
2327
|
// src/data/navigate/services/walkablepath/createWalkablePathUtils.ts
|
|
2166
|
-
var
|
|
2328
|
+
var import_lodash21 = __toESM(require("lodash"));
|
|
2167
2329
|
var import_invariant3 = require("@turf/invariant");
|
|
2330
|
+
var import_buffer = require("@turf/buffer");
|
|
2168
2331
|
var import_difference = __toESM(require("@turf/difference"));
|
|
2169
2332
|
var import_envelope = __toESM(require("@turf/envelope"));
|
|
2170
|
-
var import_boolean_overlap = __toESM(require("@turf/boolean-overlap"));
|
|
2171
2333
|
var import_boolean_intersects = __toESM(require("@turf/boolean-intersects"));
|
|
2172
2334
|
|
|
2173
2335
|
// ../../node_modules/@turf/meta/dist/esm/index.js
|
|
@@ -2293,15 +2455,15 @@ function bbox(geojson, options = {}) {
|
|
|
2293
2455
|
var index_default = bbox;
|
|
2294
2456
|
|
|
2295
2457
|
// src/data/navigate/services/walkablepath/turf-shortest-path/v6.5.0/shortestPath.ts
|
|
2296
|
-
var
|
|
2297
|
-
var
|
|
2458
|
+
var import_boolean_point_in_polygon4 = __toESM(require("@turf/boolean-point-in-polygon"));
|
|
2459
|
+
var import_distance8 = __toESM(require("@turf/distance"));
|
|
2298
2460
|
var import_transform_scale = __toESM(require("@turf/transform-scale"));
|
|
2299
2461
|
var import_union = __toESM(require("@turf/union"));
|
|
2300
2462
|
var import_bbox_polygon = __toESM(require("@turf/bbox-polygon"));
|
|
2301
2463
|
var import_clean_coords = require("@turf/clean-coords");
|
|
2302
2464
|
var import_invariant2 = require("@turf/invariant");
|
|
2303
2465
|
var import_pathfinding = __toESM(require("pathfinding"));
|
|
2304
|
-
var
|
|
2466
|
+
var import_lodash20 = require("lodash");
|
|
2305
2467
|
|
|
2306
2468
|
// src/data/navigate/services/walkablepath/turf-shortest-path/utils/stringPull.ts
|
|
2307
2469
|
function stringPull(grid, path) {
|
|
@@ -2356,39 +2518,6 @@ function stringPull(grid, path) {
|
|
|
2356
2518
|
return out;
|
|
2357
2519
|
}
|
|
2358
2520
|
|
|
2359
|
-
// src/data/navigate/services/walkablepath/turf-shortest-path/utils/pruneSmallAngle.ts
|
|
2360
|
-
function pruneSmallAngles(path, minDeg = 10) {
|
|
2361
|
-
if (path.length <= 2) return path;
|
|
2362
|
-
const out = [path[0]];
|
|
2363
|
-
for (let i = 1; i < path.length - 1; i++) {
|
|
2364
|
-
const a = out.at(-1);
|
|
2365
|
-
const b = path[i];
|
|
2366
|
-
const c = path[i + 1];
|
|
2367
|
-
const abx = b[0] - a[0], aby = b[1] - a[1];
|
|
2368
|
-
const bcx = c[0] - b[0], bcy = c[1] - b[1];
|
|
2369
|
-
const dot = abx * bcx + aby * bcy;
|
|
2370
|
-
const ab = Math.hypot(abx, aby);
|
|
2371
|
-
const bc = Math.hypot(bcx, bcy);
|
|
2372
|
-
const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
|
|
2373
|
-
if (angle > minDeg) out.push(b);
|
|
2374
|
-
}
|
|
2375
|
-
out.push(path.at(-1));
|
|
2376
|
-
return out;
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2379
|
-
// src/data/navigate/services/walkablepath/turf-shortest-path/utils/pruneShortSegments.ts
|
|
2380
|
-
function pruneShortSegments(path, minLen = 2) {
|
|
2381
|
-
const out = [path[0]];
|
|
2382
|
-
for (let i = 1; i < path.length; i++) {
|
|
2383
|
-
const [x0, y0] = out.at(-1);
|
|
2384
|
-
const [x1, y1] = path[i];
|
|
2385
|
-
if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
|
|
2386
|
-
out.push(path[i]);
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
return out;
|
|
2390
|
-
}
|
|
2391
|
-
|
|
2392
2521
|
// src/data/navigate/services/walkablepath/turf-shortest-path/utils/clearance.ts
|
|
2393
2522
|
function buildClearanceGrid(matrix) {
|
|
2394
2523
|
const h = matrix.length;
|
|
@@ -2440,7 +2569,7 @@ function snapPointToClearancePeak(p, clearance, isWalkableCell, radius = 4) {
|
|
|
2440
2569
|
const y = py + dy;
|
|
2441
2570
|
if (!isWalkableCell(x, y)) continue;
|
|
2442
2571
|
const score = clearance[y][x];
|
|
2443
|
-
const penalty = Math.hypot(dx, dy) *
|
|
2572
|
+
const penalty = Math.hypot(dx, dy) * 0.5;
|
|
2444
2573
|
const finalScore = score - penalty;
|
|
2445
2574
|
if (finalScore > bestScore) {
|
|
2446
2575
|
bestScore = finalScore;
|
|
@@ -2450,8 +2579,8 @@ function snapPointToClearancePeak(p, clearance, isWalkableCell, radius = 4) {
|
|
|
2450
2579
|
}
|
|
2451
2580
|
return best;
|
|
2452
2581
|
}
|
|
2453
|
-
function centerlineSnapPath(path,
|
|
2454
|
-
const snapped = path.map((p) => snapPointToClearancePeak(p,
|
|
2582
|
+
function centerlineSnapPath(path, clearanceGrid, isWalkableCell, radius = 4) {
|
|
2583
|
+
const snapped = path.map((p) => snapPointToClearancePeak(p, clearanceGrid, isWalkableCell, radius));
|
|
2455
2584
|
return snapped;
|
|
2456
2585
|
}
|
|
2457
2586
|
|
|
@@ -2463,19 +2592,19 @@ function shortestPath(start, end, options) {
|
|
|
2463
2592
|
let obstacles = options.obstacles || featureCollection([]);
|
|
2464
2593
|
if (!start) throw new Error("start is required");
|
|
2465
2594
|
if (!end) throw new Error("end is required");
|
|
2466
|
-
if (resolution && !
|
|
2595
|
+
if (resolution && !isNumber(resolution) || resolution <= 0)
|
|
2467
2596
|
throw new Error("options.resolution must be a number, greater than 0");
|
|
2468
2597
|
const startCoord = (0, import_invariant2.getCoord)(start);
|
|
2469
2598
|
const endCoord = (0, import_invariant2.getCoord)(end);
|
|
2470
|
-
start =
|
|
2471
|
-
end =
|
|
2599
|
+
start = point(startCoord);
|
|
2600
|
+
end = point(endCoord);
|
|
2472
2601
|
switch ((0, import_invariant2.getType)(obstacles)) {
|
|
2473
2602
|
case "FeatureCollection":
|
|
2474
2603
|
if (obstacles.features.length === 0)
|
|
2475
2604
|
return lineString([startCoord, endCoord]);
|
|
2476
2605
|
break;
|
|
2477
2606
|
case "Polygon":
|
|
2478
|
-
obstacles = featureCollection([
|
|
2607
|
+
obstacles = featureCollection([feature((0, import_invariant2.getGeom)(obstacles))]);
|
|
2479
2608
|
break;
|
|
2480
2609
|
default:
|
|
2481
2610
|
throw new Error("invalid obstacles");
|
|
@@ -2484,15 +2613,15 @@ function shortestPath(start, end, options) {
|
|
|
2484
2613
|
collection.features.push(start, end);
|
|
2485
2614
|
const box = index_default((0, import_transform_scale.default)((0, import_bbox_polygon.default)(index_default(collection)), 1.15));
|
|
2486
2615
|
if (!resolution) {
|
|
2487
|
-
const width = (0,
|
|
2616
|
+
const width = (0, import_distance8.default)([box[0], box[1]], [box[2], box[1]], options);
|
|
2488
2617
|
resolution = width / 100;
|
|
2489
2618
|
}
|
|
2490
2619
|
collection.features.pop();
|
|
2491
2620
|
collection.features.pop();
|
|
2492
2621
|
const [west, south, east, north] = box;
|
|
2493
|
-
const xFraction = resolution / (0,
|
|
2622
|
+
const xFraction = resolution / (0, import_distance8.default)([west, south], [east, south], options);
|
|
2494
2623
|
const cellWidth = xFraction * (east - west);
|
|
2495
|
-
const yFraction = resolution / (0,
|
|
2624
|
+
const yFraction = resolution / (0, import_distance8.default)([west, south], [west, north], options);
|
|
2496
2625
|
const cellHeight = yFraction * (north - south);
|
|
2497
2626
|
const bboxHorizontalSide = east - west;
|
|
2498
2627
|
const bboxVerticalSide = north - south;
|
|
@@ -2522,16 +2651,16 @@ function shortestPath(start, end, options) {
|
|
|
2522
2651
|
}
|
|
2523
2652
|
}
|
|
2524
2653
|
while (totalRounds--) {
|
|
2525
|
-
pt =
|
|
2526
|
-
isInsideObstacle = (0,
|
|
2527
|
-
(0,
|
|
2528
|
-
(0,
|
|
2529
|
-
distStart = (0,
|
|
2654
|
+
pt = point([currentX, currentY]);
|
|
2655
|
+
isInsideObstacle = (0, import_boolean_point_in_polygon4.default)(pt, combinedObstacle);
|
|
2656
|
+
(0, import_lodash20.set)(matrix, `[${row}][${column}]`, isInsideObstacle ? 1 : 0);
|
|
2657
|
+
(0, import_lodash20.set)(pointMatrix, `[${row}][${column}]`, `${currentX}|${currentY}`);
|
|
2658
|
+
distStart = (0, import_distance8.default)(pt, start);
|
|
2530
2659
|
if (!isInsideObstacle && distStart < minDistStart) {
|
|
2531
2660
|
minDistStart = distStart;
|
|
2532
2661
|
closestToStart = { x: column, y: row };
|
|
2533
2662
|
}
|
|
2534
|
-
distEnd = (0,
|
|
2663
|
+
distEnd = (0, import_distance8.default)(pt, end);
|
|
2535
2664
|
if (!isInsideObstacle && distEnd < minDistEnd) {
|
|
2536
2665
|
minDistEnd = distEnd;
|
|
2537
2666
|
closestToEnd = { x: column, y: row };
|
|
@@ -2562,9 +2691,6 @@ function shortestPath(start, end, options) {
|
|
|
2562
2691
|
const clearanceGrid = buildClearanceGrid(matrix);
|
|
2563
2692
|
const isWalkable = (x, y) => grid.isInside(x, y) && grid.isWalkableAt(x, y);
|
|
2564
2693
|
result = centerlineSnapPath(result, clearanceGrid, isWalkable);
|
|
2565
|
-
result = stringPull(grid, result);
|
|
2566
|
-
result = pruneSmallAngles(result);
|
|
2567
|
-
result = pruneShortSegments(result);
|
|
2568
2694
|
}
|
|
2569
2695
|
result.pop();
|
|
2570
2696
|
result.shift();
|
|
@@ -2584,8 +2710,28 @@ var createWalkablePathService = (ctx, options) => {
|
|
|
2584
2710
|
const { units = [], kiosks = [], fixtures = [] } = ctx.data;
|
|
2585
2711
|
const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
|
|
2586
2712
|
const filterObstaclesByOrdinal = (levelId) => {
|
|
2587
|
-
|
|
2588
|
-
|
|
2713
|
+
const OBSTACLE_FEATURETYPE_AND_CATEGORIES = [
|
|
2714
|
+
"fixture.vegetation",
|
|
2715
|
+
"fixture.water",
|
|
2716
|
+
"fixture.stage",
|
|
2717
|
+
"fixture.wall",
|
|
2718
|
+
"kiosk",
|
|
2719
|
+
"unit.nonpublic",
|
|
2720
|
+
"unit.opentobelow",
|
|
2721
|
+
"unit.elevator",
|
|
2722
|
+
"unit.escalator",
|
|
2723
|
+
"unit.stairs",
|
|
2724
|
+
"unit.room",
|
|
2725
|
+
"unit.unspecified",
|
|
2726
|
+
"unit.structure",
|
|
2727
|
+
"unit.brick",
|
|
2728
|
+
"unit.concrete",
|
|
2729
|
+
"unit.drywall",
|
|
2730
|
+
"unit.column"
|
|
2731
|
+
];
|
|
2732
|
+
return possibleObstacleFeatures.filter((f) => f.properties.level_id === levelId).filter(({ feature_type, properties }) => {
|
|
2733
|
+
const featureTypeAndCat = `${feature_type}${"category" in properties ? `.${properties.category}` : ``}`;
|
|
2734
|
+
return OBSTACLE_FEATURETYPE_AND_CATEGORIES.includes(featureTypeAndCat);
|
|
2589
2735
|
});
|
|
2590
2736
|
};
|
|
2591
2737
|
const findObstaclesFromWalkway = (intermediaryUnit, exceptionIds = []) => {
|
|
@@ -2597,13 +2743,38 @@ var createWalkablePathService = (ctx, options) => {
|
|
|
2597
2743
|
);
|
|
2598
2744
|
const relatedObstacleWithIntermediary = obstacleOnLevel.reduce(
|
|
2599
2745
|
(obstacles, feature3) => {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2746
|
+
try {
|
|
2747
|
+
if (
|
|
2748
|
+
// Prevent detecting itself as an obstacle
|
|
2749
|
+
// Ex. Unable to draw a line to amenity located with in a room as room is also consider as obstacle
|
|
2750
|
+
feature3.id !== intermediaryUnit.id && (0, import_boolean_intersects.default)(intermediaryUnit, feature3)
|
|
2751
|
+
) {
|
|
2752
|
+
const type = (0, import_invariant3.getType)(feature3);
|
|
2753
|
+
switch (type) {
|
|
2754
|
+
case "Polygon":
|
|
2755
|
+
obstacles.push(feature3);
|
|
2756
|
+
break;
|
|
2757
|
+
case "MultiPolygon": {
|
|
2758
|
+
feature3.geometry.coordinates.map((p) => {
|
|
2759
|
+
const f = polygon(p, { id: feature3.id });
|
|
2760
|
+
obstacles.push(f);
|
|
2761
|
+
});
|
|
2762
|
+
break;
|
|
2763
|
+
}
|
|
2764
|
+
case "LineString": {
|
|
2765
|
+
obstacles.push((0, import_buffer.buffer)(feature3.geometry, 0.3, { units: "meters" }));
|
|
2766
|
+
break;
|
|
2767
|
+
}
|
|
2768
|
+
case "MultiLineString": {
|
|
2769
|
+
feature3.geometry.coordinates.map((line) => {
|
|
2770
|
+
const f = (0, import_buffer.buffer)(lineString(line), 0.3, { units: "meters" });
|
|
2771
|
+
obstacles.push(f);
|
|
2772
|
+
});
|
|
2773
|
+
break;
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
} catch (e) {
|
|
2607
2778
|
}
|
|
2608
2779
|
return obstacles;
|
|
2609
2780
|
},
|
|
@@ -2627,14 +2798,13 @@ var createWalkablePathService = (ctx, options) => {
|
|
|
2627
2798
|
return stepPath;
|
|
2628
2799
|
};
|
|
2629
2800
|
const findWalkablePath = (from, to, intermediaries) => {
|
|
2630
|
-
const t0 = performance.now();
|
|
2631
2801
|
const relatedWalkablePlatform = intermediaries.find(
|
|
2632
|
-
(feature3) =>
|
|
2802
|
+
(feature3) => WALKABLE_UNIT_CATEGORY.includes(feature3.properties.category)
|
|
2633
2803
|
);
|
|
2634
2804
|
const exceptionFeatureIds = [];
|
|
2635
2805
|
const obstacles = findObstaclesFromWalkway(
|
|
2636
2806
|
relatedWalkablePlatform,
|
|
2637
|
-
|
|
2807
|
+
import_lodash21.default.compact(exceptionFeatureIds)
|
|
2638
2808
|
);
|
|
2639
2809
|
const line = findPathOnArea(from, to, {
|
|
2640
2810
|
resolution,
|
|
@@ -2649,7 +2819,7 @@ var createWalkablePathService = (ctx, options) => {
|
|
|
2649
2819
|
|
|
2650
2820
|
// src/data/navigate/services/steps/createStepService.ts
|
|
2651
2821
|
var createStepService = (ctx) => {
|
|
2652
|
-
const { data: { units, relationships }, findByIdSync, landmarkService } = ctx;
|
|
2822
|
+
const { data: { units, occupants = [], relationships }, findByIdSync, landmarkService } = ctx;
|
|
2653
2823
|
const walkablePathUtils = createWalkablePathService(ctx, { resolution: 88e-5 });
|
|
2654
2824
|
const findUnitBetweenOpenings = (originId, destinationId) => {
|
|
2655
2825
|
const origin = findByIdSync(originId);
|
|
@@ -2658,7 +2828,7 @@ var createStepService = (ctx) => {
|
|
|
2658
2828
|
const matchOneUnits = matchedOne ? [matchedOne.properties.origin, matchedOne.properties.destination] : [];
|
|
2659
2829
|
const matchedTwo = relationships.find((rel) => (rel.properties.intermediary || []).map((int) => int.id).includes(destination.id));
|
|
2660
2830
|
const matchTwoUnits = matchedTwo ? [matchedTwo.properties.origin, matchedTwo.properties.destination] : [];
|
|
2661
|
-
const unitIds = (0,
|
|
2831
|
+
const unitIds = (0, import_lodash22.intersectionBy)(matchOneUnits, matchTwoUnits, "id");
|
|
2662
2832
|
return unitIds.map(({ id }) => findByIdSync(id));
|
|
2663
2833
|
};
|
|
2664
2834
|
const findHorizontalIntermediary = (from, to) => {
|
|
@@ -2674,7 +2844,7 @@ var createStepService = (ctx) => {
|
|
|
2674
2844
|
};
|
|
2675
2845
|
const getAdjacentUnitsByOpening = (openingId) => {
|
|
2676
2846
|
const relationship = relationships.find((rel) => (rel.properties.intermediary || []).map((int) => int.id).includes(openingId));
|
|
2677
|
-
const units2 = (0,
|
|
2847
|
+
const units2 = (0, import_lodash22.compact)([
|
|
2678
2848
|
relationship?.properties.origin.id,
|
|
2679
2849
|
relationship?.properties.destination.id
|
|
2680
2850
|
]).map((unitId) => findByIdSync(unitId));
|
|
@@ -2688,11 +2858,18 @@ var createStepService = (ctx) => {
|
|
|
2688
2858
|
const verticalUnits = [...firstAdjacentUnits, ...secondAdjacentUnits].filter((unit) => VERTICAL_TRAVERSAL_CATEGORY.includes(unit.properties.category));
|
|
2689
2859
|
return verticalUnits;
|
|
2690
2860
|
};
|
|
2861
|
+
const findOccupantForUnit = (unit) => {
|
|
2862
|
+
return occupants.find(
|
|
2863
|
+
(o) => o.properties.main_location === unit.id || (o.properties.correlated_locations ?? []).includes(unit.id)
|
|
2864
|
+
);
|
|
2865
|
+
};
|
|
2691
2866
|
const createHorizontalStep = (from, to) => {
|
|
2692
2867
|
const intermediary = findHorizontalIntermediary(from, to);
|
|
2693
2868
|
const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
|
|
2694
|
-
const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
|
|
2869
|
+
const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] ?? "unspecified" : "unspecified";
|
|
2695
2870
|
const intermediaryIds = intermediary.map((unit) => unit.id);
|
|
2871
|
+
const occupant = intermediary[0] ? findOccupantForUnit(intermediary[0]) : void 0;
|
|
2872
|
+
const intermediaryName = occupant?.properties.name.en ?? intermediaryCategory;
|
|
2696
2873
|
const toward = landmarkService.findTowardLandmark(from.point, to.point, to.ordinal);
|
|
2697
2874
|
const nearBy = landmarkService.findNearestLandmark(to.point, to.ordinal);
|
|
2698
2875
|
const path = walkablePathUtils.findWalkablePath(from.point, to.point, intermediary);
|
|
@@ -2704,9 +2881,9 @@ var createStepService = (ctx) => {
|
|
|
2704
2881
|
intermediaryCategory,
|
|
2705
2882
|
intermediaryIds,
|
|
2706
2883
|
description: describeHorizontalStep(
|
|
2707
|
-
|
|
2708
|
-
toward ? toward.name :
|
|
2709
|
-
nearBy ? nearBy.name :
|
|
2884
|
+
intermediaryName,
|
|
2885
|
+
toward ? toward.name : void 0,
|
|
2886
|
+
nearBy ? nearBy.name : void 0
|
|
2710
2887
|
),
|
|
2711
2888
|
path: path.map((coord) => [...coord, from.ordinal * 9])
|
|
2712
2889
|
};
|
|
@@ -2782,7 +2959,7 @@ var mergeStepsByOrdinal = (steps) => {
|
|
|
2782
2959
|
let current = steps[0];
|
|
2783
2960
|
for (let i = 1; i < steps.length; i++) {
|
|
2784
2961
|
const next = steps[i];
|
|
2785
|
-
if (arrayEqual(current.ordinals, next.ordinals)) {
|
|
2962
|
+
if (arrayEqual(current.ordinals, next.ordinals) && !current.to.checkpoint) {
|
|
2786
2963
|
current = mergeTwoSteps(current, next);
|
|
2787
2964
|
} else {
|
|
2788
2965
|
out.push(current);
|
|
@@ -2810,7 +2987,7 @@ var getNavigateClient = (options) => {
|
|
|
2810
2987
|
const findCoordinateOrdinalLocatedUnit = (params, sourceUnits = units) => {
|
|
2811
2988
|
const [lng, lat, ordinal] = parseOrdinalCoordinate(params);
|
|
2812
2989
|
const levelIdsWithOrdinal = levels.filter((level) => level.properties.ordinal === ordinal).map((level) => level.id);
|
|
2813
|
-
const unit = sourceUnits.find((unit2) => levelIdsWithOrdinal.includes(unit2.properties.level_id) && (0,
|
|
2990
|
+
const unit = sourceUnits.find((unit2) => levelIdsWithOrdinal.includes(unit2.properties.level_id) && (0, import_boolean_point_in_polygon5.booleanPointInPolygon)([lng, lat], unit2));
|
|
2814
2991
|
return unit;
|
|
2815
2992
|
};
|
|
2816
2993
|
const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
|
|
@@ -2912,6 +3089,13 @@ var getSearchClient = ({ occupants, amenities }) => {
|
|
|
2912
3089
|
};
|
|
2913
3090
|
|
|
2914
3091
|
// src/data/getDataClient.ts
|
|
3092
|
+
var resolveFeatureTypeFromId = (id) => {
|
|
3093
|
+
if (id === null || id === void 0) return null;
|
|
3094
|
+
const featureType = id.split("-")[0];
|
|
3095
|
+
const override = ID_PREFIX_TO_FEATURE_TYPE[featureType];
|
|
3096
|
+
if (override) return override;
|
|
3097
|
+
return featureType || null;
|
|
3098
|
+
};
|
|
2915
3099
|
var getDataClient = (options) => {
|
|
2916
3100
|
let searchClient;
|
|
2917
3101
|
let navigateClient;
|
|
@@ -2944,7 +3128,11 @@ var getDataClient = (options) => {
|
|
|
2944
3128
|
};
|
|
2945
3129
|
const internalFindById = async (id) => {
|
|
2946
3130
|
if (id === null || id === void 0) return null;
|
|
2947
|
-
const featureType =
|
|
3131
|
+
const featureType = resolveFeatureTypeFromId(id);
|
|
3132
|
+
if (!featureType) {
|
|
3133
|
+
console.warn(`[venue-js] Cannot resolve feature type from id "${id}"`);
|
|
3134
|
+
return null;
|
|
3135
|
+
}
|
|
2948
3136
|
const feature3 = await queryClient.ensureQueryData({
|
|
2949
3137
|
queryKey: ["_deliveryapi", featureType, id],
|
|
2950
3138
|
queryFn: async () => {
|
|
@@ -2959,20 +3147,28 @@ var getDataClient = (options) => {
|
|
|
2959
3147
|
};
|
|
2960
3148
|
const populator = createPopulator({ internalFindById, internalFilterByType });
|
|
2961
3149
|
const registerObserver = (featureType, refetchInterval) => {
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
3150
|
+
const existing = observers.get(featureType);
|
|
3151
|
+
if (existing) {
|
|
3152
|
+
if (refetchInterval === existing.refetchInterval) {
|
|
3153
|
+
return existing.observer;
|
|
3154
|
+
} else if (refetchInterval > existing.refetchInterval) {
|
|
3155
|
+
console.warn(`[venue-js] Observer for "${featureType}" not registered \u2014 existing observer already uses a smaller interval (${existing.refetchInterval}ms < ${refetchInterval}ms)`);
|
|
3156
|
+
return existing.observer;
|
|
3157
|
+
} else if (refetchInterval < existing.refetchInterval) {
|
|
3158
|
+
console.warn(`[venue-js] Observer for "${featureType}" re-registering with smaller interval (${refetchInterval}ms < ${existing.refetchInterval}ms)`);
|
|
3159
|
+
existing.unsubscribe();
|
|
3160
|
+
observers.delete(featureType);
|
|
3161
|
+
}
|
|
2966
3162
|
}
|
|
2967
3163
|
const options2 = createDeliveryApiQueryOptions(featureType);
|
|
2968
3164
|
const observer = new import_query_core.QueryObserver(queryClient, {
|
|
2969
3165
|
...options2,
|
|
2970
3166
|
refetchInterval
|
|
2971
3167
|
});
|
|
3168
|
+
console.log(`[venue-js] Listening to ${featureType} changes (interval = ${refetchInterval}ms)`);
|
|
2972
3169
|
const unsubscribe = observer.subscribe(() => {
|
|
2973
|
-
console.log(`[venue-js] Listening to ${featureType} changes (interval = ${refetchInterval}ms)`);
|
|
2974
3170
|
});
|
|
2975
|
-
observers.set(featureType, { observer, unsubscribe });
|
|
3171
|
+
observers.set(featureType, { observer, unsubscribe, refetchInterval });
|
|
2976
3172
|
return observer;
|
|
2977
3173
|
};
|
|
2978
3174
|
const destroyObserver = (featureType) => {
|
|
@@ -3039,7 +3235,7 @@ var getDataClient = (options) => {
|
|
|
3039
3235
|
};
|
|
3040
3236
|
const navigateFn = async (origin, destination, options2) => {
|
|
3041
3237
|
if (!navigateClient) {
|
|
3042
|
-
const [levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors] = await Promise.all([
|
|
3238
|
+
const [levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors, sections] = await Promise.all([
|
|
3043
3239
|
filterByType("level"),
|
|
3044
3240
|
filterByType("occupant"),
|
|
3045
3241
|
filterByType("opening"),
|
|
@@ -3048,9 +3244,10 @@ var getDataClient = (options) => {
|
|
|
3048
3244
|
filterByType("fixture"),
|
|
3049
3245
|
filterByType("kiosk"),
|
|
3050
3246
|
filterByType("amenity"),
|
|
3051
|
-
filterByType("anchor")
|
|
3247
|
+
filterByType("anchor"),
|
|
3248
|
+
filterByType("section")
|
|
3052
3249
|
]);
|
|
3053
|
-
const haystack = { levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors };
|
|
3250
|
+
const haystack = { levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors, sections };
|
|
3054
3251
|
navigateClient = getNavigateClient({ data: haystack, unitDistanceOptions: options2?.unitDistanceOptions });
|
|
3055
3252
|
}
|
|
3056
3253
|
return navigateClient.findRoute(origin, destination, options2);
|
|
@@ -3075,6 +3272,7 @@ var getDataClient = (options) => {
|
|
|
3075
3272
|
ALL_FEATURE_TYPES,
|
|
3076
3273
|
DEFAULT_BASE_URL,
|
|
3077
3274
|
GEOJSON_FEATURE_TYPES,
|
|
3275
|
+
ID_PREFIX_TO_FEATURE_TYPE,
|
|
3078
3276
|
IMDF_FEATURE_TYPES,
|
|
3079
3277
|
IMDF_UNIT_CATEGORIES,
|
|
3080
3278
|
NONIMDF_FEATURE_TYPES,
|
|
@@ -3101,6 +3299,7 @@ var getDataClient = (options) => {
|
|
|
3101
3299
|
getDataClient,
|
|
3102
3300
|
getInstructionText,
|
|
3103
3301
|
getNavigateClient,
|
|
3302
|
+
getPointOnFeature,
|
|
3104
3303
|
getSearchClient,
|
|
3105
3304
|
getTurn,
|
|
3106
3305
|
matchFilter,
|