venue-js 1.4.0-next.18 → 1.4.0-next.19
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 +3 -941
- package/dist/data/index.d.ts +3 -941
- package/dist/data/index.js +1618 -1300
- package/dist/data/index.js.map +1 -1
- package/dist/data/index.mjs +1608 -1300
- package/dist/data/index.mjs.map +1 -1
- package/dist/index-C1nZyY-F.d.mts +1002 -0
- package/dist/index-C1nZyY-F.d.ts +1002 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1819 -1714
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1805 -1700
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -1
package/dist/data/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
7
|
var __export = (target, all) => {
|
|
6
8
|
for (var name in all)
|
|
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
14
16
|
}
|
|
15
17
|
return to;
|
|
16
18
|
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
17
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
28
|
|
|
19
29
|
// src/data/index.ts
|
|
@@ -312,8 +322,8 @@ var safeFetchFeature = async (featureType, params) => {
|
|
|
312
322
|
};
|
|
313
323
|
|
|
314
324
|
// src/data/utils/geometry-validator.ts
|
|
315
|
-
var isValidCoordinate = (
|
|
316
|
-
return
|
|
325
|
+
var isValidCoordinate = (point2) => {
|
|
326
|
+
return point2.length === 2 && point2.every((coord) => typeof coord === "number");
|
|
317
327
|
};
|
|
318
328
|
function isValidLinearRingCoordinates(ring) {
|
|
319
329
|
if (ring.length < 4) {
|
|
@@ -321,16 +331,16 @@ function isValidLinearRingCoordinates(ring) {
|
|
|
321
331
|
}
|
|
322
332
|
return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
|
|
323
333
|
}
|
|
324
|
-
var isValidPolygonCoordinates = (
|
|
325
|
-
if (Array.isArray(
|
|
326
|
-
return isValidLinearRingCoordinates(
|
|
334
|
+
var isValidPolygonCoordinates = (polygon2) => {
|
|
335
|
+
if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
|
|
336
|
+
return isValidLinearRingCoordinates(polygon2);
|
|
327
337
|
}
|
|
328
|
-
if (Array.isArray(
|
|
329
|
-
if (!isValidLinearRingCoordinates(
|
|
338
|
+
if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
|
|
339
|
+
if (!isValidLinearRingCoordinates(polygon2[0])) {
|
|
330
340
|
return false;
|
|
331
341
|
}
|
|
332
|
-
for (let i = 1; i <
|
|
333
|
-
if (!isValidLinearRingCoordinates(
|
|
342
|
+
for (let i = 1; i < polygon2.length; i++) {
|
|
343
|
+
if (!isValidLinearRingCoordinates(polygon2[i])) {
|
|
334
344
|
return false;
|
|
335
345
|
}
|
|
336
346
|
}
|
|
@@ -341,16 +351,16 @@ var isValidPolygonCoordinates = (polygon) => {
|
|
|
341
351
|
var isValidMultiPolygonCoordinates = (multipolygon) => {
|
|
342
352
|
return multipolygon.every(isValidPolygonCoordinates);
|
|
343
353
|
};
|
|
344
|
-
var isValidLineStringCoordinates = (
|
|
345
|
-
if (!Array.isArray(
|
|
354
|
+
var isValidLineStringCoordinates = (lineString2) => {
|
|
355
|
+
if (!Array.isArray(lineString2) || lineString2.length < 2) {
|
|
346
356
|
return false;
|
|
347
357
|
}
|
|
348
|
-
const firstPoint =
|
|
349
|
-
const lastPoint =
|
|
358
|
+
const firstPoint = lineString2[0];
|
|
359
|
+
const lastPoint = lineString2[lineString2.length - 1];
|
|
350
360
|
if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
|
|
351
361
|
return false;
|
|
352
362
|
}
|
|
353
|
-
return
|
|
363
|
+
return lineString2.every(isValidCoordinate);
|
|
354
364
|
};
|
|
355
365
|
var isValidMultiPolygon = (geometry) => {
|
|
356
366
|
const { type, coordinates } = geometry;
|
|
@@ -447,6 +457,19 @@ var findContainingUnit = (poi, units) => {
|
|
|
447
457
|
);
|
|
448
458
|
return unit;
|
|
449
459
|
};
|
|
460
|
+
var findContainingUnitAtPoint = (point2, levelId, units) => {
|
|
461
|
+
const unit = units.find(
|
|
462
|
+
(unit2) => {
|
|
463
|
+
try {
|
|
464
|
+
return unit2.properties.level_id === levelId && (0, import_boolean_point_in_polygon.booleanPointInPolygon)(point2, unit2);
|
|
465
|
+
} catch (e) {
|
|
466
|
+
console.log(`Cannot find containing unit of (point: ${point2}, levelId: ${levelId}):`, e.message);
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
);
|
|
471
|
+
return unit;
|
|
472
|
+
};
|
|
450
473
|
|
|
451
474
|
// src/data/populator/index.ts
|
|
452
475
|
var createPopulator = ({
|
|
@@ -619,6 +642,19 @@ var createPopulator = ({
|
|
|
619
642
|
}
|
|
620
643
|
};
|
|
621
644
|
};
|
|
645
|
+
const populateSection = async (section) => {
|
|
646
|
+
const venue = await internalFindById(section.properties.venue_id);
|
|
647
|
+
const level = await internalFindById(section.properties.level_id);
|
|
648
|
+
return {
|
|
649
|
+
...section,
|
|
650
|
+
properties: {
|
|
651
|
+
...section.properties,
|
|
652
|
+
venue,
|
|
653
|
+
level: await populateLevel(level),
|
|
654
|
+
ordinal: level.properties.ordinal
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
};
|
|
622
658
|
const populateRelationship = async (relationship) => {
|
|
623
659
|
const originId = relationship.properties.origin?.id;
|
|
624
660
|
const destinationId = relationship.properties.destination?.id;
|
|
@@ -636,19 +672,6 @@ var createPopulator = ({
|
|
|
636
672
|
}
|
|
637
673
|
};
|
|
638
674
|
};
|
|
639
|
-
const populateSection = async (section) => {
|
|
640
|
-
const venue = await internalFindById(section.properties.venue_id);
|
|
641
|
-
const level = await internalFindById(section.properties.level_id);
|
|
642
|
-
return {
|
|
643
|
-
...section,
|
|
644
|
-
properties: {
|
|
645
|
-
...section.properties,
|
|
646
|
-
venue,
|
|
647
|
-
level: await populateLevel(level),
|
|
648
|
-
ordinal: level.properties.ordinal
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
};
|
|
652
675
|
const populateUnit = async (unit) => {
|
|
653
676
|
const venue = await internalFindById(unit.properties.venue_id);
|
|
654
677
|
const level = await internalFindById(unit.properties.level_id);
|
|
@@ -696,7 +719,7 @@ var createPopulator = ({
|
|
|
696
719
|
console.log(`error finding level`, { model3d, level });
|
|
697
720
|
}
|
|
698
721
|
};
|
|
699
|
-
const populateFeature = (
|
|
722
|
+
const populateFeature = (feature2) => Promise.resolve(feature2);
|
|
700
723
|
return {
|
|
701
724
|
address: populateAddress,
|
|
702
725
|
building: populateBuilding,
|
|
@@ -725,1366 +748,1642 @@ var createPopulator = ({
|
|
|
725
748
|
};
|
|
726
749
|
};
|
|
727
750
|
|
|
728
|
-
//
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
var
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
var
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
var
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
751
|
+
// src/data/search/getSearchClient.ts
|
|
752
|
+
var import_fuse = __toESM(require("fuse.js"));
|
|
753
|
+
|
|
754
|
+
// src/data/search/utils/sanitizeInput.ts
|
|
755
|
+
var sanitizeInput = (str) => str.replace(/[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, "").replace(/[\-–—_./()]+/g, "").normalize("NFC").trim();
|
|
756
|
+
|
|
757
|
+
// src/data/search/getSearchClient.ts
|
|
758
|
+
var getSearchClient = ({ occupants, amenities }) => {
|
|
759
|
+
const fuseAmenities = new import_fuse.default(amenities, {
|
|
760
|
+
threshold: 0.2,
|
|
761
|
+
keys: [
|
|
762
|
+
{ name: "properties.name", "weight": 1, getFn: (obj) => Object.values(obj.properties.name || {}) },
|
|
763
|
+
{ name: "properties.category", "weight": 1 }
|
|
764
|
+
]
|
|
765
|
+
});
|
|
766
|
+
const fuseOccupants = new import_fuse.default(occupants, {
|
|
767
|
+
threshold: 0.25,
|
|
768
|
+
// 0.2 is too strict (can't find Mo-Mo Paradise with "momo" search string)
|
|
769
|
+
includeScore: true,
|
|
770
|
+
shouldSort: true,
|
|
771
|
+
keys: [
|
|
772
|
+
{ name: "properties.name", "weight": 4, getFn: (obj) => Object.values(obj.properties.name || {}) },
|
|
773
|
+
{ name: "properties.keywords", "weight": 0.5 },
|
|
774
|
+
{ name: "properties.category", "weight": 0.25 },
|
|
775
|
+
{ name: "properties.local_category_names", "weight": 0.25 },
|
|
776
|
+
{ name: "properties.description", "weight": 0.25, getFn: (occ) => Object.values(occ.properties.description || {}) },
|
|
777
|
+
{ name: "properties.unit_name", "weight": 0.25 },
|
|
778
|
+
{ name: "properties.kiosk_name", "weight": 0.25 }
|
|
779
|
+
]
|
|
780
|
+
});
|
|
781
|
+
const search = (value) => {
|
|
782
|
+
const sanitizedValue = sanitizeInput(value);
|
|
783
|
+
const matchedAmenities = fuseAmenities.search(sanitizedValue);
|
|
784
|
+
const matchedOccupants = fuseOccupants.search(sanitizedValue);
|
|
785
|
+
return [...matchedAmenities, ...matchedOccupants];
|
|
786
|
+
};
|
|
787
|
+
return {
|
|
788
|
+
search
|
|
789
|
+
};
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
// src/data/navigate/getNavigateClient.ts
|
|
793
|
+
var import_boolean_point_in_polygon4 = require("@turf/boolean-point-in-polygon");
|
|
794
|
+
|
|
795
|
+
// src/data/navigate/graph/prepare.ts
|
|
796
|
+
var import_lodash10 = __toESM(require("lodash"));
|
|
797
|
+
var import_node_dijkstra = __toESM(require("node-dijkstra"));
|
|
798
|
+
var import_distance3 = require("@turf/distance");
|
|
799
|
+
var import_center5 = require("@turf/center");
|
|
800
|
+
|
|
801
|
+
// src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
|
|
802
|
+
var import_distance = require("@turf/distance");
|
|
803
|
+
var import_center3 = require("@turf/center");
|
|
804
|
+
var import_lodash3 = __toESM(require("lodash"));
|
|
805
|
+
|
|
806
|
+
// src/data/navigate/graph/constants.ts
|
|
807
|
+
var ROOM_BASEDISTANCE = 1e3;
|
|
808
|
+
var TERRACE_BASEDISTANCE = 1e3;
|
|
809
|
+
var ESCALATOR_BASEDISTANCE = 200;
|
|
810
|
+
var RAMP_BASEDISTANCE = 200;
|
|
811
|
+
var ELEVATOR_BASEDISTANCE = 500;
|
|
812
|
+
var STAIR_BASEDISTANCE = 1e5;
|
|
813
|
+
var BASE_POI_BASEDISTANCE = 9999999;
|
|
814
|
+
var DEFAULT_UNIT_BASEDISTANCE_OPTIONS = {
|
|
815
|
+
default: { baseDistance: 0 },
|
|
816
|
+
byCategory: {
|
|
817
|
+
room: { baseDistance: ROOM_BASEDISTANCE },
|
|
818
|
+
terrace: { baseDistance: TERRACE_BASEDISTANCE },
|
|
819
|
+
escalator: { baseDistance: ESCALATOR_BASEDISTANCE, scaleDistanceByLevel: false },
|
|
820
|
+
ramp: { baseDistance: RAMP_BASEDISTANCE, scaleDistanceByLevel: false },
|
|
821
|
+
elevator: { baseDistance: ELEVATOR_BASEDISTANCE, scaleDistanceByLevel: false },
|
|
822
|
+
stairs: {
|
|
823
|
+
baseDistance: STAIR_BASEDISTANCE,
|
|
824
|
+
scaleDistanceByLevel: true
|
|
825
|
+
},
|
|
826
|
+
"stairs.emergencyexit": {
|
|
827
|
+
baseDistance: STAIR_BASEDISTANCE,
|
|
828
|
+
scaleDistanceByLevel: true
|
|
829
|
+
}
|
|
796
830
|
}
|
|
797
831
|
};
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
832
|
+
|
|
833
|
+
// src/data/navigate/graph/utils/getDistanceOption.ts
|
|
834
|
+
var getDistanceOptions = (options, category) => {
|
|
835
|
+
if (!options) return DEFAULT_UNIT_BASEDISTANCE_OPTIONS.byCategory[category];
|
|
836
|
+
return (category && options.byCategory?.[category]) ?? DEFAULT_UNIT_BASEDISTANCE_OPTIONS.byCategory[category] ?? options?.default ?? DEFAULT_UNIT_BASEDISTANCE_OPTIONS.default;
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
// src/data/utils/trace.ts
|
|
840
|
+
var trace = (namespace, text, ms, color) => {
|
|
841
|
+
console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
// src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
|
|
845
|
+
var createTraversalNodeMap = (unitOpenings, options) => {
|
|
846
|
+
const { units } = options.data;
|
|
847
|
+
let counter = 0;
|
|
848
|
+
const calculateFeatureDistanceWithinUnit = (features, distanceOptions) => {
|
|
849
|
+
let relationshipGraph = {};
|
|
850
|
+
for (let currentIndex = 0; currentIndex < features.length; currentIndex++) {
|
|
851
|
+
const isLastItem = currentIndex + 1 === features.length;
|
|
852
|
+
if (isLastItem) break;
|
|
853
|
+
for (let j = currentIndex + 1; j < features.length; j++) {
|
|
854
|
+
const opening = features[currentIndex];
|
|
855
|
+
const feature2 = features[j];
|
|
856
|
+
try {
|
|
857
|
+
const distance5 = (0, import_distance.distance)(
|
|
858
|
+
(0, import_center3.center)(opening.geometry),
|
|
859
|
+
(0, import_center3.center)(feature2.geometry),
|
|
860
|
+
{ units: "meters" }
|
|
861
|
+
) + (distanceOptions?.baseDistance ?? 0);
|
|
862
|
+
if (opening.id === feature2.id) continue;
|
|
863
|
+
import_lodash3.default.set(relationshipGraph, `${opening.id}.${feature2.id}`, distance5);
|
|
864
|
+
import_lodash3.default.set(relationshipGraph, `${feature2.id}.${opening.id}`, distance5);
|
|
865
|
+
counter++;
|
|
866
|
+
} catch (error) {
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
811
870
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
871
|
+
return relationshipGraph;
|
|
872
|
+
};
|
|
873
|
+
const t0 = performance.now();
|
|
874
|
+
const nodeMap = import_lodash3.default.reduce(
|
|
875
|
+
unitOpenings,
|
|
876
|
+
(acc, openings, unitId) => {
|
|
877
|
+
const unit = units.find((unit2) => unit2.id === unitId);
|
|
878
|
+
const unitDistanceOption = getDistanceOptions(options.unitDistanceOptions, unit.properties.category);
|
|
879
|
+
return import_lodash3.default.merge(
|
|
880
|
+
acc,
|
|
881
|
+
calculateFeatureDistanceWithinUnit(openings, unitDistanceOption)
|
|
882
|
+
);
|
|
883
|
+
},
|
|
884
|
+
{}
|
|
885
|
+
);
|
|
886
|
+
const t1 = performance.now();
|
|
887
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} traversal relationships`, t1 - t0);
|
|
888
|
+
return nodeMap;
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
// src/data/navigate/graph/nodemap/createElevatorNodeMap.ts
|
|
892
|
+
var import_lodash4 = __toESM(require("lodash"));
|
|
893
|
+
var createElevatorNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
|
|
894
|
+
const t0 = performance.now();
|
|
895
|
+
const { levels, units } = options.data;
|
|
896
|
+
const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "elevator");
|
|
897
|
+
const {
|
|
898
|
+
baseDistance = ELEVATOR_BASEDISTANCE,
|
|
899
|
+
scaleDistanceByLevel = false
|
|
900
|
+
} = distanceOptions;
|
|
901
|
+
let elevatorNodeMap = {};
|
|
902
|
+
let counter = 0;
|
|
903
|
+
for (const relationship of elevatorLikeRelationships) {
|
|
904
|
+
try {
|
|
905
|
+
const {
|
|
906
|
+
origin: originTypeAndId,
|
|
907
|
+
intermediary,
|
|
908
|
+
destination: destinationTypeAndId
|
|
909
|
+
} = relationship.properties;
|
|
910
|
+
const origin = units.find((unit) => unit.id === originTypeAndId.id);
|
|
911
|
+
if (!origin) return;
|
|
912
|
+
const originOpenings = compact(unitOpenings[origin.id]);
|
|
913
|
+
const originLevel = levels.find((level) => level.id === origin.properties.level_id);
|
|
914
|
+
const destination = units.find((unit) => unit.id === destinationTypeAndId.id);
|
|
915
|
+
const destinationOpenings = unitOpenings[destination.id];
|
|
916
|
+
const destinationOpeningAndLevels = destinationOpenings.map((opening) => {
|
|
917
|
+
const level = levels.find((level2) => level2.id === destination.properties.level_id);
|
|
918
|
+
return { opening, level };
|
|
919
|
+
});
|
|
920
|
+
const intermediaryOpeningAndLevels = intermediary.map((unitTypeAndId) => {
|
|
921
|
+
const openings = unitOpenings[unitTypeAndId.id];
|
|
922
|
+
const unit = units.find((unit2) => unit2.id === unitTypeAndId.id);
|
|
923
|
+
const level = levels.find((level2) => level2.id === unit.properties.level_id);
|
|
924
|
+
return openings.map((opening) => ({ opening, level }));
|
|
925
|
+
}).flat();
|
|
926
|
+
const connections = compact([...intermediaryOpeningAndLevels, ...destinationOpeningAndLevels]);
|
|
927
|
+
if (!originOpenings || originOpenings.length === 0) return;
|
|
928
|
+
for (const originOpening of originOpenings) {
|
|
929
|
+
for (const connection of connections) {
|
|
930
|
+
const { opening, level } = connection;
|
|
931
|
+
let distance5 = baseDistance;
|
|
932
|
+
if (scaleDistanceByLevel) {
|
|
933
|
+
const originOrdinal = originLevel.properties.ordinal;
|
|
934
|
+
const connectionOrdinal = level.properties.ordinal;
|
|
935
|
+
const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
|
|
936
|
+
if (levelDifference > 0) distance5 *= levelDifference;
|
|
937
|
+
}
|
|
938
|
+
import_lodash4.default.set(elevatorNodeMap, `${originOpening.id}.${opening.id}`, distance5);
|
|
939
|
+
import_lodash4.default.set(elevatorNodeMap, `${opening.id}.${originOpening.id}`, distance5);
|
|
940
|
+
counter++;
|
|
941
|
+
}
|
|
818
942
|
}
|
|
943
|
+
} catch (err) {
|
|
944
|
+
console.log(err);
|
|
945
|
+
console.log("cannot create elevatorNodeMap for ", { relationship });
|
|
819
946
|
}
|
|
820
|
-
path = createKeyPath(name);
|
|
821
|
-
id = createKeyId(name);
|
|
822
|
-
getFn = key.getFn;
|
|
823
947
|
}
|
|
824
|
-
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
let
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
948
|
+
const t1 = performance.now();
|
|
949
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} escalator relationships`, t1 - t0);
|
|
950
|
+
return elevatorNodeMap;
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
// src/data/navigate/graph/nodemap/createEscalatorNodeMap.ts
|
|
954
|
+
var import_set = __toESM(require("lodash/set"));
|
|
955
|
+
var createEscalatorNodeMap = (relationships, options) => {
|
|
956
|
+
const t0 = performance.now();
|
|
957
|
+
const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "escalator");
|
|
958
|
+
let counter = 0;
|
|
959
|
+
let nodeMap = {};
|
|
960
|
+
for (const relationship of relationships) {
|
|
961
|
+
const {
|
|
962
|
+
properties: { direction, origin, destination }
|
|
963
|
+
} = relationship;
|
|
964
|
+
(0, import_set.default)(nodeMap, `${origin.id}.${destination.id}`, distanceOptions.baseDistance);
|
|
965
|
+
if (direction === "undirected") {
|
|
966
|
+
(0, import_set.default)(nodeMap, `${destination.id}.${origin.id}`, distanceOptions.baseDistance);
|
|
838
967
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
968
|
+
counter++;
|
|
969
|
+
}
|
|
970
|
+
const t1 = performance.now();
|
|
971
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} escalator relationships`, t1 - t0);
|
|
972
|
+
return nodeMap;
|
|
973
|
+
};
|
|
974
|
+
|
|
975
|
+
// src/data/navigate/graph/nodemap/createRampNodeMap.ts
|
|
976
|
+
var import_set2 = __toESM(require("lodash/set"));
|
|
977
|
+
var createRampNodeMap = (relationships, options) => {
|
|
978
|
+
const t0 = performance.now();
|
|
979
|
+
const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "ramp");
|
|
980
|
+
let counter = 0;
|
|
981
|
+
let nodeMap = {};
|
|
982
|
+
relationships.forEach((relationship) => {
|
|
983
|
+
const {
|
|
984
|
+
properties: { origin, destination }
|
|
985
|
+
} = relationship;
|
|
986
|
+
(0, import_set2.default)(nodeMap, `${origin.id}.${destination.id}`, distanceOptions.baseDistance);
|
|
987
|
+
(0, import_set2.default)(nodeMap, `${destination.id}.${origin.id}`, distanceOptions.baseDistance);
|
|
988
|
+
counter++;
|
|
989
|
+
});
|
|
990
|
+
const t1 = performance.now();
|
|
991
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} ramp relationships`, t1 - t0);
|
|
992
|
+
return nodeMap;
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
// src/data/navigate/graph/nodemap/createStairNodeMap.ts
|
|
996
|
+
var import_lodash6 = __toESM(require("lodash"));
|
|
997
|
+
var createStairNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
|
|
998
|
+
const t0 = performance.now();
|
|
999
|
+
const { levels = [], openings = [], units = [] } = options.data;
|
|
1000
|
+
const { baseDistance, scaleDistanceByLevel } = getDistanceOptions(options.unitDistanceOptions, "stairs");
|
|
1001
|
+
let elevatorNodeMap = {};
|
|
1002
|
+
let counter = 0;
|
|
1003
|
+
for (const relationship of elevatorLikeRelationships) {
|
|
1004
|
+
try {
|
|
1005
|
+
const {
|
|
1006
|
+
origin: { id: originId },
|
|
1007
|
+
intermediary,
|
|
1008
|
+
destination: { id: destinationId }
|
|
1009
|
+
} = relationship.properties;
|
|
1010
|
+
const origin = openings.find((opening) => opening.id === originId);
|
|
1011
|
+
if (!origin) return;
|
|
1012
|
+
const originLevel = levels.find((level) => level.id === origin.properties.level_id);
|
|
1013
|
+
const destination = openings.find((opening) => opening.id === destinationId);
|
|
1014
|
+
const destinationOpeningAndLevel = {
|
|
1015
|
+
opening: destination,
|
|
1016
|
+
level: levels.find((level) => level.id === destination.properties.level_id)
|
|
1017
|
+
};
|
|
1018
|
+
const intermediaryOpeningAndLevels = intermediary.map((unitTypeAndId) => {
|
|
1019
|
+
const openings2 = unitOpenings[unitTypeAndId.id];
|
|
1020
|
+
const unit = units.find((unit2) => unit2.id === unitTypeAndId.id);
|
|
1021
|
+
const level = levels.find((level2) => level2.id === unit.properties.level_id);
|
|
1022
|
+
return openings2.map((opening) => ({ opening, level }));
|
|
1023
|
+
}).flat();
|
|
1024
|
+
const connections = [...intermediaryOpeningAndLevels, destinationOpeningAndLevel];
|
|
1025
|
+
if (!origin) return;
|
|
1026
|
+
for (const connection of connections) {
|
|
1027
|
+
const { opening, level } = connection;
|
|
1028
|
+
let distance5 = baseDistance;
|
|
1029
|
+
if (scaleDistanceByLevel) {
|
|
1030
|
+
const originOrdinal = originLevel.properties.ordinal;
|
|
1031
|
+
const connectionOrdinal = level.properties.ordinal;
|
|
1032
|
+
const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
|
|
1033
|
+
if (levelDifference > 0) distance5 *= levelDifference;
|
|
853
1034
|
}
|
|
854
|
-
|
|
855
|
-
|
|
1035
|
+
import_lodash6.default.set(elevatorNodeMap, `${origin.id}.${opening.id}`, distance5);
|
|
1036
|
+
import_lodash6.default.set(elevatorNodeMap, `${opening.id}.${origin.id}`, distance5);
|
|
1037
|
+
counter++;
|
|
856
1038
|
}
|
|
1039
|
+
} catch (err) {
|
|
1040
|
+
console.warn(
|
|
1041
|
+
"Failed to create stairNodeMap",
|
|
1042
|
+
{
|
|
1043
|
+
relationshipId: relationship.id,
|
|
1044
|
+
featureType: relationship.feature_type,
|
|
1045
|
+
error: err instanceof Error ? err.message : err,
|
|
1046
|
+
stack: err instanceof Error ? err.stack : void 0
|
|
1047
|
+
}
|
|
1048
|
+
);
|
|
857
1049
|
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
1050
|
+
}
|
|
1051
|
+
const t1 = performance.now();
|
|
1052
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} stairs relationships`, t1 - t0);
|
|
1053
|
+
return elevatorNodeMap;
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// src/data/navigate/graph/nodemap/createOccupantNodeMap.ts
|
|
1057
|
+
var import_lodash7 = __toESM(require("lodash"));
|
|
1058
|
+
var createOccupantNodeMap = (occupants) => {
|
|
1059
|
+
const t0 = performance.now();
|
|
1060
|
+
let nodeMap = {};
|
|
1061
|
+
let counter = 0;
|
|
1062
|
+
occupants.forEach((occupant) => {
|
|
1063
|
+
const { unit_id, unit_ids = [], kiosk_id, kiosk_ids = [] } = occupant.properties;
|
|
1064
|
+
const occupantRoomIds = compact([unit_id, ...unit_ids]);
|
|
1065
|
+
const occupantKioskIds = compact([kiosk_id, ...kiosk_ids]);
|
|
1066
|
+
for (const roomId of occupantRoomIds) {
|
|
1067
|
+
import_lodash7.default.set(nodeMap, `${roomId}.${occupant.id}`, 1e-3);
|
|
1068
|
+
import_lodash7.default.set(nodeMap, `${occupant.id}.${roomId}`, 1e-3);
|
|
1069
|
+
counter++;
|
|
1070
|
+
}
|
|
1071
|
+
for (const kioskId of occupantKioskIds) {
|
|
1072
|
+
import_lodash7.default.set(nodeMap, `${kioskId}.${occupant.id}`, 1e-3);
|
|
1073
|
+
import_lodash7.default.set(nodeMap, `${occupant.id}.${kioskId}`, 1e-3);
|
|
1074
|
+
counter++;
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
const t1 = performance.now();
|
|
1078
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} occupants relationships`, t1 - t0);
|
|
1079
|
+
return nodeMap;
|
|
872
1080
|
};
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1081
|
+
|
|
1082
|
+
// src/data/navigate/graph/nodemap/createPOINodeMaps.ts
|
|
1083
|
+
var import_center4 = require("@turf/center");
|
|
1084
|
+
var import_distance2 = require("@turf/distance");
|
|
1085
|
+
var import_lodash9 = __toESM(require("lodash"));
|
|
1086
|
+
var createPOINodeMap = (features, getFeatureUnit, unitOpenings) => {
|
|
1087
|
+
const t0 = performance.now();
|
|
1088
|
+
let nodeMap = {};
|
|
1089
|
+
let counter = 0;
|
|
1090
|
+
features.forEach((feat) => {
|
|
1091
|
+
try {
|
|
1092
|
+
const locatedOnUnitId = getFeatureUnit(feat);
|
|
1093
|
+
const openings = unitOpenings[locatedOnUnitId];
|
|
1094
|
+
const center7 = (0, import_center4.center)(feat);
|
|
1095
|
+
for (const opening of openings) {
|
|
1096
|
+
try {
|
|
1097
|
+
const openingCenter = (0, import_center4.center)(opening);
|
|
1098
|
+
const dis = (0, import_distance2.distance)(center7, openingCenter, { units: "meters" }) + BASE_POI_BASEDISTANCE;
|
|
1099
|
+
import_lodash9.default.set(nodeMap, `${opening.id}.${feat.id}`, dis);
|
|
1100
|
+
import_lodash9.default.set(nodeMap, `${feat.id}.${opening.id}`, dis);
|
|
1101
|
+
counter++;
|
|
1102
|
+
} catch (err) {
|
|
1103
|
+
console.log(err, opening);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
console.log(err);
|
|
1108
|
+
console.log(`cannot connect poi to openings`, err.message, { feat });
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
const type = features.length > 0 ? features[0].feature_type : "-";
|
|
1112
|
+
const t1 = performance.now();
|
|
1113
|
+
trace("nav", ` \u2502 \u251C\u2500 add ${counter} ${type} relationships`, t1 - t0);
|
|
1114
|
+
return nodeMap;
|
|
887
1115
|
};
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1116
|
+
|
|
1117
|
+
// src/data/navigate/graph/utils/mergeNodeMap.ts
|
|
1118
|
+
var mergeNodeMap = (nodeMaps) => {
|
|
1119
|
+
const out = {};
|
|
1120
|
+
for (const nodeMap of nodeMaps) {
|
|
1121
|
+
for (const from in nodeMap) {
|
|
1122
|
+
out[from] = {
|
|
1123
|
+
...out[from] ?? {},
|
|
1124
|
+
...nodeMap[from]
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
return out;
|
|
900
1129
|
};
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1130
|
+
|
|
1131
|
+
// src/data/navigate/graph/utils/createUnitOpenings.ts
|
|
1132
|
+
var import_uniqBy = __toESM(require("lodash/uniqBy"));
|
|
1133
|
+
var createUnitOpenings = (relationships, units, openings) => {
|
|
1134
|
+
const openingConnections = {};
|
|
1135
|
+
const relationshipMap = /* @__PURE__ */ new Map();
|
|
1136
|
+
relationships.forEach((relationship) => {
|
|
1137
|
+
const originId = relationship.properties.origin?.id || null;
|
|
1138
|
+
const destinationId = relationship.properties.destination?.id || null;
|
|
1139
|
+
if (!relationshipMap.has(originId)) {
|
|
1140
|
+
relationshipMap.set(originId, []);
|
|
1141
|
+
}
|
|
1142
|
+
if (!relationshipMap.has(destinationId)) {
|
|
1143
|
+
relationshipMap.set(destinationId, []);
|
|
1144
|
+
}
|
|
1145
|
+
relationshipMap.get(originId).push(relationship);
|
|
1146
|
+
relationshipMap.get(destinationId).push(relationship);
|
|
1147
|
+
});
|
|
1148
|
+
units.forEach((unit) => {
|
|
1149
|
+
const unitId = unit.id;
|
|
1150
|
+
const connectedRelationshop = relationshipMap.get(unitId) || [];
|
|
1151
|
+
const relationshipIntermediaryTypeAndId = connectedRelationshop.map(
|
|
1152
|
+
(relationship) => relationship.properties.intermediary[0]
|
|
1153
|
+
// Assuming intermediary is always an array
|
|
1154
|
+
);
|
|
1155
|
+
const relationshipIntermediary = relationshipIntermediaryTypeAndId.map(({ id }) => {
|
|
1156
|
+
return openings.find((opening) => opening.id === id);
|
|
1157
|
+
});
|
|
1158
|
+
openingConnections[unitId] = (0, import_uniqBy.default)(
|
|
1159
|
+
[...openingConnections[unitId] || [], ...relationshipIntermediary],
|
|
1160
|
+
"id"
|
|
1161
|
+
);
|
|
1162
|
+
});
|
|
1163
|
+
return openingConnections;
|
|
917
1164
|
};
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
...AdvancedOptions
|
|
1165
|
+
|
|
1166
|
+
// src/data/navigate/parsers.ts
|
|
1167
|
+
var parseOrdinalCoordinate = (id) => {
|
|
1168
|
+
return id.slice(0, -1).split(",").map(Number);
|
|
923
1169
|
};
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1170
|
+
|
|
1171
|
+
// src/data/navigate/graph/prepare.ts
|
|
1172
|
+
var prepareGraph = (options) => {
|
|
1173
|
+
const {
|
|
1174
|
+
data: {
|
|
1175
|
+
amenities = [],
|
|
1176
|
+
anchors = [],
|
|
1177
|
+
occupants = [],
|
|
1178
|
+
relationships = [],
|
|
1179
|
+
openings = [],
|
|
1180
|
+
units = [],
|
|
1181
|
+
kiosks = [],
|
|
1182
|
+
levels = []
|
|
1183
|
+
}
|
|
1184
|
+
} = options;
|
|
1185
|
+
const {
|
|
1186
|
+
traversal: traversalRelationships = [],
|
|
1187
|
+
escalator: escalatorRelationships = [],
|
|
1188
|
+
ramp: rampRelationships = [],
|
|
1189
|
+
elevator: elevatorRelationships = [],
|
|
1190
|
+
stairs: stairsRelationships = []
|
|
1191
|
+
} = import_lodash10.default.groupBy(relationships, "properties.category");
|
|
1192
|
+
const unitOpenings = createUnitOpenings(traversalRelationships, units, openings);
|
|
1193
|
+
const traversalNodeMap = createTraversalNodeMap(unitOpenings, options);
|
|
1194
|
+
const escalatorNodeMap = createEscalatorNodeMap(escalatorRelationships, options);
|
|
1195
|
+
const rampNodeMap = createRampNodeMap(rampRelationships, options);
|
|
1196
|
+
const elevatorNodeMap = createElevatorNodeMap(
|
|
1197
|
+
elevatorRelationships,
|
|
1198
|
+
unitOpenings,
|
|
1199
|
+
options
|
|
1200
|
+
);
|
|
1201
|
+
const stairNodeMap = createStairNodeMap(
|
|
1202
|
+
stairsRelationships,
|
|
1203
|
+
unitOpenings,
|
|
1204
|
+
options
|
|
1205
|
+
);
|
|
1206
|
+
const amenityNodeMap = createPOINodeMap(amenities, (amenity) => amenity.properties.unit_ids[0], unitOpenings);
|
|
1207
|
+
const anchorsNodeMap = createPOINodeMap(anchors, (anchor) => anchor.properties.unit_id, unitOpenings);
|
|
1208
|
+
const walkwayUnits = units.filter((unit) => unit.properties.category === "walkway");
|
|
1209
|
+
const kioskNodeMap = createPOINodeMap(kiosks, (kiosk) => findContainingUnit(kiosk, walkwayUnits)?.id, unitOpenings);
|
|
1210
|
+
const unitNodeMap = createPOINodeMap(units, (unit) => unit.id, unitOpenings);
|
|
1211
|
+
const occupantNodeMap = createOccupantNodeMap(occupants);
|
|
1212
|
+
const defaultGraph = new import_node_dijkstra.default(mergeNodeMap([
|
|
1213
|
+
traversalNodeMap,
|
|
1214
|
+
escalatorNodeMap,
|
|
1215
|
+
rampNodeMap,
|
|
1216
|
+
elevatorNodeMap,
|
|
1217
|
+
stairNodeMap,
|
|
1218
|
+
amenityNodeMap,
|
|
1219
|
+
anchorsNodeMap,
|
|
1220
|
+
kioskNodeMap,
|
|
1221
|
+
unitNodeMap,
|
|
1222
|
+
occupantNodeMap
|
|
1223
|
+
]));
|
|
1224
|
+
const accessibleGraph = new import_node_dijkstra.default(mergeNodeMap([
|
|
1225
|
+
traversalNodeMap,
|
|
1226
|
+
rampNodeMap,
|
|
1227
|
+
elevatorNodeMap,
|
|
1228
|
+
amenityNodeMap,
|
|
1229
|
+
anchorsNodeMap,
|
|
1230
|
+
kioskNodeMap,
|
|
1231
|
+
unitNodeMap,
|
|
1232
|
+
occupantNodeMap
|
|
1233
|
+
]));
|
|
1234
|
+
const addCoordinateOrdinalNode = (params, locatedOnUnit) => {
|
|
1235
|
+
const [lat, lng, ordinal] = parseOrdinalCoordinate(params);
|
|
1236
|
+
if (locatedOnUnit) {
|
|
1237
|
+
const openings2 = unitOpenings[locatedOnUnit.id];
|
|
1238
|
+
for (const opening of openings2) {
|
|
1239
|
+
const openingCenter = (0, import_center5.center)(opening);
|
|
1240
|
+
const dis = (0, import_distance3.distance)([lat, lng], openingCenter, { units: "meters" });
|
|
1241
|
+
defaultGraph.addNode(params, { [opening.id]: dis }).addNode(opening.id, { [params]: dis });
|
|
1242
|
+
accessibleGraph.addNode(params, { [opening.id]: dis }).addNode(opening.id, { [params]: dis });
|
|
933
1243
|
}
|
|
934
|
-
const norm2 = 1 / Math.pow(numTokens, 0.5 * weight);
|
|
935
|
-
const n = parseFloat(Math.round(norm2 * m) / m);
|
|
936
|
-
cache.set(numTokens, n);
|
|
937
|
-
return n;
|
|
938
|
-
},
|
|
939
|
-
clear() {
|
|
940
|
-
cache.clear();
|
|
941
1244
|
}
|
|
942
1245
|
};
|
|
1246
|
+
return { defaultGraph, accessibleGraph, unitOpenings, addCoordinateOrdinalNode };
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
// src/data/navigate/steps/createStepUtils.ts
|
|
1250
|
+
var import_lodash12 = require("lodash");
|
|
1251
|
+
var import_intersectionBy = __toESM(require("lodash/intersectionBy"));
|
|
1252
|
+
var import_center9 = require("@turf/center");
|
|
1253
|
+
|
|
1254
|
+
// src/data/navigate/description/describe.ts
|
|
1255
|
+
var t = (template, locale, options) => {
|
|
1256
|
+
return template.replace(`{{intermediary}}`, options.intermediary ?? "").replace(`{{toward}}`, options.toward?.[locale] ?? "").replace(`{{landmark}}`, options.landmark?.[locale] ?? "");
|
|
1257
|
+
};
|
|
1258
|
+
var describeVerticalStep = (fromLevel, toLevel, intermediary) => {
|
|
1259
|
+
const dir = fromLevel.properties.ordinal < toLevel.properties.ordinal ? "up" : "down";
|
|
1260
|
+
const template = `Take the {{intermediary}} ${dir} to {{toward}}`;
|
|
1261
|
+
return {
|
|
1262
|
+
template,
|
|
1263
|
+
text: t(template, "en", { intermediary, toward: toLevel.properties.name })
|
|
1264
|
+
};
|
|
1265
|
+
};
|
|
1266
|
+
var describeHorizontalStep = (intermediary, toward, landmark) => {
|
|
1267
|
+
const template = `Follow the path ${intermediary === "walkway" ? `along the walkway` : `through {{intermediary}}`} ${toward ? `toward {{toward}}` : ``} ${landmark ? `near {{landmark}}` : ``}`.trim();
|
|
1268
|
+
return {
|
|
1269
|
+
text: t(template, "en", { intermediary, toward, landmark }),
|
|
1270
|
+
template
|
|
1271
|
+
};
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
// src/data/navigate/steps/path/index.ts
|
|
1275
|
+
var import_lodash11 = __toESM(require("lodash"));
|
|
1276
|
+
|
|
1277
|
+
// src/data/navigate/constants.ts
|
|
1278
|
+
var OBSTACLE_FEATURE_TYPES = [
|
|
1279
|
+
"kiosk"
|
|
1280
|
+
/* , "fixture" */
|
|
1281
|
+
];
|
|
1282
|
+
var OBSTACLE_CATEGORIES = [
|
|
1283
|
+
"fixture.water",
|
|
1284
|
+
"fixture.stage",
|
|
1285
|
+
"nonpublic",
|
|
1286
|
+
"opentobelow",
|
|
1287
|
+
"elevator",
|
|
1288
|
+
"escalator",
|
|
1289
|
+
"stairs",
|
|
1290
|
+
"stairs.emergencyexit",
|
|
1291
|
+
"room",
|
|
1292
|
+
"unspecified",
|
|
1293
|
+
"structure",
|
|
1294
|
+
"brick",
|
|
1295
|
+
"concrete",
|
|
1296
|
+
"drywall",
|
|
1297
|
+
"glass",
|
|
1298
|
+
"wood",
|
|
1299
|
+
"column"
|
|
1300
|
+
];
|
|
1301
|
+
var WALKABLE_CATEGORY = [
|
|
1302
|
+
"walkway",
|
|
1303
|
+
"parking",
|
|
1304
|
+
"room",
|
|
1305
|
+
"terrace",
|
|
1306
|
+
"unenclosedarea",
|
|
1307
|
+
"vegetation",
|
|
1308
|
+
"unspecified"
|
|
1309
|
+
];
|
|
1310
|
+
|
|
1311
|
+
// node_modules/@turf/helpers/dist/esm/index.js
|
|
1312
|
+
var earthRadius = 63710088e-1;
|
|
1313
|
+
var factors = {
|
|
1314
|
+
centimeters: earthRadius * 100,
|
|
1315
|
+
centimetres: earthRadius * 100,
|
|
1316
|
+
degrees: 360 / (2 * Math.PI),
|
|
1317
|
+
feet: earthRadius * 3.28084,
|
|
1318
|
+
inches: earthRadius * 39.37,
|
|
1319
|
+
kilometers: earthRadius / 1e3,
|
|
1320
|
+
kilometres: earthRadius / 1e3,
|
|
1321
|
+
meters: earthRadius,
|
|
1322
|
+
metres: earthRadius,
|
|
1323
|
+
miles: earthRadius / 1609.344,
|
|
1324
|
+
millimeters: earthRadius * 1e3,
|
|
1325
|
+
millimetres: earthRadius * 1e3,
|
|
1326
|
+
nauticalmiles: earthRadius / 1852,
|
|
1327
|
+
radians: 1,
|
|
1328
|
+
yards: earthRadius * 1.0936
|
|
1329
|
+
};
|
|
1330
|
+
function feature(geom, properties, options = {}) {
|
|
1331
|
+
const feat = { type: "Feature" };
|
|
1332
|
+
if (options.id === 0 || options.id) {
|
|
1333
|
+
feat.id = options.id;
|
|
1334
|
+
}
|
|
1335
|
+
if (options.bbox) {
|
|
1336
|
+
feat.bbox = options.bbox;
|
|
1337
|
+
}
|
|
1338
|
+
feat.properties = properties || {};
|
|
1339
|
+
feat.geometry = geom;
|
|
1340
|
+
return feat;
|
|
943
1341
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
fieldNormWeight = Config.fieldNormWeight
|
|
948
|
-
} = {}) {
|
|
949
|
-
this.norm = norm(fieldNormWeight, 3);
|
|
950
|
-
this.getFn = getFn;
|
|
951
|
-
this.isCreated = false;
|
|
952
|
-
this.setIndexRecords();
|
|
1342
|
+
function point(coordinates, properties, options = {}) {
|
|
1343
|
+
if (!coordinates) {
|
|
1344
|
+
throw new Error("coordinates is required");
|
|
953
1345
|
}
|
|
954
|
-
|
|
955
|
-
|
|
1346
|
+
if (!Array.isArray(coordinates)) {
|
|
1347
|
+
throw new Error("coordinates must be an Array");
|
|
956
1348
|
}
|
|
957
|
-
|
|
958
|
-
|
|
1349
|
+
if (coordinates.length < 2) {
|
|
1350
|
+
throw new Error("coordinates must be at least 2 numbers long");
|
|
959
1351
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
this._keysMap = {};
|
|
963
|
-
keys.forEach((key, idx) => {
|
|
964
|
-
this._keysMap[key.id] = idx;
|
|
965
|
-
});
|
|
1352
|
+
if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
|
|
1353
|
+
throw new Error("coordinates must contain numbers");
|
|
966
1354
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1355
|
+
const geom = {
|
|
1356
|
+
type: "Point",
|
|
1357
|
+
coordinates
|
|
1358
|
+
};
|
|
1359
|
+
return feature(geom, properties, options);
|
|
1360
|
+
}
|
|
1361
|
+
function polygon(coordinates, properties, options = {}) {
|
|
1362
|
+
for (const ring of coordinates) {
|
|
1363
|
+
if (ring.length < 4) {
|
|
1364
|
+
throw new Error(
|
|
1365
|
+
"Each LinearRing of a Polygon must have 4 or more Positions."
|
|
1366
|
+
);
|
|
970
1367
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
this.docs.forEach((doc, docIndex) => {
|
|
974
|
-
this._addString(doc, docIndex);
|
|
975
|
-
});
|
|
976
|
-
} else {
|
|
977
|
-
this.docs.forEach((doc, docIndex) => {
|
|
978
|
-
this._addObject(doc, docIndex);
|
|
979
|
-
});
|
|
1368
|
+
if (ring[ring.length - 1].length !== ring[0].length) {
|
|
1369
|
+
throw new Error("First and last Position are not equivalent.");
|
|
980
1370
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
const idx = this.size();
|
|
986
|
-
if (isString(doc)) {
|
|
987
|
-
this._addString(doc, idx);
|
|
988
|
-
} else {
|
|
989
|
-
this._addObject(doc, idx);
|
|
1371
|
+
for (let j = 0; j < ring[ring.length - 1].length; j++) {
|
|
1372
|
+
if (ring[ring.length - 1][j] !== ring[0][j]) {
|
|
1373
|
+
throw new Error("First and last Position are not equivalent.");
|
|
1374
|
+
}
|
|
990
1375
|
}
|
|
991
1376
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1377
|
+
const geom = {
|
|
1378
|
+
type: "Polygon",
|
|
1379
|
+
coordinates
|
|
1380
|
+
};
|
|
1381
|
+
return feature(geom, properties, options);
|
|
1382
|
+
}
|
|
1383
|
+
function lineString(coordinates, properties, options = {}) {
|
|
1384
|
+
if (coordinates.length < 2) {
|
|
1385
|
+
throw new Error("coordinates must be an array of two or more positions");
|
|
998
1386
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1387
|
+
const geom = {
|
|
1388
|
+
type: "LineString",
|
|
1389
|
+
coordinates
|
|
1390
|
+
};
|
|
1391
|
+
return feature(geom, properties, options);
|
|
1392
|
+
}
|
|
1393
|
+
function featureCollection(features, options = {}) {
|
|
1394
|
+
const fc = { type: "FeatureCollection" };
|
|
1395
|
+
if (options.id) {
|
|
1396
|
+
fc.id = options.id;
|
|
1001
1397
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1398
|
+
if (options.bbox) {
|
|
1399
|
+
fc.bbox = options.bbox;
|
|
1004
1400
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1401
|
+
fc.features = features;
|
|
1402
|
+
return fc;
|
|
1403
|
+
}
|
|
1404
|
+
function isNumber(num) {
|
|
1405
|
+
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
1406
|
+
}
|
|
1407
|
+
function isObject(input) {
|
|
1408
|
+
return input !== null && typeof input === "object" && !Array.isArray(input);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
// node_modules/@turf/invariant/dist/esm/index.js
|
|
1412
|
+
function getCoord(coord) {
|
|
1413
|
+
if (!coord) {
|
|
1414
|
+
throw new Error("coord is required");
|
|
1415
|
+
}
|
|
1416
|
+
if (!Array.isArray(coord)) {
|
|
1417
|
+
if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {
|
|
1418
|
+
return [...coord.geometry.coordinates];
|
|
1419
|
+
}
|
|
1420
|
+
if (coord.type === "Point") {
|
|
1421
|
+
return [...coord.coordinates];
|
|
1008
1422
|
}
|
|
1009
|
-
let record = {
|
|
1010
|
-
v: doc,
|
|
1011
|
-
i: docIndex,
|
|
1012
|
-
n: this.norm.get(doc)
|
|
1013
|
-
};
|
|
1014
|
-
this.records.push(record);
|
|
1015
|
-
}
|
|
1016
|
-
_addObject(doc, docIndex) {
|
|
1017
|
-
let record = { i: docIndex, $: {} };
|
|
1018
|
-
this.keys.forEach((key, keyIndex) => {
|
|
1019
|
-
let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
|
|
1020
|
-
if (!isDefined(value)) {
|
|
1021
|
-
return;
|
|
1022
|
-
}
|
|
1023
|
-
if (isArray(value)) {
|
|
1024
|
-
let subRecords = [];
|
|
1025
|
-
const stack = [{ nestedArrIndex: -1, value }];
|
|
1026
|
-
while (stack.length) {
|
|
1027
|
-
const { nestedArrIndex, value: value2 } = stack.pop();
|
|
1028
|
-
if (!isDefined(value2)) {
|
|
1029
|
-
continue;
|
|
1030
|
-
}
|
|
1031
|
-
if (isString(value2) && !isBlank(value2)) {
|
|
1032
|
-
let subRecord = {
|
|
1033
|
-
v: value2,
|
|
1034
|
-
i: nestedArrIndex,
|
|
1035
|
-
n: this.norm.get(value2)
|
|
1036
|
-
};
|
|
1037
|
-
subRecords.push(subRecord);
|
|
1038
|
-
} else if (isArray(value2)) {
|
|
1039
|
-
value2.forEach((item, k) => {
|
|
1040
|
-
stack.push({
|
|
1041
|
-
nestedArrIndex: k,
|
|
1042
|
-
value: item
|
|
1043
|
-
});
|
|
1044
|
-
});
|
|
1045
|
-
} else ;
|
|
1046
|
-
}
|
|
1047
|
-
record.$[keyIndex] = subRecords;
|
|
1048
|
-
} else if (isString(value) && !isBlank(value)) {
|
|
1049
|
-
let subRecord = {
|
|
1050
|
-
v: value,
|
|
1051
|
-
n: this.norm.get(value)
|
|
1052
|
-
};
|
|
1053
|
-
record.$[keyIndex] = subRecord;
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
this.records.push(record);
|
|
1057
1423
|
}
|
|
1058
|
-
|
|
1059
|
-
return
|
|
1060
|
-
keys: this.keys,
|
|
1061
|
-
records: this.records
|
|
1062
|
-
};
|
|
1424
|
+
if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {
|
|
1425
|
+
return [...coord];
|
|
1063
1426
|
}
|
|
1064
|
-
|
|
1065
|
-
function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
|
|
1066
|
-
const myIndex = new FuseIndex({ getFn, fieldNormWeight });
|
|
1067
|
-
myIndex.setKeys(keys.map(createKey));
|
|
1068
|
-
myIndex.setSources(docs);
|
|
1069
|
-
myIndex.create();
|
|
1070
|
-
return myIndex;
|
|
1427
|
+
throw new Error("coord must be GeoJSON Point or an Array of numbers");
|
|
1071
1428
|
}
|
|
1072
|
-
function
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
return myIndex;
|
|
1429
|
+
function getGeom(geojson) {
|
|
1430
|
+
if (geojson.type === "Feature") {
|
|
1431
|
+
return geojson.geometry;
|
|
1432
|
+
}
|
|
1433
|
+
return geojson;
|
|
1078
1434
|
}
|
|
1079
|
-
function
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
expectedLocation = 0,
|
|
1083
|
-
distance = Config.distance,
|
|
1084
|
-
ignoreLocation = Config.ignoreLocation
|
|
1085
|
-
} = {}) {
|
|
1086
|
-
const accuracy = errors / pattern.length;
|
|
1087
|
-
if (ignoreLocation) {
|
|
1088
|
-
return accuracy;
|
|
1435
|
+
function getType(geojson, _name) {
|
|
1436
|
+
if (geojson.type === "FeatureCollection") {
|
|
1437
|
+
return "FeatureCollection";
|
|
1089
1438
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
return proximity ? 1 : accuracy;
|
|
1439
|
+
if (geojson.type === "GeometryCollection") {
|
|
1440
|
+
return "GeometryCollection";
|
|
1093
1441
|
}
|
|
1094
|
-
|
|
1442
|
+
if (geojson.type === "Feature" && geojson.geometry !== null) {
|
|
1443
|
+
return geojson.geometry.type;
|
|
1444
|
+
}
|
|
1445
|
+
return geojson.type;
|
|
1095
1446
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1447
|
+
|
|
1448
|
+
// src/data/navigate/steps/path/index.ts
|
|
1449
|
+
var import_difference = __toESM(require("@turf/difference"));
|
|
1450
|
+
var import_envelope = __toESM(require("@turf/envelope"));
|
|
1451
|
+
var import_boolean_overlap = __toESM(require("@turf/boolean-overlap"));
|
|
1452
|
+
var import_boolean_intersects = __toESM(require("@turf/boolean-intersects"));
|
|
1453
|
+
|
|
1454
|
+
// ../../node_modules/@turf/meta/dist/esm/index.js
|
|
1455
|
+
function coordEach(geojson, callback, excludeWrapCoord) {
|
|
1456
|
+
if (geojson === null) return;
|
|
1457
|
+
var j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", stop = isFeatureCollection ? geojson.features.length : 1;
|
|
1458
|
+
for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
|
|
1459
|
+
geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
|
|
1460
|
+
isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
|
|
1461
|
+
stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
|
|
1462
|
+
for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
|
|
1463
|
+
var multiFeatureIndex = 0;
|
|
1464
|
+
var geometryIndex = 0;
|
|
1465
|
+
geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
|
|
1466
|
+
if (geometry === null) continue;
|
|
1467
|
+
coords = geometry.coordinates;
|
|
1468
|
+
var geomType = geometry.type;
|
|
1469
|
+
wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
|
|
1470
|
+
switch (geomType) {
|
|
1471
|
+
case null:
|
|
1472
|
+
break;
|
|
1473
|
+
case "Point":
|
|
1474
|
+
if (callback(
|
|
1475
|
+
coords,
|
|
1476
|
+
coordIndex,
|
|
1477
|
+
featureIndex,
|
|
1478
|
+
multiFeatureIndex,
|
|
1479
|
+
geometryIndex
|
|
1480
|
+
) === false)
|
|
1481
|
+
return false;
|
|
1482
|
+
coordIndex++;
|
|
1483
|
+
multiFeatureIndex++;
|
|
1484
|
+
break;
|
|
1485
|
+
case "LineString":
|
|
1486
|
+
case "MultiPoint":
|
|
1487
|
+
for (j = 0; j < coords.length; j++) {
|
|
1488
|
+
if (callback(
|
|
1489
|
+
coords[j],
|
|
1490
|
+
coordIndex,
|
|
1491
|
+
featureIndex,
|
|
1492
|
+
multiFeatureIndex,
|
|
1493
|
+
geometryIndex
|
|
1494
|
+
) === false)
|
|
1495
|
+
return false;
|
|
1496
|
+
coordIndex++;
|
|
1497
|
+
if (geomType === "MultiPoint") multiFeatureIndex++;
|
|
1498
|
+
}
|
|
1499
|
+
if (geomType === "LineString") multiFeatureIndex++;
|
|
1500
|
+
break;
|
|
1501
|
+
case "Polygon":
|
|
1502
|
+
case "MultiLineString":
|
|
1503
|
+
for (j = 0; j < coords.length; j++) {
|
|
1504
|
+
for (k = 0; k < coords[j].length - wrapShrink; k++) {
|
|
1505
|
+
if (callback(
|
|
1506
|
+
coords[j][k],
|
|
1507
|
+
coordIndex,
|
|
1508
|
+
featureIndex,
|
|
1509
|
+
multiFeatureIndex,
|
|
1510
|
+
geometryIndex
|
|
1511
|
+
) === false)
|
|
1512
|
+
return false;
|
|
1513
|
+
coordIndex++;
|
|
1514
|
+
}
|
|
1515
|
+
if (geomType === "MultiLineString") multiFeatureIndex++;
|
|
1516
|
+
if (geomType === "Polygon") geometryIndex++;
|
|
1517
|
+
}
|
|
1518
|
+
if (geomType === "Polygon") multiFeatureIndex++;
|
|
1519
|
+
break;
|
|
1520
|
+
case "MultiPolygon":
|
|
1521
|
+
for (j = 0; j < coords.length; j++) {
|
|
1522
|
+
geometryIndex = 0;
|
|
1523
|
+
for (k = 0; k < coords[j].length; k++) {
|
|
1524
|
+
for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
|
|
1525
|
+
if (callback(
|
|
1526
|
+
coords[j][k][l],
|
|
1527
|
+
coordIndex,
|
|
1528
|
+
featureIndex,
|
|
1529
|
+
multiFeatureIndex,
|
|
1530
|
+
geometryIndex
|
|
1531
|
+
) === false)
|
|
1532
|
+
return false;
|
|
1533
|
+
coordIndex++;
|
|
1534
|
+
}
|
|
1535
|
+
geometryIndex++;
|
|
1536
|
+
}
|
|
1537
|
+
multiFeatureIndex++;
|
|
1538
|
+
}
|
|
1539
|
+
break;
|
|
1540
|
+
case "GeometryCollection":
|
|
1541
|
+
for (j = 0; j < geometry.geometries.length; j++)
|
|
1542
|
+
if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
|
|
1543
|
+
return false;
|
|
1544
|
+
break;
|
|
1545
|
+
default:
|
|
1546
|
+
throw new Error("Unknown Geometry Type");
|
|
1109
1547
|
}
|
|
1110
|
-
start = -1;
|
|
1111
1548
|
}
|
|
1112
1549
|
}
|
|
1113
|
-
if (matchmask[i - 1] && i - start >= minMatchCharLength) {
|
|
1114
|
-
indices.push([start, i - 1]);
|
|
1115
|
-
}
|
|
1116
|
-
return indices;
|
|
1117
1550
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
if (pattern.length > MAX_BITS) {
|
|
1129
|
-
throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
|
|
1130
|
-
}
|
|
1131
|
-
const patternLen = pattern.length;
|
|
1132
|
-
const textLen = text.length;
|
|
1133
|
-
const expectedLocation = Math.max(0, Math.min(location, textLen));
|
|
1134
|
-
let currentThreshold = threshold;
|
|
1135
|
-
let bestLocation = expectedLocation;
|
|
1136
|
-
const computeMatches = minMatchCharLength > 1 || includeMatches;
|
|
1137
|
-
const matchMask = computeMatches ? Array(textLen) : [];
|
|
1138
|
-
let index;
|
|
1139
|
-
while ((index = text.indexOf(pattern, bestLocation)) > -1) {
|
|
1140
|
-
let score = computeScore$1(pattern, {
|
|
1141
|
-
currentLocation: index,
|
|
1142
|
-
expectedLocation,
|
|
1143
|
-
distance,
|
|
1144
|
-
ignoreLocation
|
|
1145
|
-
});
|
|
1146
|
-
currentThreshold = Math.min(score, currentThreshold);
|
|
1147
|
-
bestLocation = index + patternLen;
|
|
1148
|
-
if (computeMatches) {
|
|
1149
|
-
let i = 0;
|
|
1150
|
-
while (i < patternLen) {
|
|
1151
|
-
matchMask[index + i] = 1;
|
|
1152
|
-
i += 1;
|
|
1153
|
-
}
|
|
1551
|
+
|
|
1552
|
+
// ../../node_modules/@turf/bbox/dist/esm/index.js
|
|
1553
|
+
function bbox(geojson, options = {}) {
|
|
1554
|
+
if (geojson.bbox != null && true !== options.recompute) {
|
|
1555
|
+
return geojson.bbox;
|
|
1556
|
+
}
|
|
1557
|
+
const result = [Infinity, Infinity, -Infinity, -Infinity];
|
|
1558
|
+
coordEach(geojson, (coord) => {
|
|
1559
|
+
if (result[0] > coord[0]) {
|
|
1560
|
+
result[0] = coord[0];
|
|
1154
1561
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
let lastBitArr = [];
|
|
1158
|
-
let finalScore = 1;
|
|
1159
|
-
let binMax = patternLen + textLen;
|
|
1160
|
-
const mask = 1 << patternLen - 1;
|
|
1161
|
-
for (let i = 0; i < patternLen; i += 1) {
|
|
1162
|
-
let binMin = 0;
|
|
1163
|
-
let binMid = binMax;
|
|
1164
|
-
while (binMin < binMid) {
|
|
1165
|
-
const score2 = computeScore$1(pattern, {
|
|
1166
|
-
errors: i,
|
|
1167
|
-
currentLocation: expectedLocation + binMid,
|
|
1168
|
-
expectedLocation,
|
|
1169
|
-
distance,
|
|
1170
|
-
ignoreLocation
|
|
1171
|
-
});
|
|
1172
|
-
if (score2 <= currentThreshold) {
|
|
1173
|
-
binMin = binMid;
|
|
1174
|
-
} else {
|
|
1175
|
-
binMax = binMid;
|
|
1176
|
-
}
|
|
1177
|
-
binMid = Math.floor((binMax - binMin) / 2 + binMin);
|
|
1178
|
-
}
|
|
1179
|
-
binMax = binMid;
|
|
1180
|
-
let start = Math.max(1, expectedLocation - binMid + 1);
|
|
1181
|
-
let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
|
|
1182
|
-
let bitArr = Array(finish + 2);
|
|
1183
|
-
bitArr[finish + 1] = (1 << i) - 1;
|
|
1184
|
-
for (let j = finish; j >= start; j -= 1) {
|
|
1185
|
-
let currentLocation = j - 1;
|
|
1186
|
-
let charMatch = patternAlphabet[text.charAt(currentLocation)];
|
|
1187
|
-
if (computeMatches) {
|
|
1188
|
-
matchMask[currentLocation] = +!!charMatch;
|
|
1189
|
-
}
|
|
1190
|
-
bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
|
|
1191
|
-
if (i) {
|
|
1192
|
-
bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
|
|
1193
|
-
}
|
|
1194
|
-
if (bitArr[j] & mask) {
|
|
1195
|
-
finalScore = computeScore$1(pattern, {
|
|
1196
|
-
errors: i,
|
|
1197
|
-
currentLocation,
|
|
1198
|
-
expectedLocation,
|
|
1199
|
-
distance,
|
|
1200
|
-
ignoreLocation
|
|
1201
|
-
});
|
|
1202
|
-
if (finalScore <= currentThreshold) {
|
|
1203
|
-
currentThreshold = finalScore;
|
|
1204
|
-
bestLocation = currentLocation;
|
|
1205
|
-
if (bestLocation <= expectedLocation) {
|
|
1206
|
-
break;
|
|
1207
|
-
}
|
|
1208
|
-
start = Math.max(1, 2 * expectedLocation - bestLocation);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1562
|
+
if (result[1] > coord[1]) {
|
|
1563
|
+
result[1] = coord[1];
|
|
1211
1564
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
currentLocation: expectedLocation,
|
|
1215
|
-
expectedLocation,
|
|
1216
|
-
distance,
|
|
1217
|
-
ignoreLocation
|
|
1218
|
-
});
|
|
1219
|
-
if (score > currentThreshold) {
|
|
1220
|
-
break;
|
|
1565
|
+
if (result[2] < coord[0]) {
|
|
1566
|
+
result[2] = coord[0];
|
|
1221
1567
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
const result = {
|
|
1225
|
-
isMatch: bestLocation >= 0,
|
|
1226
|
-
// Count exact matches (those with a score of 0) to be "almost" exact
|
|
1227
|
-
score: Math.max(1e-3, finalScore)
|
|
1228
|
-
};
|
|
1229
|
-
if (computeMatches) {
|
|
1230
|
-
const indices = convertMaskToIndices(matchMask, minMatchCharLength);
|
|
1231
|
-
if (!indices.length) {
|
|
1232
|
-
result.isMatch = false;
|
|
1233
|
-
} else if (includeMatches) {
|
|
1234
|
-
result.indices = indices;
|
|
1568
|
+
if (result[3] < coord[1]) {
|
|
1569
|
+
result[3] = coord[1];
|
|
1235
1570
|
}
|
|
1236
|
-
}
|
|
1571
|
+
});
|
|
1237
1572
|
return result;
|
|
1238
1573
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
var
|
|
1248
|
-
var
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (!this.pattern.length) {
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
|
-
const addChunk = (pattern2, startIndex) => {
|
|
1279
|
-
this.chunks.push({
|
|
1280
|
-
pattern: pattern2,
|
|
1281
|
-
alphabet: createPatternAlphabet(pattern2),
|
|
1282
|
-
startIndex
|
|
1283
|
-
});
|
|
1284
|
-
};
|
|
1285
|
-
const len = this.pattern.length;
|
|
1286
|
-
if (len > MAX_BITS) {
|
|
1287
|
-
let i = 0;
|
|
1288
|
-
const remainder = len % MAX_BITS;
|
|
1289
|
-
const end = len - remainder;
|
|
1290
|
-
while (i < end) {
|
|
1291
|
-
addChunk(this.pattern.substr(i, MAX_BITS), i);
|
|
1292
|
-
i += MAX_BITS;
|
|
1574
|
+
var index_default = bbox;
|
|
1575
|
+
|
|
1576
|
+
// src/data/navigate/steps/path/turf/shortestPath.ts
|
|
1577
|
+
var import_boolean_point_in_polygon3 = __toESM(require("@turf/boolean-point-in-polygon"));
|
|
1578
|
+
var import_distance4 = __toESM(require("@turf/distance"));
|
|
1579
|
+
var import_transform_scale = __toESM(require("@turf/transform-scale"));
|
|
1580
|
+
var import_union = __toESM(require("@turf/union"));
|
|
1581
|
+
var import_bbox_polygon = __toESM(require("@turf/bbox-polygon"));
|
|
1582
|
+
var import_clean_coords = require("@turf/clean-coords");
|
|
1583
|
+
var import_pathfinding = __toESM(require("pathfinding"));
|
|
1584
|
+
var import_set3 = __toESM(require("lodash/set"));
|
|
1585
|
+
|
|
1586
|
+
// src/data/navigate/steps/path/turf/stringPull.ts
|
|
1587
|
+
function stringPull(grid, path) {
|
|
1588
|
+
const isWalkable = (x, y) => grid.isInside(x, y) && grid.isWalkableAt(x, y);
|
|
1589
|
+
function hasLOS(a, b) {
|
|
1590
|
+
let x0 = a[0], y0 = a[1];
|
|
1591
|
+
const x1 = b[0], y1 = b[1];
|
|
1592
|
+
if (!isWalkable(x0, y0) || !isWalkable(x1, y1)) return false;
|
|
1593
|
+
const dx = Math.abs(x1 - x0);
|
|
1594
|
+
const dy = Math.abs(y1 - y0);
|
|
1595
|
+
const sx = x0 < x1 ? 1 : -1;
|
|
1596
|
+
const sy = y0 < y1 ? 1 : -1;
|
|
1597
|
+
let err = dx - dy;
|
|
1598
|
+
while (true) {
|
|
1599
|
+
if (!isWalkable(x0, y0)) return false;
|
|
1600
|
+
if (x0 === x1 && y0 === y1) break;
|
|
1601
|
+
const e2 = err * 2;
|
|
1602
|
+
let nx = x0;
|
|
1603
|
+
let ny = y0;
|
|
1604
|
+
let movedX = false;
|
|
1605
|
+
let movedY = false;
|
|
1606
|
+
if (e2 > -dy) {
|
|
1607
|
+
err -= dy;
|
|
1608
|
+
nx += sx;
|
|
1609
|
+
movedX = true;
|
|
1293
1610
|
}
|
|
1294
|
-
if (
|
|
1295
|
-
|
|
1296
|
-
|
|
1611
|
+
if (e2 < dx) {
|
|
1612
|
+
err += dx;
|
|
1613
|
+
ny += sy;
|
|
1614
|
+
movedY = true;
|
|
1297
1615
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
searchIn(text) {
|
|
1303
|
-
const { isCaseSensitive, ignoreDiacritics, includeMatches } = this.options;
|
|
1304
|
-
text = isCaseSensitive ? text : text.toLowerCase();
|
|
1305
|
-
text = ignoreDiacritics ? stripDiacritics(text) : text;
|
|
1306
|
-
if (this.pattern === text) {
|
|
1307
|
-
let result2 = {
|
|
1308
|
-
isMatch: true,
|
|
1309
|
-
score: 0
|
|
1310
|
-
};
|
|
1311
|
-
if (includeMatches) {
|
|
1312
|
-
result2.indices = [[0, text.length - 1]];
|
|
1616
|
+
if (movedX && movedY) {
|
|
1617
|
+
if (!isWalkable(nx, y0) || !isWalkable(x0, ny)) return false;
|
|
1313
1618
|
}
|
|
1314
|
-
|
|
1619
|
+
x0 = nx;
|
|
1620
|
+
y0 = ny;
|
|
1315
1621
|
}
|
|
1316
|
-
|
|
1317
|
-
location,
|
|
1318
|
-
distance,
|
|
1319
|
-
threshold,
|
|
1320
|
-
findAllMatches,
|
|
1321
|
-
minMatchCharLength,
|
|
1322
|
-
ignoreLocation
|
|
1323
|
-
} = this.options;
|
|
1324
|
-
let allIndices = [];
|
|
1325
|
-
let totalScore = 0;
|
|
1326
|
-
let hasMatches = false;
|
|
1327
|
-
this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
|
|
1328
|
-
const { isMatch, score, indices } = search(text, pattern, alphabet, {
|
|
1329
|
-
location: location + startIndex,
|
|
1330
|
-
distance,
|
|
1331
|
-
threshold,
|
|
1332
|
-
findAllMatches,
|
|
1333
|
-
minMatchCharLength,
|
|
1334
|
-
includeMatches,
|
|
1335
|
-
ignoreLocation
|
|
1336
|
-
});
|
|
1337
|
-
if (isMatch) {
|
|
1338
|
-
hasMatches = true;
|
|
1339
|
-
}
|
|
1340
|
-
totalScore += score;
|
|
1341
|
-
if (isMatch && indices) {
|
|
1342
|
-
allIndices = [...allIndices, ...indices];
|
|
1343
|
-
}
|
|
1344
|
-
});
|
|
1345
|
-
let result = {
|
|
1346
|
-
isMatch: hasMatches,
|
|
1347
|
-
score: hasMatches ? totalScore / this.chunks.length : 1
|
|
1348
|
-
};
|
|
1349
|
-
if (hasMatches && includeMatches) {
|
|
1350
|
-
result.indices = allIndices;
|
|
1351
|
-
}
|
|
1352
|
-
return result;
|
|
1353
|
-
}
|
|
1354
|
-
};
|
|
1355
|
-
var BaseMatch = class {
|
|
1356
|
-
constructor(pattern) {
|
|
1357
|
-
this.pattern = pattern;
|
|
1358
|
-
}
|
|
1359
|
-
static isMultiMatch(pattern) {
|
|
1360
|
-
return getMatch(pattern, this.multiRegex);
|
|
1361
|
-
}
|
|
1362
|
-
static isSingleMatch(pattern) {
|
|
1363
|
-
return getMatch(pattern, this.singleRegex);
|
|
1622
|
+
return true;
|
|
1364
1623
|
}
|
|
1365
|
-
|
|
1624
|
+
if (path.length <= 2) return path;
|
|
1625
|
+
const out = [path[0]];
|
|
1626
|
+
let i = 0;
|
|
1627
|
+
while (i < path.length - 1) {
|
|
1628
|
+
let best = i + 1;
|
|
1629
|
+
for (let j = i + 2; j < path.length; j++) {
|
|
1630
|
+
if (hasLOS(path[i], path[j])) best = j;
|
|
1631
|
+
else break;
|
|
1632
|
+
}
|
|
1633
|
+
out.push(path[best]);
|
|
1634
|
+
i = best;
|
|
1366
1635
|
}
|
|
1367
|
-
|
|
1368
|
-
function getMatch(pattern, exp) {
|
|
1369
|
-
const matches = pattern.match(exp);
|
|
1370
|
-
return matches ? matches[1] : null;
|
|
1636
|
+
return out;
|
|
1371
1637
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
const
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
static get multiRegex() {
|
|
1402
|
-
return /^!"(.*)"$/;
|
|
1403
|
-
}
|
|
1404
|
-
static get singleRegex() {
|
|
1405
|
-
return /^!(.*)$/;
|
|
1406
|
-
}
|
|
1407
|
-
search(text) {
|
|
1408
|
-
const index = text.indexOf(this.pattern);
|
|
1409
|
-
const isMatch = index === -1;
|
|
1410
|
-
return {
|
|
1411
|
-
isMatch,
|
|
1412
|
-
score: isMatch ? 0 : 1,
|
|
1413
|
-
indices: [0, text.length - 1]
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
};
|
|
1417
|
-
var PrefixExactMatch = class extends BaseMatch {
|
|
1418
|
-
constructor(pattern) {
|
|
1419
|
-
super(pattern);
|
|
1420
|
-
}
|
|
1421
|
-
static get type() {
|
|
1422
|
-
return "prefix-exact";
|
|
1423
|
-
}
|
|
1424
|
-
static get multiRegex() {
|
|
1425
|
-
return /^\^"(.*)"$/;
|
|
1426
|
-
}
|
|
1427
|
-
static get singleRegex() {
|
|
1428
|
-
return /^\^(.*)$/;
|
|
1429
|
-
}
|
|
1430
|
-
search(text) {
|
|
1431
|
-
const isMatch = text.startsWith(this.pattern);
|
|
1432
|
-
return {
|
|
1433
|
-
isMatch,
|
|
1434
|
-
score: isMatch ? 0 : 1,
|
|
1435
|
-
indices: [0, this.pattern.length - 1]
|
|
1436
|
-
};
|
|
1437
|
-
}
|
|
1438
|
-
};
|
|
1439
|
-
var InversePrefixExactMatch = class extends BaseMatch {
|
|
1440
|
-
constructor(pattern) {
|
|
1441
|
-
super(pattern);
|
|
1442
|
-
}
|
|
1443
|
-
static get type() {
|
|
1444
|
-
return "inverse-prefix-exact";
|
|
1445
|
-
}
|
|
1446
|
-
static get multiRegex() {
|
|
1447
|
-
return /^!\^"(.*)"$/;
|
|
1448
|
-
}
|
|
1449
|
-
static get singleRegex() {
|
|
1450
|
-
return /^!\^(.*)$/;
|
|
1451
|
-
}
|
|
1452
|
-
search(text) {
|
|
1453
|
-
const isMatch = !text.startsWith(this.pattern);
|
|
1454
|
-
return {
|
|
1455
|
-
isMatch,
|
|
1456
|
-
score: isMatch ? 0 : 1,
|
|
1457
|
-
indices: [0, text.length - 1]
|
|
1458
|
-
};
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
var SuffixExactMatch = class extends BaseMatch {
|
|
1462
|
-
constructor(pattern) {
|
|
1463
|
-
super(pattern);
|
|
1464
|
-
}
|
|
1465
|
-
static get type() {
|
|
1466
|
-
return "suffix-exact";
|
|
1467
|
-
}
|
|
1468
|
-
static get multiRegex() {
|
|
1469
|
-
return /^"(.*)"\$$/;
|
|
1470
|
-
}
|
|
1471
|
-
static get singleRegex() {
|
|
1472
|
-
return /^(.*)\$$/;
|
|
1473
|
-
}
|
|
1474
|
-
search(text) {
|
|
1475
|
-
const isMatch = text.endsWith(this.pattern);
|
|
1476
|
-
return {
|
|
1477
|
-
isMatch,
|
|
1478
|
-
score: isMatch ? 0 : 1,
|
|
1479
|
-
indices: [text.length - this.pattern.length, text.length - 1]
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
var InverseSuffixExactMatch = class extends BaseMatch {
|
|
1484
|
-
constructor(pattern) {
|
|
1485
|
-
super(pattern);
|
|
1486
|
-
}
|
|
1487
|
-
static get type() {
|
|
1488
|
-
return "inverse-suffix-exact";
|
|
1489
|
-
}
|
|
1490
|
-
static get multiRegex() {
|
|
1491
|
-
return /^!"(.*)"\$$/;
|
|
1492
|
-
}
|
|
1493
|
-
static get singleRegex() {
|
|
1494
|
-
return /^!(.*)\$$/;
|
|
1495
|
-
}
|
|
1496
|
-
search(text) {
|
|
1497
|
-
const isMatch = !text.endsWith(this.pattern);
|
|
1498
|
-
return {
|
|
1499
|
-
isMatch,
|
|
1500
|
-
score: isMatch ? 0 : 1,
|
|
1501
|
-
indices: [0, text.length - 1]
|
|
1502
|
-
};
|
|
1503
|
-
}
|
|
1504
|
-
};
|
|
1505
|
-
var FuzzyMatch = class extends BaseMatch {
|
|
1506
|
-
constructor(pattern, {
|
|
1507
|
-
location = Config.location,
|
|
1508
|
-
threshold = Config.threshold,
|
|
1509
|
-
distance = Config.distance,
|
|
1510
|
-
includeMatches = Config.includeMatches,
|
|
1511
|
-
findAllMatches = Config.findAllMatches,
|
|
1512
|
-
minMatchCharLength = Config.minMatchCharLength,
|
|
1513
|
-
isCaseSensitive = Config.isCaseSensitive,
|
|
1514
|
-
ignoreDiacritics = Config.ignoreDiacritics,
|
|
1515
|
-
ignoreLocation = Config.ignoreLocation
|
|
1516
|
-
} = {}) {
|
|
1517
|
-
super(pattern);
|
|
1518
|
-
this._bitapSearch = new BitapSearch(pattern, {
|
|
1519
|
-
location,
|
|
1520
|
-
threshold,
|
|
1521
|
-
distance,
|
|
1522
|
-
includeMatches,
|
|
1523
|
-
findAllMatches,
|
|
1524
|
-
minMatchCharLength,
|
|
1525
|
-
isCaseSensitive,
|
|
1526
|
-
ignoreDiacritics,
|
|
1527
|
-
ignoreLocation
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
static get type() {
|
|
1531
|
-
return "fuzzy";
|
|
1532
|
-
}
|
|
1533
|
-
static get multiRegex() {
|
|
1534
|
-
return /^"(.*)"$/;
|
|
1535
|
-
}
|
|
1536
|
-
static get singleRegex() {
|
|
1537
|
-
return /^(.*)$/;
|
|
1538
|
-
}
|
|
1539
|
-
search(text) {
|
|
1540
|
-
return this._bitapSearch.searchIn(text);
|
|
1541
|
-
}
|
|
1542
|
-
};
|
|
1543
|
-
var IncludeMatch = class extends BaseMatch {
|
|
1544
|
-
constructor(pattern) {
|
|
1545
|
-
super(pattern);
|
|
1546
|
-
}
|
|
1547
|
-
static get type() {
|
|
1548
|
-
return "include";
|
|
1549
|
-
}
|
|
1550
|
-
static get multiRegex() {
|
|
1551
|
-
return /^'"(.*)"$/;
|
|
1552
|
-
}
|
|
1553
|
-
static get singleRegex() {
|
|
1554
|
-
return /^'(.*)$/;
|
|
1555
|
-
}
|
|
1556
|
-
search(text) {
|
|
1557
|
-
let location = 0;
|
|
1558
|
-
let index;
|
|
1559
|
-
const indices = [];
|
|
1560
|
-
const patternLen = this.pattern.length;
|
|
1561
|
-
while ((index = text.indexOf(this.pattern, location)) > -1) {
|
|
1562
|
-
location = index + patternLen;
|
|
1563
|
-
indices.push([index, location - 1]);
|
|
1638
|
+
|
|
1639
|
+
// src/data/navigate/steps/path/turf/pruneSmallAngle.ts
|
|
1640
|
+
function pruneSmallAngles(path, minDeg = 10) {
|
|
1641
|
+
if (path.length <= 2) return path;
|
|
1642
|
+
const out = [path[0]];
|
|
1643
|
+
for (let i = 1; i < path.length - 1; i++) {
|
|
1644
|
+
const a = out[out.length - 1];
|
|
1645
|
+
const b = path[i];
|
|
1646
|
+
const c = path[i + 1];
|
|
1647
|
+
const abx = b[0] - a[0], aby = b[1] - a[1];
|
|
1648
|
+
const bcx = c[0] - b[0], bcy = c[1] - b[1];
|
|
1649
|
+
const dot = abx * bcx + aby * bcy;
|
|
1650
|
+
const ab = Math.hypot(abx, aby);
|
|
1651
|
+
const bc = Math.hypot(bcx, bcy);
|
|
1652
|
+
const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
|
|
1653
|
+
if (angle > minDeg) out.push(b);
|
|
1654
|
+
}
|
|
1655
|
+
out.push(path[path.length - 1]);
|
|
1656
|
+
return out;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// src/data/navigate/steps/path/turf/pruneShortSegments.ts
|
|
1660
|
+
function pruneShortSegments(path, minLen = 5) {
|
|
1661
|
+
const out = [path[0]];
|
|
1662
|
+
for (let i = 1; i < path.length; i++) {
|
|
1663
|
+
const [x0, y0] = out[out.length - 1];
|
|
1664
|
+
const [x1, y1] = path[i];
|
|
1665
|
+
if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
|
|
1666
|
+
out.push(path[i]);
|
|
1564
1667
|
}
|
|
1565
|
-
const isMatch = !!indices.length;
|
|
1566
|
-
return {
|
|
1567
|
-
isMatch,
|
|
1568
|
-
score: isMatch ? 0 : 1,
|
|
1569
|
-
indices
|
|
1570
|
-
};
|
|
1571
1668
|
}
|
|
1572
|
-
|
|
1573
|
-
var searchers = [
|
|
1574
|
-
ExactMatch,
|
|
1575
|
-
IncludeMatch,
|
|
1576
|
-
PrefixExactMatch,
|
|
1577
|
-
InversePrefixExactMatch,
|
|
1578
|
-
InverseSuffixExactMatch,
|
|
1579
|
-
SuffixExactMatch,
|
|
1580
|
-
InverseExactMatch,
|
|
1581
|
-
FuzzyMatch
|
|
1582
|
-
];
|
|
1583
|
-
var searchersLen = searchers.length;
|
|
1584
|
-
var SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
|
|
1585
|
-
var OR_TOKEN = "|";
|
|
1586
|
-
function parseQuery(pattern, options = {}) {
|
|
1587
|
-
return pattern.split(OR_TOKEN).map((item) => {
|
|
1588
|
-
let query = item.trim().split(SPACE_RE).filter((item2) => item2 && !!item2.trim());
|
|
1589
|
-
let results = [];
|
|
1590
|
-
for (let i = 0, len = query.length; i < len; i += 1) {
|
|
1591
|
-
const queryItem = query[i];
|
|
1592
|
-
let found = false;
|
|
1593
|
-
let idx = -1;
|
|
1594
|
-
while (!found && ++idx < searchersLen) {
|
|
1595
|
-
const searcher = searchers[idx];
|
|
1596
|
-
let token = searcher.isMultiMatch(queryItem);
|
|
1597
|
-
if (token) {
|
|
1598
|
-
results.push(new searcher(token, options));
|
|
1599
|
-
found = true;
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
if (found) {
|
|
1603
|
-
continue;
|
|
1604
|
-
}
|
|
1605
|
-
idx = -1;
|
|
1606
|
-
while (++idx < searchersLen) {
|
|
1607
|
-
const searcher = searchers[idx];
|
|
1608
|
-
let token = searcher.isSingleMatch(queryItem);
|
|
1609
|
-
if (token) {
|
|
1610
|
-
results.push(new searcher(token, options));
|
|
1611
|
-
break;
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
return results;
|
|
1616
|
-
});
|
|
1669
|
+
return out;
|
|
1617
1670
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
this.query = null;
|
|
1632
|
-
this.options = {
|
|
1633
|
-
isCaseSensitive,
|
|
1634
|
-
ignoreDiacritics,
|
|
1635
|
-
includeMatches,
|
|
1636
|
-
minMatchCharLength,
|
|
1637
|
-
findAllMatches,
|
|
1638
|
-
ignoreLocation,
|
|
1639
|
-
location,
|
|
1640
|
-
threshold,
|
|
1641
|
-
distance
|
|
1642
|
-
};
|
|
1643
|
-
pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
|
|
1644
|
-
pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
|
|
1645
|
-
this.pattern = pattern;
|
|
1646
|
-
this.query = parseQuery(this.pattern, this.options);
|
|
1647
|
-
}
|
|
1648
|
-
static condition(_, options) {
|
|
1649
|
-
return options.useExtendedSearch;
|
|
1650
|
-
}
|
|
1651
|
-
searchIn(text) {
|
|
1652
|
-
const query = this.query;
|
|
1653
|
-
if (!query) {
|
|
1654
|
-
return {
|
|
1655
|
-
isMatch: false,
|
|
1656
|
-
score: 1
|
|
1657
|
-
};
|
|
1658
|
-
}
|
|
1659
|
-
const { includeMatches, isCaseSensitive, ignoreDiacritics } = this.options;
|
|
1660
|
-
text = isCaseSensitive ? text : text.toLowerCase();
|
|
1661
|
-
text = ignoreDiacritics ? stripDiacritics(text) : text;
|
|
1662
|
-
let numMatches = 0;
|
|
1663
|
-
let allIndices = [];
|
|
1664
|
-
let totalScore = 0;
|
|
1665
|
-
for (let i = 0, qLen = query.length; i < qLen; i += 1) {
|
|
1666
|
-
const searchers2 = query[i];
|
|
1667
|
-
allIndices.length = 0;
|
|
1668
|
-
numMatches = 0;
|
|
1669
|
-
for (let j = 0, pLen = searchers2.length; j < pLen; j += 1) {
|
|
1670
|
-
const searcher = searchers2[j];
|
|
1671
|
-
const { isMatch, indices, score } = searcher.search(text);
|
|
1672
|
-
if (isMatch) {
|
|
1673
|
-
numMatches += 1;
|
|
1674
|
-
totalScore += score;
|
|
1675
|
-
if (includeMatches) {
|
|
1676
|
-
const type = searcher.constructor.type;
|
|
1677
|
-
if (MultiMatchSet.has(type)) {
|
|
1678
|
-
allIndices = [...allIndices, ...indices];
|
|
1679
|
-
} else {
|
|
1680
|
-
allIndices.push(indices);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
} else {
|
|
1684
|
-
totalScore = 0;
|
|
1685
|
-
numMatches = 0;
|
|
1686
|
-
allIndices.length = 0;
|
|
1687
|
-
break;
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
if (numMatches) {
|
|
1691
|
-
let result = {
|
|
1692
|
-
isMatch: true,
|
|
1693
|
-
score: totalScore / numMatches
|
|
1694
|
-
};
|
|
1695
|
-
if (includeMatches) {
|
|
1696
|
-
result.indices = allIndices;
|
|
1697
|
-
}
|
|
1698
|
-
return result;
|
|
1671
|
+
|
|
1672
|
+
// src/data/navigate/steps/path/turf/clearance.ts
|
|
1673
|
+
function buildClearanceGrid(matrix) {
|
|
1674
|
+
const h = matrix.length;
|
|
1675
|
+
const w = matrix[0].length;
|
|
1676
|
+
const INF = 1e9;
|
|
1677
|
+
const dist = Array.from({ length: h }, () => Array(w).fill(INF));
|
|
1678
|
+
const q = [];
|
|
1679
|
+
for (let y = 0; y < h; y++) {
|
|
1680
|
+
for (let x = 0; x < w; x++) {
|
|
1681
|
+
if (matrix[y][x] === 1) {
|
|
1682
|
+
dist[y][x] = 0;
|
|
1683
|
+
q.push([x, y]);
|
|
1699
1684
|
}
|
|
1700
1685
|
}
|
|
1701
|
-
return {
|
|
1702
|
-
isMatch: false,
|
|
1703
|
-
score: 1
|
|
1704
|
-
};
|
|
1705
1686
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1687
|
+
const dirs = [
|
|
1688
|
+
[1, 0],
|
|
1689
|
+
[-1, 0],
|
|
1690
|
+
[0, 1],
|
|
1691
|
+
[0, -1],
|
|
1692
|
+
[1, 1],
|
|
1693
|
+
[1, -1],
|
|
1694
|
+
[-1, 1],
|
|
1695
|
+
[-1, -1]
|
|
1696
|
+
];
|
|
1697
|
+
let qi = 0;
|
|
1698
|
+
while (qi < q.length) {
|
|
1699
|
+
const [x, y] = q[qi++];
|
|
1700
|
+
const d0 = dist[y][x];
|
|
1701
|
+
for (const [dx, dy] of dirs) {
|
|
1702
|
+
const nx = x + dx, ny = y + dy;
|
|
1703
|
+
if (nx < 0 || ny < 0 || nx >= w || ny >= h) continue;
|
|
1704
|
+
const nd = d0 + 1;
|
|
1705
|
+
if (nd < dist[ny][nx]) {
|
|
1706
|
+
dist[ny][nx] = nd;
|
|
1707
|
+
q.push([nx, ny]);
|
|
1708
|
+
}
|
|
1716
1709
|
}
|
|
1717
1710
|
}
|
|
1718
|
-
return
|
|
1711
|
+
return dist;
|
|
1719
1712
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
});
|
|
1736
|
-
function parse(query, options, { auto = true } = {}) {
|
|
1737
|
-
const next = (query2) => {
|
|
1738
|
-
let keys = Object.keys(query2);
|
|
1739
|
-
const isQueryPath = isPath(query2);
|
|
1740
|
-
if (!isQueryPath && keys.length > 1 && !isExpression(query2)) {
|
|
1741
|
-
return next(convertToExplicit(query2));
|
|
1742
|
-
}
|
|
1743
|
-
if (isLeaf(query2)) {
|
|
1744
|
-
const key = isQueryPath ? query2[KeyType.PATH] : keys[0];
|
|
1745
|
-
const pattern = isQueryPath ? query2[KeyType.PATTERN] : query2[key];
|
|
1746
|
-
if (!isString(pattern)) {
|
|
1747
|
-
throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
|
|
1748
|
-
}
|
|
1749
|
-
const obj = {
|
|
1750
|
-
keyId: createKeyId(key),
|
|
1751
|
-
pattern
|
|
1752
|
-
};
|
|
1753
|
-
if (auto) {
|
|
1754
|
-
obj.searcher = createSearcher(pattern, options);
|
|
1713
|
+
function snapPointToClearancePeak(p, clearance, isWalkableCell, radius = 4) {
|
|
1714
|
+
const [px, py] = p;
|
|
1715
|
+
let best = p;
|
|
1716
|
+
let bestScore = clearance[py]?.[px] ?? -Infinity;
|
|
1717
|
+
for (let dy = -radius; dy <= radius; dy++) {
|
|
1718
|
+
for (let dx = -radius; dx <= radius; dx++) {
|
|
1719
|
+
const x = px + dx;
|
|
1720
|
+
const y = py + dy;
|
|
1721
|
+
if (!isWalkableCell(x, y)) continue;
|
|
1722
|
+
const score = clearance[y][x];
|
|
1723
|
+
const penalty = Math.hypot(dx, dy) * 5e-3;
|
|
1724
|
+
const finalScore = score - penalty;
|
|
1725
|
+
if (finalScore > bestScore) {
|
|
1726
|
+
bestScore = finalScore;
|
|
1727
|
+
best = [x, y];
|
|
1755
1728
|
}
|
|
1756
|
-
return obj;
|
|
1757
1729
|
}
|
|
1758
|
-
let node = {
|
|
1759
|
-
children: [],
|
|
1760
|
-
operator: keys[0]
|
|
1761
|
-
};
|
|
1762
|
-
keys.forEach((key) => {
|
|
1763
|
-
const value = query2[key];
|
|
1764
|
-
if (isArray(value)) {
|
|
1765
|
-
value.forEach((item) => {
|
|
1766
|
-
node.children.push(next(item));
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
1769
|
-
});
|
|
1770
|
-
return node;
|
|
1771
|
-
};
|
|
1772
|
-
if (!isExpression(query)) {
|
|
1773
|
-
query = convertToExplicit(query);
|
|
1774
1730
|
}
|
|
1775
|
-
return
|
|
1731
|
+
return best;
|
|
1776
1732
|
}
|
|
1777
|
-
function
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
result.matches.forEach(({ key, norm: norm2, score }) => {
|
|
1781
|
-
const weight = key ? key.weight : null;
|
|
1782
|
-
totalScore *= Math.pow(
|
|
1783
|
-
score === 0 && weight ? Number.EPSILON : score,
|
|
1784
|
-
(weight || 1) * (ignoreFieldNorm ? 1 : norm2)
|
|
1785
|
-
);
|
|
1786
|
-
});
|
|
1787
|
-
result.score = totalScore;
|
|
1788
|
-
});
|
|
1733
|
+
function centerlineSnapPath(path, clearance, isWalkableCell, radius = 4) {
|
|
1734
|
+
const snapped = path.map((p) => snapPointToClearancePeak(p, clearance, isWalkableCell, radius));
|
|
1735
|
+
return snapped;
|
|
1789
1736
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1737
|
+
|
|
1738
|
+
// src/data/navigate/steps/path/turf/shortestPath.ts
|
|
1739
|
+
function shortestPath(start, end, options) {
|
|
1740
|
+
options = options || {};
|
|
1741
|
+
if (!isObject(options)) throw new Error("options is invalid");
|
|
1742
|
+
let resolution = options.resolution;
|
|
1743
|
+
const smoothenPath = options.smoothenPath;
|
|
1744
|
+
let obstacles = options.obstacles || featureCollection([]);
|
|
1745
|
+
if (!start) throw new Error("start is required");
|
|
1746
|
+
if (!end) throw new Error("end is required");
|
|
1747
|
+
if (resolution && !isNumber(resolution) || resolution <= 0)
|
|
1748
|
+
throw new Error("options.resolution must be a number, greater than 0");
|
|
1749
|
+
const startCoord = getCoord(start);
|
|
1750
|
+
const endCoord = getCoord(end);
|
|
1751
|
+
start = point(startCoord);
|
|
1752
|
+
end = point(endCoord);
|
|
1753
|
+
switch (getType(obstacles)) {
|
|
1754
|
+
case "FeatureCollection":
|
|
1755
|
+
if (obstacles.features.length === 0)
|
|
1756
|
+
return lineString([startCoord, endCoord]);
|
|
1757
|
+
break;
|
|
1758
|
+
case "Polygon":
|
|
1759
|
+
obstacles = featureCollection([feature(getGeom(obstacles))]);
|
|
1760
|
+
break;
|
|
1761
|
+
default:
|
|
1762
|
+
throw new Error("invalid obstacles");
|
|
1763
|
+
}
|
|
1764
|
+
const collection = obstacles;
|
|
1765
|
+
collection.features.push(start, end);
|
|
1766
|
+
const box = index_default((0, import_transform_scale.default)((0, import_bbox_polygon.default)(index_default(collection)), 1.15));
|
|
1767
|
+
if (!resolution) {
|
|
1768
|
+
const width = (0, import_distance4.default)([box[0], box[1]], [box[2], box[1]], options);
|
|
1769
|
+
resolution = width / 100;
|
|
1770
|
+
}
|
|
1771
|
+
collection.features.pop();
|
|
1772
|
+
collection.features.pop();
|
|
1773
|
+
const [west, south, east, north] = box;
|
|
1774
|
+
const xFraction = resolution / (0, import_distance4.default)([west, south], [east, south], options);
|
|
1775
|
+
const cellWidth = xFraction * (east - west);
|
|
1776
|
+
const yFraction = resolution / (0, import_distance4.default)([west, south], [west, north], options);
|
|
1777
|
+
const cellHeight = yFraction * (north - south);
|
|
1778
|
+
const bboxHorizontalSide = east - west;
|
|
1779
|
+
const bboxVerticalSide = north - south;
|
|
1780
|
+
const columns = Math.floor(bboxHorizontalSide / cellWidth);
|
|
1781
|
+
const rows = Math.floor(bboxVerticalSide / cellHeight);
|
|
1782
|
+
const deltaX = (bboxHorizontalSide - columns * cellWidth) / 2;
|
|
1783
|
+
const deltaY = (bboxVerticalSide - rows * cellHeight) / 2;
|
|
1784
|
+
let closestToStart = null, closestToEnd = null, minDistStart = Infinity, minDistEnd = Infinity, currentY = north - deltaY, currentX = west + deltaX, row = 0, column = 0, distStart, distEnd, pt, isInsideObstacle;
|
|
1785
|
+
const roundLoopY = Math.ceil((currentY - south) / cellHeight);
|
|
1786
|
+
const roundLoopX = Math.ceil((east - currentX) / cellWidth);
|
|
1787
|
+
let totalRounds = roundLoopX * roundLoopY;
|
|
1788
|
+
const pointMatrix = [];
|
|
1789
|
+
const matrix = [];
|
|
1790
|
+
const obstacleTotal = collection.features.length;
|
|
1791
|
+
const obstacleFeatures = collection.features;
|
|
1792
|
+
let combinedObstacle = obstacleFeatures[0];
|
|
1793
|
+
let obstacleIndex = 0;
|
|
1794
|
+
for (obstacleIndex = 0; obstacleIndex < obstacleTotal; obstacleIndex++) {
|
|
1795
|
+
const nextObstacleFeature = obstacleFeatures[obstacleIndex + 1];
|
|
1796
|
+
if (!nextObstacleFeature) continue;
|
|
1797
|
+
try {
|
|
1798
|
+
combinedObstacle = (0, import_union.default)(
|
|
1799
|
+
featureCollection([combinedObstacle, nextObstacleFeature])
|
|
1800
|
+
);
|
|
1801
|
+
} catch (e) {
|
|
1802
|
+
console.log(e);
|
|
1803
|
+
}
|
|
1795
1804
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1805
|
+
while (totalRounds--) {
|
|
1806
|
+
pt = point([currentX, currentY]);
|
|
1807
|
+
isInsideObstacle = (0, import_boolean_point_in_polygon3.default)(pt, combinedObstacle);
|
|
1808
|
+
(0, import_set3.default)(matrix, `[${row}][${column}]`, isInsideObstacle ? 1 : 0);
|
|
1809
|
+
(0, import_set3.default)(pointMatrix, `[${row}][${column}]`, `${currentX}|${currentY}`);
|
|
1810
|
+
distStart = (0, import_distance4.default)(pt, start);
|
|
1811
|
+
if (!isInsideObstacle && distStart < minDistStart) {
|
|
1812
|
+
minDistStart = distStart;
|
|
1813
|
+
closestToStart = { x: column, y: row };
|
|
1799
1814
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
};
|
|
1805
|
-
if (match.key) {
|
|
1806
|
-
obj.key = match.key.src;
|
|
1815
|
+
distEnd = (0, import_distance4.default)(pt, end);
|
|
1816
|
+
if (!isInsideObstacle && distEnd < minDistEnd) {
|
|
1817
|
+
minDistEnd = distEnd;
|
|
1818
|
+
closestToEnd = { x: column, y: row };
|
|
1807
1819
|
}
|
|
1808
|
-
if (
|
|
1809
|
-
|
|
1820
|
+
if (column < roundLoopX) {
|
|
1821
|
+
currentX += cellWidth;
|
|
1822
|
+
column++;
|
|
1823
|
+
continue;
|
|
1810
1824
|
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1817
|
-
function format(results, docs, {
|
|
1818
|
-
includeMatches = Config.includeMatches,
|
|
1819
|
-
includeScore = Config.includeScore
|
|
1820
|
-
} = {}) {
|
|
1821
|
-
const transformers = [];
|
|
1822
|
-
if (includeMatches) transformers.push(transformMatches);
|
|
1823
|
-
if (includeScore) transformers.push(transformScore);
|
|
1824
|
-
return results.map((result) => {
|
|
1825
|
-
const { idx } = result;
|
|
1826
|
-
const data = {
|
|
1827
|
-
item: docs[idx],
|
|
1828
|
-
refIndex: idx
|
|
1829
|
-
};
|
|
1830
|
-
if (transformers.length) {
|
|
1831
|
-
transformers.forEach((transformer) => {
|
|
1832
|
-
transformer(result, data);
|
|
1833
|
-
});
|
|
1825
|
+
if (row < roundLoopY) {
|
|
1826
|
+
currentY -= cellHeight;
|
|
1827
|
+
currentX = west + deltaX;
|
|
1828
|
+
column = 0;
|
|
1829
|
+
row++;
|
|
1834
1830
|
}
|
|
1835
|
-
|
|
1831
|
+
}
|
|
1832
|
+
const finder = new import_pathfinding.default.AStarFinder({
|
|
1833
|
+
allowDiagonal: true,
|
|
1834
|
+
dontCrossCorners: true,
|
|
1835
|
+
heuristic: import_pathfinding.default.Heuristic.euclidean
|
|
1836
|
+
});
|
|
1837
|
+
const grid = new import_pathfinding.default.Grid(matrix);
|
|
1838
|
+
const startOnMatrix = [closestToStart.x, closestToStart.y];
|
|
1839
|
+
const endOnMatrix = [closestToEnd.x, closestToEnd.y];
|
|
1840
|
+
let result = finder.findPath(...startOnMatrix, ...endOnMatrix, grid);
|
|
1841
|
+
if (result.length > 0) {
|
|
1842
|
+
result = stringPull(grid, result);
|
|
1843
|
+
const clearanceGrid = buildClearanceGrid(matrix);
|
|
1844
|
+
const isWalkable = (x, y) => grid.isInside(x, y) && grid.isWalkableAt(x, y);
|
|
1845
|
+
result = centerlineSnapPath(result, clearanceGrid, isWalkable);
|
|
1846
|
+
result = stringPull(grid, result);
|
|
1847
|
+
result = pruneSmallAngles(result);
|
|
1848
|
+
result = pruneShortSegments(result);
|
|
1849
|
+
}
|
|
1850
|
+
result.pop();
|
|
1851
|
+
result.shift();
|
|
1852
|
+
const path = [startCoord];
|
|
1853
|
+
result.forEach((coord) => {
|
|
1854
|
+
const coords = pointMatrix[coord[1]][coord[0]].split("|");
|
|
1855
|
+
path.push([+coords[0], +coords[1]]);
|
|
1836
1856
|
});
|
|
1857
|
+
path.push(endCoord);
|
|
1858
|
+
return (0, import_clean_coords.cleanCoords)(lineString(path));
|
|
1837
1859
|
}
|
|
1838
|
-
var
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
this._docs = docs;
|
|
1849
|
-
if (index && !(index instanceof FuseIndex)) {
|
|
1850
|
-
throw new Error(INCORRECT_INDEX_TYPE);
|
|
1851
|
-
}
|
|
1852
|
-
this._myIndex = index || createIndex(this.options.keys, this._docs, {
|
|
1853
|
-
getFn: this.options.getFn,
|
|
1854
|
-
fieldNormWeight: this.options.fieldNormWeight
|
|
1860
|
+
var shortestPath_default = shortestPath;
|
|
1861
|
+
|
|
1862
|
+
// src/data/navigate/steps/path/index.ts
|
|
1863
|
+
var createStepPathUtils = (options) => {
|
|
1864
|
+
const resolution = options.resolution ?? 88e-5;
|
|
1865
|
+
const { units, kiosks, fixtures } = options.data;
|
|
1866
|
+
const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
|
|
1867
|
+
const filterObstaclesByOrdinal = (levelId) => {
|
|
1868
|
+
return possibleObstacleFeatures.filter(({ feature_type, properties, geometry }) => {
|
|
1869
|
+
return properties.level_id === levelId && ["Polygon", "MultiPolygon"].includes(geometry.type) && (OBSTACLE_FEATURE_TYPES.includes(feature_type) || "category" in properties && OBSTACLE_CATEGORIES.includes(properties.category));
|
|
1855
1870
|
});
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1871
|
+
};
|
|
1872
|
+
const findObstaclesFromWalkway = (intermediaryUnit, exceptionIds = []) => {
|
|
1873
|
+
const result = featureCollection([]);
|
|
1874
|
+
if (!intermediaryUnit) return result;
|
|
1875
|
+
const walkwayLevelId = intermediaryUnit.properties.level_id;
|
|
1876
|
+
const obstacleOnLevel = filterObstaclesByOrdinal(walkwayLevelId).filter(
|
|
1877
|
+
(obstacle) => !exceptionIds.includes(obstacle.id)
|
|
1878
|
+
);
|
|
1879
|
+
const relatedObstacleWithIntermediary = obstacleOnLevel.reduce(
|
|
1880
|
+
(obstacles, feature2) => {
|
|
1881
|
+
if (
|
|
1882
|
+
// Prevent detecting itself as an obstacle
|
|
1883
|
+
// Ex. Unable to draw a line to amenity located with in a room as room is also consider as obstacle
|
|
1884
|
+
feature2.id !== intermediaryUnit.id && ((0, import_boolean_overlap.default)(intermediaryUnit, feature2) || (0, import_boolean_intersects.default)(intermediaryUnit, feature2))
|
|
1885
|
+
) {
|
|
1886
|
+
const polygons = getType(feature2) === "Polygon" ? [polygon(feature2.geometry.coordinates, { id: feature2.id })] : feature2.geometry.coordinates.map((ring) => polygon(ring, { id: feature2.id }));
|
|
1887
|
+
obstacles.push(...polygons);
|
|
1888
|
+
}
|
|
1889
|
+
return obstacles;
|
|
1890
|
+
},
|
|
1891
|
+
[]
|
|
1892
|
+
);
|
|
1893
|
+
const intermediaryExtends = (0, import_envelope.default)(intermediaryUnit);
|
|
1894
|
+
const walkwayPerimeter = (0, import_difference.default)(
|
|
1895
|
+
featureCollection([intermediaryExtends, intermediaryUnit])
|
|
1896
|
+
);
|
|
1897
|
+
result.features.push(...relatedObstacleWithIntermediary, walkwayPerimeter);
|
|
1898
|
+
return result;
|
|
1899
|
+
};
|
|
1900
|
+
const findPathOnArea = (originPoint, destinationPoint, options2) => {
|
|
1901
|
+
const { obstacles = featureCollection([]), resolution: resolution2, properties } = options2 || {};
|
|
1902
|
+
const stepPath = shortestPath_default(originPoint, destinationPoint, {
|
|
1903
|
+
obstacles,
|
|
1904
|
+
smoothenPath: false,
|
|
1905
|
+
resolution: resolution2
|
|
1906
|
+
});
|
|
1907
|
+
stepPath.properties = properties;
|
|
1908
|
+
return stepPath;
|
|
1909
|
+
};
|
|
1910
|
+
const findStepPath = (from, to, intermediaries) => {
|
|
1911
|
+
const t0 = performance.now();
|
|
1912
|
+
const relatedWalkablePlatform = intermediaries.find(
|
|
1913
|
+
(feature2) => WALKABLE_CATEGORY.includes(feature2.properties.category)
|
|
1914
|
+
);
|
|
1915
|
+
const exceptionFeatureIds = [];
|
|
1916
|
+
const obstacles = findObstaclesFromWalkway(
|
|
1917
|
+
relatedWalkablePlatform,
|
|
1918
|
+
import_lodash11.default.compact(exceptionFeatureIds)
|
|
1919
|
+
);
|
|
1920
|
+
const line = findPathOnArea(from, to, {
|
|
1921
|
+
resolution,
|
|
1922
|
+
obstacles
|
|
1923
|
+
});
|
|
1924
|
+
return line.geometry.coordinates;
|
|
1925
|
+
};
|
|
1926
|
+
return {
|
|
1927
|
+
findStepPath
|
|
1928
|
+
};
|
|
1929
|
+
};
|
|
1930
|
+
|
|
1931
|
+
// src/data/navigate/landmark/createLandmarkUtils.ts
|
|
1932
|
+
var import_center6 = require("@turf/center");
|
|
1933
|
+
var import_distance5 = __toESM(require("@turf/distance"));
|
|
1934
|
+
var NEARBY_DISTANCE = 30;
|
|
1935
|
+
var createLandmarkUtils = (options) => {
|
|
1936
|
+
const { data, findByIdSync } = options;
|
|
1937
|
+
const { occupants } = data;
|
|
1938
|
+
const occupantToLandmark = (occupant) => {
|
|
1939
|
+
const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
|
|
1940
|
+
const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
|
|
1941
|
+
const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
|
|
1942
|
+
const level = findByIdSync(location.properties.level_id);
|
|
1943
|
+
return {
|
|
1944
|
+
name: occupant.properties.name,
|
|
1945
|
+
point: (0, import_center6.center)(location.geometry).geometry.coordinates,
|
|
1946
|
+
level_id: location.properties.level_id,
|
|
1947
|
+
is_priority: occupant.properties.is_landmark,
|
|
1948
|
+
ordinal: level.properties.ordinal
|
|
1949
|
+
};
|
|
1950
|
+
};
|
|
1951
|
+
const landmarks = [
|
|
1952
|
+
...occupants.map(occupantToLandmark)
|
|
1953
|
+
];
|
|
1954
|
+
const findNearbyLandmarks = (point2, levelId) => {
|
|
1955
|
+
if (point2 === null || levelId === null) return [];
|
|
1956
|
+
return landmarks.map((landmark) => {
|
|
1957
|
+
const landmarkAndDistance = {
|
|
1958
|
+
landmark,
|
|
1959
|
+
d: (0, import_distance5.default)(point2, landmark.point, { units: "meters" })
|
|
1960
|
+
};
|
|
1961
|
+
return landmarkAndDistance;
|
|
1962
|
+
}).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
|
|
1963
|
+
const aPriority = a.landmark.is_priority ? 0 : 1;
|
|
1964
|
+
const bPriority = b.landmark.is_priority ? 0 : 1;
|
|
1965
|
+
if (aPriority !== bPriority) return aPriority - bPriority;
|
|
1966
|
+
return a.d - b.d;
|
|
1967
|
+
}).map(({ landmark }) => landmark);
|
|
1968
|
+
};
|
|
1969
|
+
const findNearestLandmark = (point2, levelId) => {
|
|
1970
|
+
const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
|
|
1971
|
+
const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
|
|
1972
|
+
return nearestLandmark;
|
|
1973
|
+
};
|
|
1974
|
+
return { findNearbyLandmarks, findNearestLandmark };
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1977
|
+
// src/data/navigate/steps/utils/extractStartPoint.ts
|
|
1978
|
+
var import_center7 = require("@turf/center");
|
|
1979
|
+
|
|
1980
|
+
// src/data/navigate/steps/utils/featureIdGuard.ts
|
|
1981
|
+
var isOccupant = (id) => !!id && id.startsWith("occupant-");
|
|
1982
|
+
var isUnit = (id) => !!id && id.startsWith("unit-");
|
|
1983
|
+
var isKiosk = (id) => !!id && id.startsWith("kiosk-");
|
|
1984
|
+
var isOpening = (id) => !!id && id.startsWith("opening-");
|
|
1985
|
+
|
|
1986
|
+
// src/data/navigate/type-guard.ts
|
|
1987
|
+
function isCoordinateOrdinalString(id) {
|
|
1988
|
+
return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
// src/data/navigate/steps/utils/extractStartPoint.ts
|
|
1992
|
+
var extractStartPoint = (path, options) => {
|
|
1993
|
+
const { findByIdSync } = options;
|
|
1994
|
+
const [a, b, c] = path;
|
|
1995
|
+
if (isOccupant(a) && isUnit(b) && isOpening(c)) {
|
|
1996
|
+
const occ = findByIdSync(a);
|
|
1997
|
+
const opening = findByIdSync(c);
|
|
1998
|
+
const level = findByIdSync(opening.properties.level_id);
|
|
1999
|
+
return [
|
|
2000
|
+
{
|
|
2001
|
+
id: occ.id,
|
|
2002
|
+
type: "start",
|
|
2003
|
+
name: occ.properties.name,
|
|
2004
|
+
point: (0, import_center7.center)(opening).geometry.coordinates,
|
|
2005
|
+
levelId: opening.properties.level_id,
|
|
2006
|
+
ordinal: level.properties.ordinal,
|
|
2007
|
+
source: { type: "opening", id: opening.id }
|
|
2008
|
+
},
|
|
2009
|
+
path.slice(3)
|
|
2010
|
+
];
|
|
2011
|
+
}
|
|
2012
|
+
if (isOccupant(a) && isKiosk(b)) {
|
|
2013
|
+
const occ = findByIdSync(a);
|
|
2014
|
+
const kiosk = findByIdSync(c);
|
|
2015
|
+
const level = findByIdSync(kiosk.properties.level_id);
|
|
2016
|
+
return [
|
|
2017
|
+
{
|
|
2018
|
+
id: occ.id,
|
|
2019
|
+
type: "start",
|
|
2020
|
+
name: occ.properties.name,
|
|
2021
|
+
point: (0, import_center7.center)(kiosk).geometry.coordinates,
|
|
2022
|
+
levelId: kiosk.properties.level_id,
|
|
2023
|
+
ordinal: level.properties.ordinal,
|
|
2024
|
+
source: { type: "kiosk", id: kiosk.id }
|
|
2025
|
+
},
|
|
2026
|
+
path.slice(2)
|
|
2027
|
+
];
|
|
2028
|
+
}
|
|
2029
|
+
if (isCoordinateOrdinalString(a) && isOpening(b)) {
|
|
2030
|
+
const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
|
|
2031
|
+
const opening = findByIdSync(b);
|
|
2032
|
+
return [
|
|
2033
|
+
{
|
|
2034
|
+
id: a,
|
|
2035
|
+
type: "start",
|
|
2036
|
+
name: { en: `Your location` },
|
|
2037
|
+
point: [lng, lat],
|
|
2038
|
+
levelId: opening.properties.level_id,
|
|
2039
|
+
ordinal,
|
|
2040
|
+
source: { type: "opening", id: opening.id }
|
|
2041
|
+
},
|
|
2042
|
+
path.slice(1)
|
|
2043
|
+
];
|
|
2044
|
+
}
|
|
2045
|
+
return [null, path];
|
|
2046
|
+
};
|
|
2047
|
+
|
|
2048
|
+
// src/data/navigate/steps/utils/extractEndPint.ts
|
|
2049
|
+
var import_center8 = require("@turf/center");
|
|
2050
|
+
var extractEndPoint = (path, options) => {
|
|
2051
|
+
const { findByIdSync } = options;
|
|
2052
|
+
const [c, b, a] = path.slice(-3);
|
|
2053
|
+
if (isOccupant(a) && isUnit(b) && isOpening(c)) {
|
|
2054
|
+
const occ = findByIdSync(a);
|
|
2055
|
+
const opening = findByIdSync(c);
|
|
2056
|
+
const level = findByIdSync(opening.properties.level_id);
|
|
2057
|
+
return [
|
|
2058
|
+
{
|
|
2059
|
+
id: occ.id,
|
|
2060
|
+
type: "end",
|
|
2061
|
+
name: occ.properties.name,
|
|
2062
|
+
point: (0, import_center8.center)(opening).geometry.coordinates,
|
|
2063
|
+
levelId: opening.properties.level_id,
|
|
2064
|
+
ordinal: level.properties.ordinal,
|
|
2065
|
+
source: { type: "opening", id: opening.id }
|
|
2066
|
+
},
|
|
2067
|
+
path.slice(0, -3)
|
|
2068
|
+
];
|
|
2069
|
+
}
|
|
2070
|
+
if (isOccupant(a) && isKiosk(b)) {
|
|
2071
|
+
const occ = findByIdSync(a);
|
|
2072
|
+
const kiosk = findByIdSync(c);
|
|
2073
|
+
const level = findByIdSync(kiosk.properties.level_id);
|
|
2074
|
+
return [
|
|
2075
|
+
{
|
|
2076
|
+
id: occ.id,
|
|
2077
|
+
type: "end",
|
|
2078
|
+
name: occ.properties.name,
|
|
2079
|
+
point: (0, import_center8.center)(kiosk).geometry.coordinates,
|
|
2080
|
+
levelId: kiosk.properties.level_id,
|
|
2081
|
+
ordinal: level.properties.ordinal,
|
|
2082
|
+
source: { type: "kiosk", id: kiosk.id }
|
|
2083
|
+
},
|
|
2084
|
+
path.slice(0, -2)
|
|
2085
|
+
];
|
|
2086
|
+
}
|
|
2087
|
+
if (isCoordinateOrdinalString(a)) {
|
|
2088
|
+
const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
|
|
2089
|
+
const opening = findByIdSync(b);
|
|
2090
|
+
return [
|
|
2091
|
+
{
|
|
2092
|
+
id: a,
|
|
2093
|
+
type: "end",
|
|
2094
|
+
name: { en: `Your location` },
|
|
2095
|
+
point: [lng, lat],
|
|
2096
|
+
levelId: opening.properties.level_id,
|
|
2097
|
+
ordinal,
|
|
2098
|
+
source: { type: "opening", id: opening.id }
|
|
2099
|
+
},
|
|
2100
|
+
path.slice(0, -2)
|
|
2101
|
+
];
|
|
2102
|
+
}
|
|
2103
|
+
return [null, path];
|
|
2104
|
+
};
|
|
2105
|
+
|
|
2106
|
+
// src/data/navigate/steps/utils/combineWalkwaySteps.ts
|
|
2107
|
+
var import_uniq = __toESM(require("lodash/uniq"));
|
|
2108
|
+
var combineWalkwaySteps = (steps) => {
|
|
2109
|
+
let result = [];
|
|
2110
|
+
for (let i = 0; i < steps.length; i++) {
|
|
2111
|
+
const thisStep = steps[i];
|
|
2112
|
+
if (i === steps.length - 1) {
|
|
2113
|
+
result.push(thisStep);
|
|
2114
|
+
continue;
|
|
1860
2115
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
2116
|
+
const nextStep = steps[i + 1];
|
|
2117
|
+
if (thisStep.intermediaryCategory === "walkway" && nextStep.intermediaryCategory === "walkway" && thisStep.from.source.type === "opening" && nextStep.from.source.type === "opening") {
|
|
2118
|
+
console.log({ i, len: steps.length, thisStep, nextStep });
|
|
2119
|
+
result.push({
|
|
2120
|
+
from: thisStep.from,
|
|
2121
|
+
to: nextStep.to,
|
|
2122
|
+
levelIds: (0, import_uniq.default)([...thisStep.levelIds, ...nextStep.levelIds]),
|
|
2123
|
+
ordinals: (0, import_uniq.default)([...thisStep.ordinals, ...nextStep.ordinals]),
|
|
2124
|
+
intermediaryCategory: "walkway",
|
|
2125
|
+
description: nextStep.description,
|
|
2126
|
+
path: [
|
|
2127
|
+
...thisStep.path,
|
|
2128
|
+
...nextStep.path
|
|
2129
|
+
]
|
|
2130
|
+
});
|
|
2131
|
+
i++;
|
|
2132
|
+
} else {
|
|
2133
|
+
result.push(thisStep);
|
|
1874
2134
|
}
|
|
1875
|
-
return results;
|
|
1876
|
-
}
|
|
1877
|
-
removeAt(idx) {
|
|
1878
|
-
this._docs.splice(idx, 1);
|
|
1879
|
-
this._myIndex.removeAt(idx);
|
|
1880
|
-
}
|
|
1881
|
-
getIndex() {
|
|
1882
|
-
return this._myIndex;
|
|
1883
2135
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2136
|
+
return result;
|
|
2137
|
+
};
|
|
2138
|
+
|
|
2139
|
+
// src/data/navigate/steps/createStepUtils.ts
|
|
2140
|
+
var createStepUtils = (options) => {
|
|
2141
|
+
const { data: { units, relationships }, findByIdSync } = options;
|
|
2142
|
+
const landmarkUtils = createLandmarkUtils(options);
|
|
2143
|
+
const stepPathUtils = createStepPathUtils({ ...options, resolution: 88e-5 });
|
|
2144
|
+
const findUnitBetweenOpenings = (originId, destinationId) => {
|
|
2145
|
+
const origin = findByIdSync(originId);
|
|
2146
|
+
const destination = findByIdSync(destinationId);
|
|
2147
|
+
const matchedOne = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(origin.id));
|
|
2148
|
+
const matchOneUnits = [matchedOne.properties.origin, matchedOne.properties.destination];
|
|
2149
|
+
const matchedTwo = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(destination.id));
|
|
2150
|
+
const matchTwoUnits = [matchedTwo.properties.origin, matchedTwo.properties.destination];
|
|
2151
|
+
const unitIds = (0, import_intersectionBy.default)(matchOneUnits, matchTwoUnits, "id");
|
|
2152
|
+
return unitIds.map(({ id }) => findByIdSync(id));
|
|
2153
|
+
};
|
|
2154
|
+
const findHorizontalIntermediary = (from, to) => {
|
|
2155
|
+
if (from.source.type !== "opening") {
|
|
2156
|
+
const unit = findContainingUnitAtPoint(from.point, from.levelId, units);
|
|
2157
|
+
return unit ? [unit] : [];
|
|
1896
2158
|
}
|
|
1897
|
-
if (
|
|
1898
|
-
|
|
2159
|
+
if (to.source.type !== "opening") {
|
|
2160
|
+
const unit = findContainingUnitAtPoint(to.point, to.levelId, units);
|
|
2161
|
+
return unit ? [unit] : [];
|
|
1899
2162
|
}
|
|
1900
|
-
return
|
|
1901
|
-
|
|
1902
|
-
|
|
2163
|
+
return findUnitBetweenOpenings(from.source.id, to.source.id);
|
|
2164
|
+
};
|
|
2165
|
+
const findVerticalIntermediary = (from, to) => {
|
|
2166
|
+
const firstOpeningId = from.source.id;
|
|
2167
|
+
const secondOpeningId = to.source.id;
|
|
2168
|
+
const relationship = relationships.find((rel) => {
|
|
2169
|
+
return rel.properties.origin?.id === firstOpeningId && rel.properties.destination?.id === secondOpeningId || rel.properties.origin?.id === secondOpeningId && rel.properties.destination?.id === firstOpeningId;
|
|
1903
2170
|
});
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2171
|
+
const intermediaryTypeAndId = relationship.properties.intermediary;
|
|
2172
|
+
return intermediaryTypeAndId.map(({ id }) => findByIdSync(id));
|
|
2173
|
+
};
|
|
2174
|
+
const formatCategoryLabel = (category) => {
|
|
2175
|
+
return (0, import_lodash12.capitalize)(category);
|
|
2176
|
+
};
|
|
2177
|
+
const getToward = (from, to, intermediary) => {
|
|
2178
|
+
if (to.type === "end") return to.name;
|
|
2179
|
+
const intermediaryIds = intermediary.map((int) => int.id);
|
|
2180
|
+
const relationship = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(to.source.id));
|
|
2181
|
+
if (!relationship) return to.name;
|
|
2182
|
+
const candidates = [relationship.properties.origin.id, relationship.properties.destination.id];
|
|
2183
|
+
const nextUnitId = candidates.filter((id) => !intermediaryIds.includes(id))[0];
|
|
2184
|
+
if (!nextUnitId) return to.name;
|
|
2185
|
+
const nextUnit = findByIdSync(nextUnitId);
|
|
2186
|
+
return { en: formatCategoryLabel(`${nextUnit.properties.category}`) };
|
|
2187
|
+
};
|
|
2188
|
+
const toWaypoints = (path) => {
|
|
2189
|
+
const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
|
|
2190
|
+
const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
|
|
2191
|
+
const waypoints = middlePoints.map((openingId) => {
|
|
2192
|
+
const opening = findByIdSync(openingId);
|
|
2193
|
+
const level = findByIdSync(opening.properties.level_id);
|
|
2194
|
+
const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
|
|
2195
|
+
const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
|
|
2196
|
+
return {
|
|
2197
|
+
id: `${opening.properties.level_id}:${openingId}`,
|
|
2198
|
+
type: "between",
|
|
2199
|
+
point: coordinates,
|
|
2200
|
+
name: null,
|
|
2201
|
+
levelId: opening.properties.level_id,
|
|
2202
|
+
ordinal: level.properties.ordinal,
|
|
2203
|
+
hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
|
|
2204
|
+
source: { type: "opening", id: opening.id }
|
|
2205
|
+
};
|
|
1921
2206
|
});
|
|
1922
|
-
return
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
const
|
|
1926
|
-
const
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
matches
|
|
1940
|
-
}
|
|
1941
|
-
];
|
|
1942
|
-
}
|
|
1943
|
-
return [];
|
|
1944
|
-
}
|
|
1945
|
-
const res = [];
|
|
1946
|
-
for (let i = 0, len = node.children.length; i < len; i += 1) {
|
|
1947
|
-
const child = node.children[i];
|
|
1948
|
-
const result = evaluate(child, item, idx);
|
|
1949
|
-
if (result.length) {
|
|
1950
|
-
res.push(...result);
|
|
1951
|
-
} else if (node.operator === LogicalOperator.AND) {
|
|
1952
|
-
return [];
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
return res;
|
|
2207
|
+
return [startPoint, ...waypoints, endPoint];
|
|
2208
|
+
};
|
|
2209
|
+
const createHorizontalStep = (from, to) => {
|
|
2210
|
+
const intermediary = findHorizontalIntermediary(from, to);
|
|
2211
|
+
const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
|
|
2212
|
+
const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
|
|
2213
|
+
const toward = getToward(from, to, intermediary);
|
|
2214
|
+
const landmark = to.hint?.kind === "landmark" ? to.hint.name : null;
|
|
2215
|
+
const path = stepPathUtils.findStepPath(from.point, to.point, intermediary);
|
|
2216
|
+
const step = {
|
|
2217
|
+
from,
|
|
2218
|
+
to,
|
|
2219
|
+
levelIds: [from.levelId],
|
|
2220
|
+
ordinals: [from.ordinal],
|
|
2221
|
+
intermediaryCategory,
|
|
2222
|
+
description: describeHorizontalStep(intermediaryCategory, toward, landmark),
|
|
2223
|
+
path: path.map((coord) => [...coord, from.ordinal * 9])
|
|
1956
2224
|
};
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
const
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
});
|
|
1994
|
-
|
|
1995
|
-
results.push({
|
|
1996
|
-
idx,
|
|
1997
|
-
item,
|
|
1998
|
-
matches
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
});
|
|
2002
|
-
return results;
|
|
2003
|
-
}
|
|
2004
|
-
_findMatches({ key, value, searcher }) {
|
|
2005
|
-
if (!isDefined(value)) {
|
|
2006
|
-
return [];
|
|
2007
|
-
}
|
|
2008
|
-
let matches = [];
|
|
2009
|
-
if (isArray(value)) {
|
|
2010
|
-
value.forEach(({ v: text, i: idx, n: norm2 }) => {
|
|
2011
|
-
if (!isDefined(text)) {
|
|
2012
|
-
return;
|
|
2013
|
-
}
|
|
2014
|
-
const { isMatch, score, indices } = searcher.searchIn(text);
|
|
2015
|
-
if (isMatch) {
|
|
2016
|
-
matches.push({
|
|
2017
|
-
score,
|
|
2018
|
-
key,
|
|
2019
|
-
value: text,
|
|
2020
|
-
idx,
|
|
2021
|
-
norm: norm2,
|
|
2022
|
-
indices
|
|
2023
|
-
});
|
|
2024
|
-
}
|
|
2025
|
-
});
|
|
2026
|
-
} else {
|
|
2027
|
-
const { v: text, n: norm2 } = value;
|
|
2028
|
-
const { isMatch, score, indices } = searcher.searchIn(text);
|
|
2029
|
-
if (isMatch) {
|
|
2030
|
-
matches.push({ score, key, value: text, norm: norm2, indices });
|
|
2031
|
-
}
|
|
2225
|
+
return step;
|
|
2226
|
+
};
|
|
2227
|
+
const createVerticalStep = (from, to) => {
|
|
2228
|
+
const intermediary = findVerticalIntermediary(from, to);
|
|
2229
|
+
const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
|
|
2230
|
+
const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
|
|
2231
|
+
const fromLevel = findByIdSync(from.levelId);
|
|
2232
|
+
const toLevel = findByIdSync(to.levelId);
|
|
2233
|
+
return {
|
|
2234
|
+
from,
|
|
2235
|
+
to,
|
|
2236
|
+
levelIds: [from.levelId, to.levelId],
|
|
2237
|
+
ordinals: [from.ordinal, to.ordinal],
|
|
2238
|
+
intermediaryCategory,
|
|
2239
|
+
description: describeVerticalStep(fromLevel, toLevel, intermediaryCategory),
|
|
2240
|
+
path: [
|
|
2241
|
+
[...from.point, from.ordinal * 9],
|
|
2242
|
+
[...to.point, to.ordinal * 9]
|
|
2243
|
+
]
|
|
2244
|
+
};
|
|
2245
|
+
};
|
|
2246
|
+
const isVertical = (from, to) => {
|
|
2247
|
+
const fromLevel = findByIdSync(from.levelId);
|
|
2248
|
+
const toLevel = findByIdSync(to.levelId);
|
|
2249
|
+
return !!fromLevel && !!toLevel && fromLevel.properties.ordinal !== toLevel.properties.ordinal;
|
|
2250
|
+
};
|
|
2251
|
+
const toSteps = (waypoints) => {
|
|
2252
|
+
let steps = [];
|
|
2253
|
+
const t0_allSteps = performance.now();
|
|
2254
|
+
for (let i = 0; i < waypoints.length - 1; i++) {
|
|
2255
|
+
const from = waypoints[i];
|
|
2256
|
+
const to = waypoints[i + 1];
|
|
2257
|
+
const t0 = performance.now();
|
|
2258
|
+
const step = isVertical(from, to) ? createVerticalStep(from, to) : createHorizontalStep(from, to);
|
|
2259
|
+
steps.push(step);
|
|
2260
|
+
const t1 = performance.now();
|
|
2261
|
+
trace("nav", ` \u2502 \u251C\u2500 #${i} ${from.id.padEnd(25)} \u2192 ${`(${step.intermediaryCategory})`.padEnd(12)} \u2192 ${to.id}`, t1 - t0);
|
|
2262
|
+
trace("nav", ` \u2502 \u2502 ${step.description.text}`, void 0, "#bada55");
|
|
2032
2263
|
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2264
|
+
const simplifySteps = combineWalkwaySteps(steps);
|
|
2265
|
+
const t1_allSteps = performance.now();
|
|
2266
|
+
trace("nav", " \u2502 \u2514\u2500 Total ", t1_allSteps - t0_allSteps);
|
|
2267
|
+
return simplifySteps;
|
|
2268
|
+
};
|
|
2269
|
+
return {
|
|
2270
|
+
// createSteps,
|
|
2271
|
+
toWaypoints,
|
|
2272
|
+
toSteps
|
|
2273
|
+
};
|
|
2035
2274
|
};
|
|
2036
|
-
Fuse.version = "7.1.0";
|
|
2037
|
-
Fuse.createIndex = createIndex;
|
|
2038
|
-
Fuse.parseIndex = parseIndex;
|
|
2039
|
-
Fuse.config = Config;
|
|
2040
|
-
{
|
|
2041
|
-
Fuse.parseQuery = parse;
|
|
2042
|
-
}
|
|
2043
|
-
{
|
|
2044
|
-
register(ExtendedSearch);
|
|
2045
|
-
}
|
|
2046
2275
|
|
|
2047
|
-
// src/data/
|
|
2048
|
-
var
|
|
2276
|
+
// src/data/navigate/utils/timeDistance.ts
|
|
2277
|
+
var import_length = __toESM(require("@turf/length"));
|
|
2278
|
+
var WALKING_SPEED = 1.4;
|
|
2279
|
+
var calculatePathLength = (feature2) => (0, import_length.default)(feature2, { units: "kilometers" }) * 1e3;
|
|
2280
|
+
var calculateTravelingDuration = (distance5) => {
|
|
2281
|
+
const duration = distance5 / WALKING_SPEED;
|
|
2282
|
+
const minutes = Math.round(duration / 60);
|
|
2283
|
+
return minutes > 0 ? minutes : 1;
|
|
2284
|
+
};
|
|
2285
|
+
var calculateTotalDistance = (steps = []) => {
|
|
2286
|
+
return steps.reduce((acc, { path }) => acc + calculatePathLength(lineString(path)), 0);
|
|
2287
|
+
};
|
|
2288
|
+
var calculateRoundedDistance = (distance5) => {
|
|
2289
|
+
return Math.round(distance5 - distance5 % 25);
|
|
2290
|
+
};
|
|
2049
2291
|
|
|
2050
|
-
// src/data/
|
|
2051
|
-
var
|
|
2052
|
-
const
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2292
|
+
// src/data/navigate/utils/createFindByIdSync.ts
|
|
2293
|
+
var createFindByIdSync = (data) => {
|
|
2294
|
+
const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
|
|
2295
|
+
const featureById = /* @__PURE__ */ new Map();
|
|
2296
|
+
const entries = [
|
|
2297
|
+
...amenities,
|
|
2298
|
+
...anchors,
|
|
2299
|
+
...fixtures,
|
|
2300
|
+
...levels,
|
|
2301
|
+
...kiosks,
|
|
2302
|
+
...relationships,
|
|
2303
|
+
...occupants,
|
|
2304
|
+
...openings,
|
|
2305
|
+
...units
|
|
2306
|
+
];
|
|
2307
|
+
for (const f of entries) featureById.set(f.id, f);
|
|
2308
|
+
const findByIdSync = (id) => {
|
|
2309
|
+
return featureById.get(id);
|
|
2310
|
+
};
|
|
2311
|
+
return { findByIdSync };
|
|
2312
|
+
};
|
|
2313
|
+
|
|
2314
|
+
// src/data/navigate/getNavigateClient.ts
|
|
2315
|
+
var getNavigateClient = (options) => {
|
|
2316
|
+
const { data } = options;
|
|
2317
|
+
const { levels, units } = data;
|
|
2318
|
+
trace("nav", "\u2713 prepare");
|
|
2319
|
+
const t0 = performance.now();
|
|
2320
|
+
trace("nav", " \u251C\u2500 createGraph (dijkstra)");
|
|
2321
|
+
const { defaultGraph, accessibleGraph, addCoordinateOrdinalNode } = prepareGraph({ data });
|
|
2322
|
+
const t1 = performance.now();
|
|
2323
|
+
trace("nav", " \u2502 \u2514\u2500 Total ", t1 - t0);
|
|
2324
|
+
const t2 = performance.now();
|
|
2325
|
+
const { findByIdSync } = createFindByIdSync(data);
|
|
2326
|
+
const t3 = performance.now();
|
|
2327
|
+
trace("nav", " \u2514\u2500 findByIdSync", t3 - t2);
|
|
2328
|
+
const findCoordinateOrdinalUnit = (params) => {
|
|
2329
|
+
const [lat, lng, ordinal] = parseOrdinalCoordinate(params);
|
|
2330
|
+
const levelIdsWithOrdinal = levels.filter((level) => level.properties.ordinal === ordinal).map((level) => level.id);
|
|
2331
|
+
const unit = units.find((unit2) => levelIdsWithOrdinal.includes(unit2.properties.level_id) && (0, import_boolean_point_in_polygon4.booleanPointInPolygon)([lat, lng], unit2));
|
|
2332
|
+
return unit;
|
|
2333
|
+
};
|
|
2334
|
+
const stepUtils = createStepUtils({ ...options, findByIdSync });
|
|
2335
|
+
const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
|
|
2336
|
+
if (!routeOriginParam || !routeDestinationParam) return null;
|
|
2337
|
+
const graph = options2?.mode === "accessible" ? accessibleGraph : defaultGraph;
|
|
2338
|
+
if (isCoordinateOrdinalString(routeOriginParam)) {
|
|
2339
|
+
const walkwayUnit = findCoordinateOrdinalUnit(routeOriginParam);
|
|
2340
|
+
addCoordinateOrdinalNode(routeOriginParam, walkwayUnit);
|
|
2341
|
+
}
|
|
2342
|
+
if (isCoordinateOrdinalString(routeDestinationParam)) {
|
|
2343
|
+
const walkwayUnit = findCoordinateOrdinalUnit(routeDestinationParam);
|
|
2344
|
+
addCoordinateOrdinalNode(routeDestinationParam, walkwayUnit);
|
|
2345
|
+
}
|
|
2346
|
+
try {
|
|
2347
|
+
trace("nav", "\u2713 findRoute", 0);
|
|
2348
|
+
const t02 = performance.now();
|
|
2349
|
+
const path = graph.path(routeOriginParam, routeDestinationParam);
|
|
2350
|
+
const t12 = performance.now();
|
|
2351
|
+
trace("nav", " \u251C\u2500 path (dijkstra)", t12 - t02);
|
|
2352
|
+
const waypoints = stepUtils.toWaypoints(path);
|
|
2353
|
+
console.log({ waypoints });
|
|
2354
|
+
const t22 = performance.now();
|
|
2355
|
+
trace("nav", " \u251C\u2500 toWaypoints", t22 - t12);
|
|
2356
|
+
trace("nav", " \u251C\u2500 toSteps", 0);
|
|
2357
|
+
const steps = stepUtils.toSteps(waypoints);
|
|
2358
|
+
const t32 = performance.now();
|
|
2359
|
+
const totalDistance = calculateTotalDistance(steps);
|
|
2360
|
+
const roundedDistance = calculateRoundedDistance(totalDistance);
|
|
2361
|
+
const duration = calculateTravelingDuration(totalDistance);
|
|
2362
|
+
const t4 = performance.now();
|
|
2363
|
+
trace("nav", " \u2514\u2500 postProcess", t4 - t32);
|
|
2364
|
+
return {
|
|
2365
|
+
// origin: routeOrigin,
|
|
2366
|
+
// destination: routeDestination,
|
|
2367
|
+
description: null,
|
|
2368
|
+
distance: roundedDistance,
|
|
2369
|
+
duration,
|
|
2370
|
+
steps
|
|
2371
|
+
};
|
|
2372
|
+
} catch (error) {
|
|
2373
|
+
console.log(error);
|
|
2374
|
+
throw error;
|
|
2375
|
+
}
|
|
2079
2376
|
};
|
|
2080
2377
|
return {
|
|
2081
|
-
|
|
2378
|
+
findRoute,
|
|
2379
|
+
findByIdSync
|
|
2082
2380
|
};
|
|
2083
2381
|
};
|
|
2084
2382
|
|
|
2085
2383
|
// src/data/getDataClient.ts
|
|
2086
2384
|
var getDataClient = (options) => {
|
|
2087
2385
|
let searchClient;
|
|
2386
|
+
let navigateClient;
|
|
2088
2387
|
const observers = /* @__PURE__ */ new Map();
|
|
2089
2388
|
const queryClient = options.queryClient ?? new import_query_core.QueryClient();
|
|
2090
2389
|
const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
|
|
@@ -2115,17 +2414,17 @@ var getDataClient = (options) => {
|
|
|
2115
2414
|
const internalFindById = async (id) => {
|
|
2116
2415
|
if (id === null || id === void 0) return null;
|
|
2117
2416
|
const featureType = id.slice(0, id.lastIndexOf("-"));
|
|
2118
|
-
const
|
|
2417
|
+
const feature2 = await queryClient.ensureQueryData({
|
|
2119
2418
|
queryKey: ["_deliveryapi", featureType, id],
|
|
2120
2419
|
queryFn: async () => {
|
|
2121
2420
|
const features = await internalFilterByType(featureType);
|
|
2122
|
-
const
|
|
2421
|
+
const feature3 = features.find(
|
|
2123
2422
|
(f) => f.id === id
|
|
2124
2423
|
);
|
|
2125
|
-
return
|
|
2424
|
+
return feature3 ?? null;
|
|
2126
2425
|
}
|
|
2127
2426
|
});
|
|
2128
|
-
return
|
|
2427
|
+
return feature2;
|
|
2129
2428
|
};
|
|
2130
2429
|
const populator = createPopulator({ internalFindById, internalFilterByType });
|
|
2131
2430
|
const registerObserver = (featureType, refetchInterval) => {
|
|
@@ -2174,8 +2473,8 @@ var getDataClient = (options) => {
|
|
|
2174
2473
|
const createFindByIdQueryOptions = (featureType, id, params = {}, options2 = {}) => ({
|
|
2175
2474
|
queryKey: [featureType, "detail", id, params],
|
|
2176
2475
|
queryFn: async () => {
|
|
2177
|
-
const
|
|
2178
|
-
return params.populate === true ? await populator[featureType](
|
|
2476
|
+
const feature2 = await internalFindById(id);
|
|
2477
|
+
return params.populate === true ? await populator[featureType](feature2) : Promise.resolve(feature2);
|
|
2179
2478
|
},
|
|
2180
2479
|
...options2 ?? {}
|
|
2181
2480
|
});
|
|
@@ -2193,8 +2492,8 @@ var getDataClient = (options) => {
|
|
|
2193
2492
|
id,
|
|
2194
2493
|
params
|
|
2195
2494
|
);
|
|
2196
|
-
const
|
|
2197
|
-
return
|
|
2495
|
+
const feature2 = await queryClient.ensureQueryData(findQueryOptions);
|
|
2496
|
+
return feature2;
|
|
2198
2497
|
}
|
|
2199
2498
|
const searchFn = async (txt) => {
|
|
2200
2499
|
if (!searchClient) {
|
|
@@ -2207,6 +2506,24 @@ var getDataClient = (options) => {
|
|
|
2207
2506
|
}
|
|
2208
2507
|
return searchClient.search(txt);
|
|
2209
2508
|
};
|
|
2509
|
+
const navigateFn = async (origin, destination) => {
|
|
2510
|
+
if (!navigateClient) {
|
|
2511
|
+
const [levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors] = await Promise.all([
|
|
2512
|
+
filterByType("level"),
|
|
2513
|
+
filterByType("occupant"),
|
|
2514
|
+
filterByType("opening"),
|
|
2515
|
+
filterByType("relationship"),
|
|
2516
|
+
filterByType("unit"),
|
|
2517
|
+
filterByType("fixture"),
|
|
2518
|
+
filterByType("kiosk"),
|
|
2519
|
+
filterByType("amenity"),
|
|
2520
|
+
filterByType("anchor")
|
|
2521
|
+
]);
|
|
2522
|
+
const haystack = { levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors };
|
|
2523
|
+
navigateClient = getNavigateClient({ data: haystack });
|
|
2524
|
+
}
|
|
2525
|
+
return navigateClient.findRoute(origin, destination);
|
|
2526
|
+
};
|
|
2210
2527
|
return {
|
|
2211
2528
|
projectId,
|
|
2212
2529
|
queryClient,
|
|
@@ -2218,7 +2535,8 @@ var getDataClient = (options) => {
|
|
|
2218
2535
|
_internalFindById: internalFindById,
|
|
2219
2536
|
filterByType,
|
|
2220
2537
|
findById,
|
|
2221
|
-
search: searchFn
|
|
2538
|
+
search: searchFn,
|
|
2539
|
+
navigate: navigateFn
|
|
2222
2540
|
};
|
|
2223
2541
|
};
|
|
2224
2542
|
// Annotate the CommonJS export names for ESM import in node:
|