venue-js 1.4.0-next.2 → 1.4.0-next.20

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/index.mjs CHANGED
@@ -27,6 +27,71 @@ var IMDF_FEATURE_TYPES = [
27
27
  "unit",
28
28
  "venue"
29
29
  ];
30
+ var IMDF_UNIT_CATEGORIES = [
31
+ "auditorium",
32
+ "brick",
33
+ "classroom",
34
+ "column",
35
+ "concrete",
36
+ "conferenceroom",
37
+ "drywall",
38
+ "elevator",
39
+ "escalator",
40
+ "fieldofplay",
41
+ "firstaid",
42
+ "fitnessroom",
43
+ "foodservice",
44
+ "footbridge",
45
+ "glass",
46
+ "huddleroom",
47
+ "kitchen",
48
+ "laboratory",
49
+ "library",
50
+ "lobby",
51
+ "lounge",
52
+ "mailroom",
53
+ "mothersroom",
54
+ "movietheater",
55
+ "movingwalkway",
56
+ "nonpublic",
57
+ "office",
58
+ "opentobelow",
59
+ "parking",
60
+ "phoneroom",
61
+ "platform",
62
+ "privatelounge",
63
+ "ramp",
64
+ "recreation",
65
+ "restroom",
66
+ "restroom.family",
67
+ "restroom.female",
68
+ "restroom.female.wheelchair",
69
+ "restroom.male",
70
+ "restroom.male.wheelchair",
71
+ "restroom.transgender",
72
+ "restroom.transgender.wheelchair",
73
+ "restroom.unisex",
74
+ "restroom.unisex.wheelchair",
75
+ "restroom.wheelchair",
76
+ "road",
77
+ "room",
78
+ "serverroom",
79
+ "shower",
80
+ "smokingarea",
81
+ "stairs",
82
+ "steps",
83
+ "storage",
84
+ "structure",
85
+ "terrace",
86
+ "theater",
87
+ "unenclosedarea",
88
+ "unspecified",
89
+ "vegetation",
90
+ "waitingroom",
91
+ "walkway",
92
+ "walkway.island",
93
+ "wood"
94
+ ];
30
95
  var NONIMDF_FEATURE_TYPES = [
31
96
  "taxonomy",
32
97
  "event",
@@ -85,6 +150,119 @@ var defaultFeatureQueryOptionsMap = {
85
150
  model3d: {}
86
151
  };
87
152
 
153
+ // src/data/utils/geometry-validator.ts
154
+ var isValidCoordinate = (point2) => {
155
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
156
+ };
157
+ function isValidLinearRingCoordinates(ring) {
158
+ if (ring.length < 4) {
159
+ return false;
160
+ }
161
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
162
+ }
163
+ var isValidPolygonCoordinates = (polygon2) => {
164
+ if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
165
+ return isValidLinearRingCoordinates(polygon2);
166
+ }
167
+ if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
168
+ if (!isValidLinearRingCoordinates(polygon2[0])) {
169
+ return false;
170
+ }
171
+ for (let i = 1; i < polygon2.length; i++) {
172
+ if (!isValidLinearRingCoordinates(polygon2[i])) {
173
+ return false;
174
+ }
175
+ }
176
+ return true;
177
+ }
178
+ return false;
179
+ };
180
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
181
+ return multipolygon.every(isValidPolygonCoordinates);
182
+ };
183
+ var isValidLineStringCoordinates = (lineString2) => {
184
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
185
+ return false;
186
+ }
187
+ const firstPoint = lineString2[0];
188
+ const lastPoint = lineString2[lineString2.length - 1];
189
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
190
+ return false;
191
+ }
192
+ return lineString2.every(isValidCoordinate);
193
+ };
194
+ var isValidMultiPolygon = (geometry) => {
195
+ const { type, coordinates } = geometry;
196
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
197
+ };
198
+ var isValidPolygon = (geometry) => {
199
+ const { type, coordinates } = geometry;
200
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
201
+ };
202
+ var isValidLineString = (geometry) => {
203
+ const { type, coordinates } = geometry;
204
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
205
+ };
206
+ var isValidPoint = (geometry) => {
207
+ const { type, coordinates } = geometry;
208
+ return type === "Point" && isValidCoordinate(coordinates);
209
+ };
210
+
211
+ // src/data/utils/match-filters.ts
212
+ function isInFilter(filter) {
213
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
214
+ }
215
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
216
+ function matchFilter(value, filter) {
217
+ if (Array.isArray(value)) {
218
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
219
+ return value.includes(filter);
220
+ } else {
221
+ if (isInFilter(filter)) return filter.$in.includes(value);
222
+ return value === filter;
223
+ }
224
+ }
225
+ function matchFilters(item, filters) {
226
+ return Object.entries(filters).every(([key, filter]) => {
227
+ return matchFilter(item.properties[key], filter);
228
+ });
229
+ }
230
+
231
+ // src/data/utils/occupant-helper.ts
232
+ var occupant_helper_exports = {};
233
+ __export(occupant_helper_exports, {
234
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
235
+ getOccupantMainLocation: () => getOccupantMainLocation,
236
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
237
+ });
238
+
239
+ // src/data/utils/lodash/compact.ts
240
+ var compact = (arr) => arr.filter((item) => Boolean(item));
241
+
242
+ // src/data/utils/occupant-helper.ts
243
+ var getOccupantMainLocation = (occupant) => {
244
+ return occupant.properties.kiosk || occupant.properties.unit;
245
+ };
246
+ var getOccupantCorrelatedLocations = (occupant) => {
247
+ const allCorrelatedLocations = [
248
+ ...occupant.properties.units,
249
+ ...occupant.properties.kiosks
250
+ ];
251
+ return compact(allCorrelatedLocations);
252
+ };
253
+ var getOccupantMarkerLocations = (occupant, options) => {
254
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
255
+ const mainLocation = getOccupantMainLocation(occupant);
256
+ const mainLocationLevel = mainLocation?.properties?.level_id;
257
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
258
+ if (placementType === "ALL_LOCATIONS") {
259
+ return compact([mainLocation, ...allCorrelatedLocations]);
260
+ }
261
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
262
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
263
+ return compact([mainLocation, ...onePerLevelLocations]);
264
+ };
265
+
88
266
  // src/data/api/delivery-project.ts
89
267
  async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
90
268
  switch (featureType) {
@@ -206,115 +384,6 @@ var safeFetchFeature = async (featureType, params) => {
206
384
  }
207
385
  };
208
386
 
209
- // src/data/utils/geometry-validator.ts
210
- var isValidCoordinate = (point2) => {
211
- return point2.length === 2 && point2.every((coord) => typeof coord === "number");
212
- };
213
- function isValidLinearRingCoordinates(ring) {
214
- if (ring.length < 4) {
215
- return false;
216
- }
217
- return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
218
- }
219
- var isValidPolygonCoordinates = (polygon2) => {
220
- if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
221
- return isValidLinearRingCoordinates(polygon2);
222
- }
223
- if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
224
- if (!isValidLinearRingCoordinates(polygon2[0])) {
225
- return false;
226
- }
227
- for (let i = 1; i < polygon2.length; i++) {
228
- if (!isValidLinearRingCoordinates(polygon2[i])) {
229
- return false;
230
- }
231
- }
232
- return true;
233
- }
234
- return false;
235
- };
236
- var isValidMultiPolygonCoordinates = (multipolygon) => {
237
- return multipolygon.every(isValidPolygonCoordinates);
238
- };
239
- var isValidLineStringCoordinates = (lineString2) => {
240
- if (!Array.isArray(lineString2) || lineString2.length < 2) {
241
- return false;
242
- }
243
- const firstPoint = lineString2[0];
244
- const lastPoint = lineString2[lineString2.length - 1];
245
- if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
246
- return false;
247
- }
248
- return lineString2.every(isValidCoordinate);
249
- };
250
- var isValidMultiPolygon = (geometry) => {
251
- const { type, coordinates } = geometry;
252
- return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
253
- };
254
- var isValidPolygon = (geometry) => {
255
- const { type, coordinates } = geometry;
256
- return type === "Polygon" && isValidPolygonCoordinates(coordinates);
257
- };
258
- var isValidLineString = (geometry) => {
259
- const { type, coordinates } = geometry;
260
- return type === "LineString" && isValidLineStringCoordinates(coordinates);
261
- };
262
- var isValidPoint = (geometry) => {
263
- const { type, coordinates } = geometry;
264
- return type === "Point" && isValidCoordinate(coordinates);
265
- };
266
-
267
- // src/data/utils/match-filters.ts
268
- function isInFilter(filter) {
269
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
270
- }
271
- var someIntersect = (a, b) => a.some((v2) => b.includes(v2));
272
- function matchFilter(value, filter) {
273
- if (Array.isArray(value)) {
274
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
275
- return value.includes(filter);
276
- } else {
277
- if (isInFilter(filter)) return filter.$in.includes(value);
278
- return value === filter;
279
- }
280
- }
281
- function matchFilters(item, filters) {
282
- return Object.entries(filters).every(([key, filter]) => {
283
- return matchFilter(item.properties[key], filter);
284
- });
285
- }
286
-
287
- // src/data/utils/occupant-helper.ts
288
- var occupant_helper_exports = {};
289
- __export(occupant_helper_exports, {
290
- getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
291
- getOccupantMainLocation: () => getOccupantMainLocation,
292
- getOccupantMarkerLocations: () => getOccupantMarkerLocations
293
- });
294
- import { compact } from "lodash-es";
295
- var getOccupantMainLocation = (occupant) => {
296
- return occupant.properties.kiosk || occupant.properties.unit;
297
- };
298
- var getOccupantCorrelatedLocations = (occupant) => {
299
- const allCorrelatedLocations = [
300
- ...occupant.properties.units,
301
- ...occupant.properties.kiosks
302
- ];
303
- return compact(allCorrelatedLocations);
304
- };
305
- var getOccupantMarkerLocations = (occupant, options) => {
306
- const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
307
- const mainLocation = getOccupantMainLocation(occupant);
308
- const mainLocationLevel = mainLocation?.properties?.level_id;
309
- const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
310
- if (placementType === "ALL_LOCATIONS") {
311
- return compact([mainLocation, ...allCorrelatedLocations]);
312
- }
313
- const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
314
- const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
315
- return compact([mainLocation, ...onePerLevelLocations]);
316
- };
317
-
318
387
  // src/data/getDataClient.ts
319
388
  import {
320
389
  QueryClient,
@@ -322,8 +391,40 @@ import {
322
391
  } from "@tanstack/query-core";
323
392
 
324
393
  // src/data/populator/index.ts
325
- import { compact as compact2 } from "lodash-es";
326
- import { booleanWithin } from "@turf/boolean-within";
394
+ import { center as center2 } from "@turf/center";
395
+ import { booleanPointInPolygon as booleanPointInPolygon2 } from "@turf/boolean-point-in-polygon";
396
+
397
+ // src/data/utils/findContaining.ts
398
+ import { center } from "@turf/center";
399
+ import { booleanPointInPolygon } from "@turf/boolean-point-in-polygon";
400
+ var findContainingUnit = (poi, units) => {
401
+ const unit = units.find(
402
+ (unit2) => {
403
+ try {
404
+ return unit2.properties.level_id === poi.properties.level_id && booleanPointInPolygon(center(poi), unit2);
405
+ } catch (e) {
406
+ console.log(`Cannot find containing unit of (${poi.id}):`, e.message);
407
+ return false;
408
+ }
409
+ }
410
+ );
411
+ return unit;
412
+ };
413
+ var findContainingUnitAtPoint = (point2, levelId, units) => {
414
+ const unit = units.find(
415
+ (unit2) => {
416
+ try {
417
+ return unit2.properties.level_id === levelId && booleanPointInPolygon(point2, unit2);
418
+ } catch (e) {
419
+ console.log(`Cannot find containing unit of (point: ${point2}, levelId: ${levelId}):`, e.message);
420
+ return false;
421
+ }
422
+ }
423
+ );
424
+ return unit;
425
+ };
426
+
427
+ // src/data/populator/index.ts
327
428
  var createPopulator = ({
328
429
  internalFindById,
329
430
  internalFilterByType
@@ -333,7 +434,6 @@ var createPopulator = ({
333
434
  const populateDetail = (detail) => Promise.resolve(detail);
334
435
  const populateFootprint = (footprint) => Promise.resolve(footprint);
335
436
  const populateGeofence = (geofence) => Promise.resolve(geofence);
336
- const populateRelationship = (relationship) => Promise.resolve(relationship);
337
437
  const populatePrivilege = (privilege) => Promise.resolve(privilege);
338
438
  const populateEvent = (event) => Promise.resolve(event);
339
439
  const populatePromotion = async (promotion) => {
@@ -357,13 +457,14 @@ var createPopulator = ({
357
457
  const ordinalKiosks = kiosks.filter(
358
458
  (kiosk2) => kiosk2.properties.level_id === defaultLevel.id
359
459
  );
360
- const kiosk = ordinalKiosks.find((kiosk2) => booleanWithin(amenity, kiosk2));
460
+ const kiosk = ordinalKiosks.find((kiosk2) => booleanPointInPolygon2(amenity, kiosk2));
361
461
  return {
362
462
  ...amenity,
363
463
  properties: {
364
464
  ...amenity.properties,
365
465
  ordinal: defaultLevel.properties.ordinal,
366
466
  level_name: defaultLevel.properties.name.en,
467
+ level: defaultLevel,
367
468
  units: populatedUnits,
368
469
  venue,
369
470
  _experimental_kiosk: kiosk ? await populateKiosk(kiosk) : null
@@ -375,7 +476,7 @@ var createPopulator = ({
375
476
  const venue = await internalFindById(unit.properties.venue_id);
376
477
  const level = await internalFindById(unit.properties.level_id);
377
478
  const sections = await internalFilterByType("section");
378
- const section = sections.find((section2) => booleanWithin(anchor, section2));
479
+ const section = sections.find((section2) => booleanPointInPolygon2(anchor, section2));
379
480
  return {
380
481
  ...anchor,
381
482
  properties: {
@@ -408,20 +509,11 @@ var createPopulator = ({
408
509
  const venue = await internalFindById(kiosk.properties.venue_id);
409
510
  const anchor = await internalFindById(kiosk.properties.anchor_id);
410
511
  const units = await internalFilterByType("unit");
411
- const unit = units.find(
412
- (unit2) => {
413
- try {
414
- return unit2.properties.category === "walkway" && unit2.properties.level_id === kiosk.properties.level_id && booleanWithin(kiosk, unit2);
415
- } catch (e) {
416
- console.log(`Cannot find kiosk(${kiosk.id})'s units:`, e.message);
417
- return false;
418
- }
419
- }
420
- );
512
+ const unit = findContainingUnit(kiosk, units.filter((unit2) => unit2.properties.category === "walkway"));
421
513
  let section = null;
422
514
  if (anchor) {
423
515
  const sections = await internalFilterByType("section");
424
- section = sections.find((section2) => booleanWithin(anchor, section2));
516
+ section = sections.find((section2) => booleanPointInPolygon2(anchor, section2));
425
517
  }
426
518
  return {
427
519
  ...kiosk,
@@ -451,8 +543,8 @@ var createPopulator = ({
451
543
  anchor_id,
452
544
  venue_id,
453
545
  local_category_ids,
454
- promotion_ids,
455
- privilege_ids,
546
+ promotion_ids = [],
547
+ privilege_ids = [],
456
548
  kiosk_id,
457
549
  unit_id,
458
550
  kiosk_ids = [],
@@ -479,7 +571,7 @@ var createPopulator = ({
479
571
  ...occupant.properties,
480
572
  anchor: anchor ? await populateAnchor(anchor) : null,
481
573
  local_categories: await Promise.all(
482
- compact2(localCategories).map(populateTaxonomy)
574
+ compact(localCategories).map(populateTaxonomy)
483
575
  ),
484
576
  venue,
485
577
  promotions,
@@ -516,12 +608,29 @@ var createPopulator = ({
516
608
  }
517
609
  };
518
610
  };
611
+ const populateRelationship = async (relationship) => {
612
+ const originId = relationship.properties.origin?.id;
613
+ const destinationId = relationship.properties.destination?.id;
614
+ const origin = originId ? await internalFindById(originId) : null;
615
+ const destination = destinationId ? await internalFindById(destinationId) : null;
616
+ const intermediary_ids = (relationship.properties.intermediary || []).map(({ id }) => id);
617
+ const intermediary = await Promise.all(intermediary_ids.map(internalFindById));
618
+ return {
619
+ ...relationship,
620
+ properties: {
621
+ ...relationship.properties,
622
+ origin,
623
+ destination,
624
+ intermediary
625
+ }
626
+ };
627
+ };
519
628
  const populateUnit = async (unit) => {
520
629
  const venue = await internalFindById(unit.properties.venue_id);
521
630
  const level = await internalFindById(unit.properties.level_id);
522
631
  const sections = await internalFilterByType("section");
523
632
  try {
524
- const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => booleanWithin(unit, section2)) : null;
633
+ const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => booleanPointInPolygon2(center2(unit), section2)) : null;
525
634
  return {
526
635
  ...unit,
527
636
  properties: {
@@ -549,6 +658,20 @@ var createPopulator = ({
549
658
  }
550
659
  };
551
660
  };
661
+ const populateModel3D = async (model3d) => {
662
+ const level = await internalFindById(model3d.properties.level_id);
663
+ try {
664
+ return {
665
+ ...model3d,
666
+ properties: {
667
+ ...model3d.properties,
668
+ level: await populateLevel(level)
669
+ }
670
+ };
671
+ } catch (err) {
672
+ console.log(`error finding level`, { model3d, level });
673
+ }
674
+ };
552
675
  const populateFeature = (feature2) => Promise.resolve(feature2);
553
676
  return {
554
677
  address: populateAddress,
@@ -573,150 +696,571 @@ var createPopulator = ({
573
696
  section: populateSection,
574
697
  unit: populateUnit,
575
698
  venue: populateVenue,
576
- taxonomy: populateTaxonomy
699
+ taxonomy: populateTaxonomy,
700
+ model3d: populateModel3D
577
701
  };
578
702
  };
579
703
 
580
- // src/data/getDataClient.ts
581
- var getDataClient = (options) => {
582
- const observers = /* @__PURE__ */ new Map();
583
- const queryClient = options.queryClient ?? new QueryClient();
584
- const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
585
- if (!projectId)
586
- throw new Error(
587
- "Cannot create VenueDataClient. Reason: `projectId` is missing"
588
- );
589
- if (mode === "delivery" && !apiKey)
590
- throw new Error(
591
- "Cannot create VenueDataClient. Reason: `apiKey` is missing"
592
- );
593
- if (mode === "preview" && !previewToken)
594
- throw new Error(
595
- "Cannot create VenueDataClient. Reason: `previewToken` is missing"
596
- );
597
- const createDeliveryApiQueryOptions = (featureType) => ({
598
- queryKey: ["_deliveryapi", featureType],
599
- queryFn: () => safeFetchFeature(featureType, { mode, projectId, apiKey, previewToken, baseUrl })
704
+ // src/data/search/getSearchClient.ts
705
+ import Fuse from "fuse.js";
706
+
707
+ // src/data/search/utils/sanitizeInput.ts
708
+ var sanitizeInput = (str) => str.replace(/[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, "").replace(/[\-–—_./()]+/g, "").normalize("NFC").trim();
709
+
710
+ // src/data/search/getSearchClient.ts
711
+ var getSearchClient = ({ occupants, amenities }) => {
712
+ const fuseAmenities = new Fuse(amenities, {
713
+ threshold: 0.2,
714
+ keys: [
715
+ { name: "properties.name", "weight": 1, getFn: (obj) => Object.values(obj.properties.name || {}) },
716
+ { name: "properties.category", "weight": 1 }
717
+ ]
600
718
  });
601
- const internalFilterByType = async (featureType) => {
602
- try {
603
- const features = await queryClient.ensureQueryData(createDeliveryApiQueryOptions(featureType));
604
- return features;
605
- } catch (error) {
606
- throw error;
607
- }
719
+ const fuseOccupants = new Fuse(occupants, {
720
+ threshold: 0.25,
721
+ // 0.2 is too strict (can't find Mo-Mo Paradise with "momo" search string)
722
+ includeScore: true,
723
+ shouldSort: true,
724
+ keys: [
725
+ { name: "properties.name", "weight": 4, getFn: (obj) => Object.values(obj.properties.name || {}) },
726
+ { name: "properties.keywords", "weight": 0.5 },
727
+ { name: "properties.category", "weight": 0.25 },
728
+ { name: "properties.local_category_names", "weight": 0.25 },
729
+ { name: "properties.description", "weight": 0.25, getFn: (occ) => Object.values(occ.properties.description || {}) },
730
+ { name: "properties.unit_name", "weight": 0.25 },
731
+ { name: "properties.kiosk_name", "weight": 0.25 }
732
+ ]
733
+ });
734
+ const search = (value) => {
735
+ const sanitizedValue = sanitizeInput(value);
736
+ const matchedAmenities = fuseAmenities.search(sanitizedValue);
737
+ const matchedOccupants = fuseOccupants.search(sanitizedValue);
738
+ return [...matchedAmenities, ...matchedOccupants];
608
739
  };
609
- const internalFindById = async (id) => {
610
- if (id === null) return null;
611
- const featureType = id.slice(0, id.lastIndexOf("-"));
612
- const feature2 = await queryClient.ensureQueryData({
613
- queryKey: ["_deliveryapi", featureType, id],
614
- queryFn: async () => {
615
- const features = await internalFilterByType(featureType);
616
- const feature3 = features.find(
617
- (f) => f.id === id
618
- );
619
- return feature3 ?? null;
620
- }
621
- });
622
- return feature2;
740
+ return {
741
+ search
623
742
  };
624
- const populator = createPopulator({ internalFindById, internalFilterByType });
625
- const registerObserver = (featureType, refetchInterval) => {
626
- if (observers.has(featureType)) {
627
- console.warn(`Observer for ${featureType} already exists`);
628
- const record = observers.get(featureType);
629
- return record.observer;
743
+ };
744
+
745
+ // src/data/navigate/getNavigateClient.ts
746
+ import { booleanPointInPolygon as booleanPointInPolygon4 } from "@turf/boolean-point-in-polygon";
747
+
748
+ // src/data/navigate/graph/prepare.ts
749
+ import _6 from "lodash";
750
+ import DijstraGraph from "node-dijkstra";
751
+ import { distance as distance2 } from "@turf/distance";
752
+ import { center as turfCenter3 } from "@turf/center";
753
+
754
+ // src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
755
+ import { distance as turfDistance } from "@turf/distance";
756
+ import { center as turfCenter } from "@turf/center";
757
+ import _ from "lodash";
758
+
759
+ // src/data/navigate/graph/constants.ts
760
+ var ROOM_BASEDISTANCE = 1e3;
761
+ var TERRACE_BASEDISTANCE = 1e3;
762
+ var ESCALATOR_BASEDISTANCE = 200;
763
+ var RAMP_BASEDISTANCE = 200;
764
+ var ELEVATOR_BASEDISTANCE = 500;
765
+ var STAIR_BASEDISTANCE = 1e5;
766
+ var BASE_POI_BASEDISTANCE = 9999999;
767
+ var DEFAULT_UNIT_BASEDISTANCE_OPTIONS = {
768
+ default: { baseDistance: 0 },
769
+ byCategory: {
770
+ room: { baseDistance: ROOM_BASEDISTANCE },
771
+ terrace: { baseDistance: TERRACE_BASEDISTANCE },
772
+ escalator: { baseDistance: ESCALATOR_BASEDISTANCE, scaleDistanceByLevel: false },
773
+ ramp: { baseDistance: RAMP_BASEDISTANCE, scaleDistanceByLevel: false },
774
+ elevator: { baseDistance: ELEVATOR_BASEDISTANCE, scaleDistanceByLevel: false },
775
+ stairs: {
776
+ baseDistance: STAIR_BASEDISTANCE,
777
+ scaleDistanceByLevel: true
778
+ },
779
+ "stairs.emergencyexit": {
780
+ baseDistance: STAIR_BASEDISTANCE,
781
+ scaleDistanceByLevel: true
630
782
  }
631
- const options2 = createDeliveryApiQueryOptions(featureType);
632
- const observer = new QueryObserver(queryClient, {
633
- ...options2,
634
- refetchInterval
635
- });
636
- const unsubscribe = observer.subscribe(() => {
637
- console.log(`[venue-js] Listening to ${featureType} changes (interval = ${refetchInterval}ms)`);
638
- });
639
- observers.set(featureType, { observer, unsubscribe });
640
- return observer;
641
- };
642
- const destroyObserver = (featureType) => {
643
- const record = observers.get(featureType);
644
- if (!record) return;
645
- record.unsubscribe();
646
- observers.delete(featureType);
647
- };
648
- const destroyObservers = () => {
649
- observers.forEach(({ observer, unsubscribe }) => {
650
- unsubscribe();
651
- observer.destroy();
652
- });
653
- observers.clear();
654
- };
655
- const createFilterByTypeQueryOptions = (featureType, params = {}, options2 = {}) => ({
656
- queryKey: [featureType, "list", params],
657
- queryFn: async () => {
658
- const features = await internalFilterByType(featureType);
659
- const filters = params.filters ?? {};
660
- let result = features;
661
- if (params.filters) {
662
- result = features.filter((f) => matchFilters(f, filters));
783
+ }
784
+ };
785
+
786
+ // src/data/navigate/graph/utils/getDistanceOption.ts
787
+ var getDistanceOptions = (options, category) => {
788
+ if (!options) return DEFAULT_UNIT_BASEDISTANCE_OPTIONS.byCategory[category];
789
+ return (category && options.byCategory?.[category]) ?? DEFAULT_UNIT_BASEDISTANCE_OPTIONS.byCategory[category] ?? options?.default ?? DEFAULT_UNIT_BASEDISTANCE_OPTIONS.default;
790
+ };
791
+
792
+ // src/data/utils/trace.ts
793
+ var trace = (namespace, text, ms, color) => {
794
+ if (process.env.NODE_ENV !== "test") console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
795
+ };
796
+
797
+ // src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
798
+ var createTraversalNodeMap = (unitOpenings, options) => {
799
+ const { units } = options.data;
800
+ let counter = 0;
801
+ const calculateFeatureDistanceWithinUnit = (features, distanceOptions) => {
802
+ let relationshipGraph = {};
803
+ for (let currentIndex = 0; currentIndex < features.length; currentIndex++) {
804
+ const isLastItem = currentIndex + 1 === features.length;
805
+ if (isLastItem) break;
806
+ for (let j = currentIndex + 1; j < features.length; j++) {
807
+ const opening = features[currentIndex];
808
+ const feature2 = features[j];
809
+ try {
810
+ const distance5 = turfDistance(
811
+ turfCenter(opening.geometry),
812
+ turfCenter(feature2.geometry),
813
+ { units: "meters" }
814
+ ) + (distanceOptions?.baseDistance ?? 0);
815
+ if (opening.id === feature2.id) continue;
816
+ _.set(relationshipGraph, `${opening.id}.${feature2.id}`, distance5);
817
+ _.set(relationshipGraph, `${feature2.id}.${opening.id}`, distance5);
818
+ counter++;
819
+ } catch (error) {
820
+ continue;
821
+ }
663
822
  }
664
- return params.populate === true ? await Promise.all(result.map((f) => populator[featureType](f))) : result;
823
+ }
824
+ return relationshipGraph;
825
+ };
826
+ const t0 = performance.now();
827
+ const nodeMap = _.reduce(
828
+ unitOpenings,
829
+ (acc, openings, unitId) => {
830
+ const unit = units.find((unit2) => unit2.id === unitId);
831
+ const unitDistanceOption = getDistanceOptions(options.unitDistanceOptions, unit.properties.category);
832
+ return _.merge(
833
+ acc,
834
+ calculateFeatureDistanceWithinUnit(openings, unitDistanceOption)
835
+ );
665
836
  },
666
- ...options2 ?? {}
837
+ {}
838
+ );
839
+ const t1 = performance.now();
840
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} traversal relationships`, t1 - t0);
841
+ return nodeMap;
842
+ };
843
+
844
+ // src/data/navigate/graph/nodemap/createElevatorNodeMap.ts
845
+ import _2 from "lodash";
846
+ var createElevatorNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
847
+ const t0 = performance.now();
848
+ const { levels, units } = options.data;
849
+ const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "elevator");
850
+ const {
851
+ baseDistance = ELEVATOR_BASEDISTANCE,
852
+ scaleDistanceByLevel = false
853
+ } = distanceOptions;
854
+ let elevatorNodeMap = {};
855
+ let counter = 0;
856
+ for (const relationship of elevatorLikeRelationships) {
857
+ try {
858
+ const {
859
+ origin: originTypeAndId,
860
+ intermediary,
861
+ destination: destinationTypeAndId
862
+ } = relationship.properties;
863
+ const origin = units.find((unit) => unit.id === originTypeAndId.id);
864
+ if (!origin) return;
865
+ const originOpenings = compact(unitOpenings[origin.id]);
866
+ const originLevel = levels.find((level) => level.id === origin.properties.level_id);
867
+ const destination = units.find((unit) => unit.id === destinationTypeAndId.id);
868
+ const destinationOpenings = unitOpenings[destination.id];
869
+ const destinationOpeningAndLevels = destinationOpenings.map((opening) => {
870
+ const level = levels.find((level2) => level2.id === destination.properties.level_id);
871
+ return { opening, level };
872
+ });
873
+ const intermediaryOpeningAndLevels = intermediary.map((unitTypeAndId) => {
874
+ const openings = unitOpenings[unitTypeAndId.id];
875
+ const unit = units.find((unit2) => unit2.id === unitTypeAndId.id);
876
+ const level = levels.find((level2) => level2.id === unit.properties.level_id);
877
+ return openings.map((opening) => ({ opening, level }));
878
+ }).flat();
879
+ const connections = compact([...intermediaryOpeningAndLevels, ...destinationOpeningAndLevels]);
880
+ if (!originOpenings || originOpenings.length === 0) return;
881
+ for (const originOpening of originOpenings) {
882
+ for (const connection of connections) {
883
+ const { opening, level } = connection;
884
+ let distance5 = baseDistance;
885
+ if (scaleDistanceByLevel) {
886
+ const originOrdinal = originLevel.properties.ordinal;
887
+ const connectionOrdinal = level.properties.ordinal;
888
+ const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
889
+ if (levelDifference > 0) distance5 *= levelDifference;
890
+ }
891
+ _2.set(elevatorNodeMap, `${originOpening.id}.${opening.id}`, distance5);
892
+ _2.set(elevatorNodeMap, `${opening.id}.${originOpening.id}`, distance5);
893
+ counter++;
894
+ }
895
+ }
896
+ } catch (err) {
897
+ console.log(err);
898
+ console.log("cannot create elevatorNodeMap for ", { relationship });
899
+ }
900
+ }
901
+ const t1 = performance.now();
902
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} escalator relationships`, t1 - t0);
903
+ return elevatorNodeMap;
904
+ };
905
+
906
+ // src/data/navigate/graph/nodemap/createEscalatorNodeMap.ts
907
+ import set from "lodash/set";
908
+ var createEscalatorNodeMap = (relationships, options) => {
909
+ const t0 = performance.now();
910
+ const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "escalator");
911
+ let counter = 0;
912
+ let nodeMap = {};
913
+ for (const relationship of relationships) {
914
+ const {
915
+ properties: { direction, origin, destination }
916
+ } = relationship;
917
+ set(nodeMap, `${origin.id}.${destination.id}`, distanceOptions.baseDistance);
918
+ if (direction === "undirected") {
919
+ set(nodeMap, `${destination.id}.${origin.id}`, distanceOptions.baseDistance);
920
+ }
921
+ counter++;
922
+ }
923
+ const t1 = performance.now();
924
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} escalator relationships`, t1 - t0);
925
+ return nodeMap;
926
+ };
927
+
928
+ // src/data/navigate/graph/nodemap/createRampNodeMap.ts
929
+ import set2 from "lodash/set";
930
+ var createRampNodeMap = (relationships, options) => {
931
+ const t0 = performance.now();
932
+ const distanceOptions = getDistanceOptions(options.unitDistanceOptions, "ramp");
933
+ let counter = 0;
934
+ let nodeMap = {};
935
+ relationships.forEach((relationship) => {
936
+ const {
937
+ properties: { origin, destination }
938
+ } = relationship;
939
+ set2(nodeMap, `${origin.id}.${destination.id}`, distanceOptions.baseDistance);
940
+ set2(nodeMap, `${destination.id}.${origin.id}`, distanceOptions.baseDistance);
941
+ counter++;
667
942
  });
668
- const createFindByIdQueryOptions = (featureType, id, params = {}, options2 = {}) => ({
669
- queryKey: [featureType, "detail", id, params],
670
- queryFn: async () => {
671
- const feature2 = await internalFindById(id);
672
- return params.populate === true ? await populator[featureType](feature2) : Promise.resolve(feature2);
673
- },
674
- ...options2 ?? {}
943
+ const t1 = performance.now();
944
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} ramp relationships`, t1 - t0);
945
+ return nodeMap;
946
+ };
947
+
948
+ // src/data/navigate/graph/nodemap/createStairNodeMap.ts
949
+ import _3 from "lodash";
950
+ var createStairNodeMap = (elevatorLikeRelationships, unitOpenings, options) => {
951
+ const t0 = performance.now();
952
+ const { levels = [], openings = [], units = [] } = options.data;
953
+ const { baseDistance, scaleDistanceByLevel } = getDistanceOptions(options.unitDistanceOptions, "stairs");
954
+ let elevatorNodeMap = {};
955
+ let counter = 0;
956
+ for (const relationship of elevatorLikeRelationships) {
957
+ try {
958
+ const {
959
+ origin: { id: originId },
960
+ intermediary,
961
+ destination: { id: destinationId }
962
+ } = relationship.properties;
963
+ const origin = openings.find((opening) => opening.id === originId);
964
+ if (!origin) return;
965
+ const originLevel = levels.find((level) => level.id === origin.properties.level_id);
966
+ const destination = openings.find((opening) => opening.id === destinationId);
967
+ const destinationOpeningAndLevel = {
968
+ opening: destination,
969
+ level: levels.find((level) => level.id === destination.properties.level_id)
970
+ };
971
+ const intermediaryOpeningAndLevels = intermediary.map((unitTypeAndId) => {
972
+ const openings2 = unitOpenings[unitTypeAndId.id];
973
+ const unit = units.find((unit2) => unit2.id === unitTypeAndId.id);
974
+ const level = levels.find((level2) => level2.id === unit.properties.level_id);
975
+ return openings2.map((opening) => ({ opening, level }));
976
+ }).flat();
977
+ const connections = [...intermediaryOpeningAndLevels, destinationOpeningAndLevel];
978
+ if (!origin) return;
979
+ for (const connection of connections) {
980
+ const { opening, level } = connection;
981
+ let distance5 = baseDistance;
982
+ if (scaleDistanceByLevel) {
983
+ const originOrdinal = originLevel.properties.ordinal;
984
+ const connectionOrdinal = level.properties.ordinal;
985
+ const levelDifference = Math.abs(originOrdinal - connectionOrdinal);
986
+ if (levelDifference > 0) distance5 *= levelDifference;
987
+ }
988
+ _3.set(elevatorNodeMap, `${origin.id}.${opening.id}`, distance5);
989
+ _3.set(elevatorNodeMap, `${opening.id}.${origin.id}`, distance5);
990
+ counter++;
991
+ }
992
+ } catch (err) {
993
+ console.warn(
994
+ "Failed to create stairNodeMap",
995
+ {
996
+ relationshipId: relationship.id,
997
+ featureType: relationship.feature_type,
998
+ error: err instanceof Error ? err.message : err,
999
+ stack: err instanceof Error ? err.stack : void 0
1000
+ }
1001
+ );
1002
+ }
1003
+ }
1004
+ const t1 = performance.now();
1005
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} stairs relationships`, t1 - t0);
1006
+ return elevatorNodeMap;
1007
+ };
1008
+
1009
+ // src/data/navigate/graph/nodemap/createOccupantNodeMap.ts
1010
+ import _4 from "lodash";
1011
+ var createOccupantNodeMap = (occupants) => {
1012
+ const t0 = performance.now();
1013
+ let nodeMap = {};
1014
+ let counter = 0;
1015
+ occupants.forEach((occupant) => {
1016
+ const { unit_id, unit_ids = [], kiosk_id, kiosk_ids = [] } = occupant.properties;
1017
+ const occupantRoomIds = compact([unit_id, ...unit_ids]);
1018
+ const occupantKioskIds = compact([kiosk_id, ...kiosk_ids]);
1019
+ for (const roomId of occupantRoomIds) {
1020
+ _4.set(nodeMap, `${roomId}.${occupant.id}`, 1e-3);
1021
+ _4.set(nodeMap, `${occupant.id}.${roomId}`, 1e-3);
1022
+ counter++;
1023
+ }
1024
+ for (const kioskId of occupantKioskIds) {
1025
+ _4.set(nodeMap, `${kioskId}.${occupant.id}`, 1e-3);
1026
+ _4.set(nodeMap, `${occupant.id}.${kioskId}`, 1e-3);
1027
+ counter++;
1028
+ }
675
1029
  });
676
- async function filterByType(featureType, params) {
677
- const filterQueryOptions = createFilterByTypeQueryOptions(
678
- featureType,
679
- params
680
- );
681
- const features = await queryClient.ensureQueryData(filterQueryOptions);
682
- return params?.populate === true ? features : features;
1030
+ const t1 = performance.now();
1031
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} occupants relationships`, t1 - t0);
1032
+ return nodeMap;
1033
+ };
1034
+
1035
+ // src/data/navigate/graph/nodemap/createPOINodeMaps.ts
1036
+ import { center as turfCenter2 } from "@turf/center";
1037
+ import { distance } from "@turf/distance";
1038
+ import _5 from "lodash";
1039
+ var createPOINodeMap = (features, getFeatureUnit, unitOpenings) => {
1040
+ const t0 = performance.now();
1041
+ let nodeMap = {};
1042
+ let counter = 0;
1043
+ features.forEach((feat) => {
1044
+ try {
1045
+ const locatedOnUnitId = getFeatureUnit(feat);
1046
+ const openings = unitOpenings[locatedOnUnitId];
1047
+ const center8 = turfCenter2(feat);
1048
+ for (const opening of openings) {
1049
+ try {
1050
+ const openingCenter = turfCenter2(opening);
1051
+ const dis = distance(center8, openingCenter, { units: "meters" }) + BASE_POI_BASEDISTANCE;
1052
+ _5.set(nodeMap, `${opening.id}.${feat.id}`, dis);
1053
+ _5.set(nodeMap, `${feat.id}.${opening.id}`, dis);
1054
+ counter++;
1055
+ } catch (err) {
1056
+ console.log(err, opening);
1057
+ }
1058
+ }
1059
+ } catch (err) {
1060
+ console.log(err);
1061
+ console.log(`cannot connect poi to openings`, err.message, { feat });
1062
+ }
1063
+ });
1064
+ const type = features.length > 0 ? features[0].feature_type : "-";
1065
+ const t1 = performance.now();
1066
+ trace("nav", ` \u2502 \u251C\u2500 add ${counter} ${type} relationships`, t1 - t0);
1067
+ return nodeMap;
1068
+ };
1069
+
1070
+ // src/data/navigate/graph/utils/mergeNodeMap.ts
1071
+ var mergeNodeMap = (nodeMaps) => {
1072
+ const out = {};
1073
+ for (const nodeMap of nodeMaps) {
1074
+ for (const from in nodeMap) {
1075
+ out[from] = {
1076
+ ...out[from] ?? {},
1077
+ ...nodeMap[from]
1078
+ };
1079
+ }
683
1080
  }
684
- async function findById(featureType, id, params) {
685
- const findQueryOptions = createFindByIdQueryOptions(
686
- featureType,
687
- id,
688
- params
1081
+ return out;
1082
+ };
1083
+
1084
+ // src/data/navigate/graph/utils/createUnitOpenings.ts
1085
+ import uniqBy from "lodash/uniqBy";
1086
+ var createUnitOpenings = (relationships, units, openings) => {
1087
+ const openingConnections = {};
1088
+ const relationshipMap = /* @__PURE__ */ new Map();
1089
+ relationships.forEach((relationship) => {
1090
+ const originId = relationship.properties.origin?.id || null;
1091
+ const destinationId = relationship.properties.destination?.id || null;
1092
+ if (!relationshipMap.has(originId)) {
1093
+ relationshipMap.set(originId, []);
1094
+ }
1095
+ if (!relationshipMap.has(destinationId)) {
1096
+ relationshipMap.set(destinationId, []);
1097
+ }
1098
+ relationshipMap.get(originId).push(relationship);
1099
+ relationshipMap.get(destinationId).push(relationship);
1100
+ });
1101
+ units.forEach((unit) => {
1102
+ const unitId = unit.id;
1103
+ const connectedRelationshop = relationshipMap.get(unitId) || [];
1104
+ const relationshipIntermediaryTypeAndId = connectedRelationshop.map(
1105
+ (relationship) => relationship.properties.intermediary[0]
1106
+ // Assuming intermediary is always an array
689
1107
  );
690
- const feature2 = await queryClient.ensureQueryData(findQueryOptions);
691
- return feature2;
692
- }
1108
+ const relationshipIntermediary = relationshipIntermediaryTypeAndId.map(({ id }) => {
1109
+ return openings.find((opening) => opening.id === id);
1110
+ });
1111
+ openingConnections[unitId] = uniqBy(
1112
+ [...openingConnections[unitId] || [], ...relationshipIntermediary],
1113
+ "id"
1114
+ );
1115
+ });
1116
+ return openingConnections;
1117
+ };
1118
+
1119
+ // src/data/navigate/parsers.ts
1120
+ var parseOrdinalCoordinate = (id) => {
1121
+ return id.slice(0, -1).split(",").map(Number);
1122
+ };
1123
+
1124
+ // src/data/navigate/graph/prepare.ts
1125
+ var prepareGraph = (options) => {
1126
+ const {
1127
+ data: {
1128
+ amenities = [],
1129
+ anchors = [],
1130
+ occupants = [],
1131
+ relationships = [],
1132
+ openings = [],
1133
+ units = [],
1134
+ kiosks = [],
1135
+ levels = []
1136
+ }
1137
+ } = options;
1138
+ const {
1139
+ traversal: traversalRelationships = [],
1140
+ escalator: escalatorRelationships = [],
1141
+ ramp: rampRelationships = [],
1142
+ elevator: elevatorRelationships = [],
1143
+ stairs: stairsRelationships = []
1144
+ } = _6.groupBy(relationships, "properties.category");
1145
+ const unitOpenings = createUnitOpenings(traversalRelationships, units, openings);
1146
+ const traversalNodeMap = createTraversalNodeMap(unitOpenings, options);
1147
+ const escalatorNodeMap = createEscalatorNodeMap(escalatorRelationships, options);
1148
+ const rampNodeMap = createRampNodeMap(rampRelationships, options);
1149
+ const elevatorNodeMap = createElevatorNodeMap(
1150
+ elevatorRelationships,
1151
+ unitOpenings,
1152
+ options
1153
+ );
1154
+ const stairNodeMap = createStairNodeMap(
1155
+ stairsRelationships,
1156
+ unitOpenings,
1157
+ options
1158
+ );
1159
+ const amenityNodeMap = createPOINodeMap(amenities, (amenity) => amenity.properties.unit_ids[0], unitOpenings);
1160
+ const anchorsNodeMap = createPOINodeMap(anchors, (anchor) => anchor.properties.unit_id, unitOpenings);
1161
+ const walkwayUnits = units.filter((unit) => unit.properties.category === "walkway");
1162
+ const kioskNodeMap = createPOINodeMap(kiosks, (kiosk) => findContainingUnit(kiosk, walkwayUnits)?.id, unitOpenings);
1163
+ const unitNodeMap = createPOINodeMap(units, (unit) => unit.id, unitOpenings);
1164
+ const occupantNodeMap = createOccupantNodeMap(occupants);
1165
+ const defaultGraph = new DijstraGraph(mergeNodeMap([
1166
+ traversalNodeMap,
1167
+ escalatorNodeMap,
1168
+ rampNodeMap,
1169
+ elevatorNodeMap,
1170
+ stairNodeMap,
1171
+ amenityNodeMap,
1172
+ anchorsNodeMap,
1173
+ kioskNodeMap,
1174
+ unitNodeMap,
1175
+ occupantNodeMap
1176
+ ]));
1177
+ const accessibleGraph = new DijstraGraph(mergeNodeMap([
1178
+ traversalNodeMap,
1179
+ rampNodeMap,
1180
+ elevatorNodeMap,
1181
+ amenityNodeMap,
1182
+ anchorsNodeMap,
1183
+ kioskNodeMap,
1184
+ unitNodeMap,
1185
+ occupantNodeMap
1186
+ ]));
1187
+ const addCoordinateOrdinalNode = (params, locatedOnUnit) => {
1188
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(params);
1189
+ if (locatedOnUnit) {
1190
+ const openings2 = unitOpenings[locatedOnUnit.id];
1191
+ for (const opening of openings2) {
1192
+ const openingCenter = turfCenter3(opening);
1193
+ const dis = distance2([lat, lng], openingCenter, { units: "meters" });
1194
+ defaultGraph.addNode(params, { [opening.id]: dis }).addNode(opening.id, { [params]: dis });
1195
+ accessibleGraph.addNode(params, { [opening.id]: dis }).addNode(opening.id, { [params]: dis });
1196
+ }
1197
+ }
1198
+ };
1199
+ return { defaultGraph, accessibleGraph, unitOpenings, addCoordinateOrdinalNode };
1200
+ };
1201
+
1202
+ // src/data/navigate/steps/createStepUtils.ts
1203
+ import { capitalize } from "lodash";
1204
+ import _intersectionBy from "lodash/intersectionBy";
1205
+
1206
+ // src/data/navigate/description/describe.ts
1207
+ var t = (template, locale, options) => {
1208
+ return template.replace(`{{intermediary}}`, options.intermediary ?? "").replace(`{{toward}}`, options.toward?.[locale] ?? "").replace(`{{landmark}}`, options.landmark?.[locale] ?? "");
1209
+ };
1210
+ var describeVerticalStep = (fromLevel, toLevel, intermediary) => {
1211
+ const dir = fromLevel.properties.ordinal < toLevel.properties.ordinal ? "up" : "down";
1212
+ const template = `Take the {{intermediary}} ${dir} to {{toward}}`;
693
1213
  return {
694
- projectId,
695
- queryClient,
696
- registerObserver,
697
- destroyObserver,
698
- destroyObservers,
699
- createFilterByTypeQueryOptions,
700
- createFindByIdQueryOptions,
701
- filterByType,
702
- findById
1214
+ template,
1215
+ text: t(template, "en", { intermediary, toward: toLevel.properties.name })
1216
+ };
1217
+ };
1218
+ var describeHorizontalStep = (intermediary, toward, landmark) => {
1219
+ const template = `Follow the path ${intermediary === "walkway" ? `along the walkway` : `through {{intermediary}}`} ${toward ? `toward {{toward}}` : ``} ${landmark ? `near {{landmark}}` : ``}`.trim();
1220
+ return {
1221
+ text: t(template, "en", { intermediary, toward, landmark }),
1222
+ template
703
1223
  };
704
1224
  };
705
1225
 
706
- // src/IndoorMap/IndoorMap.ts
707
- import {
708
- Map as Map2,
709
- TileLayer,
710
- LineString as LineString3,
711
- Coordinate as Coordinate4,
712
- GroupGLLayer,
713
- GLTFLayer
714
- } from "maptalks-gl";
715
- import "@maptalks/transcoders.draco";
716
- import TWEEN from "@tweenjs/tween.js";
717
- import _5 from "lodash";
1226
+ // src/data/navigate/steps/path/index.ts
1227
+ import _7 from "lodash";
1228
+
1229
+ // src/data/navigate/constants.ts
1230
+ var OBSTACLE_FEATURE_TYPES = [
1231
+ "kiosk"
1232
+ /* , "fixture" */
1233
+ ];
1234
+ var OBSTACLE_CATEGORIES = [
1235
+ "fixture.water",
1236
+ "fixture.stage",
1237
+ "nonpublic",
1238
+ "opentobelow",
1239
+ "elevator",
1240
+ "escalator",
1241
+ "stairs",
1242
+ "stairs.emergencyexit",
1243
+ "room",
1244
+ "unspecified",
1245
+ "structure",
1246
+ "brick",
1247
+ "concrete",
1248
+ "drywall",
1249
+ "glass",
1250
+ "wood",
1251
+ "column"
1252
+ ];
1253
+ var WALKABLE_CATEGORY = [
1254
+ "walkway",
1255
+ "parking",
1256
+ "room",
1257
+ "terrace",
1258
+ "unenclosedarea",
1259
+ "vegetation",
1260
+ "unspecified"
1261
+ ];
718
1262
 
719
- // ../../node_modules/@turf/helpers/dist/esm/index.js
1263
+ // node_modules/@turf/helpers/dist/esm/index.js
720
1264
  var earthRadius = 63710088e-1;
721
1265
  var factors = {
722
1266
  centimeters: earthRadius * 100,
@@ -803,26 +1347,1175 @@ function featureCollection(features, options = {}) {
803
1347
  if (options.id) {
804
1348
  fc.id = options.id;
805
1349
  }
806
- if (options.bbox) {
807
- fc.bbox = options.bbox;
1350
+ if (options.bbox) {
1351
+ fc.bbox = options.bbox;
1352
+ }
1353
+ fc.features = features;
1354
+ return fc;
1355
+ }
1356
+ function multiPoint(coordinates, properties, options = {}) {
1357
+ const geom = {
1358
+ type: "MultiPoint",
1359
+ coordinates
1360
+ };
1361
+ return feature(geom, properties, options);
1362
+ }
1363
+ function isNumber(num) {
1364
+ return !isNaN(num) && num !== null && !Array.isArray(num);
1365
+ }
1366
+ function isObject(input) {
1367
+ return input !== null && typeof input === "object" && !Array.isArray(input);
1368
+ }
1369
+
1370
+ // node_modules/@turf/invariant/dist/esm/index.js
1371
+ function getCoord(coord) {
1372
+ if (!coord) {
1373
+ throw new Error("coord is required");
1374
+ }
1375
+ if (!Array.isArray(coord)) {
1376
+ if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {
1377
+ return [...coord.geometry.coordinates];
1378
+ }
1379
+ if (coord.type === "Point") {
1380
+ return [...coord.coordinates];
1381
+ }
1382
+ }
1383
+ if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {
1384
+ return [...coord];
1385
+ }
1386
+ throw new Error("coord must be GeoJSON Point or an Array of numbers");
1387
+ }
1388
+ function getGeom(geojson) {
1389
+ if (geojson.type === "Feature") {
1390
+ return geojson.geometry;
1391
+ }
1392
+ return geojson;
1393
+ }
1394
+ function getType(geojson, _name) {
1395
+ if (geojson.type === "FeatureCollection") {
1396
+ return "FeatureCollection";
1397
+ }
1398
+ if (geojson.type === "GeometryCollection") {
1399
+ return "GeometryCollection";
1400
+ }
1401
+ if (geojson.type === "Feature" && geojson.geometry !== null) {
1402
+ return geojson.geometry.type;
1403
+ }
1404
+ return geojson.type;
1405
+ }
1406
+
1407
+ // src/data/navigate/steps/path/index.ts
1408
+ import difference from "@turf/difference";
1409
+ import envelope from "@turf/envelope";
1410
+ import booleanOverlap from "@turf/boolean-overlap";
1411
+ import booleanIntersects from "@turf/boolean-intersects";
1412
+
1413
+ // ../../node_modules/@turf/meta/dist/esm/index.js
1414
+ function coordEach(geojson, callback, excludeWrapCoord) {
1415
+ if (geojson === null) return;
1416
+ 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;
1417
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
1418
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
1419
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
1420
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
1421
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
1422
+ var multiFeatureIndex = 0;
1423
+ var geometryIndex = 0;
1424
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
1425
+ if (geometry === null) continue;
1426
+ coords = geometry.coordinates;
1427
+ var geomType = geometry.type;
1428
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
1429
+ switch (geomType) {
1430
+ case null:
1431
+ break;
1432
+ case "Point":
1433
+ if (callback(
1434
+ coords,
1435
+ coordIndex,
1436
+ featureIndex,
1437
+ multiFeatureIndex,
1438
+ geometryIndex
1439
+ ) === false)
1440
+ return false;
1441
+ coordIndex++;
1442
+ multiFeatureIndex++;
1443
+ break;
1444
+ case "LineString":
1445
+ case "MultiPoint":
1446
+ for (j = 0; j < coords.length; j++) {
1447
+ if (callback(
1448
+ coords[j],
1449
+ coordIndex,
1450
+ featureIndex,
1451
+ multiFeatureIndex,
1452
+ geometryIndex
1453
+ ) === false)
1454
+ return false;
1455
+ coordIndex++;
1456
+ if (geomType === "MultiPoint") multiFeatureIndex++;
1457
+ }
1458
+ if (geomType === "LineString") multiFeatureIndex++;
1459
+ break;
1460
+ case "Polygon":
1461
+ case "MultiLineString":
1462
+ for (j = 0; j < coords.length; j++) {
1463
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
1464
+ if (callback(
1465
+ coords[j][k],
1466
+ coordIndex,
1467
+ featureIndex,
1468
+ multiFeatureIndex,
1469
+ geometryIndex
1470
+ ) === false)
1471
+ return false;
1472
+ coordIndex++;
1473
+ }
1474
+ if (geomType === "MultiLineString") multiFeatureIndex++;
1475
+ if (geomType === "Polygon") geometryIndex++;
1476
+ }
1477
+ if (geomType === "Polygon") multiFeatureIndex++;
1478
+ break;
1479
+ case "MultiPolygon":
1480
+ for (j = 0; j < coords.length; j++) {
1481
+ geometryIndex = 0;
1482
+ for (k = 0; k < coords[j].length; k++) {
1483
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
1484
+ if (callback(
1485
+ coords[j][k][l],
1486
+ coordIndex,
1487
+ featureIndex,
1488
+ multiFeatureIndex,
1489
+ geometryIndex
1490
+ ) === false)
1491
+ return false;
1492
+ coordIndex++;
1493
+ }
1494
+ geometryIndex++;
1495
+ }
1496
+ multiFeatureIndex++;
1497
+ }
1498
+ break;
1499
+ case "GeometryCollection":
1500
+ for (j = 0; j < geometry.geometries.length; j++)
1501
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
1502
+ return false;
1503
+ break;
1504
+ default:
1505
+ throw new Error("Unknown Geometry Type");
1506
+ }
1507
+ }
1508
+ }
1509
+ }
1510
+
1511
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
1512
+ function bbox(geojson, options = {}) {
1513
+ if (geojson.bbox != null && true !== options.recompute) {
1514
+ return geojson.bbox;
1515
+ }
1516
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
1517
+ coordEach(geojson, (coord) => {
1518
+ if (result[0] > coord[0]) {
1519
+ result[0] = coord[0];
1520
+ }
1521
+ if (result[1] > coord[1]) {
1522
+ result[1] = coord[1];
1523
+ }
1524
+ if (result[2] < coord[0]) {
1525
+ result[2] = coord[0];
1526
+ }
1527
+ if (result[3] < coord[1]) {
1528
+ result[3] = coord[1];
1529
+ }
1530
+ });
1531
+ return result;
1532
+ }
1533
+ var index_default = bbox;
1534
+
1535
+ // src/data/navigate/steps/path/turf/shortestPath.ts
1536
+ import booleanPointInPolygon3 from "@turf/boolean-point-in-polygon";
1537
+ import distance3 from "@turf/distance";
1538
+ import scale from "@turf/transform-scale";
1539
+ import union from "@turf/union";
1540
+ import bboxPolygon from "@turf/bbox-polygon";
1541
+ import { cleanCoords } from "@turf/clean-coords";
1542
+ import PF from "pathfinding";
1543
+ import set3 from "lodash/set";
1544
+
1545
+ // src/data/navigate/steps/path/turf/stringPull.ts
1546
+ function stringPull(grid, path) {
1547
+ const isWalkable = (x, y) => grid.isInside(x, y) && grid.isWalkableAt(x, y);
1548
+ function hasLOS(a, b) {
1549
+ let x0 = a[0], y0 = a[1];
1550
+ const x1 = b[0], y1 = b[1];
1551
+ if (!isWalkable(x0, y0) || !isWalkable(x1, y1)) return false;
1552
+ const dx = Math.abs(x1 - x0);
1553
+ const dy = Math.abs(y1 - y0);
1554
+ const sx = x0 < x1 ? 1 : -1;
1555
+ const sy = y0 < y1 ? 1 : -1;
1556
+ let err = dx - dy;
1557
+ while (true) {
1558
+ if (!isWalkable(x0, y0)) return false;
1559
+ if (x0 === x1 && y0 === y1) break;
1560
+ const e2 = err * 2;
1561
+ let nx = x0;
1562
+ let ny = y0;
1563
+ let movedX = false;
1564
+ let movedY = false;
1565
+ if (e2 > -dy) {
1566
+ err -= dy;
1567
+ nx += sx;
1568
+ movedX = true;
1569
+ }
1570
+ if (e2 < dx) {
1571
+ err += dx;
1572
+ ny += sy;
1573
+ movedY = true;
1574
+ }
1575
+ if (movedX && movedY) {
1576
+ if (!isWalkable(nx, y0) || !isWalkable(x0, ny)) return false;
1577
+ }
1578
+ x0 = nx;
1579
+ y0 = ny;
1580
+ }
1581
+ return true;
1582
+ }
1583
+ if (path.length <= 2) return path;
1584
+ const out = [path[0]];
1585
+ let i = 0;
1586
+ while (i < path.length - 1) {
1587
+ let best = i + 1;
1588
+ for (let j = i + 2; j < path.length; j++) {
1589
+ if (hasLOS(path[i], path[j])) best = j;
1590
+ else break;
1591
+ }
1592
+ out.push(path[best]);
1593
+ i = best;
1594
+ }
1595
+ return out;
1596
+ }
1597
+
1598
+ // src/data/navigate/steps/path/turf/pruneSmallAngle.ts
1599
+ function pruneSmallAngles(path, minDeg = 10) {
1600
+ if (path.length <= 2) return path;
1601
+ const out = [path[0]];
1602
+ for (let i = 1; i < path.length - 1; i++) {
1603
+ const a = out.at(-1);
1604
+ const b = path[i];
1605
+ const c = path[i + 1];
1606
+ const abx = b[0] - a[0], aby = b[1] - a[1];
1607
+ const bcx = c[0] - b[0], bcy = c[1] - b[1];
1608
+ const dot = abx * bcx + aby * bcy;
1609
+ const ab = Math.hypot(abx, aby);
1610
+ const bc = Math.hypot(bcx, bcy);
1611
+ const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
1612
+ if (angle > minDeg) out.push(b);
1613
+ }
1614
+ out.push(path.at(-1));
1615
+ return out;
1616
+ }
1617
+
1618
+ // src/data/navigate/steps/path/turf/pruneShortSegments.ts
1619
+ function pruneShortSegments(path, minLen = 5) {
1620
+ const out = [path[0]];
1621
+ for (let i = 1; i < path.length; i++) {
1622
+ const [x0, y0] = out.at(-1);
1623
+ const [x1, y1] = path[i];
1624
+ if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
1625
+ out.push(path[i]);
1626
+ }
1627
+ }
1628
+ return out;
1629
+ }
1630
+
1631
+ // src/data/navigate/steps/path/turf/clearance.ts
1632
+ function buildClearanceGrid(matrix) {
1633
+ const h = matrix.length;
1634
+ const w = matrix[0].length;
1635
+ const INF = 1e9;
1636
+ const dist = Array.from({ length: h }, () => Array(w).fill(INF));
1637
+ const q = [];
1638
+ for (let y = 0; y < h; y++) {
1639
+ for (let x = 0; x < w; x++) {
1640
+ if (matrix[y][x] === 1) {
1641
+ dist[y][x] = 0;
1642
+ q.push([x, y]);
1643
+ }
1644
+ }
1645
+ }
1646
+ const dirs = [
1647
+ [1, 0],
1648
+ [-1, 0],
1649
+ [0, 1],
1650
+ [0, -1],
1651
+ [1, 1],
1652
+ [1, -1],
1653
+ [-1, 1],
1654
+ [-1, -1]
1655
+ ];
1656
+ let qi = 0;
1657
+ while (qi < q.length) {
1658
+ const [x, y] = q[qi++];
1659
+ const d0 = dist[y][x];
1660
+ for (const [dx, dy] of dirs) {
1661
+ const nx = x + dx, ny = y + dy;
1662
+ if (nx < 0 || ny < 0 || nx >= w || ny >= h) continue;
1663
+ const nd = d0 + 1;
1664
+ if (nd < dist[ny][nx]) {
1665
+ dist[ny][nx] = nd;
1666
+ q.push([nx, ny]);
1667
+ }
1668
+ }
1669
+ }
1670
+ return dist;
1671
+ }
1672
+ function snapPointToClearancePeak(p, clearance, isWalkableCell, radius = 4) {
1673
+ const [px, py] = p;
1674
+ let best = p;
1675
+ let bestScore = clearance[py]?.[px] ?? -Infinity;
1676
+ for (let dy = -radius; dy <= radius; dy++) {
1677
+ for (let dx = -radius; dx <= radius; dx++) {
1678
+ const x = px + dx;
1679
+ const y = py + dy;
1680
+ if (!isWalkableCell(x, y)) continue;
1681
+ const score = clearance[y][x];
1682
+ const penalty = Math.hypot(dx, dy) * 5e-3;
1683
+ const finalScore = score - penalty;
1684
+ if (finalScore > bestScore) {
1685
+ bestScore = finalScore;
1686
+ best = [x, y];
1687
+ }
1688
+ }
1689
+ }
1690
+ return best;
1691
+ }
1692
+ function centerlineSnapPath(path, clearance, isWalkableCell, radius = 4) {
1693
+ const snapped = path.map((p) => snapPointToClearancePeak(p, clearance, isWalkableCell, radius));
1694
+ return snapped;
1695
+ }
1696
+
1697
+ // src/data/navigate/steps/path/turf/shortestPath.ts
1698
+ function shortestPath(start, end, options) {
1699
+ options = options || {};
1700
+ if (!isObject(options)) throw new Error("options is invalid");
1701
+ let resolution = options.resolution;
1702
+ const smoothenPath = options.smoothenPath;
1703
+ let obstacles = options.obstacles || featureCollection([]);
1704
+ if (!start) throw new Error("start is required");
1705
+ if (!end) throw new Error("end is required");
1706
+ if (resolution && !isNumber(resolution) || resolution <= 0)
1707
+ throw new Error("options.resolution must be a number, greater than 0");
1708
+ const startCoord = getCoord(start);
1709
+ const endCoord = getCoord(end);
1710
+ start = point(startCoord);
1711
+ end = point(endCoord);
1712
+ switch (getType(obstacles)) {
1713
+ case "FeatureCollection":
1714
+ if (obstacles.features.length === 0)
1715
+ return lineString([startCoord, endCoord]);
1716
+ break;
1717
+ case "Polygon":
1718
+ obstacles = featureCollection([feature(getGeom(obstacles))]);
1719
+ break;
1720
+ default:
1721
+ throw new Error("invalid obstacles");
1722
+ }
1723
+ const collection = obstacles;
1724
+ collection.features.push(start, end);
1725
+ const box = index_default(scale(bboxPolygon(index_default(collection)), 1.15));
1726
+ if (!resolution) {
1727
+ const width = distance3([box[0], box[1]], [box[2], box[1]], options);
1728
+ resolution = width / 100;
1729
+ }
1730
+ collection.features.pop();
1731
+ collection.features.pop();
1732
+ const [west, south, east, north] = box;
1733
+ const xFraction = resolution / distance3([west, south], [east, south], options);
1734
+ const cellWidth = xFraction * (east - west);
1735
+ const yFraction = resolution / distance3([west, south], [west, north], options);
1736
+ const cellHeight = yFraction * (north - south);
1737
+ const bboxHorizontalSide = east - west;
1738
+ const bboxVerticalSide = north - south;
1739
+ const columns = Math.floor(bboxHorizontalSide / cellWidth);
1740
+ const rows = Math.floor(bboxVerticalSide / cellHeight);
1741
+ const deltaX = (bboxHorizontalSide - columns * cellWidth) / 2;
1742
+ const deltaY = (bboxVerticalSide - rows * cellHeight) / 2;
1743
+ let closestToStart = null, closestToEnd = null, minDistStart = Infinity, minDistEnd = Infinity, currentY = north - deltaY, currentX = west + deltaX, row = 0, column = 0, distStart, distEnd, pt, isInsideObstacle;
1744
+ const roundLoopY = Math.ceil((currentY - south) / cellHeight);
1745
+ const roundLoopX = Math.ceil((east - currentX) / cellWidth);
1746
+ let totalRounds = roundLoopX * roundLoopY;
1747
+ const pointMatrix = [];
1748
+ const matrix = [];
1749
+ const obstacleTotal = collection.features.length;
1750
+ const obstacleFeatures = collection.features;
1751
+ let combinedObstacle = obstacleFeatures[0];
1752
+ let obstacleIndex = 0;
1753
+ for (obstacleIndex = 0; obstacleIndex < obstacleTotal; obstacleIndex++) {
1754
+ const nextObstacleFeature = obstacleFeatures[obstacleIndex + 1];
1755
+ if (!nextObstacleFeature) continue;
1756
+ try {
1757
+ combinedObstacle = union(
1758
+ featureCollection([combinedObstacle, nextObstacleFeature])
1759
+ );
1760
+ } catch (e) {
1761
+ console.log(e);
1762
+ }
1763
+ }
1764
+ while (totalRounds--) {
1765
+ pt = point([currentX, currentY]);
1766
+ isInsideObstacle = booleanPointInPolygon3(pt, combinedObstacle);
1767
+ set3(matrix, `[${row}][${column}]`, isInsideObstacle ? 1 : 0);
1768
+ set3(pointMatrix, `[${row}][${column}]`, `${currentX}|${currentY}`);
1769
+ distStart = distance3(pt, start);
1770
+ if (!isInsideObstacle && distStart < minDistStart) {
1771
+ minDistStart = distStart;
1772
+ closestToStart = { x: column, y: row };
1773
+ }
1774
+ distEnd = distance3(pt, end);
1775
+ if (!isInsideObstacle && distEnd < minDistEnd) {
1776
+ minDistEnd = distEnd;
1777
+ closestToEnd = { x: column, y: row };
1778
+ }
1779
+ if (column < roundLoopX) {
1780
+ currentX += cellWidth;
1781
+ column++;
1782
+ continue;
1783
+ }
1784
+ if (row < roundLoopY) {
1785
+ currentY -= cellHeight;
1786
+ currentX = west + deltaX;
1787
+ column = 0;
1788
+ row++;
1789
+ }
1790
+ }
1791
+ const finder = new PF.AStarFinder({
1792
+ allowDiagonal: true,
1793
+ dontCrossCorners: true,
1794
+ heuristic: PF.Heuristic.euclidean
1795
+ });
1796
+ const grid = new PF.Grid(matrix);
1797
+ const startOnMatrix = [closestToStart.x, closestToStart.y];
1798
+ const endOnMatrix = [closestToEnd.x, closestToEnd.y];
1799
+ let result = finder.findPath(...startOnMatrix, ...endOnMatrix, grid);
1800
+ if (result.length > 0) {
1801
+ result = stringPull(grid, result);
1802
+ const clearanceGrid = buildClearanceGrid(matrix);
1803
+ const isWalkable = (x, y) => grid.isInside(x, y) && grid.isWalkableAt(x, y);
1804
+ result = centerlineSnapPath(result, clearanceGrid, isWalkable);
1805
+ result = stringPull(grid, result);
1806
+ result = pruneSmallAngles(result);
1807
+ result = pruneShortSegments(result);
1808
+ }
1809
+ result.pop();
1810
+ result.shift();
1811
+ const path = [startCoord];
1812
+ result.forEach((coord) => {
1813
+ const coords = pointMatrix[coord[1]][coord[0]].split("|");
1814
+ path.push([+coords[0], +coords[1]]);
1815
+ });
1816
+ path.push(endCoord);
1817
+ return cleanCoords(lineString(path));
1818
+ }
1819
+ var shortestPath_default = shortestPath;
1820
+
1821
+ // src/data/navigate/steps/path/index.ts
1822
+ var createStepPathUtils = (options) => {
1823
+ const resolution = options.resolution ?? 88e-5;
1824
+ const { units = [], kiosks = [], fixtures = [] } = options.data;
1825
+ const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
1826
+ const filterObstaclesByOrdinal = (levelId) => {
1827
+ return possibleObstacleFeatures.filter(({ feature_type, properties, geometry }) => {
1828
+ return properties.level_id === levelId && ["Polygon", "MultiPolygon"].includes(geometry.type) && (OBSTACLE_FEATURE_TYPES.includes(feature_type) || "category" in properties && OBSTACLE_CATEGORIES.includes(properties.category));
1829
+ });
1830
+ };
1831
+ const findObstaclesFromWalkway = (intermediaryUnit, exceptionIds = []) => {
1832
+ const result = featureCollection([]);
1833
+ if (!intermediaryUnit) return result;
1834
+ const walkwayLevelId = intermediaryUnit.properties.level_id;
1835
+ const obstacleOnLevel = filterObstaclesByOrdinal(walkwayLevelId).filter(
1836
+ (obstacle) => !exceptionIds.includes(obstacle.id)
1837
+ );
1838
+ const relatedObstacleWithIntermediary = obstacleOnLevel.reduce(
1839
+ (obstacles, feature2) => {
1840
+ if (
1841
+ // Prevent detecting itself as an obstacle
1842
+ // Ex. Unable to draw a line to amenity located with in a room as room is also consider as obstacle
1843
+ feature2.id !== intermediaryUnit.id && (booleanOverlap(intermediaryUnit, feature2) || booleanIntersects(intermediaryUnit, feature2))
1844
+ ) {
1845
+ const polygons = getType(feature2) === "Polygon" ? [polygon(feature2.geometry.coordinates, { id: feature2.id })] : feature2.geometry.coordinates.map((ring) => polygon(ring, { id: feature2.id }));
1846
+ obstacles.push(...polygons);
1847
+ }
1848
+ return obstacles;
1849
+ },
1850
+ []
1851
+ );
1852
+ const intermediaryExtends = envelope(intermediaryUnit);
1853
+ const walkwayPerimeter = difference(
1854
+ featureCollection([intermediaryExtends, intermediaryUnit])
1855
+ );
1856
+ result.features.push(...relatedObstacleWithIntermediary, walkwayPerimeter);
1857
+ return result;
1858
+ };
1859
+ const findPathOnArea = (originPoint, destinationPoint, options2) => {
1860
+ const { obstacles = featureCollection([]), resolution: resolution2, properties } = options2 || {};
1861
+ const stepPath = shortestPath_default(originPoint, destinationPoint, {
1862
+ obstacles,
1863
+ smoothenPath: false,
1864
+ resolution: resolution2
1865
+ });
1866
+ stepPath.properties = properties;
1867
+ return stepPath;
1868
+ };
1869
+ const findStepPath = (from, to, intermediaries) => {
1870
+ const t0 = performance.now();
1871
+ const relatedWalkablePlatform = intermediaries.find(
1872
+ (feature2) => WALKABLE_CATEGORY.includes(feature2.properties.category)
1873
+ );
1874
+ const exceptionFeatureIds = [];
1875
+ const obstacles = findObstaclesFromWalkway(
1876
+ relatedWalkablePlatform,
1877
+ _7.compact(exceptionFeatureIds)
1878
+ );
1879
+ const line = findPathOnArea(from, to, {
1880
+ resolution,
1881
+ obstacles
1882
+ });
1883
+ return line.geometry.coordinates;
1884
+ };
1885
+ return {
1886
+ findStepPath
1887
+ };
1888
+ };
1889
+
1890
+ // src/data/navigate/steps/utils/combineWalkwaySteps.ts
1891
+ import uniq from "lodash/uniq";
1892
+ var combineWalkwaySteps = (steps) => {
1893
+ let result = [];
1894
+ for (let i = 0; i < steps.length; i++) {
1895
+ const thisStep = steps[i];
1896
+ if (i === steps.length - 1) {
1897
+ result.push(thisStep);
1898
+ continue;
1899
+ }
1900
+ const nextStep = steps[i + 1];
1901
+ if (thisStep.intermediaryCategory === "walkway" && nextStep.intermediaryCategory === "walkway" && thisStep.from.source.type === "opening" && nextStep.from.source.type === "opening") {
1902
+ result.push({
1903
+ from: thisStep.from,
1904
+ to: nextStep.to,
1905
+ levelIds: uniq([...thisStep.levelIds, ...nextStep.levelIds]),
1906
+ ordinals: uniq([...thisStep.ordinals, ...nextStep.ordinals]),
1907
+ intermediaryCategory: "walkway",
1908
+ description: nextStep.description,
1909
+ path: [
1910
+ ...thisStep.path,
1911
+ ...nextStep.path
1912
+ ]
1913
+ });
1914
+ i++;
1915
+ } else {
1916
+ result.push(thisStep);
1917
+ }
1918
+ }
1919
+ return result;
1920
+ };
1921
+
1922
+ // src/data/navigate/steps/createStepUtils.ts
1923
+ var createStepUtils = (options) => {
1924
+ const { data: { units, relationships }, findByIdSync } = options;
1925
+ const stepPathUtils = createStepPathUtils({ ...options, resolution: 88e-5 });
1926
+ const findUnitBetweenOpenings = (originId, destinationId) => {
1927
+ const origin = findByIdSync(originId);
1928
+ const destination = findByIdSync(destinationId);
1929
+ const matchedOne = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(origin.id));
1930
+ const matchOneUnits = matchedOne ? [matchedOne.properties.origin, matchedOne.properties.destination] : [];
1931
+ const matchedTwo = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(destination.id));
1932
+ const matchTwoUnits = matchedTwo ? [matchedTwo.properties.origin, matchedTwo.properties.destination] : [];
1933
+ const unitIds = _intersectionBy(matchOneUnits, matchTwoUnits, "id");
1934
+ return unitIds.map(({ id }) => findByIdSync(id));
1935
+ };
1936
+ const findHorizontalIntermediary = (from, to) => {
1937
+ if (from.source.type !== "opening") {
1938
+ const unit = findContainingUnitAtPoint(from.point, from.levelId, units);
1939
+ return unit ? [unit] : [];
1940
+ }
1941
+ if (to.source.type !== "opening") {
1942
+ const unit = findContainingUnitAtPoint(to.point, to.levelId, units);
1943
+ return unit ? [unit] : [];
1944
+ }
1945
+ return findUnitBetweenOpenings(from.source.id, to.source.id);
1946
+ };
1947
+ const findVerticalIntermediary = (from, to) => {
1948
+ const firstOpeningId = from.source.id;
1949
+ const secondOpeningId = to.source.id;
1950
+ const relationship = relationships.find((rel) => {
1951
+ return rel.properties.origin?.id === firstOpeningId && rel.properties.destination?.id === secondOpeningId || rel.properties.origin?.id === secondOpeningId && rel.properties.destination?.id === firstOpeningId;
1952
+ });
1953
+ const intermediaryTypeAndId = relationship.properties.intermediary;
1954
+ return intermediaryTypeAndId.map(({ id }) => findByIdSync(id));
1955
+ };
1956
+ const formatCategoryLabel = (category) => {
1957
+ return capitalize(category);
1958
+ };
1959
+ const getNextStepIntermediary = (from, to, intermediary) => {
1960
+ if (to.type === "end") return to.name;
1961
+ const intermediaryIds = intermediary.map((int) => int.id);
1962
+ const relationship = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(to.source.id));
1963
+ if (!relationship) return to.name;
1964
+ const candidates = [relationship.properties.origin.id, relationship.properties.destination.id];
1965
+ const nextUnitId = candidates.filter((id) => !intermediaryIds.includes(id))[0];
1966
+ if (!nextUnitId) return to.name;
1967
+ const nextUnit = findByIdSync(nextUnitId);
1968
+ return { en: formatCategoryLabel(`${nextUnit.properties.category}`) };
1969
+ };
1970
+ const createHorizontalStep = (from, to) => {
1971
+ const intermediary = findHorizontalIntermediary(from, to);
1972
+ const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
1973
+ const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
1974
+ const toward = getNextStepIntermediary(from, to, intermediary);
1975
+ const landmark = to.hint?.kind === "landmark" ? to.hint.name : null;
1976
+ const path = stepPathUtils.findStepPath(from.point, to.point, intermediary);
1977
+ const step = {
1978
+ from,
1979
+ to,
1980
+ levelIds: [from.levelId],
1981
+ ordinals: [from.ordinal],
1982
+ intermediaryCategory,
1983
+ description: describeHorizontalStep(intermediaryCategory, toward, landmark),
1984
+ path: path.map((coord) => [...coord, from.ordinal * 9])
1985
+ };
1986
+ return step;
1987
+ };
1988
+ const createVerticalStep = (from, to) => {
1989
+ const intermediary = findVerticalIntermediary(from, to);
1990
+ const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
1991
+ const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
1992
+ const fromLevel = findByIdSync(from.levelId);
1993
+ const toLevel = findByIdSync(to.levelId);
1994
+ return {
1995
+ from,
1996
+ to,
1997
+ levelIds: [from.levelId, to.levelId],
1998
+ ordinals: [from.ordinal, to.ordinal],
1999
+ intermediaryCategory,
2000
+ description: describeVerticalStep(fromLevel, toLevel, intermediaryCategory),
2001
+ path: [
2002
+ [...from.point, from.ordinal * 9],
2003
+ [...to.point, to.ordinal * 9]
2004
+ ]
2005
+ };
2006
+ };
2007
+ const isVertical = (from, to) => {
2008
+ const fromLevel = findByIdSync(from.levelId);
2009
+ const toLevel = findByIdSync(to.levelId);
2010
+ return !!fromLevel && !!toLevel && fromLevel.properties.ordinal !== toLevel.properties.ordinal;
2011
+ };
2012
+ const toSteps = (waypoints) => {
2013
+ let steps = [];
2014
+ const t0_allSteps = performance.now();
2015
+ for (let i = 0; i < waypoints.length - 1; i++) {
2016
+ const from = waypoints[i];
2017
+ const to = waypoints[i + 1];
2018
+ const t0 = performance.now();
2019
+ const step = isVertical(from, to) ? createVerticalStep(from, to) : createHorizontalStep(from, to);
2020
+ steps.push(step);
2021
+ const t1 = performance.now();
2022
+ trace("nav", ` \u2502 \u251C\u2500 #${i} ${from.id.padEnd(25)} \u2192 ${`(${step.intermediaryCategory})`.padEnd(12)} \u2192 ${to.id}`, t1 - t0);
2023
+ trace("nav", ` \u2502 \u2502 ${step.description.text}`, void 0, "#bada55");
2024
+ }
2025
+ const simplifySteps = combineWalkwaySteps(steps);
2026
+ const t1_allSteps = performance.now();
2027
+ trace("nav", " \u2502 \u2514\u2500 Total ", t1_allSteps - t0_allSteps);
2028
+ return simplifySteps;
2029
+ };
2030
+ return {
2031
+ toSteps
2032
+ };
2033
+ };
2034
+
2035
+ // src/data/navigate/utils/timeDistance.ts
2036
+ import calculateLength from "@turf/length";
2037
+ var WALKING_SPEED = 1.4;
2038
+ var calculatePathLength = (feature2) => calculateLength(feature2, { units: "kilometers" }) * 1e3;
2039
+ var calculateTravelingDuration = (distance5) => {
2040
+ const duration = distance5 / WALKING_SPEED;
2041
+ const minutes = Math.round(duration / 60);
2042
+ return minutes > 0 ? minutes : 1;
2043
+ };
2044
+ var calculateTotalDistance = (steps = []) => {
2045
+ return steps.reduce((acc, { path }) => acc + calculatePathLength(lineString(path)), 0);
2046
+ };
2047
+ var calculateRoundedDistance = (distance5) => {
2048
+ return Math.round(distance5 - distance5 % 25);
2049
+ };
2050
+
2051
+ // src/data/navigate/type-guard.ts
2052
+ function isCoordinateOrdinalString(id) {
2053
+ return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
2054
+ }
2055
+
2056
+ // src/data/navigate/utils/createFindByIdSync.ts
2057
+ var createFindByIdSync = (data) => {
2058
+ const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
2059
+ const featureById = /* @__PURE__ */ new Map();
2060
+ const entries = [
2061
+ ...amenities,
2062
+ ...anchors,
2063
+ ...fixtures,
2064
+ ...levels,
2065
+ ...kiosks,
2066
+ ...relationships,
2067
+ ...occupants,
2068
+ ...openings,
2069
+ ...units
2070
+ ];
2071
+ for (const f of entries) featureById.set(f.id, f);
2072
+ const findByIdSync = (id) => {
2073
+ return featureById.get(id);
2074
+ };
2075
+ return { findByIdSync };
2076
+ };
2077
+
2078
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2079
+ import { center as center6 } from "@turf/center";
2080
+
2081
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2082
+ import { center as center3 } from "@turf/center";
2083
+
2084
+ // src/data/navigate/waypoint/featureIdGuard.ts
2085
+ var isOccupant = (id) => !!id && id.startsWith("occupant-");
2086
+ var isUnit = (id) => !!id && id.startsWith("unit-");
2087
+ var isKiosk = (id) => !!id && id.startsWith("kiosk-");
2088
+ var isOpening = (id) => !!id && id.startsWith("opening-");
2089
+
2090
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2091
+ var extractEndPoint = (path, options) => {
2092
+ const { findByIdSync } = options;
2093
+ const [c, b, a] = path.slice(-3);
2094
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2095
+ const occ = findByIdSync(a);
2096
+ const opening = findByIdSync(c);
2097
+ const level = findByIdSync(opening.properties.level_id);
2098
+ return [
2099
+ {
2100
+ id: occ.id,
2101
+ type: "end",
2102
+ name: occ.properties.name,
2103
+ point: center3(opening).geometry.coordinates,
2104
+ levelId: opening.properties.level_id,
2105
+ ordinal: level.properties.ordinal,
2106
+ source: { type: "opening", id: opening.id }
2107
+ },
2108
+ path.slice(0, -3)
2109
+ ];
2110
+ }
2111
+ if (isOccupant(a) && isKiosk(b)) {
2112
+ const occ = findByIdSync(a);
2113
+ const kiosk = findByIdSync(b);
2114
+ const level = findByIdSync(kiosk.properties.level_id);
2115
+ return [
2116
+ {
2117
+ id: occ.id,
2118
+ type: "end",
2119
+ name: occ.properties.name,
2120
+ point: center3(kiosk).geometry.coordinates,
2121
+ levelId: kiosk.properties.level_id,
2122
+ ordinal: level.properties.ordinal,
2123
+ source: { type: "kiosk", id: kiosk.id }
2124
+ },
2125
+ path.slice(0, -2)
2126
+ ];
2127
+ }
2128
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2129
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2130
+ const opening = findByIdSync(b);
2131
+ return [
2132
+ {
2133
+ id: a,
2134
+ type: "end",
2135
+ name: { en: a },
2136
+ point: [lng, lat],
2137
+ levelId: opening.properties.level_id,
2138
+ ordinal,
2139
+ source: { type: "coordinate", raw: a }
2140
+ },
2141
+ path.slice(0, -1)
2142
+ ];
2143
+ }
2144
+ return [null, path];
2145
+ };
2146
+
2147
+ // src/data/navigate/waypoint/extractStartWaypoint.ts
2148
+ import { center as center4 } from "@turf/center";
2149
+ var extractStartPoint = (path, options) => {
2150
+ const { findByIdSync } = options;
2151
+ const [a, b, c] = path;
2152
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2153
+ const occ = findByIdSync(a);
2154
+ const opening = findByIdSync(c);
2155
+ const level = findByIdSync(opening.properties.level_id);
2156
+ return [
2157
+ {
2158
+ id: occ.id,
2159
+ type: "start",
2160
+ name: occ.properties.name,
2161
+ point: center4(opening).geometry.coordinates,
2162
+ levelId: opening.properties.level_id,
2163
+ ordinal: level.properties.ordinal,
2164
+ source: { type: "opening", id: opening.id }
2165
+ },
2166
+ path.slice(3)
2167
+ ];
2168
+ }
2169
+ if (isOccupant(a) && isKiosk(b)) {
2170
+ const occ = findByIdSync(a);
2171
+ const kiosk = findByIdSync(b);
2172
+ const level = findByIdSync(kiosk.properties.level_id);
2173
+ return [
2174
+ {
2175
+ id: occ.id,
2176
+ type: "start",
2177
+ name: occ.properties.name,
2178
+ point: center4(kiosk).geometry.coordinates,
2179
+ levelId: kiosk.properties.level_id,
2180
+ ordinal: level.properties.ordinal,
2181
+ source: { type: "kiosk", id: kiosk.id }
2182
+ },
2183
+ path.slice(2)
2184
+ ];
2185
+ }
2186
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2187
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2188
+ const opening = findByIdSync(b);
2189
+ return [
2190
+ {
2191
+ id: a,
2192
+ type: "start",
2193
+ name: { en: a },
2194
+ point: [lng, lat],
2195
+ levelId: opening.properties.level_id,
2196
+ ordinal,
2197
+ source: { type: "coordinate", raw: a }
2198
+ },
2199
+ path.slice(1)
2200
+ ];
2201
+ }
2202
+ return [null, path];
2203
+ };
2204
+
2205
+ // src/data/navigate/landmark/createLandmarkUtils.ts
2206
+ import { center as center5 } from "@turf/center";
2207
+ import distance4 from "@turf/distance";
2208
+ var NEARBY_DISTANCE = 30;
2209
+ var createLandmarkUtils = (options) => {
2210
+ const { data, findByIdSync } = options;
2211
+ const { occupants = [] } = data;
2212
+ const occupantToLandmark = (occupant) => {
2213
+ const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
2214
+ const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
2215
+ const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
2216
+ const level = findByIdSync(location.properties.level_id);
2217
+ return {
2218
+ name: occupant.properties.name,
2219
+ point: center5(location.geometry).geometry.coordinates,
2220
+ level_id: location.properties.level_id,
2221
+ is_priority: occupant.properties.is_landmark,
2222
+ ordinal: level.properties.ordinal
2223
+ };
2224
+ };
2225
+ const landmarks = [
2226
+ ...occupants.map(occupantToLandmark)
2227
+ ];
2228
+ const findNearbyLandmarks = (point2, levelId) => {
2229
+ if (point2 === null || levelId === null) return [];
2230
+ return landmarks.map((landmark) => {
2231
+ const landmarkAndDistance = {
2232
+ landmark,
2233
+ d: distance4(point2, landmark.point, { units: "meters" })
2234
+ };
2235
+ return landmarkAndDistance;
2236
+ }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
2237
+ const aPriority = a.landmark.is_priority ? 0 : 1;
2238
+ const bPriority = b.landmark.is_priority ? 0 : 1;
2239
+ if (aPriority !== bPriority) return aPriority - bPriority;
2240
+ return a.d - b.d;
2241
+ }).map(({ landmark }) => landmark);
2242
+ };
2243
+ const findNearestLandmark = (point2, levelId) => {
2244
+ const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
2245
+ const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
2246
+ return nearestLandmark;
2247
+ };
2248
+ return { findNearbyLandmarks, findNearestLandmark };
2249
+ };
2250
+
2251
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2252
+ var createWaypointUtils = (options) => {
2253
+ const { findByIdSync } = options;
2254
+ const landmarkUtils = createLandmarkUtils(options);
2255
+ const toWaypoints = (path) => {
2256
+ const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2257
+ const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2258
+ const waypoints = middlePoints.map((openingId) => {
2259
+ const opening = findByIdSync(openingId);
2260
+ const level = findByIdSync(opening.properties.level_id);
2261
+ const coordinates = center6(opening).geometry.coordinates;
2262
+ const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2263
+ return {
2264
+ id: `${opening.properties.level_id}:${openingId}`,
2265
+ type: "between",
2266
+ point: coordinates,
2267
+ name: null,
2268
+ levelId: opening.properties.level_id,
2269
+ ordinal: level.properties.ordinal,
2270
+ hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2271
+ source: { type: "opening", id: opening.id }
2272
+ };
2273
+ });
2274
+ return [startPoint, ...waypoints, endPoint];
2275
+ };
2276
+ return { toWaypoints };
2277
+ };
2278
+
2279
+ // src/data/navigate/getNavigateClient.ts
2280
+ var getNavigateClient = (options) => {
2281
+ const { data } = options;
2282
+ const { levels, units } = data;
2283
+ trace("nav", "\u2713 prepare");
2284
+ const t0 = performance.now();
2285
+ trace("nav", " \u251C\u2500 createGraph (dijkstra)");
2286
+ const { defaultGraph, accessibleGraph, addCoordinateOrdinalNode } = prepareGraph({ data });
2287
+ const t1 = performance.now();
2288
+ trace("nav", " \u2502 \u2514\u2500 Total ", t1 - t0);
2289
+ const t2 = performance.now();
2290
+ const { findByIdSync } = createFindByIdSync(data);
2291
+ const t3 = performance.now();
2292
+ trace("nav", " \u2514\u2500 findByIdSync", t3 - t2);
2293
+ const findCoordinateOrdinalUnit = (params) => {
2294
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(params);
2295
+ const levelIdsWithOrdinal = levels.filter((level) => level.properties.ordinal === ordinal).map((level) => level.id);
2296
+ const unit = units.find((unit2) => levelIdsWithOrdinal.includes(unit2.properties.level_id) && booleanPointInPolygon4([lat, lng], unit2));
2297
+ return unit;
2298
+ };
2299
+ const stepUtils = createStepUtils({ ...options, findByIdSync });
2300
+ const waypointUtils = createWaypointUtils({ ...options, findByIdSync });
2301
+ const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
2302
+ if (!routeOriginParam || !routeDestinationParam) return null;
2303
+ const graph = options2?.mode === "accessible" ? accessibleGraph : defaultGraph;
2304
+ if (isCoordinateOrdinalString(routeOriginParam)) {
2305
+ const walkwayUnit = findCoordinateOrdinalUnit(routeOriginParam);
2306
+ addCoordinateOrdinalNode(routeOriginParam, walkwayUnit);
2307
+ }
2308
+ if (isCoordinateOrdinalString(routeDestinationParam)) {
2309
+ const walkwayUnit = findCoordinateOrdinalUnit(routeDestinationParam);
2310
+ addCoordinateOrdinalNode(routeDestinationParam, walkwayUnit);
2311
+ }
2312
+ try {
2313
+ trace("nav", "\u2713 findRoute", 0);
2314
+ const t02 = performance.now();
2315
+ const path = graph.path(routeOriginParam, routeDestinationParam);
2316
+ const t12 = performance.now();
2317
+ trace("nav", " \u251C\u2500 path (dijkstra)", t12 - t02);
2318
+ const waypoints = waypointUtils.toWaypoints(path);
2319
+ const t22 = performance.now();
2320
+ trace("nav", " \u251C\u2500 toWaypoints", t22 - t12);
2321
+ trace("nav", " \u251C\u2500 toSteps", 0);
2322
+ const steps = stepUtils.toSteps(waypoints);
2323
+ const t32 = performance.now();
2324
+ const totalDistance = calculateTotalDistance(steps);
2325
+ const roundedDistance = calculateRoundedDistance(totalDistance);
2326
+ const duration = calculateTravelingDuration(totalDistance);
2327
+ const t4 = performance.now();
2328
+ trace("nav", " \u2514\u2500 postProcess", t4 - t32);
2329
+ return {
2330
+ distance: roundedDistance,
2331
+ duration,
2332
+ steps
2333
+ };
2334
+ } catch (error) {
2335
+ console.log(error);
2336
+ throw error;
2337
+ }
2338
+ };
2339
+ return {
2340
+ findRoute,
2341
+ findByIdSync
2342
+ };
2343
+ };
2344
+
2345
+ // src/data/getDataClient.ts
2346
+ var getDataClient = (options) => {
2347
+ let searchClient;
2348
+ let navigateClient;
2349
+ const observers = /* @__PURE__ */ new Map();
2350
+ const queryClient = options.queryClient ?? new QueryClient();
2351
+ const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
2352
+ if (!projectId)
2353
+ throw new Error(
2354
+ "Cannot create VenueDataClient. Reason: `projectId` is missing"
2355
+ );
2356
+ if (mode === "delivery" && !apiKey)
2357
+ throw new Error(
2358
+ "Cannot create VenueDataClient. Reason: `apiKey` is missing"
2359
+ );
2360
+ if (mode === "preview" && !previewToken)
2361
+ throw new Error(
2362
+ "Cannot create VenueDataClient. Reason: `previewToken` is missing"
2363
+ );
2364
+ const createDeliveryApiQueryOptions = (featureType) => ({
2365
+ queryKey: ["_deliveryapi", featureType],
2366
+ queryFn: () => safeFetchFeature(featureType, { mode, projectId, apiKey, previewToken, baseUrl })
2367
+ });
2368
+ const internalFilterByType = async (featureType) => {
2369
+ try {
2370
+ const features = await queryClient.ensureQueryData(createDeliveryApiQueryOptions(featureType));
2371
+ return features;
2372
+ } catch (error) {
2373
+ throw error;
2374
+ }
2375
+ };
2376
+ const internalFindById = async (id) => {
2377
+ if (id === null || id === void 0) return null;
2378
+ const featureType = id.slice(0, id.lastIndexOf("-"));
2379
+ const feature2 = await queryClient.ensureQueryData({
2380
+ queryKey: ["_deliveryapi", featureType, id],
2381
+ queryFn: async () => {
2382
+ const features = await internalFilterByType(featureType);
2383
+ const feature3 = features.find(
2384
+ (f) => f.id === id
2385
+ );
2386
+ return feature3 ?? null;
2387
+ }
2388
+ });
2389
+ return feature2;
2390
+ };
2391
+ const populator = createPopulator({ internalFindById, internalFilterByType });
2392
+ const registerObserver = (featureType, refetchInterval) => {
2393
+ if (observers.has(featureType)) {
2394
+ console.warn(`Observer for ${featureType} already exists`);
2395
+ const record = observers.get(featureType);
2396
+ return record.observer;
2397
+ }
2398
+ const options2 = createDeliveryApiQueryOptions(featureType);
2399
+ const observer = new QueryObserver(queryClient, {
2400
+ ...options2,
2401
+ refetchInterval
2402
+ });
2403
+ const unsubscribe = observer.subscribe(() => {
2404
+ console.log(`[venue-js] Listening to ${featureType} changes (interval = ${refetchInterval}ms)`);
2405
+ });
2406
+ observers.set(featureType, { observer, unsubscribe });
2407
+ return observer;
2408
+ };
2409
+ const destroyObserver = (featureType) => {
2410
+ const record = observers.get(featureType);
2411
+ if (!record) return;
2412
+ record.unsubscribe();
2413
+ observers.delete(featureType);
2414
+ };
2415
+ const destroyObservers = () => {
2416
+ observers.forEach(({ observer, unsubscribe }) => {
2417
+ unsubscribe();
2418
+ observer.destroy();
2419
+ });
2420
+ observers.clear();
2421
+ };
2422
+ const createFilterByTypeQueryOptions = (featureType, params = {}, options2 = {}) => ({
2423
+ queryKey: [featureType, "list", params],
2424
+ queryFn: async () => {
2425
+ const features = await internalFilterByType(featureType);
2426
+ const filters = params.filters ?? {};
2427
+ let result = features;
2428
+ if (params.filters) {
2429
+ result = features.filter((f) => matchFilters(f, filters));
2430
+ }
2431
+ return params.populate === true ? await Promise.all(result.map((f) => populator[featureType](f))) : result;
2432
+ },
2433
+ ...options2 ?? {}
2434
+ });
2435
+ const createFindByIdQueryOptions = (featureType, id, params = {}, options2 = {}) => ({
2436
+ queryKey: [featureType, "detail", id, params],
2437
+ queryFn: async () => {
2438
+ const feature2 = await internalFindById(id);
2439
+ return params.populate === true ? await populator[featureType](feature2) : Promise.resolve(feature2);
2440
+ },
2441
+ ...options2 ?? {}
2442
+ });
2443
+ async function filterByType(featureType, params) {
2444
+ const filterQueryOptions = createFilterByTypeQueryOptions(
2445
+ featureType,
2446
+ params
2447
+ );
2448
+ const features = await queryClient.ensureQueryData(filterQueryOptions);
2449
+ return params?.populate === true ? features : features;
2450
+ }
2451
+ async function findById(featureType, id, params) {
2452
+ const findQueryOptions = createFindByIdQueryOptions(
2453
+ featureType,
2454
+ id,
2455
+ params
2456
+ );
2457
+ const feature2 = await queryClient.ensureQueryData(findQueryOptions);
2458
+ return feature2;
808
2459
  }
809
- fc.features = features;
810
- return fc;
811
- }
812
- function multiPoint(coordinates, properties, options = {}) {
813
- const geom = {
814
- type: "MultiPoint",
815
- coordinates
2460
+ const searchFn = async (txt) => {
2461
+ if (!searchClient) {
2462
+ const [occupants, amenities] = await Promise.all([
2463
+ filterByType("occupant"),
2464
+ filterByType("amenity")
2465
+ ]);
2466
+ const haystack = { occupants, amenities };
2467
+ searchClient = getSearchClient(haystack);
2468
+ }
2469
+ return searchClient.search(txt);
816
2470
  };
817
- return feature(geom, properties, options);
818
- }
819
- function isNumber(num) {
820
- return !isNaN(num) && num !== null && !Array.isArray(num);
821
- }
2471
+ const navigateFn = async (origin, destination) => {
2472
+ if (!navigateClient) {
2473
+ const [levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors] = await Promise.all([
2474
+ filterByType("level"),
2475
+ filterByType("occupant"),
2476
+ filterByType("opening"),
2477
+ filterByType("relationship"),
2478
+ filterByType("unit"),
2479
+ filterByType("fixture"),
2480
+ filterByType("kiosk"),
2481
+ filterByType("amenity"),
2482
+ filterByType("anchor")
2483
+ ]);
2484
+ const haystack = { levels, occupants, openings, relationships, units, fixtures, kiosks, amenities, anchors };
2485
+ navigateClient = getNavigateClient({ data: haystack });
2486
+ }
2487
+ return navigateClient.findRoute(origin, destination);
2488
+ };
2489
+ return {
2490
+ projectId,
2491
+ queryClient,
2492
+ registerObserver,
2493
+ destroyObserver,
2494
+ destroyObservers,
2495
+ createFilterByTypeQueryOptions,
2496
+ createFindByIdQueryOptions,
2497
+ _internalFindById: internalFindById,
2498
+ filterByType,
2499
+ findById,
2500
+ search: searchFn,
2501
+ navigate: navigateFn
2502
+ };
2503
+ };
822
2504
 
823
2505
  // src/IndoorMap/IndoorMap.ts
824
- import turfDistance from "@turf/distance";
825
- import turfCenter3 from "@turf/center";
2506
+ import {
2507
+ Map as Map2,
2508
+ TileLayer,
2509
+ LineString as LineString3,
2510
+ Coordinate as Coordinate4,
2511
+ GroupGLLayer,
2512
+ GLTFLayer
2513
+ } from "maptalks-gl";
2514
+ import "@maptalks/transcoders.draco";
2515
+ import TWEEN from "@tweenjs/tween.js";
2516
+ import _13 from "lodash";
2517
+ import turfDistance2 from "@turf/distance";
2518
+ import turfCenter6 from "@turf/center";
826
2519
  import { PerspectiveCamera } from "three";
827
2520
  import { ThreeLayer as ThreeLayer5 } from "maptalks.three";
828
2521
 
@@ -901,7 +2594,7 @@ var VENUE_EVENTS = {
901
2594
  };
902
2595
 
903
2596
  // src/IndoorMap/utils/createElements.js
904
- import _4 from "lodash";
2597
+ import _12 from "lodash";
905
2598
  import {
906
2599
  Polygon,
907
2600
  MultiPolygon,
@@ -911,7 +2604,7 @@ import {
911
2604
  MultiLineString,
912
2605
  ui
913
2606
  } from "maptalks";
914
- import turfCenter from "@turf/center";
2607
+ import turfCenter4 from "@turf/center";
915
2608
  import turfBuffer from "@turf/buffer";
916
2609
  import {
917
2610
  TextureLoader as TextureLoader2,
@@ -931,7 +2624,7 @@ import {
931
2624
  SpriteMaterial,
932
2625
  Sprite
933
2626
  } from "three";
934
- import _ from "lodash";
2627
+ import _9 from "lodash";
935
2628
  var OPTIONS = {
936
2629
  altitude: 25,
937
2630
  scale: 15e-5,
@@ -964,7 +2657,7 @@ var Billboard = class extends BaseObject {
964
2657
  } = options;
965
2658
  this.properties = { ...properties };
966
2659
  this._createGroup();
967
- const divider = _.clamp(window.innerWidth / 375 / 1.75, 1, 1.7);
2660
+ const divider = _9.clamp(window.innerWidth / 375 / 1.75, 1, 1.7);
968
2661
  if (showLeg) {
969
2662
  const lineMaterial = new LineBasicMaterial({
970
2663
  color: legColor,
@@ -999,9 +2692,9 @@ var Billboard = class extends BaseObject {
999
2692
  });
1000
2693
  const z = layer.altitudeToVector3(altitude, altitude).x;
1001
2694
  const position = layer.coordinateToVector3(coordinate, z);
1002
- _.set(this.properties, "default.position", position);
1003
- _.set(this.properties, "default.altitude", altitude);
1004
- _.set(this.properties, "default.scale", scale3);
2695
+ _9.set(this.properties, "default.position", position);
2696
+ _9.set(this.properties, "default.altitude", altitude);
2697
+ _9.set(this.properties, "default.scale", scale3);
1005
2698
  this.getObject3d().position.copy(position);
1006
2699
  }
1007
2700
  setLineHeight(altitude) {
@@ -1017,7 +2710,7 @@ var Billboard = class extends BaseObject {
1017
2710
  // src/IndoorMap/object3d/SpriteMarker.ts
1018
2711
  import { BaseObject as BaseObject2 } from "maptalks.three";
1019
2712
  import { Sprite as Sprite2, SpriteMaterial as SpriteMaterial2 } from "three";
1020
- import _2 from "lodash";
2713
+ import _10 from "lodash";
1021
2714
  var DEFAULT_SCALE = 0.05;
1022
2715
  var DEFAULT_ALTITUDE = 0;
1023
2716
  var DEFAULT_ALPHATEST = 0.3;
@@ -1048,7 +2741,7 @@ var SpriteMarker = class extends BaseObject2 {
1048
2741
  this.properties = { ...properties };
1049
2742
  const modifiedAltitude = altitude + 2;
1050
2743
  this.#default = { options: { scale: scale3, altitude: modifiedAltitude }, material };
1051
- this.#highlight = _2.merge({}, DEFAULT_OPTIONS.highlight, highlight);
2744
+ this.#highlight = _10.merge({}, DEFAULT_OPTIONS.highlight, highlight);
1052
2745
  if (material && material instanceof SpriteMaterial2)
1053
2746
  material.alphaTest = alphaTest;
1054
2747
  const sprite = new Sprite2(material);
@@ -1057,7 +2750,7 @@ var SpriteMarker = class extends BaseObject2 {
1057
2750
  obj3d.add(sprite);
1058
2751
  const z = layer.altitudeToVector3(modifiedAltitude, modifiedAltitude).x;
1059
2752
  const position = layer.coordinateToVector3(coordinate, z);
1060
- _2.set(this.properties, "default.position", position);
2753
+ _10.set(this.properties, "default.position", position);
1061
2754
  this.getObject3d().position.copy(position);
1062
2755
  }
1063
2756
  // Different objects need to implement their own methods
@@ -1198,15 +2891,15 @@ var NavigationPath = class extends BaseObject3 {
1198
2891
  };
1199
2892
 
1200
2893
  // src/IndoorMap/utils/geometry.ts
1201
- import center from "@turf/center";
1202
- import _3 from "lodash";
2894
+ import center7 from "@turf/center";
2895
+ import _11 from "lodash";
1203
2896
  import turfLineOffset from "@turf/line-offset";
1204
2897
  var getCenterFromGeometry = (geometry) => {
1205
2898
  try {
1206
2899
  const { type = null, coordinates = null } = geometry;
1207
2900
  if (!type || !coordinates) return null;
1208
- const centerPoint = center(geometry);
1209
- return _3.get(centerPoint, "geometry.coordinates");
2901
+ const centerPoint = center7(geometry);
2902
+ return _11.get(centerPoint, "geometry.coordinates");
1210
2903
  } catch (error) {
1211
2904
  return null;
1212
2905
  }
@@ -1357,7 +3050,7 @@ var createWaterFixture = (feature2, style, options = {}) => {
1357
3050
  const { geometry, properties } = feature2;
1358
3051
  const { allowOverride, inheritFillColorToLine, zIndex } = options;
1359
3052
  const symbolStyle = { ...style };
1360
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3053
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1361
3054
  if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1362
3055
  return new GeometryType[geometry.type](geometry.coordinates, {
1363
3056
  properties: {
@@ -1373,7 +3066,7 @@ var createVegetationFixture = (feature2, style, options = {}) => {
1373
3066
  const { geometry, properties } = feature2;
1374
3067
  const { allowOverride, inheritFillColorToLine, zIndex } = options;
1375
3068
  const symbolStyle = { ...style };
1376
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3069
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1377
3070
  if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1378
3071
  return new GeometryType[geometry.type](geometry.coordinates, {
1379
3072
  properties: {
@@ -1390,8 +3083,8 @@ var createObstructionalFixture = (feature2, style = {}, options = {}) => {
1390
3083
  const { model3d } = properties;
1391
3084
  const { allowOverride, inheritFillColorToLine, zIndex } = options;
1392
3085
  const symbolStyle = { ...style };
1393
- if (!_4.isEmpty(model3d)) return;
1394
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3086
+ if (!_12.isEmpty(model3d)) return;
3087
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1395
3088
  if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1396
3089
  if (geometry.type === "LineString") {
1397
3090
  const polygon2 = createPolygonFromLineString(geometry);
@@ -1461,7 +3154,7 @@ var createPrincipalOpening = (feature2, style, options = {}) => {
1461
3154
  const { geometry, properties } = feature2;
1462
3155
  const { allowOverride, zIndex } = options;
1463
3156
  const symbolStyle = { ...style };
1464
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3157
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1465
3158
  try {
1466
3159
  return new LineString(geometry.coordinates, {
1467
3160
  properties: {
@@ -1478,7 +3171,7 @@ var createEmergencyExitOpening = (feature2, style, options = {}) => {
1478
3171
  const { geometry, properties } = feature2;
1479
3172
  const { allowOverride, zIndex } = options;
1480
3173
  const symbolStyle = { ...style };
1481
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3174
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1482
3175
  try {
1483
3176
  return new LineString(geometry.coordinates, {
1484
3177
  properties: {
@@ -1495,7 +3188,7 @@ var createPedestrianOpening = (feature2, style, options = {}) => {
1495
3188
  const { geometry, properties, id } = feature2;
1496
3189
  const { allowOverride, zIndex } = options;
1497
3190
  const symbolStyle = { ...style };
1498
- if (allowOverride) _4.merge(symbolStyle, properties.style);
3191
+ if (allowOverride) _12.merge(symbolStyle, properties.style);
1499
3192
  try {
1500
3193
  return new LineString(geometry.coordinates, {
1501
3194
  properties: {
@@ -1533,9 +3226,9 @@ var create3DMarker = (coordinates, options, material, threeLayer, markerProperti
1533
3226
  };
1534
3227
  var getExtrudeConfigByFeature = (baseExtrudeConfig, feature2 = {}) => {
1535
3228
  const { feature_type: featureType } = feature2;
1536
- const featureExtrudeConfig = _4.get(feature2, "properties.extrude");
1537
- const featureCategory = _4.get(feature2, "properties.category");
1538
- const baseFeatureExtrudeConfig = _4.get(
3229
+ const featureExtrudeConfig = _12.get(feature2, "properties.extrude");
3230
+ const featureCategory = _12.get(feature2, "properties.category");
3231
+ const baseFeatureExtrudeConfig = _12.get(
1539
3232
  baseExtrudeConfig,
1540
3233
  `${featureType}.${featureCategory || featureType}`
1541
3234
  );
@@ -1593,50 +3286,50 @@ var createStyledUIMarkerElement = ({
1593
3286
  var styledFeatureGenerator = (mapTheme) => {
1594
3287
  const getElementSymbol = (key) => {
1595
3288
  const [featureType] = key.split(".");
1596
- const featureTypeTheme = _4.get(mapTheme, `${featureType}.geometry.symbol`);
3289
+ const featureTypeTheme = _12.get(mapTheme, `${featureType}.geometry.symbol`);
1597
3290
  if (featureType === key) return featureTypeTheme;
1598
- const categoryTheme = _4.get(mapTheme, `${key}.geometry.symbol`);
1599
- return _4.merge({}, featureTypeTheme, categoryTheme);
3291
+ const categoryTheme = _12.get(mapTheme, `${key}.geometry.symbol`);
3292
+ return _12.merge({}, featureTypeTheme, categoryTheme);
1600
3293
  };
1601
3294
  const getLabelSymbol = (key) => {
1602
3295
  const [featureType] = key.split(".");
1603
- const featureTypeTheme = _4.get(mapTheme, `${featureType}.label`);
1604
- const categoryTheme = _4.get(mapTheme, `${key}.label`);
1605
- const mergedSymbol = _4.merge({}, featureTypeTheme, categoryTheme);
1606
- let symbols = _4.values(_4.map(mergedSymbol, "symbol"));
3296
+ const featureTypeTheme = _12.get(mapTheme, `${featureType}.label`);
3297
+ const categoryTheme = _12.get(mapTheme, `${key}.label`);
3298
+ const mergedSymbol = _12.merge({}, featureTypeTheme, categoryTheme);
3299
+ let symbols = _12.values(_12.map(mergedSymbol, "symbol"));
1607
3300
  const markerIndexToMove = symbols.findIndex(
1608
3301
  ({ elementType }) => elementType === "label.marker"
1609
3302
  );
1610
3303
  if (markerIndexToMove >= 0) {
1611
- const markerSymbolToMove = _4.pullAt(symbols, markerIndexToMove)[0];
3304
+ const markerSymbolToMove = _12.pullAt(symbols, markerIndexToMove)[0];
1612
3305
  symbols.push(markerSymbolToMove);
1613
3306
  }
1614
3307
  return symbols;
1615
3308
  };
1616
3309
  const getUIMarkerSymbol = (key) => {
1617
3310
  const [featureType] = key.split(".");
1618
- const featureTypeTheme = _4.get(mapTheme, `${featureType}.ui.marker`);
1619
- const categoryTheme = _4.get(mapTheme, `${key}.ui.marker`);
1620
- const mergedSymbol = _4.merge({}, featureTypeTheme, categoryTheme);
1621
- const symbol = _4.get(mergedSymbol, "symbol");
3311
+ const featureTypeTheme = _12.get(mapTheme, `${featureType}.ui.marker`);
3312
+ const categoryTheme = _12.get(mapTheme, `${key}.ui.marker`);
3313
+ const mergedSymbol = _12.merge({}, featureTypeTheme, categoryTheme);
3314
+ const symbol = _12.get(mergedSymbol, "symbol");
1622
3315
  return symbol;
1623
3316
  };
1624
3317
  const getUIMarkerOptions = (key) => {
1625
3318
  const [featureType] = key.split(".");
1626
- const featureTypeTheme = _4.get(mapTheme, `${featureType}.ui.marker`);
1627
- const categoryTheme = _4.get(mapTheme, `${key}.ui.marker`);
1628
- const mergedSymbol = _4.merge({}, featureTypeTheme, categoryTheme);
1629
- const options = _4.get(mergedSymbol, "options");
3319
+ const featureTypeTheme = _12.get(mapTheme, `${featureType}.ui.marker`);
3320
+ const categoryTheme = _12.get(mapTheme, `${key}.ui.marker`);
3321
+ const mergedSymbol = _12.merge({}, featureTypeTheme, categoryTheme);
3322
+ const options = _12.get(mergedSymbol, "options");
1630
3323
  return options;
1631
3324
  };
1632
3325
  const getLabelOptions = (key) => {
1633
3326
  const [featureType] = key.split(".");
1634
- const featureTypeSymbol = _4.get(mapTheme, `${featureType}.label`);
1635
- const categorySymbol = _4.get(mapTheme, `${key}.label`);
1636
- const mergedSymbol = _4.merge({}, featureTypeSymbol, categorySymbol);
1637
- return _4.reduce(
3327
+ const featureTypeSymbol = _12.get(mapTheme, `${featureType}.label`);
3328
+ const categorySymbol = _12.get(mapTheme, `${key}.label`);
3329
+ const mergedSymbol = _12.merge({}, featureTypeSymbol, categorySymbol);
3330
+ return _12.reduce(
1638
3331
  mergedSymbol,
1639
- (acc, symbol) => ({ ...acc, ..._4.get(symbol, "options", {}) }),
3332
+ (acc, symbol) => ({ ...acc, ..._12.get(symbol, "options", {}) }),
1640
3333
  {}
1641
3334
  );
1642
3335
  };
@@ -1651,13 +3344,13 @@ var styledFeatureGenerator = (mapTheme) => {
1651
3344
  };
1652
3345
  const generateSpriteHighlightMarkerOption = () => {
1653
3346
  return SPRITE_HIGHLIGHT_MARKER_FEATURE.reduce((acc, featCate) => {
1654
- const categoryKey = _4.last(featCate.split("-"));
3347
+ const categoryKey = _12.last(featCate.split("-"));
1655
3348
  const defaultLabelSymbol = getLabelSymbol(categoryKey);
1656
3349
  const highlightLabelSymbol = getLabelSymbol(featCate);
1657
3350
  const [defaultBase, defaultIcon] = defaultLabelSymbol;
1658
3351
  const [highlightBase, highlightIcon] = highlightLabelSymbol;
1659
- const base = _4.merge({}, defaultBase, highlightBase);
1660
- const icon = _4.merge({}, defaultIcon, highlightIcon);
3352
+ const base = _12.merge({}, defaultBase, highlightBase);
3353
+ const icon = _12.merge({}, defaultIcon, highlightIcon);
1661
3354
  const material = createSpriteMaterialByLabelSymbol([base, icon]);
1662
3355
  const options = getLabelOptions(featCate);
1663
3356
  return { ...acc, [featCate]: { material, options } };
@@ -1667,32 +3360,32 @@ var styledFeatureGenerator = (mapTheme) => {
1667
3360
  const spriteHighlightMarkerOptionObj = generateSpriteHighlightMarkerOption();
1668
3361
  const getElementOptions = (key) => {
1669
3362
  const [featureType] = key.split(".");
1670
- const featureTypeOptions = _4.get(
3363
+ const featureTypeOptions = _12.get(
1671
3364
  mapTheme,
1672
3365
  `${featureType}.geometry.options`
1673
3366
  );
1674
- const categoryOptions = _4.get(mapTheme, `${key}.geometry.options`);
1675
- return _4.merge({}, featureTypeOptions, categoryOptions);
3367
+ const categoryOptions = _12.get(mapTheme, `${key}.geometry.options`);
3368
+ return _12.merge({}, featureTypeOptions, categoryOptions);
1676
3369
  };
1677
3370
  const createOccupantMarker = (feature2, locatedFeature, mapConfig) => {
1678
3371
  const { textMarkerType, featureExtrudeConfig } = getFeatureMarkerConfig(
1679
3372
  feature2,
1680
3373
  mapConfig
1681
3374
  );
1682
- const markerHeight = _4.get(featureExtrudeConfig, "height", 0);
3375
+ const markerHeight = _12.get(featureExtrudeConfig, "height", 0);
1683
3376
  const { properties, id, feature_type } = feature2;
1684
3377
  if (!properties.anchor) return;
1685
- const mainLocationId = _4.get(properties, "unit.id") || _4.get(properties, "kiosk.id");
3378
+ const mainLocationId = _12.get(properties, "unit.id") || _12.get(properties, "kiosk.id");
1686
3379
  const isMainLocationFeature = mainLocationId === locatedFeature?.id;
1687
3380
  const { geometry: mainLocationGeometry } = properties?.anchor;
1688
- const geometry = isMainLocationFeature ? mainLocationGeometry : turfCenter(locatedFeature)?.geometry;
3381
+ const geometry = isMainLocationFeature ? mainLocationGeometry : turfCenter4(locatedFeature)?.geometry;
1689
3382
  const baseProperties = {
1690
3383
  id,
1691
3384
  feature_type,
1692
3385
  category: properties.category,
1693
3386
  altitude: getAltitude(properties)
1694
3387
  };
1695
- const occupantName = _4.isEmpty(properties.short_name) ? properties.name : properties.short_name;
3388
+ const occupantName = _12.isEmpty(properties.short_name) ? properties.name : properties.short_name;
1696
3389
  if (locatedFeature) {
1697
3390
  const { feature_type: feature_type2, properties: properties2 } = locatedFeature;
1698
3391
  const { category } = properties2;
@@ -1706,21 +3399,21 @@ var styledFeatureGenerator = (mapTheme) => {
1706
3399
  }
1707
3400
  return requestedType;
1708
3401
  };
1709
- const logoUrl = _4.get(properties, "logo.url");
1710
- const requestedRenderType = _4.get(properties, "render_type", "Name");
3402
+ const logoUrl = _12.get(properties, "logo.url");
3403
+ const requestedRenderType = _12.get(properties, "render_type", "Name");
1711
3404
  const renderType = getValidatedRenderType(requestedRenderType, logoUrl);
1712
3405
  if (renderType === "Label") return null;
1713
3406
  const renderPriority = properties.render_priority || 3;
1714
- const labelSymbol = getLabelSymbol(`occupant-${_4.toLower(renderType)}`);
1715
- const markerSymbol = _4.last(labelSymbol);
1716
- const coordinates = _4.get(geometry, "coordinates");
3407
+ const labelSymbol = getLabelSymbol(`occupant-${_12.toLower(renderType)}`);
3408
+ const markerSymbol = _12.last(labelSymbol);
3409
+ const coordinates = _12.get(geometry, "coordinates");
1717
3410
  const priorityLabelSymbol = getLabelSymbol(
1718
- `occupant-${_4.toLower(renderType)}-${renderPriority}`
3411
+ `occupant-${_12.toLower(renderType)}-${renderPriority}`
1719
3412
  );
1720
- const priorityMarkerSymbol = _4.last(priorityLabelSymbol) || {};
3413
+ const priorityMarkerSymbol = _12.last(priorityLabelSymbol) || {};
1721
3414
  switch (renderType) {
1722
3415
  case "Logo":
1723
- _4.set(priorityMarkerSymbol, "markerFile", logoUrl);
3416
+ _12.set(priorityMarkerSymbol, "markerFile", logoUrl);
1724
3417
  return new Marker(coordinates, {
1725
3418
  properties: {
1726
3419
  altitude: getAltitude(properties) + markerHeight,
@@ -1781,13 +3474,13 @@ var styledFeatureGenerator = (mapTheme) => {
1781
3474
  });
1782
3475
  }
1783
3476
  const uiMarkerSymbol = getUIMarkerSymbol(
1784
- `occupant-${_4.toLower(renderType)}`
3477
+ `occupant-${_12.toLower(renderType)}`
1785
3478
  );
1786
3479
  const uiMarkerPrioritySymbol = getUIMarkerSymbol(
1787
- `occupant-${_4.toLower(renderType)}-${renderPriority}`
3480
+ `occupant-${_12.toLower(renderType)}-${renderPriority}`
1788
3481
  );
1789
3482
  const uiMarkerPriorityOptions = getUIMarkerOptions(
1790
- `occupant-${_4.toLower(renderType)}-${renderPriority}`
3483
+ `occupant-${_12.toLower(renderType)}-${renderPriority}`
1791
3484
  );
1792
3485
  const style = { ...uiMarkerSymbol, ...uiMarkerPrioritySymbol };
1793
3486
  return new ui.UIMarker(coordinates, {
@@ -1809,7 +3502,7 @@ var styledFeatureGenerator = (mapTheme) => {
1809
3502
  const { category, ordinal, style = {} } = properties;
1810
3503
  const elementStyle = getElementSymbol(`${feature_type}.${category}`);
1811
3504
  const { allowOverride } = getElementOptions(`${feature_type}.${category}`);
1812
- if (allowOverride) _4.merge(elementStyle, style);
3505
+ if (allowOverride) _12.merge(elementStyle, style);
1813
3506
  const { polygonFill: color } = elementStyle;
1814
3507
  const featureProperty = {
1815
3508
  id,
@@ -1898,9 +3591,9 @@ var styledFeatureGenerator = (mapTheme) => {
1898
3591
  feature2,
1899
3592
  mapConfig
1900
3593
  );
1901
- const markerHeight = _4.get(featureExtrudeConfig, "height");
3594
+ const markerHeight = _12.get(featureExtrudeConfig, "height");
1902
3595
  const { id, properties } = feature2;
1903
- const geometry = _4.get(feature2, "geometry") || _4.get(feature2, "properties.anchor.geometry");
3596
+ const geometry = _12.get(feature2, "geometry") || _12.get(feature2, "properties.anchor.geometry");
1904
3597
  const coordinates = getCenterFromGeometry(geometry);
1905
3598
  const symbol = getElementSymbol("pin-marker");
1906
3599
  try {
@@ -1920,10 +3613,10 @@ var styledFeatureGenerator = (mapTheme) => {
1920
3613
  feature2,
1921
3614
  mapConfig
1922
3615
  );
1923
- const markerHeight = _4.get(featureExtrudeConfig, "height", 0);
3616
+ const markerHeight = _12.get(featureExtrudeConfig, "height", 0);
1924
3617
  const { properties, id } = feature2;
1925
3618
  const { geometry } = properties.anchor;
1926
- const logoUrl = _4.get(properties, "logo.url");
3619
+ const logoUrl = _12.get(properties, "logo.url");
1927
3620
  const coordinates = getCenterFromGeometry(geometry);
1928
3621
  const [markerBase, markerLabel] = getLabelSymbol(
1929
3622
  "highlighted-logo-marker"
@@ -1993,7 +3686,7 @@ var styledFeatureGenerator = (mapTheme) => {
1993
3686
  feature2,
1994
3687
  mapConfig
1995
3688
  );
1996
- const markerHeight = _4.get(featureExtrudeConfig, "height");
3689
+ const markerHeight = _12.get(featureExtrudeConfig, "height");
1997
3690
  const { id, feature_type, properties } = feature2;
1998
3691
  if (!properties.anchor) return;
1999
3692
  const markerProperties = {
@@ -2003,8 +3696,8 @@ var styledFeatureGenerator = (mapTheme) => {
2003
3696
  altitude: getAltitude(properties) + markerHeight
2004
3697
  };
2005
3698
  const { geometry } = properties?.anchor;
2006
- const coordinates = _4.get(geometry, "coordinates");
2007
- const logoUrl = _4.get(properties, "logo.url");
3699
+ const coordinates = _12.get(geometry, "coordinates");
3700
+ const logoUrl = _12.get(properties, "logo.url");
2008
3701
  if (markerSymbol) {
2009
3702
  return new Marker(coordinates, {
2010
3703
  properties: markerProperties,
@@ -2019,8 +3712,8 @@ var styledFeatureGenerator = (mapTheme) => {
2019
3712
  });
2020
3713
  }
2021
3714
  const labelSymbol = getLabelSymbol("highlight-occupant-logo");
2022
- const priorityMarkerSymbol = _4.last(labelSymbol) || {};
2023
- _4.set(priorityMarkerSymbol, "markerFile", logoUrl);
3715
+ const priorityMarkerSymbol = _12.last(labelSymbol) || {};
3716
+ _12.set(priorityMarkerSymbol, "markerFile", logoUrl);
2024
3717
  return new Marker(coordinates, {
2025
3718
  properties: markerProperties,
2026
3719
  symbol: labelSymbol
@@ -2028,14 +3721,14 @@ var styledFeatureGenerator = (mapTheme) => {
2028
3721
  },
2029
3722
  createHighlight2DAmenityMarkerFrom3DMarker: (feature2, mapConfig) => {
2030
3723
  const { coordinates, units, kiosk } = feature2;
2031
- const amenityLocatedUnit = _4.first(units);
3724
+ const amenityLocatedUnit = _12.first(units);
2032
3725
  const unitConfig = getExtrudeConfigByFeature(
2033
3726
  mapConfig,
2034
3727
  amenityLocatedUnit
2035
3728
  );
2036
- const unitHeight = _4.get(unitConfig, "height", 0);
3729
+ const unitHeight = _12.get(unitConfig, "height", 0);
2037
3730
  const kioskConfig = getExtrudeConfigByFeature(mapConfig, kiosk);
2038
- const kioskHeight = _4.get(kioskConfig, "height", 0);
3731
+ const kioskHeight = _12.get(kioskConfig, "height", 0);
2039
3732
  const markerHeight = unitHeight + kioskHeight;
2040
3733
  const symbol = getElementSymbol("highlight-amenity-marker");
2041
3734
  return new Marker(coordinates, {
@@ -2111,7 +3804,7 @@ var styledFeatureGenerator = (mapTheme) => {
2111
3804
  }
2112
3805
  },
2113
3806
  createLineStringFromGeometries: (geometries) => {
2114
- const mergedCoordinates = _4(geometries).map((geometry) => {
3807
+ const mergedCoordinates = _12(geometries).map((geometry) => {
2115
3808
  switch (geometry.type) {
2116
3809
  case "Point":
2117
3810
  return [
@@ -2220,29 +3913,29 @@ var styledFeatureGenerator = (mapTheme) => {
2220
3913
  create3DAmenityMarker: (feature2, threeLayer, config) => {
2221
3914
  const { geometry, properties, feature_type, id } = feature2;
2222
3915
  const { category, units, kiosk, is_clickable } = properties;
2223
- const amenityLocatedUnit = _4.first(units);
2224
- const isLocatedUnitModel3dAvailable = !_4.isEmpty(
3916
+ const amenityLocatedUnit = _12.first(units);
3917
+ const isLocatedUnitModel3dAvailable = !_12.isEmpty(
2225
3918
  amenityLocatedUnit?.properties?.model3d
2226
3919
  );
2227
- const isLocatedKioskModel3dAvailable = !_4.isEmpty(
3920
+ const isLocatedKioskModel3dAvailable = !_12.isEmpty(
2228
3921
  kiosk?.properties?.model3d
2229
3922
  );
2230
3923
  const unitConfig = getExtrudeConfigByFeature(config, amenityLocatedUnit);
2231
- const unitHeight = isLocatedUnitModel3dAvailable ? 0 : _4.get(unitConfig, "height", 0);
3924
+ const unitHeight = isLocatedUnitModel3dAvailable ? 0 : _12.get(unitConfig, "height", 0);
2232
3925
  const kioskConfig = getExtrudeConfigByFeature(config, kiosk);
2233
- const kioskHeight = isLocatedKioskModel3dAvailable ? 0 : _4.get(kioskConfig, "height", 0);
2234
- const coordinates = _4.get(geometry, "coordinates");
3926
+ const kioskHeight = isLocatedKioskModel3dAvailable ? 0 : _12.get(kioskConfig, "height", 0);
3927
+ const coordinates = _12.get(geometry, "coordinates");
2235
3928
  const markerProperties = {
2236
3929
  ...properties,
2237
3930
  coordinates,
2238
3931
  id,
2239
3932
  feature_type
2240
3933
  };
2241
- const material = _4.get(
3934
+ const material = _12.get(
2242
3935
  spriteMarkerMaterialObj,
2243
3936
  `${feature_type}.${category}`
2244
3937
  );
2245
- const highlightOptions = _4.get(
3938
+ const highlightOptions = _12.get(
2246
3939
  spriteHighlightMarkerOptionObj,
2247
3940
  `${PREFIX_HIGHLIGHTED_SYMBOL_KEY}-${feature_type}.${category}`
2248
3941
  );
@@ -2265,24 +3958,24 @@ var styledFeatureGenerator = (mapTheme) => {
2265
3958
  const { category, unit, kiosk } = properties;
2266
3959
  const amenityLocation = kiosk || unit;
2267
3960
  const locationConfig = getExtrudeConfigByFeature(config, amenityLocation);
2268
- const coordinates = _4.get(geometry, "coordinates");
3961
+ const coordinates = _12.get(geometry, "coordinates");
2269
3962
  const markerProperties = {
2270
3963
  ...properties,
2271
3964
  coordinates,
2272
3965
  id,
2273
3966
  feature_type
2274
3967
  };
2275
- const material = _4.get(
3968
+ const material = _12.get(
2276
3969
  spriteMarkerMaterialObj,
2277
3970
  `${feature_type}.${category}`
2278
3971
  );
2279
- const highlightOptions = _4.get(
3972
+ const highlightOptions = _12.get(
2280
3973
  spriteHighlightMarkerOptionObj,
2281
3974
  `${PREFIX_HIGHLIGHTED_SYMBOL_KEY}-${feature_type}.${category}`
2282
3975
  );
2283
3976
  const options = {
2284
3977
  scale: 0.05,
2285
- altitude: _4.get(locationConfig, "height", 0),
3978
+ altitude: _12.get(locationConfig, "height", 0),
2286
3979
  highlight: highlightOptions
2287
3980
  };
2288
3981
  return create3DMarker(
@@ -2298,24 +3991,24 @@ var styledFeatureGenerator = (mapTheme) => {
2298
3991
  const { category, unit, kiosk } = properties;
2299
3992
  const amenityLocation = kiosk || unit;
2300
3993
  const locationConfig = getExtrudeConfigByFeature(config, amenityLocation);
2301
- const coordinates = _4.get(geometry, "coordinates");
3994
+ const coordinates = _12.get(geometry, "coordinates");
2302
3995
  const markerProperties = {
2303
3996
  ...properties,
2304
3997
  coordinates,
2305
3998
  id,
2306
3999
  feature_type
2307
4000
  };
2308
- const material = _4.get(
4001
+ const material = _12.get(
2309
4002
  spriteMarkerMaterialObj,
2310
4003
  `${feature_type}.${category}`
2311
4004
  );
2312
- const highlightOptions = _4.get(
4005
+ const highlightOptions = _12.get(
2313
4006
  spriteHighlightMarkerOptionObj,
2314
4007
  `${PREFIX_HIGHLIGHTED_SYMBOL_KEY}-${feature_type}.${category}`
2315
4008
  );
2316
4009
  const options = {
2317
4010
  scale: 0.05,
2318
- altitude: _4.get(locationConfig, "height", 0),
4011
+ altitude: _12.get(locationConfig, "height", 0),
2319
4012
  highlight: highlightOptions
2320
4013
  };
2321
4014
  return create3DMarker(
@@ -2327,13 +4020,13 @@ var styledFeatureGenerator = (mapTheme) => {
2327
4020
  );
2328
4021
  },
2329
4022
  createExtrudedUnit: (unit, threeLayer, options) => {
2330
- const extrudeHeight = _4.get(options, "height");
4023
+ const extrudeHeight = _12.get(options, "height");
2331
4024
  if (!extrudeHeight) return;
2332
4025
  const unitProperty = getFeatureProperties(unit);
2333
4026
  const options3d = {
2334
4027
  // TODO: Move to extrude config later
2335
4028
  offset: -0.1,
2336
- altitude: _4.get(options, "altitude", 0)
4029
+ altitude: _12.get(options, "altitude", 0)
2337
4030
  };
2338
4031
  const color = unitProperty.defaultColor;
2339
4032
  if (color === "transparent") return;
@@ -2376,14 +4069,14 @@ var EXCEPT_AMENITY_LOCATION_CATEGORIES = [
2376
4069
  "unspecified"
2377
4070
  ];
2378
4071
  var getLocationByAmenity = (feature2) => {
2379
- const unit = _4.get(feature2, "properties.units[0]", null);
2380
- const unitCategory = _4.get(unit, "properties.category");
4072
+ const unit = _12.get(feature2, "properties.units[0]", null);
4073
+ const unitCategory = _12.get(unit, "properties.category");
2381
4074
  if (!unit) return feature2.id;
2382
4075
  return EXCEPT_AMENITY_LOCATION_CATEGORIES.includes(unitCategory) ? feature2 : unit;
2383
4076
  };
2384
4077
  var getLocationByOccupant = (feature2) => {
2385
- const kiosk = _4.get(feature2, "properties.kiosk", null);
2386
- const unit = _4.get(feature2, "properties.anchor.properties.unit", null);
4078
+ const kiosk = _12.get(feature2, "properties.kiosk", null);
4079
+ const unit = _12.get(feature2, "properties.anchor.properties.unit", null);
2387
4080
  return kiosk || unit;
2388
4081
  };
2389
4082
  var getLocationIdByFeature = (feature2) => {
@@ -2411,10 +4104,10 @@ var getFeatureByLocationId = (id, features = []) => {
2411
4104
  });
2412
4105
  };
2413
4106
  var isClickableFeature = (feature2) => {
2414
- const isClickable = _4.get(feature2, "properties.is_clickable");
4107
+ const isClickable = _12.get(feature2, "properties.is_clickable");
2415
4108
  switch (feature2?.feature_type) {
2416
4109
  case "amenity":
2417
- return _4.isNull(isClickable) ? true : isClickable;
4110
+ return _12.isNull(isClickable) ? true : isClickable;
2418
4111
  case "occupant":
2419
4112
  return true;
2420
4113
  default:
@@ -2432,24 +4125,24 @@ var getLocationByFeature = (feature2) => {
2432
4125
  }
2433
4126
  };
2434
4127
  var getRelatedLocationsByOccupant = (feature2) => {
2435
- const kiosks = _4.get(feature2, "properties.kiosks", []);
2436
- const units = _4.get(feature2, "properties.units", []);
4128
+ const kiosks = _12.get(feature2, "properties.kiosks", []);
4129
+ const units = _12.get(feature2, "properties.units", []);
2437
4130
  return [...kiosks, ...units];
2438
4131
  };
2439
4132
  var getRelatedLocationsByAmenity = (feature2) => {
2440
- const units = _4.get(feature2, "properties.units", []);
4133
+ const units = _12.get(feature2, "properties.units", []);
2441
4134
  if (units.length === 0) return [feature2];
2442
4135
  return units.filter((unit) => {
2443
- const unitCategory = _4.get(unit, "properties.category");
4136
+ const unitCategory = _12.get(unit, "properties.category");
2444
4137
  return !EXCEPT_AMENITY_LOCATION_CATEGORIES.includes(unitCategory);
2445
4138
  });
2446
4139
  };
2447
4140
  var getRelatedLocationIdsByFeature = (feature2) => {
2448
4141
  switch (feature2?.feature_type) {
2449
4142
  case "amenity":
2450
- return getRelatedLocationsByAmenity(feature2).map((v2) => v2?.id);
4143
+ return getRelatedLocationsByAmenity(feature2).map((v) => v?.id);
2451
4144
  case "occupant":
2452
- return getRelatedLocationsByOccupant(feature2).map((v2) => v2?.id);
4145
+ return getRelatedLocationsByOccupant(feature2).map((v) => v?.id);
2453
4146
  default:
2454
4147
  return [];
2455
4148
  }
@@ -2466,8 +4159,8 @@ var getRelatedLocationsByFeature = (feature2) => {
2466
4159
  };
2467
4160
  var getOrdinalByLocationId = (locationId, feature2) => {
2468
4161
  if (!feature2) return null;
2469
- const mainUnit = _4.get(feature2, "properties.unit");
2470
- const mainKiosk = _4.get(feature2, "properties.kiosk");
4162
+ const mainUnit = _12.get(feature2, "properties.unit");
4163
+ const mainKiosk = _12.get(feature2, "properties.kiosk");
2471
4164
  const relatedLocations = getRelatedLocationsByFeature(feature2);
2472
4165
  const allLocations = [mainUnit, mainKiosk, ...relatedLocations].filter(
2473
4166
  Boolean
@@ -2475,7 +4168,7 @@ var getOrdinalByLocationId = (locationId, feature2) => {
2475
4168
  const targetLocation = allLocations.find(
2476
4169
  (location) => location.id === locationId
2477
4170
  );
2478
- return targetLocation ? _4.get(targetLocation, "properties.level.properties.ordinal") || _4.get(targetLocation, "properties.ordinal") : null;
4171
+ return targetLocation ? _12.get(targetLocation, "properties.level.properties.ordinal") || _12.get(targetLocation, "properties.ordinal") : null;
2479
4172
  };
2480
4173
 
2481
4174
  // src/IndoorMap/utils/math.ts
@@ -2488,140 +4181,16 @@ var getBearingBetweenPoints = (origin, destination) => {
2488
4181
  return Math.floor(radToDegree(theta));
2489
4182
  };
2490
4183
  var getSuitablyValueBetweenBearings = (newBearing, currentBearing) => {
2491
- const difference = Math.abs(newBearing - currentBearing);
2492
- if (difference > 180)
4184
+ const difference2 = Math.abs(newBearing - currentBearing);
4185
+ if (difference2 > 180)
2493
4186
  return newBearing > 0 ? newBearing - 360 : newBearing + 360;
2494
4187
  return newBearing;
2495
4188
  };
2496
4189
 
2497
4190
  // src/IndoorMap/camera/CameraManager.ts
2498
4191
  import { Extent } from "maptalks";
2499
-
2500
- // ../../node_modules/@turf/meta/dist/esm/index.js
2501
- function coordEach(geojson, callback, excludeWrapCoord) {
2502
- if (geojson === null) return;
2503
- 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;
2504
- for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2505
- geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2506
- isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2507
- stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2508
- for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2509
- var multiFeatureIndex = 0;
2510
- var geometryIndex = 0;
2511
- geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2512
- if (geometry === null) continue;
2513
- coords = geometry.coordinates;
2514
- var geomType = geometry.type;
2515
- wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2516
- switch (geomType) {
2517
- case null:
2518
- break;
2519
- case "Point":
2520
- if (callback(
2521
- coords,
2522
- coordIndex,
2523
- featureIndex,
2524
- multiFeatureIndex,
2525
- geometryIndex
2526
- ) === false)
2527
- return false;
2528
- coordIndex++;
2529
- multiFeatureIndex++;
2530
- break;
2531
- case "LineString":
2532
- case "MultiPoint":
2533
- for (j = 0; j < coords.length; j++) {
2534
- if (callback(
2535
- coords[j],
2536
- coordIndex,
2537
- featureIndex,
2538
- multiFeatureIndex,
2539
- geometryIndex
2540
- ) === false)
2541
- return false;
2542
- coordIndex++;
2543
- if (geomType === "MultiPoint") multiFeatureIndex++;
2544
- }
2545
- if (geomType === "LineString") multiFeatureIndex++;
2546
- break;
2547
- case "Polygon":
2548
- case "MultiLineString":
2549
- for (j = 0; j < coords.length; j++) {
2550
- for (k = 0; k < coords[j].length - wrapShrink; k++) {
2551
- if (callback(
2552
- coords[j][k],
2553
- coordIndex,
2554
- featureIndex,
2555
- multiFeatureIndex,
2556
- geometryIndex
2557
- ) === false)
2558
- return false;
2559
- coordIndex++;
2560
- }
2561
- if (geomType === "MultiLineString") multiFeatureIndex++;
2562
- if (geomType === "Polygon") geometryIndex++;
2563
- }
2564
- if (geomType === "Polygon") multiFeatureIndex++;
2565
- break;
2566
- case "MultiPolygon":
2567
- for (j = 0; j < coords.length; j++) {
2568
- geometryIndex = 0;
2569
- for (k = 0; k < coords[j].length; k++) {
2570
- for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2571
- if (callback(
2572
- coords[j][k][l],
2573
- coordIndex,
2574
- featureIndex,
2575
- multiFeatureIndex,
2576
- geometryIndex
2577
- ) === false)
2578
- return false;
2579
- coordIndex++;
2580
- }
2581
- geometryIndex++;
2582
- }
2583
- multiFeatureIndex++;
2584
- }
2585
- break;
2586
- case "GeometryCollection":
2587
- for (j = 0; j < geometry.geometries.length; j++)
2588
- if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2589
- return false;
2590
- break;
2591
- default:
2592
- throw new Error("Unknown Geometry Type");
2593
- }
2594
- }
2595
- }
2596
- }
2597
-
2598
- // ../../node_modules/@turf/bbox/dist/esm/index.js
2599
- function bbox(geojson, options = {}) {
2600
- if (geojson.bbox != null && true !== options.recompute) {
2601
- return geojson.bbox;
2602
- }
2603
- const result = [Infinity, Infinity, -Infinity, -Infinity];
2604
- coordEach(geojson, (coord) => {
2605
- if (result[0] > coord[0]) {
2606
- result[0] = coord[0];
2607
- }
2608
- if (result[1] > coord[1]) {
2609
- result[1] = coord[1];
2610
- }
2611
- if (result[2] < coord[0]) {
2612
- result[2] = coord[0];
2613
- }
2614
- if (result[3] < coord[1]) {
2615
- result[3] = coord[1];
2616
- }
2617
- });
2618
- return result;
2619
- }
2620
- var index_default = bbox;
2621
-
2622
- // src/IndoorMap/camera/CameraManager.ts
2623
- import scale from "@turf/transform-scale";
2624
- import bboxPolygon from "@turf/bbox-polygon";
4192
+ import scale2 from "@turf/transform-scale";
4193
+ import bboxPolygon2 from "@turf/bbox-polygon";
2625
4194
  var CameraManager = class {
2626
4195
  map;
2627
4196
  constructor(map, options) {
@@ -2647,7 +4216,7 @@ var CameraManager = class {
2647
4216
  }
2648
4217
  getFeatureExtent = (feature2, scaleFactor = 1) => {
2649
4218
  const [minX, minY, maxX, maxY] = index_default(
2650
- scale(bboxPolygon(index_default(feature2)), scaleFactor)
4219
+ scale2(bboxPolygon2(index_default(feature2)), scaleFactor)
2651
4220
  );
2652
4221
  return new Extent(minX, minY, maxX, maxY);
2653
4222
  };
@@ -2684,8 +4253,8 @@ var CameraManager = class {
2684
4253
  };
2685
4254
 
2686
4255
  // src/IndoorMap/renderer/RendererManager.ts
2687
- import { min, compact as compact3, isFunction } from "lodash-es";
2688
- import { center as turfCenter2 } from "@turf/center";
4256
+ import { min, compact as compact2, isFunction } from "lodash";
4257
+ import { center as turfCenter5 } from "@turf/center";
2689
4258
  import * as THREE4 from "three";
2690
4259
 
2691
4260
  // src/IndoorMap/renderer/3d/Element3DRenderer.ts
@@ -2693,7 +4262,7 @@ import * as maptalks4 from "maptalks-gl";
2693
4262
  import * as THREE from "three";
2694
4263
  import { BaseObject as BaseObject5 } from "maptalks.three";
2695
4264
  import turfBuffer2 from "@turf/buffer";
2696
- import { cleanCoords } from "@turf/clean-coords";
4265
+ import { cleanCoords as cleanCoords2 } from "@turf/clean-coords";
2697
4266
  import { polygonToLine } from "@turf/polygon-to-line";
2698
4267
  import { nearestPointOnLine } from "@turf/nearest-point-on-line";
2699
4268
  import { length } from "@turf/length";
@@ -2709,7 +4278,7 @@ import {
2709
4278
  PlaneGeometry
2710
4279
  } from "three";
2711
4280
  import { largestRect } from "d3plus-shape";
2712
- import { max, merge, isNumber as isNumber2, isArray, range } from "lodash-es";
4281
+ import { max, merge, isNumber as isNumber2, isArray, range } from "lodash";
2713
4282
  var OPTIONS3 = {
2714
4283
  // Allowing click through and prevent interaction
2715
4284
  interactive: false,
@@ -2789,16 +4358,16 @@ var getMaterial = (text, flatLabelOptions) => {
2789
4358
  ctx.font = `${fontWeight} ${scale3 * fontSize}px "${fontFamily}", Arial`;
2790
4359
  textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
2791
4360
  }
2792
- const center2 = { x: 0.5 * SIZE, y: 0.5 * SIZE };
4361
+ const center8 = { x: 0.5 * SIZE, y: 0.5 * SIZE };
2793
4362
  if (scale3 > scaleMin) {
2794
4363
  const totalHeight = texts.length * (fontSize * scale3 * lineHeight);
2795
- const startY = center2.y - totalHeight / 2 + fontSize * scale3 * lineHeight * 0.5;
4364
+ const startY = center8.y - totalHeight / 2 + fontSize * scale3 * lineHeight * 0.5;
2796
4365
  texts.forEach((text2, index) => {
2797
4366
  const yOffset = startY + index * (fontSize * scale3 * lineHeight);
2798
4367
  if (strokeStyle && lineWidth) {
2799
- ctx.strokeText(text2, center2.x, yOffset);
4368
+ ctx.strokeText(text2, center8.x, yOffset);
2800
4369
  }
2801
- ctx.fillText(text2, center2.x, yOffset);
4370
+ ctx.fillText(text2, center8.x, yOffset);
2802
4371
  });
2803
4372
  }
2804
4373
  const texture = new Texture(canvas);
@@ -3055,6 +4624,7 @@ var Element3DRenderer = class extends EventTarget {
3055
4624
  threeLayer;
3056
4625
  scene;
3057
4626
  lineMaterial;
4627
+ navigationLineMaterial;
3058
4628
  materialByColorMap;
3059
4629
  // Renderer is Ready
3060
4630
  isReady = false;
@@ -3066,6 +4636,7 @@ var Element3DRenderer = class extends EventTarget {
3066
4636
  this.threeLayer = groupLayer.getLayer("three");
3067
4637
  this.gltfLayer = groupLayer.getLayer("gltf");
3068
4638
  this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
4639
+ this.navigationLineMaterial = new THREE.LineBasicMaterial({ color: "#f00" });
3069
4640
  this.render();
3070
4641
  }
3071
4642
  animation() {
@@ -3181,7 +4752,7 @@ var Element3DRenderer = class extends EventTarget {
3181
4752
  const polygons = unit.geometry.type === "Polygon" ? [unit.geometry.coordinates] : unit.geometry.coordinates;
3182
4753
  return polygons.map((plg) => {
3183
4754
  return plg.map((ring) => {
3184
- const roomWall = cleanCoords(polygonToLine(polygon([ring])));
4755
+ const roomWall = cleanCoords2(polygonToLine(polygon([ring])));
3185
4756
  if (openings.length === 0) {
3186
4757
  const color = "#ababab";
3187
4758
  const material = this.getOrCreateMaterialByColor(color);
@@ -3268,10 +4839,10 @@ var Element3DRenderer = class extends EventTarget {
3268
4839
  this.threeLayer.addMesh(groundLabel);
3269
4840
  return groundLabel;
3270
4841
  }
3271
- async createModel3d(f) {
3272
- const marker = new maptalks4.GLTFMarker(f.properties.center, {
4842
+ async createModel3d(center8, url) {
4843
+ const marker = new maptalks4.GLTFMarker(center8, {
3273
4844
  symbol: {
3274
- url: f.properties.model
4845
+ url
3275
4846
  }
3276
4847
  });
3277
4848
  marker.addTo(this.gltfLayer);
@@ -3330,11 +4901,23 @@ var Element3DRenderer = class extends EventTarget {
3330
4901
  }
3331
4902
  }
3332
4903
  }
4904
+ drawNavigation = (route) => {
4905
+ const lines = [];
4906
+ route.steps.map((step) => {
4907
+ const lineString2 = new maptalks4.LineString(step.path);
4908
+ const line = this.threeLayer.toPath(lineString2, { altitude: 0.2, cornerRadius: 1, width: 1, asynchronous: true }, this.navigationLineMaterial);
4909
+ lines.push(line);
4910
+ });
4911
+ this.threeLayer.addMesh(lines);
4912
+ };
3333
4913
  render() {
3334
4914
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3335
4915
  if (this.threeLayer._needsUpdate) {
3336
4916
  this.threeLayer.redraw();
3337
4917
  }
4918
+ if (this.navigationLineMaterial?.map?.offset) {
4919
+ this.navigationLineMaterial.map.offset.x -= 2e-3;
4920
+ }
3338
4921
  requestAnimationFrame(this.render.bind(this));
3339
4922
  }
3340
4923
  };
@@ -3474,6 +5057,8 @@ var Element2DRenderer = class extends EventTarget {
3474
5057
  }
3475
5058
  };
3476
5059
  }
5060
+ drawNavigation(route) {
5061
+ }
3477
5062
  };
3478
5063
 
3479
5064
  // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
@@ -3519,7 +5104,7 @@ import * as THREE3 from "three";
3519
5104
  import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3520
5105
  import * as THREE2 from "three";
3521
5106
  import { BaseObject as BaseObject6 } from "maptalks.three";
3522
- import { isNil, set } from "lodash";
5107
+ import { isNil, set as set4 } from "lodash";
3523
5108
 
3524
5109
  // src/IndoorMap/renderer/utils/interpolateStops.ts
3525
5110
  var interpolateStops = ({ stops }, zoom) => {
@@ -3529,8 +5114,8 @@ var interpolateStops = ({ stops }, zoom) => {
3529
5114
  const [z1, v1] = stops[i];
3530
5115
  const [z2, v2] = stops[i + 1];
3531
5116
  if (zoom >= z1 && zoom <= z2) {
3532
- const t = (zoom - z1) / (z2 - z1);
3533
- return v1 + t * (v2 - v1);
5117
+ const t2 = (zoom - z1) / (z2 - z1);
5118
+ return v1 + t2 * (v2 - v1);
3534
5119
  }
3535
5120
  }
3536
5121
  };
@@ -3675,7 +5260,7 @@ var TextSpriteMarker = class extends BaseObject6 {
3675
5260
  const altitude = (options.altitude || 0) + this.#altitudeOffset;
3676
5261
  const z = layer.altitudeToVector3(altitude, altitude).x;
3677
5262
  const position = layer.coordinateToVector3(this._coordinate, z);
3678
- set(this.properties, "default.position", position);
5263
+ set4(this.properties, "default.position", position);
3679
5264
  this.getObject3d().position.copy(position);
3680
5265
  }
3681
5266
  _animation() {
@@ -3849,478 +5434,11 @@ var angleBetweenLineStrings = (line1, line2) => {
3849
5434
  return Math.atan2(dy, dx);
3850
5435
  };
3851
5436
 
3852
- // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/util.js
3853
- var epsilon = 11102230246251565e-32;
3854
- var splitter = 134217729;
3855
- var resulterrbound = (3 + 8 * epsilon) * epsilon;
3856
- function sum(elen, e, flen, f, h) {
3857
- let Q, Qnew, hh, bvirt;
3858
- let enow = e[0];
3859
- let fnow = f[0];
3860
- let eindex = 0;
3861
- let findex = 0;
3862
- if (fnow > enow === fnow > -enow) {
3863
- Q = enow;
3864
- enow = e[++eindex];
3865
- } else {
3866
- Q = fnow;
3867
- fnow = f[++findex];
3868
- }
3869
- let hindex = 0;
3870
- if (eindex < elen && findex < flen) {
3871
- if (fnow > enow === fnow > -enow) {
3872
- Qnew = enow + Q;
3873
- hh = Q - (Qnew - enow);
3874
- enow = e[++eindex];
3875
- } else {
3876
- Qnew = fnow + Q;
3877
- hh = Q - (Qnew - fnow);
3878
- fnow = f[++findex];
3879
- }
3880
- Q = Qnew;
3881
- if (hh !== 0) {
3882
- h[hindex++] = hh;
3883
- }
3884
- while (eindex < elen && findex < flen) {
3885
- if (fnow > enow === fnow > -enow) {
3886
- Qnew = Q + enow;
3887
- bvirt = Qnew - Q;
3888
- hh = Q - (Qnew - bvirt) + (enow - bvirt);
3889
- enow = e[++eindex];
3890
- } else {
3891
- Qnew = Q + fnow;
3892
- bvirt = Qnew - Q;
3893
- hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3894
- fnow = f[++findex];
3895
- }
3896
- Q = Qnew;
3897
- if (hh !== 0) {
3898
- h[hindex++] = hh;
3899
- }
3900
- }
3901
- }
3902
- while (eindex < elen) {
3903
- Qnew = Q + enow;
3904
- bvirt = Qnew - Q;
3905
- hh = Q - (Qnew - bvirt) + (enow - bvirt);
3906
- enow = e[++eindex];
3907
- Q = Qnew;
3908
- if (hh !== 0) {
3909
- h[hindex++] = hh;
3910
- }
3911
- }
3912
- while (findex < flen) {
3913
- Qnew = Q + fnow;
3914
- bvirt = Qnew - Q;
3915
- hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3916
- fnow = f[++findex];
3917
- Q = Qnew;
3918
- if (hh !== 0) {
3919
- h[hindex++] = hh;
3920
- }
3921
- }
3922
- if (Q !== 0 || hindex === 0) {
3923
- h[hindex++] = Q;
3924
- }
3925
- return hindex;
3926
- }
3927
- function estimate(elen, e) {
3928
- let Q = e[0];
3929
- for (let i = 1; i < elen; i++) Q += e[i];
3930
- return Q;
3931
- }
3932
- function vec(n) {
3933
- return new Float64Array(n);
3934
- }
3935
-
3936
- // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient2d.js
3937
- var ccwerrboundA = (3 + 16 * epsilon) * epsilon;
3938
- var ccwerrboundB = (2 + 12 * epsilon) * epsilon;
3939
- var ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;
3940
- var B = vec(4);
3941
- var C1 = vec(8);
3942
- var C2 = vec(12);
3943
- var D = vec(16);
3944
- var u = vec(4);
3945
- function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {
3946
- let acxtail, acytail, bcxtail, bcytail;
3947
- let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u32;
3948
- const acx = ax - cx;
3949
- const bcx = bx - cx;
3950
- const acy = ay - cy;
3951
- const bcy = by - cy;
3952
- s1 = acx * bcy;
3953
- c = splitter * acx;
3954
- ahi = c - (c - acx);
3955
- alo = acx - ahi;
3956
- c = splitter * bcy;
3957
- bhi = c - (c - bcy);
3958
- blo = bcy - bhi;
3959
- s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3960
- t1 = acy * bcx;
3961
- c = splitter * acy;
3962
- ahi = c - (c - acy);
3963
- alo = acy - ahi;
3964
- c = splitter * bcx;
3965
- bhi = c - (c - bcx);
3966
- blo = bcx - bhi;
3967
- t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3968
- _i = s0 - t0;
3969
- bvirt = s0 - _i;
3970
- B[0] = s0 - (_i + bvirt) + (bvirt - t0);
3971
- _j = s1 + _i;
3972
- bvirt = _j - s1;
3973
- _0 = s1 - (_j - bvirt) + (_i - bvirt);
3974
- _i = _0 - t1;
3975
- bvirt = _0 - _i;
3976
- B[1] = _0 - (_i + bvirt) + (bvirt - t1);
3977
- u32 = _j + _i;
3978
- bvirt = u32 - _j;
3979
- B[2] = _j - (u32 - bvirt) + (_i - bvirt);
3980
- B[3] = u32;
3981
- let det = estimate(4, B);
3982
- let errbound = ccwerrboundB * detsum;
3983
- if (det >= errbound || -det >= errbound) {
3984
- return det;
3985
- }
3986
- bvirt = ax - acx;
3987
- acxtail = ax - (acx + bvirt) + (bvirt - cx);
3988
- bvirt = bx - bcx;
3989
- bcxtail = bx - (bcx + bvirt) + (bvirt - cx);
3990
- bvirt = ay - acy;
3991
- acytail = ay - (acy + bvirt) + (bvirt - cy);
3992
- bvirt = by - bcy;
3993
- bcytail = by - (bcy + bvirt) + (bvirt - cy);
3994
- if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {
3995
- return det;
3996
- }
3997
- errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);
3998
- det += acx * bcytail + bcy * acxtail - (acy * bcxtail + bcx * acytail);
3999
- if (det >= errbound || -det >= errbound) return det;
4000
- s1 = acxtail * bcy;
4001
- c = splitter * acxtail;
4002
- ahi = c - (c - acxtail);
4003
- alo = acxtail - ahi;
4004
- c = splitter * bcy;
4005
- bhi = c - (c - bcy);
4006
- blo = bcy - bhi;
4007
- s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
4008
- t1 = acytail * bcx;
4009
- c = splitter * acytail;
4010
- ahi = c - (c - acytail);
4011
- alo = acytail - ahi;
4012
- c = splitter * bcx;
4013
- bhi = c - (c - bcx);
4014
- blo = bcx - bhi;
4015
- t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
4016
- _i = s0 - t0;
4017
- bvirt = s0 - _i;
4018
- u[0] = s0 - (_i + bvirt) + (bvirt - t0);
4019
- _j = s1 + _i;
4020
- bvirt = _j - s1;
4021
- _0 = s1 - (_j - bvirt) + (_i - bvirt);
4022
- _i = _0 - t1;
4023
- bvirt = _0 - _i;
4024
- u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4025
- u32 = _j + _i;
4026
- bvirt = u32 - _j;
4027
- u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4028
- u[3] = u32;
4029
- const C1len = sum(4, B, 4, u, C1);
4030
- s1 = acx * bcytail;
4031
- c = splitter * acx;
4032
- ahi = c - (c - acx);
4033
- alo = acx - ahi;
4034
- c = splitter * bcytail;
4035
- bhi = c - (c - bcytail);
4036
- blo = bcytail - bhi;
4037
- s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
4038
- t1 = acy * bcxtail;
4039
- c = splitter * acy;
4040
- ahi = c - (c - acy);
4041
- alo = acy - ahi;
4042
- c = splitter * bcxtail;
4043
- bhi = c - (c - bcxtail);
4044
- blo = bcxtail - bhi;
4045
- t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
4046
- _i = s0 - t0;
4047
- bvirt = s0 - _i;
4048
- u[0] = s0 - (_i + bvirt) + (bvirt - t0);
4049
- _j = s1 + _i;
4050
- bvirt = _j - s1;
4051
- _0 = s1 - (_j - bvirt) + (_i - bvirt);
4052
- _i = _0 - t1;
4053
- bvirt = _0 - _i;
4054
- u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4055
- u32 = _j + _i;
4056
- bvirt = u32 - _j;
4057
- u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4058
- u[3] = u32;
4059
- const C2len = sum(C1len, C1, 4, u, C2);
4060
- s1 = acxtail * bcytail;
4061
- c = splitter * acxtail;
4062
- ahi = c - (c - acxtail);
4063
- alo = acxtail - ahi;
4064
- c = splitter * bcytail;
4065
- bhi = c - (c - bcytail);
4066
- blo = bcytail - bhi;
4067
- s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
4068
- t1 = acytail * bcxtail;
4069
- c = splitter * acytail;
4070
- ahi = c - (c - acytail);
4071
- alo = acytail - ahi;
4072
- c = splitter * bcxtail;
4073
- bhi = c - (c - bcxtail);
4074
- blo = bcxtail - bhi;
4075
- t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
4076
- _i = s0 - t0;
4077
- bvirt = s0 - _i;
4078
- u[0] = s0 - (_i + bvirt) + (bvirt - t0);
4079
- _j = s1 + _i;
4080
- bvirt = _j - s1;
4081
- _0 = s1 - (_j - bvirt) + (_i - bvirt);
4082
- _i = _0 - t1;
4083
- bvirt = _0 - _i;
4084
- u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4085
- u32 = _j + _i;
4086
- bvirt = u32 - _j;
4087
- u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4088
- u[3] = u32;
4089
- const Dlen = sum(C2len, C2, 4, u, D);
4090
- return D[Dlen - 1];
4091
- }
4092
- function orient2d(ax, ay, bx, by, cx, cy) {
4093
- const detleft = (ay - cy) * (bx - cx);
4094
- const detright = (ax - cx) * (by - cy);
4095
- const det = detleft - detright;
4096
- const detsum = Math.abs(detleft + detright);
4097
- if (Math.abs(det) >= ccwerrboundA * detsum) return det;
4098
- return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);
4099
- }
4100
-
4101
- // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient3d.js
4102
- var o3derrboundA = (7 + 56 * epsilon) * epsilon;
4103
- var o3derrboundB = (3 + 28 * epsilon) * epsilon;
4104
- var o3derrboundC = (26 + 288 * epsilon) * epsilon * epsilon;
4105
- var bc = vec(4);
4106
- var ca = vec(4);
4107
- var ab = vec(4);
4108
- var at_b = vec(4);
4109
- var at_c = vec(4);
4110
- var bt_c = vec(4);
4111
- var bt_a = vec(4);
4112
- var ct_a = vec(4);
4113
- var ct_b = vec(4);
4114
- var bct = vec(8);
4115
- var cat = vec(8);
4116
- var abt = vec(8);
4117
- var u2 = vec(4);
4118
- var _8 = vec(8);
4119
- var _8b = vec(8);
4120
- var _16 = vec(8);
4121
- var _12 = vec(12);
4122
- var fin = vec(192);
4123
- var fin2 = vec(192);
4124
-
4125
- // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/incircle.js
4126
- var iccerrboundA = (10 + 96 * epsilon) * epsilon;
4127
- var iccerrboundB = (4 + 48 * epsilon) * epsilon;
4128
- var iccerrboundC = (44 + 576 * epsilon) * epsilon * epsilon;
4129
- var bc2 = vec(4);
4130
- var ca2 = vec(4);
4131
- var ab2 = vec(4);
4132
- var aa = vec(4);
4133
- var bb = vec(4);
4134
- var cc = vec(4);
4135
- var u3 = vec(4);
4136
- var v = vec(4);
4137
- var axtbc = vec(8);
4138
- var aytbc = vec(8);
4139
- var bxtca = vec(8);
4140
- var bytca = vec(8);
4141
- var cxtab = vec(8);
4142
- var cytab = vec(8);
4143
- var abt2 = vec(8);
4144
- var bct2 = vec(8);
4145
- var cat2 = vec(8);
4146
- var abtt = vec(4);
4147
- var bctt = vec(4);
4148
- var catt = vec(4);
4149
- var _82 = vec(8);
4150
- var _162 = vec(16);
4151
- var _16b = vec(16);
4152
- var _16c = vec(16);
4153
- var _32 = vec(32);
4154
- var _32b = vec(32);
4155
- var _48 = vec(48);
4156
- var _64 = vec(64);
4157
- var fin3 = vec(1152);
4158
- var fin22 = vec(1152);
4159
-
4160
- // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/insphere.js
4161
- var isperrboundA = (16 + 224 * epsilon) * epsilon;
4162
- var isperrboundB = (5 + 72 * epsilon) * epsilon;
4163
- var isperrboundC = (71 + 1408 * epsilon) * epsilon * epsilon;
4164
- var ab3 = vec(4);
4165
- var bc3 = vec(4);
4166
- var cd = vec(4);
4167
- var de = vec(4);
4168
- var ea = vec(4);
4169
- var ac = vec(4);
4170
- var bd = vec(4);
4171
- var ce = vec(4);
4172
- var da = vec(4);
4173
- var eb = vec(4);
4174
- var abc = vec(24);
4175
- var bcd = vec(24);
4176
- var cde = vec(24);
4177
- var dea = vec(24);
4178
- var eab = vec(24);
4179
- var abd = vec(24);
4180
- var bce = vec(24);
4181
- var cda = vec(24);
4182
- var deb = vec(24);
4183
- var eac = vec(24);
4184
- var adet = vec(1152);
4185
- var bdet = vec(1152);
4186
- var cdet = vec(1152);
4187
- var ddet = vec(1152);
4188
- var edet = vec(1152);
4189
- var abdet = vec(2304);
4190
- var cddet = vec(2304);
4191
- var cdedet = vec(3456);
4192
- var deter = vec(5760);
4193
- var _83 = vec(8);
4194
- var _8b2 = vec(8);
4195
- var _8c = vec(8);
4196
- var _163 = vec(16);
4197
- var _24 = vec(24);
4198
- var _482 = vec(48);
4199
- var _48b = vec(48);
4200
- var _96 = vec(96);
4201
- var _192 = vec(192);
4202
- var _384x = vec(384);
4203
- var _384y = vec(384);
4204
- var _384z = vec(384);
4205
- var _768 = vec(768);
4206
- var xdet = vec(96);
4207
- var ydet = vec(96);
4208
- var zdet = vec(96);
4209
- var fin4 = vec(1152);
4210
-
4211
- // ../../node_modules/point-in-polygon-hao/dist/esm/index.js
4212
- function pointInPolygon(p, polygon2) {
4213
- var i;
4214
- var ii;
4215
- var k = 0;
4216
- var f;
4217
- var u1;
4218
- var v1;
4219
- var u22;
4220
- var v2;
4221
- var currentP;
4222
- var nextP;
4223
- var x = p[0];
4224
- var y = p[1];
4225
- var numContours = polygon2.length;
4226
- for (i = 0; i < numContours; i++) {
4227
- ii = 0;
4228
- var contour = polygon2[i];
4229
- var contourLen = contour.length - 1;
4230
- currentP = contour[0];
4231
- if (currentP[0] !== contour[contourLen][0] && currentP[1] !== contour[contourLen][1]) {
4232
- throw new Error("First and last coordinates in a ring must be the same");
4233
- }
4234
- u1 = currentP[0] - x;
4235
- v1 = currentP[1] - y;
4236
- for (ii; ii < contourLen; ii++) {
4237
- nextP = contour[ii + 1];
4238
- u22 = nextP[0] - x;
4239
- v2 = nextP[1] - y;
4240
- if (v1 === 0 && v2 === 0) {
4241
- if (u22 <= 0 && u1 >= 0 || u1 <= 0 && u22 >= 0) {
4242
- return 0;
4243
- }
4244
- } else if (v2 >= 0 && v1 <= 0 || v2 <= 0 && v1 >= 0) {
4245
- f = orient2d(u1, u22, v1, v2, 0, 0);
4246
- if (f === 0) {
4247
- return 0;
4248
- }
4249
- if (f > 0 && v2 > 0 && v1 <= 0 || f < 0 && v2 <= 0 && v1 > 0) {
4250
- k++;
4251
- }
4252
- }
4253
- currentP = nextP;
4254
- v1 = v2;
4255
- u1 = u22;
4256
- }
4257
- }
4258
- if (k % 2 === 0) {
4259
- return false;
4260
- }
4261
- return true;
4262
- }
4263
-
4264
- // ../../node_modules/@turf/invariant/dist/esm/index.js
4265
- function getCoord(coord) {
4266
- if (!coord) {
4267
- throw new Error("coord is required");
4268
- }
4269
- if (!Array.isArray(coord)) {
4270
- if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {
4271
- return [...coord.geometry.coordinates];
4272
- }
4273
- if (coord.type === "Point") {
4274
- return [...coord.coordinates];
4275
- }
4276
- }
4277
- if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {
4278
- return [...coord];
4279
- }
4280
- throw new Error("coord must be GeoJSON Point or an Array of numbers");
4281
- }
4282
- function getGeom(geojson) {
4283
- if (geojson.type === "Feature") {
4284
- return geojson.geometry;
4285
- }
4286
- return geojson;
4287
- }
4288
-
4289
- // ../../node_modules/@turf/boolean-point-in-polygon/dist/esm/index.js
4290
- function booleanPointInPolygon(point2, polygon2, options = {}) {
4291
- if (!point2) {
4292
- throw new Error("point is required");
4293
- }
4294
- if (!polygon2) {
4295
- throw new Error("polygon is required");
4296
- }
4297
- const pt = getCoord(point2);
4298
- const geom = getGeom(polygon2);
4299
- const type = geom.type;
4300
- const bbox2 = polygon2.bbox;
4301
- let polys = geom.coordinates;
4302
- if (bbox2 && inBBox(pt, bbox2) === false) {
4303
- return false;
4304
- }
4305
- if (type === "Polygon") {
4306
- polys = [polys];
4307
- }
4308
- let result = false;
4309
- for (var i = 0; i < polys.length; ++i) {
4310
- const polyResult = pointInPolygon(pt, polys[i]);
4311
- if (polyResult === 0) return options.ignoreBoundary ? false : true;
4312
- else if (polyResult) result = true;
4313
- }
4314
- return result;
4315
- }
4316
- function inBBox(pt, bbox2) {
4317
- return bbox2[0] <= pt[0] && bbox2[1] <= pt[1] && bbox2[2] >= pt[0] && bbox2[3] >= pt[1];
4318
- }
4319
-
4320
5437
  // src/IndoorMap/renderer/utils/findUnitOnPoint.ts
5438
+ import { booleanPointInPolygon as booleanPointInPolygon5 } from "@turf/boolean-point-in-polygon";
4321
5439
  var findUnitOnPoint = (units, point2) => {
4322
5440
  try {
4323
- return units.find((unit) => booleanPointInPolygon(point2, polygon(unit.geometry.coordinates)));
5441
+ return units.find((unit) => booleanPointInPolygon5(point2, polygon(unit.geometry.coordinates)));
4324
5442
  } catch (err) {
4325
5443
  return null;
4326
5444
  }
@@ -4369,9 +5487,9 @@ var RendererManager = class extends EventTarget {
4369
5487
  const pos = geom?.attributes?.position?.array;
4370
5488
  if (!pos || pos.length === 0) return;
4371
5489
  for (let i = 0; i < pos.length; i++) {
4372
- const v2 = pos[i];
4373
- if (!Number.isFinite(v2)) {
4374
- bad.push({ mesh: obj, index: i, value: v2 });
5490
+ const v = pos[i];
5491
+ if (!Number.isFinite(v)) {
5492
+ bad.push({ mesh: obj, index: i, value: v });
4375
5493
  break;
4376
5494
  }
4377
5495
  }
@@ -4407,6 +5525,7 @@ var RendererManager = class extends EventTarget {
4407
5525
  options.onRendererReady();
4408
5526
  }
4409
5527
  _this.#createElements();
5528
+ _this.elementRenderer.createModel3d([100.54724407, 13.72699081], "https://s3.venue.in.th/all_park_f95ac5be3c.gltf");
4410
5529
  setTimeout(() => {
4411
5530
  findBadMeshes(scene);
4412
5531
  }, 3e3);
@@ -4467,7 +5586,7 @@ var RendererManager = class extends EventTarget {
4467
5586
  populate: true
4468
5587
  });
4469
5588
  units.filter(
4470
- (u4) => !["opentobelow", "escalator", "room"].includes(u4.properties.category)
5589
+ (u) => !["opentobelow", "escalator", "room"].includes(u.properties.category)
4471
5590
  ).forEach((unit) => {
4472
5591
  const element = this.elementRenderer.createGeometry(unit);
4473
5592
  if (element) {
@@ -4475,9 +5594,9 @@ var RendererManager = class extends EventTarget {
4475
5594
  this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
4476
5595
  }
4477
5596
  });
4478
- units.filter((u4) => u4.properties.category === "room").forEach((unit) => {
5597
+ units.filter((u) => u.properties.category === "room").forEach((unit) => {
4479
5598
  const openingRelationships = relationships.filter((r) => r.properties.origin?.id === unit.id || r.properties.destination?.id === unit.id);
4480
- const roomOpenings = compact3(openingRelationships.map((rel) => {
5599
+ const roomOpenings = compact2(openingRelationships.map((rel) => {
4481
5600
  const openingId = rel?.properties.intermediary[0].id;
4482
5601
  return openings.find((o) => o.id === openingId);
4483
5602
  }));
@@ -4501,7 +5620,7 @@ var RendererManager = class extends EventTarget {
4501
5620
  this.addElementsToManager(kiosk.id, _elements, kiosk.properties.level.properties.ordinal);
4502
5621
  }
4503
5622
  });
4504
- const escalators = units.filter((u4) => u4.properties.category === "escalator");
5623
+ const escalators = units.filter((u) => u.properties.category === "escalator");
4505
5624
  for (const escalator of escalators) {
4506
5625
  try {
4507
5626
  const escalatorRelationships = relationships.filter((r) => (r.properties?.intermediary || []).some((inter) => inter.id === escalator.id));
@@ -4523,7 +5642,7 @@ var RendererManager = class extends EventTarget {
4523
5642
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
4524
5643
  const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4525
5644
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
4526
- const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
5645
+ const escalatorEntryPoint = turfCenter5(thisLevelOpening).geometry.coordinates;
4527
5646
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
4528
5647
  if (element) {
4529
5648
  const _elements = Array.isArray(element) ? element : [element];
@@ -4535,8 +5654,8 @@ var RendererManager = class extends EventTarget {
4535
5654
  }
4536
5655
  const groundLabels = await this.#dataClient.filterByType("label");
4537
5656
  for (const label of groundLabels) {
4538
- const center2 = turfCenter2(polygon(label.geometry.coordinates)).geometry.coordinates;
4539
- const unit = findUnitOnPoint(units, center2);
5657
+ const center8 = turfCenter5(polygon(label.geometry.coordinates)).geometry.coordinates;
5658
+ const unit = findUnitOnPoint(units, center8);
4540
5659
  if (unit) {
4541
5660
  const element = this.elementRenderer.createGroundLabel(label, unit);
4542
5661
  if (element) {
@@ -4545,12 +5664,6 @@ var RendererManager = class extends EventTarget {
4545
5664
  }
4546
5665
  }
4547
5666
  }
4548
- if (this.options.type === "3D") {
4549
- const model3ds = await this.#dataClient.filterByType("model3d");
4550
- for (const model3d of model3ds) {
4551
- this.elementRenderer.createModel3d(model3d);
4552
- }
4553
- }
4554
5667
  this.changeLevelByOrdinal(this.currentOrdinals);
4555
5668
  this.dispatchEvent(new CustomEvent("renderermanager:elements_created"));
4556
5669
  }
@@ -4635,6 +5748,9 @@ var RendererManager = class extends EventTarget {
4635
5748
  this.markerRenderer.removeMarker(marker);
4636
5749
  }
4637
5750
  }
5751
+ drawNavigation(route) {
5752
+ this.elementRenderer.drawNavigation(route);
5753
+ }
4638
5754
  };
4639
5755
 
4640
5756
  // src/IndoorMap/IndoorMap.ts
@@ -4712,7 +5828,7 @@ var IndoorMap = class extends EventTarget {
4712
5828
  };
4713
5829
  constructor(elementId, options) {
4714
5830
  super();
4715
- const combinedOptions = _5.merge({}, defaultOptions, options);
5831
+ const combinedOptions = _13.merge({}, defaultOptions, options);
4716
5832
  this.options = combinedOptions;
4717
5833
  const {
4718
5834
  onMapReady,
@@ -4759,7 +5875,7 @@ var IndoorMap = class extends EventTarget {
4759
5875
  this.dataClient = options.dataClient;
4760
5876
  }
4761
5877
  setOptions(options) {
4762
- const combinedOptions = _5.merge({}, defaultOptions, options);
5878
+ const combinedOptions = _13.merge({}, defaultOptions, options);
4763
5879
  this.options = combinedOptions;
4764
5880
  const maptalksOptions = parseMaptalksOptions(combinedOptions);
4765
5881
  this.map.setOptions(maptalksOptions);
@@ -4769,10 +5885,10 @@ var IndoorMap = class extends EventTarget {
4769
5885
  if (!this.options.camera?.defaultView?.center) {
4770
5886
  this.#dataClient.filterByType("venue").then((venues) => {
4771
5887
  this.#venues = venues;
4772
- const venueCenters = turfCenter3(featureCollection(venues));
5888
+ const venueCenters = turfCenter6(featureCollection(venues));
4773
5889
  const [x, y] = venueCenters.geometry.coordinates;
4774
- const center2 = new Coordinate4(x, y);
4775
- this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
5890
+ const center8 = new Coordinate4(x, y);
5891
+ this.camera.setView({ center: center8, pitch: 60, zoom: 19 });
4776
5892
  });
4777
5893
  }
4778
5894
  }
@@ -4785,7 +5901,7 @@ var IndoorMap = class extends EventTarget {
4785
5901
  handleMapClick = ({ coordinate }) => {
4786
5902
  const { x, y } = coordinate;
4787
5903
  console.log(
4788
- `[Coordinates]: x: ${_5.round(x, 8)} y: ${_5.round(
5904
+ `[Coordinates]: x: ${_13.round(x, 8)} y: ${_13.round(
4789
5905
  y,
4790
5906
  8
4791
5907
  )}, [Bearing]: ${this.map.getBearing()}, [Pitch]: ${this.map.getPitch()}`
@@ -4871,7 +5987,7 @@ var IndoorMap = class extends EventTarget {
4871
5987
  if (this.#isClicked) return;
4872
5988
  this.#isClicked = true;
4873
5989
  const onClickElement = this.#onClickElement;
4874
- if (!_5.isFunction(onClickElement)) return;
5990
+ if (!_13.isFunction(onClickElement)) return;
4875
5991
  this.#onClickElement(e);
4876
5992
  this.#isClicked = false;
4877
5993
  };
@@ -4891,16 +6007,16 @@ var IndoorMap = class extends EventTarget {
4891
6007
  for (const feature2 of this.#features) {
4892
6008
  try {
4893
6009
  const { feature_type: featureType, properties, id } = feature2;
4894
- const layerName = _5.get(
6010
+ const layerName = _13.get(
4895
6011
  LAYER_FEATURE_TYPE_OBJ,
4896
6012
  featureType,
4897
6013
  featureType
4898
6014
  );
4899
6015
  const layer = this.map.getLayer(layerName);
4900
6016
  let geometry;
4901
- const category = _5.get(feature2, "properties.category");
4902
- const extrudeConfig = _5.get(this.#mapConfig, "extrude");
4903
- const textMarkerType = _5.get(
6017
+ const category = _13.get(feature2, "properties.category");
6018
+ const extrudeConfig = _13.get(this.#mapConfig, "extrude");
6019
+ const textMarkerType = _13.get(
4904
6020
  this.#mapConfig,
4905
6021
  "text_marker_type",
4906
6022
  "ui-marker"
@@ -4932,7 +6048,7 @@ var IndoorMap = class extends EventTarget {
4932
6048
  case "opening": {
4933
6049
  switch (category) {
4934
6050
  case "emergencyexit":
4935
- const { geometry: geometry2 } = turfCenter3(feature2);
6051
+ const { geometry: geometry2 } = turfCenter6(feature2);
4936
6052
  const markerFeature = {
4937
6053
  ...feature2,
4938
6054
  geometry: geometry2
@@ -5015,9 +6131,9 @@ var IndoorMap = class extends EventTarget {
5015
6131
  const mapCenter = this.map.getCenter();
5016
6132
  const result = this.#venues.reduce((closest, venue) => {
5017
6133
  const { display_point: displayPoint } = venue.properties;
5018
- const distance = turfDistance(displayPoint, [mapCenter.x, mapCenter.y]);
5019
- if (!closest || distance < closest.distance) {
5020
- return { venueId: venue.id, distance };
6134
+ const distance5 = turfDistance2(displayPoint, [mapCenter.x, mapCenter.y]);
6135
+ if (!closest || distance5 < closest.distance) {
6136
+ return { venueId: venue.id, distance: distance5 };
5021
6137
  }
5022
6138
  return closest;
5023
6139
  }, null);
@@ -5067,15 +6183,15 @@ var IndoorMap = class extends EventTarget {
5067
6183
  }
5068
6184
  }
5069
6185
  updateUserLocationSymbolByLocale(locale) {
5070
- const userLocationGeometry = _5.get(
6186
+ const userLocationGeometry = _13.get(
5071
6187
  this.#elements,
5072
6188
  `${USER_LOCATION_ELEMENT_ID}.geometry`
5073
6189
  );
5074
6190
  if (!userLocationGeometry) return;
5075
6191
  const currentSymbol = userLocationGeometry.getSymbol();
5076
6192
  const localeSymbolToUpdate = currentSymbol.map((symbol) => {
5077
- const localeSymbol = _5.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _5.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
5078
- if (!_5.isPlainObject(localeSymbol)) return symbol;
6193
+ const localeSymbol = _13.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _13.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
6194
+ if (!_13.isPlainObject(localeSymbol)) return symbol;
5079
6195
  return {
5080
6196
  ...symbol,
5081
6197
  ...localeSymbol
@@ -5149,14 +6265,14 @@ var IndoorMap = class extends EventTarget {
5149
6265
  * END of User Location
5150
6266
  ****************************/
5151
6267
  showGeometryByElementId = (elementId) => {
5152
- const geometry = _5.get(
6268
+ const geometry = _13.get(
5153
6269
  this.#elements,
5154
6270
  `${elementId}.geometry`
5155
6271
  );
5156
6272
  if (geometry) geometry.show();
5157
6273
  };
5158
6274
  hideGeometryByElementId = (elementId) => {
5159
- const geometry = _5.get(this.#elements, `${elementId}.geometry`);
6275
+ const geometry = _13.get(this.#elements, `${elementId}.geometry`);
5160
6276
  if (geometry) geometry.hide();
5161
6277
  };
5162
6278
  setSpriteMarkersOpacity = (opacity = 1) => {
@@ -5195,7 +6311,7 @@ var IndoorMap = class extends EventTarget {
5195
6311
  * Navigation
5196
6312
  ****************************/
5197
6313
  combineNearbyLineStrings(lineStrings, options = { properties: {}, distance: 3e-4 }) {
5198
- const { properties = {}, distance = 3e-4 } = options || {};
6314
+ const { properties = {}, distance: distance5 = 3e-4 } = options || {};
5199
6315
  const combinedLineStrings = [];
5200
6316
  const accLine = [];
5201
6317
  if (lineStrings.length === 1) return lineStrings;
@@ -5203,14 +6319,14 @@ var IndoorMap = class extends EventTarget {
5203
6319
  const line = lineStrings[i];
5204
6320
  const coords = line.geometry.coordinates;
5205
6321
  const prevLine = lineStrings[i - 1];
5206
- const firstCoord = _5.first(coords);
6322
+ const firstCoord = _13.first(coords);
5207
6323
  const isFirstLine = i === 0;
5208
6324
  if (isFirstLine) {
5209
6325
  accLine.push(...coords);
5210
6326
  continue;
5211
6327
  }
5212
- const prevLastCoord = _5.last(prevLine.geometry.coordinates);
5213
- const isNearby = turfDistance(point(firstCoord), point(prevLastCoord)) < distance;
6328
+ const prevLastCoord = _13.last(prevLine.geometry.coordinates);
6329
+ const isNearby = turfDistance2(point(firstCoord), point(prevLastCoord)) < distance5;
5214
6330
  if (!isNearby) {
5215
6331
  const remainingLines = lineStrings.slice(i);
5216
6332
  const res = this.combineNearbyLineStrings(remainingLines, properties);
@@ -5230,8 +6346,8 @@ var IndoorMap = class extends EventTarget {
5230
6346
  create3DStepPath
5231
6347
  } = this.#styler;
5232
6348
  const routeMarkerLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
5233
- const linesByOrdinal = _5(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5234
- const joinedLines = _5(linesByOrdinal).reduce((acc, lines, key) => {
6349
+ const linesByOrdinal = _13(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
6350
+ const joinedLines = _13(linesByOrdinal).reduce((acc, lines, key) => {
5235
6351
  const joined = this.combineNearbyLineStrings(lines, {
5236
6352
  properties: { ordinal: +key }
5237
6353
  });
@@ -5259,14 +6375,14 @@ var IndoorMap = class extends EventTarget {
5259
6375
  stepElement = createOriginMarker(stepGeometry).addTo(routeMarkerLayer);
5260
6376
  break;
5261
6377
  case "destination-marker":
5262
- const extrudeConfig = _5.get(this.#mapConfig, "extrude");
6378
+ const extrudeConfig = _13.get(this.#mapConfig, "extrude");
5263
6379
  if (destinationFeature.feature_type === "occupant") {
5264
- const stepId = _5.get(stepGeometry, "id");
6380
+ const stepId = _13.get(stepGeometry, "id");
5265
6381
  const normalizedDestinationFeature = {
5266
6382
  ...destinationFeature,
5267
6383
  id: stepId
5268
6384
  };
5269
- const logoUrl = _5.get(
6385
+ const logoUrl = _13.get(
5270
6386
  normalizedDestinationFeature,
5271
6387
  "properties.logo.url"
5272
6388
  );
@@ -5311,15 +6427,15 @@ var IndoorMap = class extends EventTarget {
5311
6427
  const routeMarkerLayer = this.map.getLayer(
5312
6428
  HIGHLIGHT_LAYER_NAME
5313
6429
  );
5314
- const originMarkerGeometry = _5.get(
6430
+ const originMarkerGeometry = _13.get(
5315
6431
  this.#elements,
5316
6432
  `${ORIGIN_MARKER_ID}.geometry`
5317
6433
  );
5318
- const destinationMarkerGeometry = _5.get(
6434
+ const destinationMarkerGeometry = _13.get(
5319
6435
  this.#elements,
5320
6436
  `${DESTINATION_MARKER_ID}.geometry`
5321
6437
  );
5322
- const geometriesToRemove = _5.compact([
6438
+ const geometriesToRemove = _13.compact([
5323
6439
  originMarkerGeometry,
5324
6440
  destinationMarkerGeometry
5325
6441
  ]);
@@ -5330,7 +6446,7 @@ var IndoorMap = class extends EventTarget {
5330
6446
  (obj) => !(obj instanceof NavigationPath)
5331
6447
  );
5332
6448
  const objects = this.#navigationGeometries || {};
5333
- _5.forEach(objects, (obj) => {
6449
+ _13.forEach(objects, (obj) => {
5334
6450
  if (!obj) return;
5335
6451
  this.#navigationGeometries[obj.properties.id] = null;
5336
6452
  obj.remove();
@@ -5367,7 +6483,7 @@ var IndoorMap = class extends EventTarget {
5367
6483
  }
5368
6484
  if (this.threeLayer) {
5369
6485
  const currentView = this.camera.getView();
5370
- const objectOpacity = _5.clamp(38 - 2 * currentView.zoom, 0, 1);
6486
+ const objectOpacity = _13.clamp(38 - 2 * currentView.zoom, 0, 1);
5371
6487
  this.#objects.forEach((object) => {
5372
6488
  object.getObject3d().traverse((child) => {
5373
6489
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5377,7 +6493,7 @@ var IndoorMap = class extends EventTarget {
5377
6493
  });
5378
6494
  if (this.#billboardObjects) {
5379
6495
  this.#billboardObjects.forEach((object) => {
5380
- const objectScale = _5.clamp(
6496
+ const objectScale = _13.clamp(
5381
6497
  20 - 1 * currentView.zoom,
5382
6498
  1,
5383
6499
  1.05
@@ -5386,7 +6502,7 @@ var IndoorMap = class extends EventTarget {
5386
6502
  });
5387
6503
  }
5388
6504
  if (this.#isLayersFadingOnZoom) {
5389
- const layerOpacity = _5.clamp(1 - objectOpacity, 0, 1);
6505
+ const layerOpacity = _13.clamp(1 - objectOpacity, 0, 1);
5390
6506
  LAYERS.forEach((layerKey) => {
5391
6507
  const layer = this.map.getLayer(layerKey);
5392
6508
  if (layer) layer.setOpacity(layerOpacity);
@@ -5415,6 +6531,7 @@ export {
5415
6531
  GEOJSON_FEATURE_TYPES,
5416
6532
  HIGHLIGHT_LAYER_NAME,
5417
6533
  IMDF_FEATURE_TYPES,
6534
+ IMDF_UNIT_CATEGORIES,
5418
6535
  IndoorMap,
5419
6536
  LAST_USER_LOCATION_ELEMENT_ID_PREFIX,
5420
6537
  LAYERS,
@@ -5446,11 +6563,13 @@ export {
5446
6563
  getLocationByFeature,
5447
6564
  getLocationByOccupant,
5448
6565
  getLocationIdByFeature,
6566
+ getNavigateClient,
5449
6567
  getOrdinalByLocationId,
5450
6568
  getRelatedLocationIdsByFeature,
5451
6569
  getRelatedLocationsByAmenity,
5452
6570
  getRelatedLocationsByFeature,
5453
6571
  getRelatedLocationsByOccupant,
6572
+ getSearchClient,
5454
6573
  getSuitablyValueBetweenBearings,
5455
6574
  isClickableFeature,
5456
6575
  isValidCoordinate,