venue-js 1.1.1 → 1.2.0-next.10

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.js CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  MARKER_LAYER_NAME: () => MARKER_LAYER_NAME,
50
50
  NONIMDF_FEATURE_TYPES: () => NONIMDF_FEATURE_TYPES,
51
51
  ORIGIN_MARKER_ID: () => ORIGIN_MARKER_ID,
52
+ OccupantHelpers: () => occupant_helper_exports,
52
53
  POI_MARKER_LAYER_NAME: () => POI_MARKER_LAYER_NAME,
53
54
  QueryObserver: () => import_query_core2.QueryObserver,
54
55
  USER_LOCATION_ELEMENT_ID: () => USER_LOCATION_ELEMENT_ID,
@@ -58,7 +59,8 @@ __export(index_exports, {
58
59
  createSpriteMaterialByLabelSymbol: () => createSpriteMaterialByLabelSymbol,
59
60
  createStyledUIMarkerElement: () => createStyledUIMarkerElement,
60
61
  defaultFeatureQueryOptionsMap: () => defaultFeatureQueryOptionsMap,
61
- fetchFeature: () => fetchFeature,
62
+ fetchDeliveryApi: () => fetchDeliveryApi,
63
+ fetchPreviewApi: () => fetchPreviewApi,
62
64
  getBearingBetweenPoints: () => getBearingBetweenPoints,
63
65
  getCenterFromGeometry: () => getCenterFromGeometry,
64
66
  getDataClient: () => getDataClient,
@@ -75,6 +77,16 @@ __export(index_exports, {
75
77
  getRelatedLocationsByOccupant: () => getRelatedLocationsByOccupant,
76
78
  getSuitablyValueBetweenBearings: () => getSuitablyValueBetweenBearings,
77
79
  isClickableFeature: () => isClickableFeature,
80
+ isValidCoordinate: () => isValidCoordinate,
81
+ isValidLineString: () => isValidLineString,
82
+ isValidLineStringCoordinates: () => isValidLineStringCoordinates,
83
+ isValidMultiPolygon: () => isValidMultiPolygon,
84
+ isValidMultiPolygonCoordinates: () => isValidMultiPolygonCoordinates,
85
+ isValidPoint: () => isValidPoint,
86
+ isValidPolygon: () => isValidPolygon,
87
+ isValidPolygonCoordinates: () => isValidPolygonCoordinates,
88
+ matchFilter: () => matchFilter,
89
+ matchFilters: () => matchFilters,
78
90
  safeFetchFeature: () => safeFetchFeature,
79
91
  styledFeatureGenerator: () => styledFeatureGenerator
80
92
  });
@@ -161,7 +173,7 @@ var defaultFeatureQueryOptionsMap = {
161
173
  };
162
174
 
163
175
  // src/data/api/delivery-project.ts
164
- async function fetchFeature(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
176
+ async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
165
177
  switch (featureType) {
166
178
  case "label":
167
179
  case "element": {
@@ -195,20 +207,193 @@ async function fetchFeature(projectId, apiKey, featureType, baseUrl = DEFAULT_BA
195
207
  }
196
208
  }
197
209
  }
198
- var safeFetchFeature = async (projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) => {
210
+ async function fetchPreviewApi(projectId, previewToken, featureType, baseUrl = DEFAULT_BASE_URL) {
211
+ switch (featureType) {
212
+ case "label":
213
+ case "element": {
214
+ const pluralFeatureType = `${featureType}s`;
215
+ const res = await fetch(
216
+ `${baseUrl}/preview/projects/${projectId}/${pluralFeatureType}.geojson`,
217
+ {
218
+ headers: {
219
+ Authorization: `Bearer ${previewToken}`
220
+ }
221
+ }
222
+ );
223
+ if (res.status !== 200) return [];
224
+ const items = await res.json();
225
+ return items;
226
+ }
227
+ case "sponsored-content": {
228
+ const res = await fetch(
229
+ `${baseUrl}/preview/projects/${projectId}/sponsored-content.json`,
230
+ {
231
+ headers: {
232
+ Authorization: `Bearer ${previewToken}`
233
+ }
234
+ }
235
+ );
236
+ if (res.status !== 200) return [];
237
+ const jsonRes = await res.json();
238
+ const items = jsonRes.data;
239
+ return items.map((item) => ({
240
+ id: item.id,
241
+ ...item.attributes
242
+ }));
243
+ }
244
+ default: {
245
+ const res = await fetch(
246
+ `${baseUrl}/preview/projects/${projectId}/imdf/${featureType}.geojson`,
247
+ {
248
+ headers: {
249
+ Authorization: `Bearer ${previewToken}`
250
+ }
251
+ }
252
+ );
253
+ if (res.status !== 200) return [];
254
+ const collections = await res.json();
255
+ return collections.features;
256
+ }
257
+ }
258
+ }
259
+ var safeFetchFeature = async (featureType, params) => {
260
+ const mode = params.mode ?? "delivery";
261
+ const projectId = params.projectId;
262
+ const apiKey = params.apiKey;
263
+ const previewToken = params.previewToken;
264
+ const baseUrl = params.baseUrl ?? DEFAULT_BASE_URL;
199
265
  try {
200
- const result = await fetchFeature(
201
- projectId,
202
- apiKey,
203
- featureType,
204
- baseUrl
205
- );
266
+ let result = [];
267
+ if (mode === "delivery") {
268
+ result = await fetchDeliveryApi(
269
+ projectId,
270
+ apiKey,
271
+ featureType,
272
+ baseUrl
273
+ );
274
+ } else if (mode === "preview") {
275
+ result = await fetchPreviewApi(
276
+ projectId,
277
+ previewToken,
278
+ featureType,
279
+ baseUrl
280
+ );
281
+ }
206
282
  return result ?? [];
207
283
  } catch (e) {
208
284
  return Promise.resolve([]);
209
285
  }
210
286
  };
211
287
 
288
+ // src/data/utils/geometry-validator.ts
289
+ var isValidCoordinate = (point2) => {
290
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
291
+ };
292
+ function isValidLinearRingCoordinates(ring) {
293
+ if (ring.length < 4) {
294
+ return false;
295
+ }
296
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
297
+ }
298
+ var isValidPolygonCoordinates = (polygon) => {
299
+ if (Array.isArray(polygon[0]) && (polygon[0].length === 0 || typeof polygon[0][0] === "number")) {
300
+ return isValidLinearRingCoordinates(polygon);
301
+ }
302
+ if (Array.isArray(polygon) && polygon.length > 0 && Array.isArray(polygon[0])) {
303
+ if (!isValidLinearRingCoordinates(polygon[0])) {
304
+ return false;
305
+ }
306
+ for (let i = 1; i < polygon.length; i++) {
307
+ if (!isValidLinearRingCoordinates(polygon[i])) {
308
+ return false;
309
+ }
310
+ }
311
+ return true;
312
+ }
313
+ return false;
314
+ };
315
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
316
+ return multipolygon.every(isValidPolygonCoordinates);
317
+ };
318
+ var isValidLineStringCoordinates = (lineString2) => {
319
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
320
+ return false;
321
+ }
322
+ const firstPoint = lineString2[0];
323
+ const lastPoint = lineString2[lineString2.length - 1];
324
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
325
+ return false;
326
+ }
327
+ return lineString2.every(isValidCoordinate);
328
+ };
329
+ var isValidMultiPolygon = (geometry) => {
330
+ const { type, coordinates } = geometry;
331
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
332
+ };
333
+ var isValidPolygon = (geometry) => {
334
+ const { type, coordinates } = geometry;
335
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
336
+ };
337
+ var isValidLineString = (geometry) => {
338
+ const { type, coordinates } = geometry;
339
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
340
+ };
341
+ var isValidPoint = (geometry) => {
342
+ const { type, coordinates } = geometry;
343
+ return type === "Point" && isValidCoordinate(coordinates);
344
+ };
345
+
346
+ // src/data/utils/match-filters.ts
347
+ function isInFilter(filter) {
348
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
349
+ }
350
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
351
+ function matchFilter(value, filter) {
352
+ if (Array.isArray(value)) {
353
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
354
+ return value.includes(filter);
355
+ } else {
356
+ if (isInFilter(filter)) return filter.$in.includes(value);
357
+ return value === filter;
358
+ }
359
+ }
360
+ function matchFilters(item, filters) {
361
+ return Object.entries(filters).every(([key, filter]) => {
362
+ return matchFilter(item.properties[key], filter);
363
+ });
364
+ }
365
+
366
+ // src/data/utils/occupant-helper.ts
367
+ var occupant_helper_exports = {};
368
+ __export(occupant_helper_exports, {
369
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
370
+ getOccupantMainLocation: () => getOccupantMainLocation,
371
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
372
+ });
373
+ var import_compact = __toESM(require("lodash/compact"));
374
+ var getOccupantMainLocation = (occupant) => {
375
+ return occupant.properties.kiosk || occupant.properties.unit;
376
+ };
377
+ var getOccupantCorrelatedLocations = (occupant) => {
378
+ const allCorrelatedLocations = [
379
+ ...occupant.properties.units,
380
+ ...occupant.properties.kiosks
381
+ ];
382
+ return (0, import_compact.default)(allCorrelatedLocations);
383
+ };
384
+ var getOccupantMarkerLocations = (occupant, options) => {
385
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
386
+ const mainLocation = getOccupantMainLocation(occupant);
387
+ const mainLocationLevel = mainLocation?.properties?.level_id;
388
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
389
+ if (placementType === "ALL_LOCATIONS") {
390
+ return (0, import_compact.default)([mainLocation, ...allCorrelatedLocations]);
391
+ }
392
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
393
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
394
+ return (0, import_compact.default)([mainLocation, ...onePerLevelLocations]);
395
+ };
396
+
212
397
  // src/data/getDataClient.ts
213
398
  var import_query_core = require("@tanstack/query-core");
214
399
 
@@ -364,8 +549,8 @@ var createPopulator = ({
364
549
  venue,
365
550
  promotions,
366
551
  privileges,
367
- kiosk,
368
- unit,
552
+ kiosk: kiosk ? await populateKiosk(kiosk) : null,
553
+ unit: unit ? await populateUnit(unit) : null,
369
554
  kiosks: await Promise.all(kiosks.map(populateKiosk)),
370
555
  units: await Promise.all(units.map(populateUnit))
371
556
  }
@@ -457,42 +642,26 @@ var createPopulator = ({
457
642
  };
458
643
  };
459
644
 
460
- // src/data/utils/match-filters.ts
461
- function isInFilter(filter) {
462
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
463
- }
464
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
465
- function matchFilter(value, filter) {
466
- if (Array.isArray(value)) {
467
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
468
- return value.includes(filter);
469
- } else {
470
- if (isInFilter(filter)) return filter.$in.includes(value);
471
- return value === filter;
472
- }
473
- }
474
- function matchFilters(item, filters) {
475
- return Object.entries(filters).every(([key, filter]) => {
476
- return matchFilter(item.properties[key], filter);
477
- });
478
- }
479
-
480
645
  // src/data/getDataClient.ts
481
646
  var getDataClient = (options) => {
482
647
  const observers = /* @__PURE__ */ new Map();
483
648
  const queryClient = options.queryClient ?? new import_query_core.QueryClient();
484
- const { projectId, apiKey, baseUrl } = options;
649
+ const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
485
650
  if (!projectId)
486
651
  throw new Error(
487
652
  "Cannot create VenueDataClient. Reason: `projectId` is missing"
488
653
  );
489
- if (!apiKey)
654
+ if (mode === "delivery" && !apiKey)
490
655
  throw new Error(
491
656
  "Cannot create VenueDataClient. Reason: `apiKey` is missing"
492
657
  );
658
+ if (mode === "preview" && !previewToken)
659
+ throw new Error(
660
+ "Cannot create VenueDataClient. Reason: `previewToken` is missing"
661
+ );
493
662
  const createDeliveryApiQueryOptions = (featureType) => ({
494
663
  queryKey: ["_deliveryapi", featureType],
495
- queryFn: () => safeFetchFeature(projectId, apiKey, featureType, baseUrl)
664
+ queryFn: () => safeFetchFeature(featureType, { mode, projectId, apiKey, previewToken, baseUrl })
496
665
  });
497
666
  const internalFilterByType = async (featureType) => {
498
667
  try {
@@ -601,6 +770,7 @@ var getDataClient = (options) => {
601
770
 
602
771
  // src/IndoorMap/IndoorMap.ts
603
772
  var import_maptalks_gl = require("maptalks-gl");
773
+ var import_transcoders = require("@maptalks/transcoders.draco");
604
774
  var import_tween2 = __toESM(require("@tweenjs/tween.js"));
605
775
  var import_lodash7 = __toESM(require("lodash"));
606
776
 
@@ -682,133 +852,8 @@ function isNumber(num) {
682
852
  // src/IndoorMap/IndoorMap.ts
683
853
  var import_distance = __toESM(require("@turf/distance"));
684
854
  var import_center4 = __toESM(require("@turf/center"));
685
-
686
- // ../../node_modules/@turf/meta/dist/esm/index.js
687
- function coordEach(geojson, callback, excludeWrapCoord) {
688
- if (geojson === null) return;
689
- 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;
690
- for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
691
- geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
692
- isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
693
- stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
694
- for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
695
- var multiFeatureIndex = 0;
696
- var geometryIndex = 0;
697
- geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
698
- if (geometry === null) continue;
699
- coords = geometry.coordinates;
700
- var geomType = geometry.type;
701
- wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
702
- switch (geomType) {
703
- case null:
704
- break;
705
- case "Point":
706
- if (callback(
707
- coords,
708
- coordIndex,
709
- featureIndex,
710
- multiFeatureIndex,
711
- geometryIndex
712
- ) === false)
713
- return false;
714
- coordIndex++;
715
- multiFeatureIndex++;
716
- break;
717
- case "LineString":
718
- case "MultiPoint":
719
- for (j = 0; j < coords.length; j++) {
720
- if (callback(
721
- coords[j],
722
- coordIndex,
723
- featureIndex,
724
- multiFeatureIndex,
725
- geometryIndex
726
- ) === false)
727
- return false;
728
- coordIndex++;
729
- if (geomType === "MultiPoint") multiFeatureIndex++;
730
- }
731
- if (geomType === "LineString") multiFeatureIndex++;
732
- break;
733
- case "Polygon":
734
- case "MultiLineString":
735
- for (j = 0; j < coords.length; j++) {
736
- for (k = 0; k < coords[j].length - wrapShrink; k++) {
737
- if (callback(
738
- coords[j][k],
739
- coordIndex,
740
- featureIndex,
741
- multiFeatureIndex,
742
- geometryIndex
743
- ) === false)
744
- return false;
745
- coordIndex++;
746
- }
747
- if (geomType === "MultiLineString") multiFeatureIndex++;
748
- if (geomType === "Polygon") geometryIndex++;
749
- }
750
- if (geomType === "Polygon") multiFeatureIndex++;
751
- break;
752
- case "MultiPolygon":
753
- for (j = 0; j < coords.length; j++) {
754
- geometryIndex = 0;
755
- for (k = 0; k < coords[j].length; k++) {
756
- for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
757
- if (callback(
758
- coords[j][k][l],
759
- coordIndex,
760
- featureIndex,
761
- multiFeatureIndex,
762
- geometryIndex
763
- ) === false)
764
- return false;
765
- coordIndex++;
766
- }
767
- geometryIndex++;
768
- }
769
- multiFeatureIndex++;
770
- }
771
- break;
772
- case "GeometryCollection":
773
- for (j = 0; j < geometry.geometries.length; j++)
774
- if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
775
- return false;
776
- break;
777
- default:
778
- throw new Error("Unknown Geometry Type");
779
- }
780
- }
781
- }
782
- }
783
-
784
- // ../../node_modules/@turf/bbox/dist/esm/index.js
785
- function bbox(geojson, options = {}) {
786
- if (geojson.bbox != null && true !== options.recompute) {
787
- return geojson.bbox;
788
- }
789
- const result = [Infinity, Infinity, -Infinity, -Infinity];
790
- coordEach(geojson, (coord) => {
791
- if (result[0] > coord[0]) {
792
- result[0] = coord[0];
793
- }
794
- if (result[1] > coord[1]) {
795
- result[1] = coord[1];
796
- }
797
- if (result[2] < coord[0]) {
798
- result[2] = coord[0];
799
- }
800
- if (result[3] < coord[1]) {
801
- result[3] = coord[1];
802
- }
803
- });
804
- return result;
805
- }
806
- var index_default = bbox;
807
-
808
- // src/IndoorMap/IndoorMap.ts
809
- var import_transform_scale = __toESM(require("@turf/transform-scale"));
810
- var import_bbox_polygon = __toESM(require("@turf/bbox-polygon"));
811
- var import_three8 = require("three");
855
+ var import_three7 = require("three");
856
+ var import_maptalks10 = require("maptalks.three");
812
857
 
813
858
  // src/IndoorMap/constants.ts
814
859
  var defaultLayerOption = { enableAltitude: true };
@@ -1804,18 +1849,6 @@ var loadModel3d = (model3d, coordinate, threeLayer) => {
1804
1849
  );
1805
1850
  });
1806
1851
  };
1807
- var create3DModels = async (models, defaultCoordinate, properties, threeLayer) => {
1808
- let modelObjs = [];
1809
- for (let j = 0; j < models.length; j++) {
1810
- const model = models[j];
1811
- const positionCoord = import_lodash4.default.get(model, "properties.position");
1812
- const coord = positionCoord || defaultCoordinate;
1813
- const object = await loadModel3d(model, coord, threeLayer);
1814
- object.properties = properties;
1815
- modelObjs.push(object);
1816
- }
1817
- return modelObjs;
1818
- };
1819
1852
  var createExtrudePolygon = (geometry, threeLayer, material, height, properties = {}, options) => {
1820
1853
  const { offset = 0, altitude = 0 } = options;
1821
1854
  const offsetGeometry = (0, import_buffer.default)(geometry, offset, { units: "meters" });
@@ -2723,44 +2756,6 @@ var styledFeatureGenerator = (mapTheme) => {
2723
2756
  markerProperties
2724
2757
  );
2725
2758
  },
2726
- createVenue3DModel: async (venue, threeLayer) => {
2727
- const { id, feature_type, properties } = venue;
2728
- const { category, model3d } = properties;
2729
- const modelProperty = {
2730
- id,
2731
- feature_type,
2732
- category
2733
- };
2734
- const center2 = (0, import_center2.default)(venue);
2735
- const centerCoord = import_lodash4.default.get(center2, "geometry.coordinates");
2736
- const modelPosition = import_lodash4.default.get(model3d, "properties.position", centerCoord);
2737
- const models = await create3DModels(
2738
- model3d,
2739
- modelPosition,
2740
- modelProperty,
2741
- threeLayer
2742
- );
2743
- return models;
2744
- },
2745
- create3DFixture: async (fixture, threeLayer) => {
2746
- const { id, feature_type, properties } = fixture;
2747
- const { category, ordinal, model3d } = properties;
2748
- const modelProperty = {
2749
- id,
2750
- feature_type,
2751
- category,
2752
- ordinal
2753
- };
2754
- const center2 = (0, import_center2.default)(fixture);
2755
- const coordinate = import_lodash4.default.get(center2, "geometry.coordinates");
2756
- const models = await create3DModels(
2757
- model3d,
2758
- coordinate,
2759
- modelProperty,
2760
- threeLayer
2761
- );
2762
- return models;
2763
- },
2764
2759
  createExtrudedUnit: (unit, threeLayer, options) => {
2765
2760
  const extrudeHeight = import_lodash4.default.get(options, "height");
2766
2761
  if (!extrudeHeight) return;
@@ -2800,24 +2795,6 @@ var styledFeatureGenerator = (mapTheme) => {
2800
2795
  options3d
2801
2796
  );
2802
2797
  return object;
2803
- },
2804
- createAmbientLight: (config) => {
2805
- const { color: colorString = "0xffffff", intensity = 1 } = config;
2806
- const color = parseInt(colorString, 16);
2807
- const ambientLight = new import_three5.AmbientLight(color, intensity);
2808
- return ambientLight;
2809
- },
2810
- createDirectionalLight: (config) => {
2811
- const {
2812
- color: colorString = "0xffffff",
2813
- intensity = 1,
2814
- position: positionString = [0, 0, 0]
2815
- } = config;
2816
- const color = parseInt(colorString, 16);
2817
- const [x, y, z] = positionString;
2818
- const light = new import_three5.DirectionalLight(color, intensity);
2819
- light.position.set(x, y, z).normalize();
2820
- return light;
2821
2798
  }
2822
2799
  };
2823
2800
  };
@@ -2987,311 +2964,229 @@ var createHighlighExtrudeObjectController = (obj, { color }) => {
2987
2964
  };
2988
2965
 
2989
2966
  // src/IndoorMap/camera/CameraManager.ts
2990
- var ZOOM_OUT_LEVEL = 21;
2991
- var ZOOM_IN_LEVEL = 24;
2992
- var CameraManager = class {
2993
- map;
2994
- constructor(map, options) {
2967
+ var import_maptalks6 = require("maptalks");
2968
+
2969
+ // ../../node_modules/@turf/meta/dist/esm/index.js
2970
+ function coordEach(geojson, callback, excludeWrapCoord) {
2971
+ if (geojson === null) return;
2972
+ 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;
2973
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2974
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2975
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2976
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2977
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2978
+ var multiFeatureIndex = 0;
2979
+ var geometryIndex = 0;
2980
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2981
+ if (geometry === null) continue;
2982
+ coords = geometry.coordinates;
2983
+ var geomType = geometry.type;
2984
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2985
+ switch (geomType) {
2986
+ case null:
2987
+ break;
2988
+ case "Point":
2989
+ if (callback(
2990
+ coords,
2991
+ coordIndex,
2992
+ featureIndex,
2993
+ multiFeatureIndex,
2994
+ geometryIndex
2995
+ ) === false)
2996
+ return false;
2997
+ coordIndex++;
2998
+ multiFeatureIndex++;
2999
+ break;
3000
+ case "LineString":
3001
+ case "MultiPoint":
3002
+ for (j = 0; j < coords.length; j++) {
3003
+ if (callback(
3004
+ coords[j],
3005
+ coordIndex,
3006
+ featureIndex,
3007
+ multiFeatureIndex,
3008
+ geometryIndex
3009
+ ) === false)
3010
+ return false;
3011
+ coordIndex++;
3012
+ if (geomType === "MultiPoint") multiFeatureIndex++;
3013
+ }
3014
+ if (geomType === "LineString") multiFeatureIndex++;
3015
+ break;
3016
+ case "Polygon":
3017
+ case "MultiLineString":
3018
+ for (j = 0; j < coords.length; j++) {
3019
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
3020
+ if (callback(
3021
+ coords[j][k],
3022
+ coordIndex,
3023
+ featureIndex,
3024
+ multiFeatureIndex,
3025
+ geometryIndex
3026
+ ) === false)
3027
+ return false;
3028
+ coordIndex++;
3029
+ }
3030
+ if (geomType === "MultiLineString") multiFeatureIndex++;
3031
+ if (geomType === "Polygon") geometryIndex++;
3032
+ }
3033
+ if (geomType === "Polygon") multiFeatureIndex++;
3034
+ break;
3035
+ case "MultiPolygon":
3036
+ for (j = 0; j < coords.length; j++) {
3037
+ geometryIndex = 0;
3038
+ for (k = 0; k < coords[j].length; k++) {
3039
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
3040
+ if (callback(
3041
+ coords[j][k][l],
3042
+ coordIndex,
3043
+ featureIndex,
3044
+ multiFeatureIndex,
3045
+ geometryIndex
3046
+ ) === false)
3047
+ return false;
3048
+ coordIndex++;
3049
+ }
3050
+ geometryIndex++;
3051
+ }
3052
+ multiFeatureIndex++;
3053
+ }
3054
+ break;
3055
+ case "GeometryCollection":
3056
+ for (j = 0; j < geometry.geometries.length; j++)
3057
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
3058
+ return false;
3059
+ break;
3060
+ default:
3061
+ throw new Error("Unknown Geometry Type");
3062
+ }
3063
+ }
3064
+ }
3065
+ }
3066
+
3067
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
3068
+ function bbox(geojson, options = {}) {
3069
+ if (geojson.bbox != null && true !== options.recompute) {
3070
+ return geojson.bbox;
3071
+ }
3072
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
3073
+ coordEach(geojson, (coord) => {
3074
+ if (result[0] > coord[0]) {
3075
+ result[0] = coord[0];
3076
+ }
3077
+ if (result[1] > coord[1]) {
3078
+ result[1] = coord[1];
3079
+ }
3080
+ if (result[2] < coord[0]) {
3081
+ result[2] = coord[0];
3082
+ }
3083
+ if (result[3] < coord[1]) {
3084
+ result[3] = coord[1];
3085
+ }
3086
+ });
3087
+ return result;
3088
+ }
3089
+ var index_default = bbox;
3090
+
3091
+ // src/IndoorMap/camera/CameraManager.ts
3092
+ var import_transform_scale = __toESM(require("@turf/transform-scale"));
3093
+ var import_bbox_polygon = __toESM(require("@turf/bbox-polygon"));
3094
+ var CameraManager = class {
3095
+ map;
3096
+ constructor(map, options) {
2995
3097
  this.map = map;
2996
3098
  if (options?.defaultView) {
2997
3099
  this.setView(options?.defaultView);
2998
3100
  }
2999
3101
  }
3000
- /** Private method */
3001
- #animateflyTo(viewOptions = {}, options = {}, callbackOption = () => {
3002
- }) {
3003
- const { start, end } = {
3004
- start: (frame) => {
3005
- },
3006
- end: (frame) => {
3007
- },
3008
- ...callbackOption
3009
- };
3010
- this.map.flyTo(viewOptions, options, (frame) => {
3011
- if (frame.state.playState === "running" && frame.state.progress === 0)
3012
- start(frame);
3013
- if (frame.state.playState === "finished") end(frame);
3014
- });
3015
- }
3016
3102
  /** Public methods */
3017
3103
  getView = () => {
3018
3104
  return this.map.getView();
3019
3105
  };
3020
- getZoom = () => {
3021
- return this.map.getView().zoom;
3022
- };
3023
3106
  setView = (value) => {
3024
- this.map.setView(value);
3025
- };
3026
- flyTo = (center2, options = {}) => {
3027
- const currentView = this.getView();
3028
- const {
3029
- zoom = ZOOM_OUT_LEVEL,
3030
- pitch = 60,
3031
- duration = 600,
3032
- easing = "out",
3033
- bearing = currentView.bearing
3034
- } = options;
3035
- this.#animateflyTo(
3036
- {
3037
- center: center2,
3038
- zoom,
3039
- pitch,
3040
- bearing
3041
- },
3042
- { duration, easing }
3043
- );
3107
+ if (this.map && Object.keys(value).length !== 0) {
3108
+ this.map.setView(value);
3109
+ }
3044
3110
  };
3045
- flyToAndZoomIn = (centerPoint, options = {}) => {
3046
- const {
3047
- zoom = ZOOM_IN_LEVEL,
3048
- pitch = 60,
3049
- duration = 600,
3050
- easing = "out"
3051
- } = options;
3052
- this.#animateflyTo(
3053
- {
3054
- center: centerPoint,
3055
- zoom,
3056
- pitch
3057
- },
3058
- { duration, easing }
3059
- );
3111
+ animateTo = (view, options = {}, step) => {
3112
+ this.map.animateTo(view, options, step);
3060
3113
  };
3061
- };
3062
-
3063
- // src/IndoorMap/renderer/RendererManager.ts
3064
- var import_min = __toESM(require("lodash/min"));
3065
- var import_center3 = require("@turf/center");
3066
- var import_maptalks8 = require("maptalks.three");
3067
- var THREE3 = __toESM(require("three"));
3068
-
3069
- // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3070
- var maptalks4 = __toESM(require("maptalks"));
3071
- var THREE2 = __toESM(require("three"));
3072
- var import_GLTFLoader2 = require("three/examples/jsm/loaders/GLTFLoader");
3073
- var import_DRACOLoader = require("three/examples/jsm/loaders/DRACOLoader");
3074
- var import_buffer2 = __toESM(require("@turf/buffer"));
3075
-
3076
- // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3077
- var element3DRendererOptions = {
3078
- unit: {
3079
- default: { color: "#ffffff", height: 4 },
3080
- byCategory: {
3081
- walkway: { color: "#cccccc", height: 0.1 },
3082
- terrace: { color: "#cccccc", height: 0.1 },
3083
- unenclosedarea: { color: "#cccccc", height: 0.2 },
3084
- nonpublic: { color: "#999999", height: 0.3 },
3085
- escalator: { height: 0.2 },
3086
- room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3087
- }
3088
- },
3089
- kiosk: {
3090
- default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3091
- },
3092
- fixture: {
3093
- default: { color: "#ffffff", height: 0.5 },
3094
- byCategory: {
3095
- water: { color: "#ACD7EC", height: 0.1 },
3096
- vegetation: { color: "#91C499", height: 0.5 }
3097
- }
3098
- }
3099
- };
3100
-
3101
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3102
- var import_maptalks6 = require("maptalks");
3103
- var THREE = __toESM(require("three"));
3104
- var import_maptalks7 = require("maptalks.three");
3105
- var import_lodash6 = require("lodash");
3106
-
3107
- // src/IndoorMap/renderer/utils/interpolateStops.ts
3108
- var interpolateStops = ({ stops }, zoom) => {
3109
- if (zoom <= stops[0][0]) return stops[0][1];
3110
- if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3111
- for (let i = 0; i < stops.length - 1; i++) {
3112
- const [z1, v1] = stops[i];
3113
- const [z2, v2] = stops[i + 1];
3114
- if (zoom >= z1 && zoom <= z2) {
3115
- const t = (zoom - z1) / (z2 - z1);
3116
- return v1 + t * (v2 - v1);
3117
- }
3118
- }
3119
- };
3120
-
3121
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3122
- var OPTIONS4 = {
3123
- // Texture options
3124
- text: "",
3125
- textAlign: "center",
3126
- color: "#ffffff",
3127
- fontFamily: "sans-serif",
3128
- fontSize: 28,
3129
- fontWeight: 400,
3130
- background: "rgba(0, 0, 0, 0.2)",
3131
- lineHeight: 32,
3132
- padding: 8,
3133
- strokeColor: "#000000",
3134
- strokeWidth: 6,
3135
- strokeStyle: "round",
3136
- // Sprite options
3137
- /* Overall scale multiplier */
3138
- scale: 1,
3139
- altitude: 0,
3140
- opacity: 1
3141
- };
3142
- var TextSpriteMarker = class extends import_maptalks7.BaseObject {
3143
- #altitudeOffset = 0;
3144
- constructor(coordinate, options, layer, properties = {}) {
3145
- options = import_maptalks6.Util.extend({}, OPTIONS4, options, { layer });
3146
- super();
3147
- this._coordinate = new import_maptalks6.Coordinate(coordinate);
3148
- this._initOptions(options);
3149
- this._createGroup();
3150
- this.properties = { ...properties };
3151
- const sprite = this._createSprite();
3152
- this.getObject3d().add(sprite);
3153
- this._updatePosition();
3154
- this.type = "TextSpriteMarker";
3155
- }
3156
- getOptions() {
3157
- return super.getOptions();
3114
+ setMaxExtent(extent) {
3115
+ return this.map.setMaxExtent(extent);
3158
3116
  }
3159
- _createSprite() {
3160
- const options = this.getOptions();
3161
- const texture = this._createTextTexture(options.text, options);
3162
- const material = new THREE.SpriteMaterial({
3163
- map: texture,
3164
- transparent: true,
3165
- alphaTest: 0.1
3166
- });
3167
- const sprite = new THREE.Sprite(material);
3168
- const w = texture.image.width;
3169
- const h = texture.image.height;
3170
- const base = 1 / 16;
3171
- const normalizedScale = options.scale / this.getMap().getGLRes();
3172
- sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3173
- this.#altitudeOffset = Math.max(
3174
- h * base * options.scale * 0.5,
3175
- 0.05
3176
- // minimum lift in world units
3117
+ getFeatureExtent = (feature2, scaleFactor = 1) => {
3118
+ const [minX, minY, maxX, maxY] = index_default(
3119
+ (0, import_transform_scale.default)((0, import_bbox_polygon.default)(index_default(feature2)), scaleFactor)
3177
3120
  );
3178
- return sprite;
3179
- }
3180
- _createTextTexture(text, options = {}) {
3181
- const {
3182
- padding,
3183
- fontSize,
3184
- fontFamily,
3185
- fontWeight,
3186
- lineHeight,
3187
- background,
3188
- color,
3189
- textAlign,
3190
- strokeColor,
3191
- strokeWidth,
3192
- maxWidth
3193
- } = options || {};
3194
- const canvas = document.createElement("canvas");
3195
- const ctx = canvas.getContext("2d");
3196
- ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3197
- const paragraphs = String(text).split("\n");
3198
- const wrappedLines = [];
3199
- paragraphs.forEach((paragraph) => {
3200
- if ((0, import_lodash6.isNil)(maxWidth) || isNaN(maxWidth)) {
3201
- wrappedLines.push(paragraph);
3202
- return;
3203
- }
3204
- const words = paragraph.split(/\s+/);
3205
- let currentLine = "";
3206
- words.forEach((word) => {
3207
- const testLine = currentLine ? currentLine + " " + word : word;
3208
- const testWidth = ctx.measureText(testLine).width;
3209
- if (testWidth > maxWidth && currentLine) {
3210
- wrappedLines.push(currentLine);
3211
- currentLine = word;
3212
- } else {
3213
- currentLine = testLine;
3214
- }
3215
- });
3216
- if (currentLine) {
3217
- wrappedLines.push(currentLine);
3218
- }
3219
- });
3220
- const lines = wrappedLines.length ? wrappedLines : [""];
3221
- const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3222
- const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3223
- const finalHeight = lineHeight * lines.length + padding * 2;
3224
- canvas.width = finalWidth;
3225
- canvas.height = finalHeight;
3226
- const ctx2 = canvas.getContext("2d");
3227
- ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3228
- ctx2.textAlign = textAlign;
3229
- if (background && background !== "transparent") {
3230
- ctx2.fillStyle = background;
3231
- ctx2.fillRect(0, 0, canvas.width, canvas.height);
3232
- }
3233
- lines.forEach((line, i) => {
3234
- const y = padding + lineHeight * (i + 0.8);
3235
- let x = padding;
3236
- if (textAlign === "center") x = canvas.width / 2;
3237
- if (textAlign === "right" || textAlign === "end")
3238
- x = canvas.width - padding;
3239
- if (strokeWidth > 0) {
3240
- ctx2.lineWidth = strokeWidth;
3241
- ctx2.lineJoin = "round";
3242
- ctx2.miterLimit = 2;
3243
- ctx2.strokeStyle = strokeColor;
3244
- ctx2.strokeText(line, x, y);
3245
- }
3246
- ctx2.fillStyle = color;
3247
- ctx2.fillText(line, x, y);
3248
- });
3249
- const texture = new THREE.CanvasTexture(canvas);
3250
- texture.needsUpdate = true;
3251
- texture.minFilter = THREE.LinearFilter;
3252
- return texture;
3253
- }
3254
- _updatePosition() {
3255
- const options = this.getOptions();
3256
- const layer = options.layer;
3257
- if (!layer) return;
3258
- const altitude = (options.altitude || 0) + this.#altitudeOffset;
3259
- const z = layer.altitudeToVector3(altitude, altitude).x;
3260
- const position = layer.coordinateToVector3(this._coordinate, z);
3261
- (0, import_lodash6.set)(this.properties, "default.position", position);
3262
- this.getObject3d().position.copy(position);
3263
- }
3264
- _animation() {
3265
- const layer = this.getLayer();
3266
- if (!this.isAdd || !layer) return;
3267
- if (this._visible === true) {
3268
- const zoom = layer.map.getZoom();
3269
- const object3d = this.getObject3d();
3270
- const { opacity } = this.getOptions();
3271
- let opacityValue;
3272
- if (typeof opacity === "number") {
3273
- opacityValue = opacity ?? 1;
3274
- } else if (Array.isArray(opacity.stops)) {
3275
- opacityValue = interpolateStops(opacity, zoom);
3276
- } else {
3277
- throw new Error(`Unknown opacity value ${opacity}`);
3278
- }
3279
- const visible = opacityValue > 0.5;
3280
- object3d.visible = visible;
3121
+ return new import_maptalks6.Extent(minX, minY, maxX, maxY);
3122
+ };
3123
+ getExtentZoom = (extent, options = {
3124
+ isFraction: false,
3125
+ padding: {
3126
+ paddingLeft: 0,
3127
+ paddingRight: 0,
3128
+ paddingTop: 0,
3129
+ paddingBottom: 0
3281
3130
  }
3131
+ }) => {
3132
+ const { isFraction = false, padding } = options;
3133
+ return this.map.getFitZoom(extent, isFraction, padding);
3134
+ };
3135
+ set maxZoom(value) {
3136
+ this.map.setMaxZoom(value);
3137
+ const spatialReference = {
3138
+ projection: "EPSG:3857",
3139
+ resolutions: (function() {
3140
+ const resolutions = [];
3141
+ const d = 2 * 6378137 * Math.PI;
3142
+ for (let i = 0; i < value; i++) {
3143
+ resolutions[i] = d / (256 * Math.pow(2, i));
3144
+ }
3145
+ return resolutions;
3146
+ })()
3147
+ };
3148
+ this.map.setSpatialReference(spatialReference);
3282
3149
  }
3283
- setText(text) {
3284
- const options = this.getOptions();
3285
- options.text = text;
3286
- const newSprite = this._createSprite();
3287
- const group = this.getObject3d();
3288
- group.children.forEach((child) => group.remove(child));
3289
- group.add(newSprite);
3290
- this._updatePosition();
3150
+ set minZoom(value) {
3151
+ this.map.setMinZoom(value);
3291
3152
  }
3292
- setAltitude(altitude) {
3293
- const bottomHeight = this.options.bottomHeight ?? 0;
3294
- return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3153
+ };
3154
+
3155
+ // src/IndoorMap/renderer/RendererManager.ts
3156
+ var import_isFunction = __toESM(require("lodash/isFunction"));
3157
+ var import_min = __toESM(require("lodash/min"));
3158
+ var import_center3 = require("@turf/center");
3159
+ var THREE3 = __toESM(require("three"));
3160
+
3161
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3162
+ var maptalks4 = __toESM(require("maptalks-gl"));
3163
+ var THREE = __toESM(require("three"));
3164
+ var import_maptalks7 = require("maptalks.three");
3165
+ var import_buffer2 = __toESM(require("@turf/buffer"));
3166
+
3167
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3168
+ var element3DRendererOptions = {
3169
+ unit: {
3170
+ default: { color: "#ffffff", height: 4 },
3171
+ byCategory: {
3172
+ walkway: { color: "#cccccc", height: 0.1 },
3173
+ terrace: { color: "#cccccc", height: 0.1 },
3174
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3175
+ nonpublic: { color: "#999999", height: 0.3 },
3176
+ escalator: { height: 0.2 },
3177
+ parking: { height: 0.1 },
3178
+ room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3179
+ }
3180
+ },
3181
+ kiosk: {
3182
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3183
+ },
3184
+ fixture: {
3185
+ default: { color: "#ffffff", height: 0.5 },
3186
+ byCategory: {
3187
+ water: { color: "#ACD7EC", height: 0.1 },
3188
+ vegetation: { color: "#91C499", height: 0.5 }
3189
+ }
3295
3190
  }
3296
3191
  };
3297
3192
 
@@ -3315,21 +3210,22 @@ var getGeometryOption = (feature2, options) => {
3315
3210
  var Element3DRenderer = class extends EventTarget {
3316
3211
  options;
3317
3212
  map;
3213
+ gltfLayer;
3318
3214
  threeLayer;
3319
- dracoLoader;
3215
+ scene;
3216
+ // private dracoLoader: DRACOLoader
3320
3217
  lineMaterial;
3321
3218
  materialByColorMap;
3322
- markerRenderer;
3323
3219
  // Renderer is Ready
3324
3220
  isReady = false;
3325
- constructor(map, options, layer) {
3221
+ constructor(map, options) {
3326
3222
  super();
3327
3223
  this.options = options;
3328
3224
  this.map = map;
3329
- this.dracoLoader = new import_DRACOLoader.DRACOLoader();
3330
- this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
3331
- this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3332
- this.threeLayer = layer;
3225
+ const groupLayer = this.map.getLayer("group");
3226
+ this.threeLayer = groupLayer.getLayer("three");
3227
+ this.gltfLayer = groupLayer.getLayer("gltf");
3228
+ this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
3333
3229
  this.render();
3334
3230
  }
3335
3231
  animation() {
@@ -3344,7 +3240,7 @@ var Element3DRenderer = class extends EventTarget {
3344
3240
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3345
3241
  const existingMaterial = this.materialByColorMap.get(color);
3346
3242
  if (existingMaterial) return existingMaterial;
3347
- const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3243
+ const created = new THREE.MeshLambertMaterial({ color, transparent: true });
3348
3244
  created.toneMapped = false;
3349
3245
  this.materialByColorMap.set(color, created);
3350
3246
  return created;
@@ -3359,46 +3255,48 @@ var Element3DRenderer = class extends EventTarget {
3359
3255
  } = getGeometryOption(feature2, this.options);
3360
3256
  const _this = this;
3361
3257
  const createPolygon = (geometry, feature3) => {
3362
- const [outerRing, ...innerRings] = geometry.coordinates;
3363
- const offsetFeature = offset !== 0 ? (0, import_buffer2.default)(geometry, offset, { units: "meters" }) : feature3;
3364
- const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3365
- if (color === "transparent") return;
3366
- const material = this.getOrCreateMaterialByColor(color);
3367
- const altitude = feature3.properties.ordinal * HEIGHT_METER;
3368
- const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3369
- const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3370
- const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3371
- offsetFeature,
3372
- { asynchronous: true, ...options, height, bottomHeight, altitude },
3373
- material
3374
- );
3375
- extrudedPolygon.on("click", (e) => {
3376
- console.log(e.target.options.polygon.id);
3377
- });
3378
- const topLineStrings = [
3379
- new maptalks4.LineString(outerRing),
3380
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3381
- ];
3382
- const topLines = this.threeLayer.toLines(
3383
- topLineStrings,
3384
- { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3385
- this.lineMaterial
3386
- );
3387
- const bottomLineStrings = [
3388
- new maptalks4.LineString(outerRing),
3389
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3390
- ];
3391
- const bottomLines = this.threeLayer.toLines(
3392
- bottomLineStrings,
3393
- { altitude, bottomHeight, interactive: false },
3394
- this.lineMaterial
3395
- );
3396
- return [extrudedPolygon, topLines, bottomLines];
3258
+ try {
3259
+ const [outerRing, ...innerRings] = geometry.coordinates;
3260
+ const offsetFeature = offset !== 0 ? (0, import_buffer2.default)(geometry, offset, { units: "meters" }) : feature3;
3261
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3262
+ if (color === "transparent") return;
3263
+ const material = this.getOrCreateMaterialByColor(color);
3264
+ const altitude = 0;
3265
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3266
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3267
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3268
+ offsetFeature,
3269
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3270
+ material
3271
+ );
3272
+ const topLineStrings = [
3273
+ new maptalks4.LineString(outerRing),
3274
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3275
+ ];
3276
+ const topLines = this.threeLayer.toLines(
3277
+ topLineStrings,
3278
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3279
+ this.lineMaterial
3280
+ );
3281
+ const bottomLineStrings = [
3282
+ new maptalks4.LineString(outerRing),
3283
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3284
+ ];
3285
+ const bottomLines = this.threeLayer.toLines(
3286
+ bottomLineStrings,
3287
+ { altitude, bottomHeight, interactive: false },
3288
+ this.lineMaterial
3289
+ );
3290
+ return [extrudedPolygon, topLines, bottomLines];
3291
+ } catch (err) {
3292
+ return [];
3293
+ }
3397
3294
  };
3398
3295
  try {
3399
3296
  switch (feature2.geometry.type) {
3400
3297
  case "MultiPolygon": {
3401
3298
  const { coordinates } = feature2.geometry;
3299
+ if (!coordinates) return [];
3402
3300
  const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3403
3301
  const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3404
3302
  this.threeLayer.addMesh(meshes);
@@ -3407,70 +3305,47 @@ var Element3DRenderer = class extends EventTarget {
3407
3305
  return multiMeshes;
3408
3306
  }
3409
3307
  case "Polygon": {
3308
+ const { coordinates } = feature2.geometry;
3309
+ if (!coordinates) return [];
3410
3310
  const meshes = createPolygon(feature2.geometry, feature2);
3411
3311
  this.threeLayer.addMesh(meshes);
3412
3312
  return meshes;
3413
3313
  }
3414
3314
  }
3415
3315
  } catch (err) {
3416
- console.log(`error createGeometry`, { feature: feature2, options });
3316
+ console.log(`error createGeometry`, err, { feature: feature2, options });
3417
3317
  }
3418
3318
  };
3419
3319
  async createEscalator(f, coordinate, options) {
3320
+ const model = {
3321
+ url: "https://cdn.venue.in.th/static/glb/escalator.glb",
3322
+ size: 4.4
3323
+ };
3420
3324
  const { direction: dir, angle } = options;
3421
- const model = await this.loadModel3d({
3422
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
3423
- properties: {
3424
- rotation: {
3425
- x: 0.5 * Math.PI,
3426
- // Rotate the model up (new_escalator.glb)
3427
- y: 0,
3428
- z: 0
3429
- },
3430
- position: { x: 0, y: 0, z: 0 },
3431
- scale: 0.01
3325
+ const rotationZ = dir === "up" ? 180 + angle : angle;
3326
+ var escalatorMarker = new maptalks4.GLTFMarker(coordinate, {
3327
+ symbol: {
3328
+ url: model.url,
3329
+ rotationZ,
3330
+ translationX: dir === "up" ? 0 : model.size * Math.cos(Math.PI * rotationZ / 180),
3331
+ translationY: dir === "up" ? 0 : model.size * Math.sin(Math.PI * rotationZ / 180),
3332
+ translationZ: dir === "up" ? -0.05 * model.size : -0.5 * model.size
3432
3333
  }
3433
3334
  });
3434
- model.rotation.y += dir === "up" ? Math.PI + angle : angle;
3435
- const box = new THREE2.Box3().setFromObject(model);
3436
- const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
3437
- 1 * (box.min.x + box.max.x),
3438
- 1 * (box.min.y + box.max.y),
3439
- 0.6 * box.max.z
3440
- );
3441
- const pivot = new THREE2.Group();
3442
- pivot.add(model);
3443
- model.position.sub(pivotPoint);
3444
- model.updateMatrixWorld(true);
3445
- const altitude = f.properties.ordinal * HEIGHT_METER;
3446
- const baseObjectModel = this.threeLayer.toModel(pivot, {
3447
- coordinate,
3448
- altitude
3449
- });
3450
- this.threeLayer.addMesh(baseObjectModel);
3451
- return baseObjectModel;
3335
+ escalatorMarker.addTo(this.gltfLayer);
3336
+ return escalatorMarker;
3452
3337
  }
3453
3338
  async createTree(coordinate, ordinal) {
3454
- const model = await this.loadModel3d({
3455
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
3456
- properties: {
3457
- rotation: {
3458
- x: 0.5 * Math.PI,
3459
- // Rotate the model up (new_escalator.glb)
3460
- y: 0,
3461
- z: 0
3462
- },
3463
- position: { x: 0, y: 0, z: 0 },
3464
- scale: 0.01
3339
+ const treeMarker = new maptalks4.GLTFMarker(coordinate, {
3340
+ symbol: {
3341
+ url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb"
3465
3342
  }
3466
3343
  });
3467
- const altitude = ordinal * HEIGHT_METER;
3468
- const baseObjectModel = this.threeLayer.toModel(model, {
3469
- coordinate,
3470
- altitude
3471
- });
3472
- this.threeLayer.addMesh(baseObjectModel);
3473
- return baseObjectModel;
3344
+ treeMarker.addTo(this.gltfLayer);
3345
+ return treeMarker;
3346
+ }
3347
+ async createBuilding(coordinate, ordinal) {
3348
+ return Promise.resolve(null);
3474
3349
  }
3475
3350
  createElement(f) {
3476
3351
  switch (f.feature_type) {
@@ -3493,34 +3368,34 @@ var Element3DRenderer = class extends EventTarget {
3493
3368
  }
3494
3369
  });
3495
3370
  }
3496
- async loadModel3d(model3d) {
3497
- const loader = new import_GLTFLoader2.GLTFLoader();
3498
- loader.setDRACOLoader(this.dracoLoader);
3499
- const { url, properties: modelProperties } = model3d;
3500
- const gltf = await loader.loadAsync(url);
3501
- const model = gltf.scene;
3502
- model.rotation.x = modelProperties.rotation.x;
3503
- model.rotation.y = modelProperties.rotation.y;
3504
- model.position.x = modelProperties.position.x;
3505
- model.position.y = modelProperties.position.y;
3506
- model.position.z = modelProperties.position.z;
3507
- const scale2 = modelProperties.scale;
3508
- model.scale.set(scale2, scale2, scale2);
3509
- return model;
3510
- }
3511
- createMarker = (coordinates, ordinal, text) => {
3512
- const options = {
3513
- // scale: 0.05,
3514
- // altitude: ordinal * HEIGHT_METER,
3515
- text
3516
- // interactive: true,
3517
- };
3518
- const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
3519
- this.threeLayer.addMesh([marker]);
3520
- return marker;
3521
- };
3522
- removeMarker = () => {
3523
- };
3371
+ createHighlightController(element) {
3372
+ if (!(element instanceof import_maptalks7.BaseObject)) {
3373
+ return null;
3374
+ }
3375
+ switch (element.type) {
3376
+ case "ExtrudePolygon": {
3377
+ const mesh = element.getObject3d();
3378
+ const originalMaterial = mesh.material;
3379
+ const highlightMaterial = this.getOrCreateMaterialByColor("#ff0000");
3380
+ return {
3381
+ start: () => {
3382
+ mesh.material = highlightMaterial;
3383
+ },
3384
+ clear: () => {
3385
+ mesh.material = originalMaterial;
3386
+ }
3387
+ };
3388
+ }
3389
+ default: {
3390
+ return {
3391
+ start() {
3392
+ },
3393
+ clear() {
3394
+ }
3395
+ };
3396
+ }
3397
+ }
3398
+ }
3524
3399
  render() {
3525
3400
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3526
3401
  if (this.threeLayer._needsUpdate) {
@@ -3628,7 +3503,10 @@ var Element2DRenderer = class extends EventTarget {
3628
3503
  async createEscalator(f, coordinates) {
3629
3504
  return Promise.resolve(null);
3630
3505
  }
3631
- async createTree(f, coordinates) {
3506
+ async createTree(coordinates) {
3507
+ return Promise.resolve(null);
3508
+ }
3509
+ async createBuilding(coordinate, ordinal) {
3632
3510
  return Promise.resolve(null);
3633
3511
  }
3634
3512
  createElement = (imdfFeature) => {
@@ -3648,6 +3526,15 @@ var Element2DRenderer = class extends EventTarget {
3648
3526
  element.hide();
3649
3527
  });
3650
3528
  }
3529
+ createHighlightController(element) {
3530
+ if (!(element instanceof maptalks5.Geometry)) return null;
3531
+ return {
3532
+ start() {
3533
+ },
3534
+ clear() {
3535
+ }
3536
+ };
3537
+ }
3651
3538
  };
3652
3539
 
3653
3540
  // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
@@ -3658,6 +3545,7 @@ var Marker2DRenderer = class extends EventTarget {
3658
3545
  markerLayer;
3659
3546
  constructor(map) {
3660
3547
  super();
3548
+ this.map = map;
3661
3549
  }
3662
3550
  createMarker = (coordinates, ordinal, content) => {
3663
3551
  const marker = new maptalks6.ui.UIMarker(coordinates, {
@@ -3666,86 +3554,216 @@ var Marker2DRenderer = class extends EventTarget {
3666
3554
  collisionFadeIn: true,
3667
3555
  altitude: 0
3668
3556
  });
3669
- marker.addTo(this.map);
3670
- return marker;
3671
- };
3672
- removeMarker = (marker) => {
3673
- marker.remove();
3674
- };
3675
- showMarkers(elements, ordinalDiff = 0) {
3557
+ marker.addTo(this.map);
3558
+ return marker;
3559
+ };
3560
+ removeMarker = (marker) => {
3561
+ marker.remove();
3562
+ };
3563
+ showMarkers(elements, ordinalDiff = 0) {
3564
+ }
3565
+ hideMarkers(elements, ordinalDiff = 0) {
3566
+ }
3567
+ };
3568
+
3569
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3570
+ var maptalks7 = __toESM(require("maptalks-gl"));
3571
+
3572
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3573
+ var import_maptalks8 = require("maptalks");
3574
+ var THREE2 = __toESM(require("three"));
3575
+ var import_maptalks9 = require("maptalks.three");
3576
+ var import_lodash6 = require("lodash");
3577
+
3578
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3579
+ var interpolateStops = ({ stops }, zoom) => {
3580
+ if (zoom <= stops[0][0]) return stops[0][1];
3581
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3582
+ for (let i = 0; i < stops.length - 1; i++) {
3583
+ const [z1, v1] = stops[i];
3584
+ const [z2, v2] = stops[i + 1];
3585
+ if (zoom >= z1 && zoom <= z2) {
3586
+ const t = (zoom - z1) / (z2 - z1);
3587
+ return v1 + t * (v2 - v1);
3588
+ }
3589
+ }
3590
+ };
3591
+
3592
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3593
+ var OPTIONS4 = {
3594
+ // Texture options
3595
+ text: "",
3596
+ textAlign: "center",
3597
+ color: "#ffffff",
3598
+ fontFamily: "sans-serif",
3599
+ fontSize: 28,
3600
+ fontWeight: 400,
3601
+ background: "transparent",
3602
+ lineHeight: 32,
3603
+ padding: 8,
3604
+ strokeColor: "#000000",
3605
+ strokeWidth: 3,
3606
+ strokeStyle: "round",
3607
+ // Sprite options
3608
+ /* Overall scale multiplier */
3609
+ scale: 1,
3610
+ altitude: 0,
3611
+ opacity: 1
3612
+ };
3613
+ var TextSpriteMarker = class extends import_maptalks9.BaseObject {
3614
+ #altitudeOffset = 0;
3615
+ constructor(coordinate, options, layer, properties = {}) {
3616
+ options = import_maptalks8.Util.extend({}, OPTIONS4, options, { layer });
3617
+ super();
3618
+ this._coordinate = new import_maptalks8.Coordinate(coordinate);
3619
+ this._initOptions(options);
3620
+ this._createGroup();
3621
+ this.properties = { ...properties };
3622
+ const sprite = this._createSprite();
3623
+ this.getObject3d().add(sprite);
3624
+ this._updatePosition();
3625
+ this.type = "TextSpriteMarker";
3626
+ }
3627
+ getOptions() {
3628
+ return super.getOptions();
3629
+ }
3630
+ _createSprite() {
3631
+ const options = this.getOptions();
3632
+ const texture = this._createTextTexture(options.text, options);
3633
+ const material = new THREE2.SpriteMaterial({
3634
+ map: texture,
3635
+ transparent: true,
3636
+ alphaTest: 0.1
3637
+ });
3638
+ const sprite = new THREE2.Sprite(material);
3639
+ const w = texture.image.width;
3640
+ const h = texture.image.height;
3641
+ const base = 1 / 16;
3642
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3643
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3644
+ this.#altitudeOffset = Math.max(
3645
+ h * base * options.scale * 0.5,
3646
+ 0.05
3647
+ // minimum lift in world units
3648
+ );
3649
+ return sprite;
3650
+ }
3651
+ _createTextTexture(text, options = {}) {
3652
+ const {
3653
+ padding,
3654
+ fontSize,
3655
+ fontFamily,
3656
+ fontWeight,
3657
+ lineHeight,
3658
+ background,
3659
+ color,
3660
+ textAlign,
3661
+ strokeColor,
3662
+ strokeWidth,
3663
+ maxWidth
3664
+ } = options || {};
3665
+ const canvas = document.createElement("canvas");
3666
+ const ctx = canvas.getContext("2d");
3667
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3668
+ const paragraphs = String(text).split("\n");
3669
+ const wrappedLines = [];
3670
+ paragraphs.forEach((paragraph) => {
3671
+ if ((0, import_lodash6.isNil)(maxWidth) || isNaN(maxWidth)) {
3672
+ wrappedLines.push(paragraph);
3673
+ return;
3674
+ }
3675
+ const words = paragraph.split(/\s+/);
3676
+ let currentLine = "";
3677
+ words.forEach((word) => {
3678
+ const testLine = currentLine ? currentLine + " " + word : word;
3679
+ const testWidth = ctx.measureText(testLine).width;
3680
+ if (testWidth > maxWidth && currentLine) {
3681
+ wrappedLines.push(currentLine);
3682
+ currentLine = word;
3683
+ } else {
3684
+ currentLine = testLine;
3685
+ }
3686
+ });
3687
+ if (currentLine) {
3688
+ wrappedLines.push(currentLine);
3689
+ }
3690
+ });
3691
+ const lines = wrappedLines.length ? wrappedLines : [""];
3692
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3693
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3694
+ const finalHeight = lineHeight * lines.length + padding * 2;
3695
+ canvas.width = finalWidth;
3696
+ canvas.height = finalHeight;
3697
+ const ctx2 = canvas.getContext("2d");
3698
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3699
+ ctx2.textAlign = textAlign;
3700
+ if (background && background !== "transparent") {
3701
+ ctx2.fillStyle = background;
3702
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3703
+ }
3704
+ lines.forEach((line, i) => {
3705
+ const y = padding + lineHeight * (i + 0.8);
3706
+ let x = padding;
3707
+ if (textAlign === "center") x = canvas.width / 2;
3708
+ if (textAlign === "right" || textAlign === "end")
3709
+ x = canvas.width - padding;
3710
+ if (strokeWidth > 0) {
3711
+ ctx2.lineWidth = strokeWidth;
3712
+ ctx2.lineJoin = "round";
3713
+ ctx2.miterLimit = 2;
3714
+ ctx2.strokeStyle = strokeColor;
3715
+ ctx2.strokeText(line, x, y);
3716
+ }
3717
+ ctx2.fillStyle = color;
3718
+ ctx2.fillText(line, x, y);
3719
+ });
3720
+ const texture = new THREE2.CanvasTexture(canvas);
3721
+ texture.needsUpdate = true;
3722
+ texture.minFilter = THREE2.LinearFilter;
3723
+ return texture;
3676
3724
  }
3677
- hideMarkers(elements, ordinalDiff = 0) {
3725
+ _updatePosition() {
3726
+ const options = this.getOptions();
3727
+ const layer = options.layer;
3728
+ if (!layer) return;
3729
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3730
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3731
+ const position = layer.coordinateToVector3(this._coordinate, z);
3732
+ (0, import_lodash6.set)(this.properties, "default.position", position);
3733
+ this.getObject3d().position.copy(position);
3678
3734
  }
3679
- };
3680
-
3681
- // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3682
- var maptalks7 = __toESM(require("maptalks"));
3683
-
3684
- // src/IndoorMap/renderer/utils/svg2material.ts
3685
- var import_three7 = require("three");
3686
- var svgToDataURL = (svgString, scaleFactor = 1) => {
3687
- const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3688
- const url = URL.createObjectURL(svgBlob);
3689
- const img = new Image();
3690
- return new Promise((resolve, reject) => {
3691
- img.onload = function() {
3692
- const newWidth = img.width * scaleFactor;
3693
- const newHeight = img.height * scaleFactor;
3694
- const canvas = document.createElement("canvas");
3695
- canvas.width = newWidth;
3696
- canvas.height = newHeight;
3697
- const ctx = canvas.getContext("2d");
3698
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
3699
- const pngDataUrl = canvas.toDataURL("image/png");
3700
- resolve(pngDataUrl);
3701
- };
3702
- img.onerror = function(error) {
3703
- reject(error);
3704
- };
3705
- img.src = url;
3706
- });
3707
- };
3708
- var createSVGPathFromMarkerSymbol2 = (style) => {
3709
- const {
3710
- markerWidth = 24,
3711
- markerDx = 0,
3712
- markerDy = 0,
3713
- // markerFill,
3714
- markerPath,
3715
- fill = "#000000"
3716
- } = style;
3717
- const scale2 = markerWidth / 24;
3718
- const strokeWidth = 2;
3719
- const halfStrokeWidth = 0.5 * strokeWidth;
3720
- if (Array.isArray(markerPath)) {
3721
- return markerPath.map(
3722
- ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3723
- );
3735
+ _animation() {
3736
+ const layer = this.getLayer();
3737
+ if (!this.isAdd || !layer) return;
3738
+ if (this._visible === true) {
3739
+ const zoom = layer.map.getZoom();
3740
+ const object3d = this.getObject3d();
3741
+ const { opacity } = this.getOptions();
3742
+ let opacityValue;
3743
+ if (typeof opacity === "number") {
3744
+ opacityValue = opacity ?? 1;
3745
+ } else if (Array.isArray(opacity.stops)) {
3746
+ opacityValue = interpolateStops(opacity, zoom);
3747
+ } else {
3748
+ throw new Error(`Unknown opacity value ${opacity}`);
3749
+ }
3750
+ const visible = opacityValue > 0.5;
3751
+ object3d.visible = visible;
3752
+ }
3724
3753
  }
3725
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3726
- };
3727
- var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3728
- const material = new import_three7.SpriteMaterial();
3729
- try {
3730
- const [base, icon] = labelSymbol ?? [{}, {}];
3731
- const { markerWidth: baseWidth = 24 } = base;
3732
- const { markerWidth: iconWidth = 24 } = icon;
3733
- const viewBoxDimension = Math.max(baseWidth, iconWidth);
3734
- const baseSVG = createSVGPathFromMarkerSymbol2(base);
3735
- const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3736
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3737
- const textureLoader = new import_three7.TextureLoader();
3738
- const scaleFactor = 200 / 24;
3739
- svgToDataURL(svg, scaleFactor).then((png) => {
3740
- const texture = textureLoader.load(png, () => {
3741
- material.map = texture;
3742
- material.needsUpdate = true;
3743
- });
3744
- });
3745
- } catch (error) {
3746
- console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3754
+ setText(text) {
3755
+ const options = this.getOptions();
3756
+ options.text = text;
3757
+ const newSprite = this._createSprite();
3758
+ const group = this.getObject3d();
3759
+ group.children.forEach((child) => group.remove(child));
3760
+ group.add(newSprite);
3761
+ this._updatePosition();
3762
+ }
3763
+ setAltitude(altitude) {
3764
+ const bottomHeight = this.options.bottomHeight ?? 0;
3765
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3747
3766
  }
3748
- return material;
3749
3767
  };
3750
3768
 
3751
3769
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
@@ -3796,40 +3814,41 @@ var Marker3DRenderer = class extends EventTarget {
3796
3814
  });
3797
3815
  }
3798
3816
  /** Marker */
3799
- getOrCreateIconMaterial(key) {
3800
- if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3801
- const existingMaterial = this.materialByKey.get(key);
3802
- if (existingMaterial) return existingMaterial;
3803
- const baseSymbol = {
3804
- markerType: "path",
3805
- markerPath: [
3806
- {
3807
- path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3808
- fill: "#ff0000"
3809
- }
3810
- ],
3811
- markerPathWidth: 24,
3812
- markerPathHeight: 24
3813
- };
3814
- const markerSymbol = {
3815
- markerType: "path",
3816
- markerPath: [],
3817
- // TODO: Get Path by featureType.category
3818
- // markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
3819
- markerPathWidth: 24,
3820
- markerPathHeight: 24,
3821
- markerWidth: 24,
3822
- markerHeight: 24,
3823
- markerDy: 1.5,
3824
- markerDx: 1.5
3825
- };
3826
- const created = createSpriteMaterialByLabelSymbol2([
3827
- baseSymbol,
3828
- markerSymbol
3829
- ]);
3830
- this.materialByKey.set(key, created);
3831
- return created;
3832
- }
3817
+ // getOrCreateIconMaterial(key) {
3818
+ // if (!this.materialByKey) this.materialByKey = new Map()
3819
+ // const existingMaterial = this.materialByKey.get(key)
3820
+ // if (existingMaterial) return existingMaterial
3821
+ // // Create new
3822
+ // const baseSymbol: maptalks.Path = {
3823
+ // markerType: "path",
3824
+ // markerPath: [
3825
+ // {
3826
+ // path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3827
+ // fill: "#ff0000",
3828
+ // },
3829
+ // ],
3830
+ // markerPathWidth: 24,
3831
+ // markerPathHeight: 24
3832
+ // }
3833
+ // const markerSymbol: maptalks.PathMarkerSymbol = {
3834
+ // markerType: "path",
3835
+ // markerPath: [],
3836
+ // // TODO: Get Path by featureType.category
3837
+ // // markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
3838
+ // markerPathWidth: 24,
3839
+ // markerPathHeight: 24,
3840
+ // markerWidth: 24,
3841
+ // markerHeight: 24,
3842
+ // markerDy: 1.5,
3843
+ // markerDx: 1.5,
3844
+ // }
3845
+ // const created = createSpriteMaterialByLabelSymbol([
3846
+ // baseSymbol,
3847
+ // markerSymbol,
3848
+ // ])
3849
+ // this.materialByKey.set(key, created)
3850
+ // return created
3851
+ // }
3833
3852
  };
3834
3853
 
3835
3854
  // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
@@ -3851,11 +3870,17 @@ var angleBetweenLineStrings = (line1, line2) => {
3851
3870
  };
3852
3871
 
3853
3872
  // src/IndoorMap/renderer/RendererManager.ts
3873
+ function delay(ms) {
3874
+ return new Promise((resolve) => setTimeout(resolve, ms));
3875
+ }
3854
3876
  var RendererManager = class extends EventTarget {
3855
3877
  map;
3856
3878
  options;
3857
3879
  // Client for fetching data
3858
3880
  #dataClient;
3881
+ #isClicked = false;
3882
+ #onClickElement = (e) => {
3883
+ };
3859
3884
  /** Elements: Responsible for converting feature info elements and add to map */
3860
3885
  elementRenderer;
3861
3886
  markerRenderer;
@@ -3864,6 +3889,7 @@ var RendererManager = class extends EventTarget {
3864
3889
  currentOrdinals;
3865
3890
  markersMap;
3866
3891
  markersByOrdinal;
3892
+ highlightControllers = [];
3867
3893
  constructor(map, dataClient, options) {
3868
3894
  super();
3869
3895
  this.map = map;
@@ -3873,48 +3899,52 @@ var RendererManager = class extends EventTarget {
3873
3899
  this.markersMap = /* @__PURE__ */ new Map();
3874
3900
  this.markersByOrdinal = /* @__PURE__ */ new Map();
3875
3901
  this.#dataClient = dataClient;
3902
+ const _this = this;
3876
3903
  if (options.type === "3D") {
3877
- const threeLayer = new import_maptalks8.ThreeLayer("elements", {
3878
- forceRenderOnMoving: true,
3879
- forceRenderOnRotating: true
3880
- });
3881
- const _this = this;
3904
+ const groupLayer = this.map.getLayer("group");
3905
+ const threeLayer = groupLayer.getLayer("three");
3882
3906
  threeLayer.prepareToDraw = function(gl, scene, camera) {
3883
3907
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3884
3908
  scene.add(ambientLight);
3885
3909
  const dirColor = 16777215;
3886
3910
  const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3887
- dllight.position.set(0, -10, 10).normalize();
3911
+ dllight.position.set(0, -10, 20).normalize();
3888
3912
  scene.add(dllight);
3889
3913
  const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3890
3914
  scene.add(hemi);
3891
- _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
3915
+ _this.elementRenderer = new Element3DRenderer(map, options.elements);
3892
3916
  _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3893
3917
  if (typeof options.onRendererReady === "function") {
3894
3918
  options.onRendererReady();
3895
3919
  }
3896
3920
  _this.#createElements();
3897
3921
  };
3898
- threeLayer.addTo(this.map);
3899
3922
  } else {
3900
3923
  this.elementRenderer = new Element2DRenderer(map, options.elements);
3901
3924
  this.markerRenderer = new Marker2DRenderer(map);
3902
3925
  this.#createElements();
3903
3926
  }
3904
3927
  }
3928
+ set onClickElement(func) {
3929
+ this.#onClickElement = func;
3930
+ }
3931
+ handleClickElement = (e) => {
3932
+ if (this.#isClicked) return;
3933
+ this.#isClicked = true;
3934
+ const onClickElement = this.#onClickElement;
3935
+ if (!(0, import_isFunction.default)(onClickElement)) return;
3936
+ this.#onClickElement(e);
3937
+ this.#isClicked = false;
3938
+ };
3905
3939
  getElementsByOrdinal = (ordinal) => {
3906
3940
  const exist = this.elementsByOrdinal.get(ordinal);
3907
3941
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3908
3942
  return this.elementsByOrdinal.get(ordinal);
3909
3943
  };
3910
- getMarkersByOrdinal = (ordinal) => {
3911
- const exist = this.markersByOrdinal.get(ordinal);
3912
- if (!exist) this.markersByOrdinal.set(ordinal, []);
3913
- return this.markersByOrdinal.get(ordinal);
3914
- };
3915
3944
  addElementsToManager = (id, elements, ordinal) => {
3916
3945
  this.elementsMap.set(id, elements);
3917
3946
  elements.forEach((el) => {
3947
+ el.on("click", (e) => this.handleClickElement(id));
3918
3948
  this.getElementsByOrdinal(ordinal).push(el);
3919
3949
  });
3920
3950
  const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
@@ -3924,19 +3954,8 @@ var RendererManager = class extends EventTarget {
3924
3954
  this.elementRenderer.hideElements(elements, ordinal);
3925
3955
  }
3926
3956
  };
3927
- addMarkersToManager = (id, markers, ordinal) => {
3928
- this.markersMap.set(id, markers);
3929
- markers.forEach((el) => {
3930
- this.getMarkersByOrdinal(ordinal).push(el);
3931
- });
3932
- const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3933
- if (inOrdinal) {
3934
- this.markerRenderer.showMarkers(markers, ordinal);
3935
- } else {
3936
- this.markerRenderer.hideMarkers(markers, ordinal);
3937
- }
3938
- };
3939
3957
  async #createElements() {
3958
+ await delay(this.options.delayBeforeCreateElements ?? 0);
3940
3959
  const levels = await this.#dataClient.filterByType("level", {
3941
3960
  populate: true
3942
3961
  });
@@ -3983,13 +4002,15 @@ var RendererManager = class extends EventTarget {
3983
4002
  }
3984
4003
  const thisOrdinal = escalator.properties.ordinal;
3985
4004
  const relationship = escalatorRelationships[0];
4005
+ if (!relationship.properties.origin?.id) throw new Error(`relationship (id=${relationship.id}) - origin not exists`);
4006
+ if (!relationship.properties.destination?.id) throw new Error(`relationship (id=${relationship.id}) - destination not exists`);
3986
4007
  const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
3987
4008
  const bothOpenings = await Promise.all(
3988
4009
  bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
3989
4010
  );
3990
4011
  const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
3991
4012
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
3992
- const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4013
+ const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
3993
4014
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
3994
4015
  const escalatorEntryPoint = (0, import_center3.center)(thisLevelOpening).geometry.coordinates;
3995
4016
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
@@ -3998,7 +4019,7 @@ var RendererManager = class extends EventTarget {
3998
4019
  this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
3999
4020
  }
4000
4021
  } catch (err) {
4001
- console.log(`cannot create escalator`, err);
4022
+ console.warn(`cannot create escalator`, err.message);
4002
4023
  }
4003
4024
  }
4004
4025
  this.changeLevelByOrdinal(this.currentOrdinals);
@@ -4034,14 +4055,48 @@ var RendererManager = class extends EventTarget {
4034
4055
  }
4035
4056
  }
4036
4057
  }
4058
+ highlightElements = (elemIds, options) => {
4059
+ const { reset = true } = options ?? {};
4060
+ if (reset) {
4061
+ this.clearHighlightElements();
4062
+ }
4063
+ const elements = elemIds.map((id) => this.elementsMap.get(id)).flat();
4064
+ elements.forEach((element) => {
4065
+ const controller = this.elementRenderer.createHighlightController(element);
4066
+ controller.start();
4067
+ this.highlightControllers.push(controller);
4068
+ });
4069
+ };
4070
+ clearHighlightElements = () => {
4071
+ this.highlightControllers.forEach((controller) => {
4072
+ if ((0, import_isFunction.default)(controller?.clear)) controller.clear();
4073
+ });
4074
+ };
4037
4075
  /**
4038
4076
  * ========================================================================
4039
4077
  * Markers
4040
4078
  * ======================================================================== */
4079
+ _getMarkersByOrdinal = (ordinal) => {
4080
+ const exist = this.markersByOrdinal.get(ordinal);
4081
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
4082
+ return this.markersByOrdinal.get(ordinal);
4083
+ };
4084
+ _addMarkersToManager = (id, markers, ordinal) => {
4085
+ this.markersMap.set(id, markers);
4086
+ markers.forEach((el) => {
4087
+ this._getMarkersByOrdinal(ordinal).push(el);
4088
+ });
4089
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
4090
+ if (inOrdinal) {
4091
+ this.markerRenderer.showMarkers(markers, ordinal);
4092
+ } else {
4093
+ this.markerRenderer.hideMarkers(markers, ordinal);
4094
+ }
4095
+ };
4041
4096
  createMarker(coordinate, ordinal, text, options) {
4042
4097
  const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
4043
4098
  const markerId = `${this.markersMap.size + 1}`;
4044
- this.addMarkersToManager(markerId, [marker], ordinal);
4099
+ this._addMarkersToManager(markerId, [marker], ordinal);
4045
4100
  }
4046
4101
  clearMarkers() {
4047
4102
  for (const [markerId, marker] of this.markersMap) {
@@ -4059,6 +4114,7 @@ var defaultOptions = {
4059
4114
  locale: DEFAULT_LOCALE
4060
4115
  };
4061
4116
  var IndoorMap = class extends EventTarget {
4117
+ options;
4062
4118
  //TODO: refac functions; let them do only 1 thing in a function
4063
4119
  /** Note: "#" means private variables */
4064
4120
  #styler = null;
@@ -4110,14 +4166,18 @@ var IndoorMap = class extends EventTarget {
4110
4166
  };
4111
4167
  constructor(elementId, options) {
4112
4168
  super();
4169
+ const combinedOptions = import_lodash7.default.merge({}, defaultOptions, options);
4170
+ this.options = options;
4113
4171
  const {
4114
4172
  onMapReady,
4115
4173
  onMapLoading,
4116
4174
  pixelRatio,
4117
4175
  locale
4118
- } = import_lodash7.default.merge({}, defaultOptions, options);
4176
+ } = combinedOptions;
4119
4177
  this.map = new import_maptalks_gl.Map(elementId, {
4120
4178
  attribution: false,
4179
+ // Temporart set, not really default view
4180
+ // Default view is set in camera manager
4121
4181
  center: INITIAL_CENTER,
4122
4182
  zoom: INITIAL_ZOOM,
4123
4183
  clickTimeThreshold: 600,
@@ -4133,8 +4193,16 @@ var IndoorMap = class extends EventTarget {
4133
4193
  }),
4134
4194
  layers: []
4135
4195
  });
4196
+ const groupLayer = new import_maptalks_gl.GroupGLLayer("group", [], {}).addTo(this.map);
4197
+ const threeLayer = new import_maptalks10.ThreeLayer("three", {
4198
+ forceRenderOnMoving: true,
4199
+ forceRenderOnRotating: true
4200
+ });
4201
+ groupLayer.addLayer(threeLayer);
4202
+ const gltfLayer = new import_maptalks_gl.GLTFLayer("gltf");
4203
+ groupLayer.addLayer(gltfLayer);
4136
4204
  this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
4137
- this.camera = new CameraManager(this.map);
4205
+ this.camera = new CameraManager(this.map, options.camera);
4138
4206
  this.locale = locale;
4139
4207
  this.pixelRatio = pixelRatio;
4140
4208
  this.onMapReady = onMapReady;
@@ -4145,19 +4213,21 @@ var IndoorMap = class extends EventTarget {
4145
4213
  }
4146
4214
  set dataClient(value) {
4147
4215
  this.#dataClient = value;
4148
- this.#dataClient.filterByType("venue").then((venues) => {
4149
- const venueCenters = (0, import_center4.default)(featureCollection(venues));
4150
- const [x, y] = venueCenters.geometry.coordinates;
4151
- const center2 = new import_maptalks_gl.Coordinate(x, y);
4152
- this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4153
- });
4154
- }
4155
- on(eventName, handler) {
4156
- this.map.on(eventName, handler);
4216
+ if (!this.options.camera?.defaultView?.center) {
4217
+ this.#dataClient.filterByType("venue").then((venues) => {
4218
+ const venueCenters = (0, import_center4.default)(featureCollection(venues));
4219
+ const [x, y] = venueCenters.geometry.coordinates;
4220
+ const center2 = new import_maptalks_gl.Coordinate(x, y);
4221
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4222
+ });
4223
+ }
4157
4224
  }
4158
4225
  /**
4159
4226
  * Events
4160
4227
  */
4228
+ on(eventName, handler) {
4229
+ this.map.on(eventName, handler);
4230
+ }
4161
4231
  handleMapClick = ({ coordinate }) => {
4162
4232
  const { x, y } = coordinate;
4163
4233
  console.log(
@@ -4213,40 +4283,12 @@ var IndoorMap = class extends EventTarget {
4213
4283
  this.map.off("moveend", this.#findAndSetVenueInView);
4214
4284
  }
4215
4285
  }
4216
- get ordinals() {
4217
- return this.#ordinals || [];
4218
- }
4219
- set ordinals(value) {
4220
- if (!Array.isArray(value)) throw new Error("ordinals must be Array");
4221
- this.#ordinals = value;
4222
- }
4223
4286
  set billboards(value) {
4224
4287
  this.#billboards = value;
4225
4288
  }
4226
- set mapConfig(value) {
4227
- this.#mapConfig = value;
4228
- }
4229
4289
  set mapDecorations(value) {
4230
4290
  this.#mapDecorations = value;
4231
4291
  }
4232
- set maxZoom(value) {
4233
- this.map.setMaxZoom(value);
4234
- const spatialReference = {
4235
- projection: "EPSG:3857",
4236
- resolutions: (function() {
4237
- const resolutions = [];
4238
- const d = 2 * 6378137 * Math.PI;
4239
- for (let i = 0; i < value; i++) {
4240
- resolutions[i] = d / (256 * Math.pow(2, i));
4241
- }
4242
- return resolutions;
4243
- })()
4244
- };
4245
- this.map.setSpatialReference(spatialReference);
4246
- }
4247
- set minZoom(value) {
4248
- this.map.setMinZoom(value);
4249
- }
4250
4292
  set groundLabels(value) {
4251
4293
  this.#groundLabels = value;
4252
4294
  }
@@ -4254,7 +4296,7 @@ var IndoorMap = class extends EventTarget {
4254
4296
  this.map.setDevicePixelRatio(value);
4255
4297
  }
4256
4298
  set onClickElement(func) {
4257
- this.#onClickElement = func;
4299
+ this.rendererManager.onClickElement = func;
4258
4300
  }
4259
4301
  set locale(value) {
4260
4302
  this.#locale = value || defaultOptions.locale;
@@ -4270,7 +4312,7 @@ var IndoorMap = class extends EventTarget {
4270
4312
  const scene = this.threeLayer.getScene();
4271
4313
  if (scene) {
4272
4314
  scene.children = scene.children.filter(
4273
- (children) => children instanceof import_three8.PerspectiveCamera
4315
+ (children) => children instanceof import_three7.PerspectiveCamera
4274
4316
  );
4275
4317
  }
4276
4318
  }
@@ -4282,9 +4324,6 @@ var IndoorMap = class extends EventTarget {
4282
4324
  this.#onClickElement(e);
4283
4325
  this.#isClicked = false;
4284
4326
  };
4285
- setCenter(center2, padding) {
4286
- this.map.setCenter(center2, padding);
4287
- }
4288
4327
  async #legacy_createElements() {
4289
4328
  const {
4290
4329
  // 2D
@@ -4298,33 +4337,14 @@ var IndoorMap = class extends EventTarget {
4298
4337
  create3DFootprint,
4299
4338
  create3DGroundLabel,
4300
4339
  create3DBillboard,
4301
- createVenue3DModel,
4302
4340
  createExtrudedUnit,
4303
- create3DFixture,
4304
4341
  create3DAmenityMarker,
4305
4342
  create3DOccupantAmenityMarker,
4306
4343
  create3DOpeningMarker,
4307
- createOccupantGroundLabel,
4308
- // Light
4309
- createAmbientLight,
4310
- createDirectionalLight
4344
+ createOccupantGroundLabel
4311
4345
  } = this.#styler;
4312
4346
  let elements = {};
4313
4347
  let object3ds = [];
4314
- const scene = this.threeLayer.getScene();
4315
- if (scene) {
4316
- const {
4317
- ambientLight: ambientLightConfig = {},
4318
- directionalLight: directionalLightConfig = {}
4319
- } = import_lodash7.default.get(this.#mapConfig, "light", {
4320
- ambientLight: {},
4321
- directionalLight: {}
4322
- });
4323
- const ambientLight = createAmbientLight(ambientLightConfig);
4324
- scene.add(ambientLight);
4325
- const light = createDirectionalLight(directionalLightConfig);
4326
- scene.add(light);
4327
- }
4328
4348
  for (const feature2 of this.#features) {
4329
4349
  try {
4330
4350
  const { feature_type: featureType, properties, id } = feature2;
@@ -4347,16 +4367,6 @@ var IndoorMap = class extends EventTarget {
4347
4367
  feature2
4348
4368
  );
4349
4369
  switch (featureType) {
4350
- case "venue": {
4351
- geometry = createVenue(feature2).addTo(layer);
4352
- const models = await createVenue3DModel(feature2, this.threeLayer);
4353
- models.forEach((model) => {
4354
- model.on("click", this.handleClickElement);
4355
- object3ds.push(model);
4356
- this.#venueObjects.push(model);
4357
- });
4358
- break;
4359
- }
4360
4370
  case "amenity": {
4361
4371
  if (feature2.properties.is_featured) {
4362
4372
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4400,127 +4410,6 @@ var IndoorMap = class extends EventTarget {
4400
4410
  geometry = createSection(feature2)?.addTo(layer);
4401
4411
  break;
4402
4412
  }
4403
- case "occupant": {
4404
- switch (category) {
4405
- // Create only marker if it is amenity occupant
4406
- case "currencyexchange":
4407
- case "donationcenter":
4408
- case "postoffice":
4409
- const markerFeature = {
4410
- ...feature2,
4411
- geometry: feature2.properties?.anchor?.geometry
4412
- };
4413
- const marker3d = create3DOccupantAmenityMarker(
4414
- markerFeature,
4415
- this.threeLayer,
4416
- extrudeConfig
4417
- )?.on("click", this.handleClickElement);
4418
- object3ds.push(marker3d);
4419
- break;
4420
- default: {
4421
- const { kiosk, anchor } = feature2.properties;
4422
- const { unit } = anchor.properties;
4423
- let mainLocation = kiosk || unit || null;
4424
- const relatedLocations = [
4425
- ...feature2.properties.units,
4426
- ...feature2.properties.kiosks
4427
- ].filter((f) => f.properties.ordinal !== properties.ordinal);
4428
- const occupantLocations = [mainLocation, ...relatedLocations];
4429
- const renderType = feature2.properties.render_type;
4430
- occupantLocations.forEach((location, index) => {
4431
- const isMainLocation = index === 0;
4432
- if (renderType === "Label") {
4433
- const occupantGroundLabel = createOccupantGroundLabel(
4434
- feature2,
4435
- location,
4436
- { textMarkerType, extrudeConfig },
4437
- this.threeLayer
4438
- );
4439
- if (occupantGroundLabel instanceof GroundLabel) {
4440
- occupantGroundLabel.on("click", this.handleClickElement);
4441
- occupantGroundLabel.addTo(this.threeLayer);
4442
- object3ds.push(occupantGroundLabel);
4443
- this.#groundObjects.push(occupantGroundLabel);
4444
- }
4445
- } else {
4446
- const occupantMarker = createOccupant(feature2, location, {
4447
- textMarkerType,
4448
- extrudeConfig
4449
- });
4450
- if (occupantMarker instanceof import_maptalks_gl.ui.UIMarker) {
4451
- occupantMarker.addTo(this.map);
4452
- } else {
4453
- occupantMarker?.on("click", this.handleClickElement);
4454
- occupantMarker?.addTo(layer);
4455
- }
4456
- if (isMainLocation) {
4457
- geometry = occupantMarker;
4458
- } else {
4459
- elements[`${feature2.id}_${index}`] = {
4460
- geometry: occupantMarker,
4461
- properties: location.properties,
4462
- featureType: "occupant",
4463
- feature: feature2
4464
- };
4465
- }
4466
- }
4467
- });
4468
- }
4469
- }
4470
- break;
4471
- }
4472
- case "fixture": {
4473
- const models = await create3DFixture(feature2, this.threeLayer);
4474
- models.forEach((model) => {
4475
- model.on("click", this.handleClickElement);
4476
- object3ds.push(model);
4477
- this.#glbObjects.push(model);
4478
- });
4479
- if (!featureExtrudeConfig) {
4480
- geometry = createFixture(feature2)?.addTo(layer);
4481
- } else {
4482
- const locatedLevel = feature2?.properties?.level;
4483
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4484
- extrudeConfig,
4485
- locatedLevel
4486
- );
4487
- const levelHeight = import_lodash7.default.get(levelExtrudeConfig, "height", 0);
4488
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4489
- const extrudedFixture = createExtrudedUnit(
4490
- feature2,
4491
- this.threeLayer,
4492
- option
4493
- );
4494
- object3ds.push(extrudedFixture);
4495
- }
4496
- break;
4497
- }
4498
- case "footprint": {
4499
- const objects = await create3DFootprint(
4500
- feature2,
4501
- this.threeLayer,
4502
- featureExtrudeConfig
4503
- );
4504
- objects.forEach((object) => {
4505
- object.on("click", () => {
4506
- const {
4507
- geometry: { coordinates }
4508
- } = (0, import_center4.default)(feature2);
4509
- this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4510
- });
4511
- object3ds.push(object);
4512
- this.#objects.push(object);
4513
- });
4514
- if (feature2.properties.logo) {
4515
- const footprintMarker = create3DBillboard(
4516
- feature2,
4517
- this.threeLayer
4518
- );
4519
- object3ds.push(footprintMarker);
4520
- this.#billboardObjects.push(footprintMarker);
4521
- }
4522
- break;
4523
- }
4524
4413
  default:
4525
4414
  break;
4526
4415
  }
@@ -4589,27 +4478,6 @@ var IndoorMap = class extends EventTarget {
4589
4478
  changeLevelByOrdinal(ordinal) {
4590
4479
  this.rendererManager.changeLevelByOrdinal(ordinal);
4591
4480
  }
4592
- getFeatureExtent = (feature2, scaleFactor = 1) => {
4593
- const [minX, minY, maxX, maxY] = index_default(
4594
- (0, import_transform_scale.default)((0, import_bbox_polygon.default)(index_default(feature2)), scaleFactor)
4595
- );
4596
- return new import_maptalks_gl.Extent(minX, minY, maxX, maxY);
4597
- };
4598
- getExtentCenter = (extent) => {
4599
- return extent.getCenter();
4600
- };
4601
- getExtentZoom = (extent, options = {
4602
- isFraction: false,
4603
- padding: {
4604
- paddingLeft: 0,
4605
- paddingRight: 0,
4606
- paddingTop: 0,
4607
- paddingBottom: 0
4608
- }
4609
- }) => {
4610
- const { isFraction = false, padding } = options;
4611
- return this.map.getFitZoom(extent, isFraction, padding);
4612
- };
4613
4481
  findVenueInView = () => {
4614
4482
  const mapCenter = this.map.getCenter();
4615
4483
  const result = this.#venues.reduce((closest, venue) => {
@@ -4622,9 +4490,6 @@ var IndoorMap = class extends EventTarget {
4622
4490
  }, null);
4623
4491
  return result;
4624
4492
  };
4625
- flyTo = (center2, options) => {
4626
- this.camera.flyTo(center2, options);
4627
- };
4628
4493
  getLineStringBearing = (feature2) => {
4629
4494
  const { geometry } = feature2;
4630
4495
  const path = new import_maptalks_gl.LineString(geometry.coordinates);
@@ -5140,33 +5005,6 @@ var IndoorMap = class extends EventTarget {
5140
5005
  /**
5141
5006
  * render (frame)
5142
5007
  */
5143
- getTargetViewCenter = (targetView, options = { offset: { top: 0, left: 0, right: 0, bottom: 0 } }) => {
5144
- const map = this.map;
5145
- const { offset } = options;
5146
- const { top = 0, left = 0, right = 0, bottom = 0 } = offset;
5147
- const originalState = {
5148
- bearing: map.getBearing(),
5149
- center: map.getCenter(),
5150
- pitch: map.getPitch(),
5151
- zoom: map.getZoom()
5152
- };
5153
- const finalView = {
5154
- bearing: import_lodash7.default.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5155
- center: import_lodash7.default.isNil(targetView.center) ? map.getCenter() : targetView.center,
5156
- pitch: import_lodash7.default.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5157
- zoom: import_lodash7.default.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5158
- };
5159
- map.setView(finalView);
5160
- const projectedTargetCenter = map.coordinateToContainerPoint(finalView.center).add(right / 2 - left / 2, bottom / 2 - top / 2);
5161
- const adjustedTargetCenter = map.containerPointToCoordinate(
5162
- projectedTargetCenter
5163
- );
5164
- map.setView(originalState);
5165
- return adjustedTargetCenter;
5166
- };
5167
- setMaxExtent(extent) {
5168
- return this.map.setMaxExtent(extent);
5169
- }
5170
5008
  render() {
5171
5009
  const view = this.map.getView();
5172
5010
  const currBearing = view.bearing;
@@ -5175,7 +5013,8 @@ var IndoorMap = class extends EventTarget {
5175
5013
  this.threeLayer.redraw();
5176
5014
  }
5177
5015
  if (this.threeLayer) {
5178
- const objectOpacity = import_lodash7.default.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5016
+ const currentView = this.camera.getView();
5017
+ const objectOpacity = import_lodash7.default.clamp(38 - 2 * currentView.zoom, 0, 1);
5179
5018
  this.#objects.forEach((object) => {
5180
5019
  object.getObject3d().traverse((child) => {
5181
5020
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5186,7 +5025,7 @@ var IndoorMap = class extends EventTarget {
5186
5025
  if (this.#billboardObjects) {
5187
5026
  this.#billboardObjects.forEach((object) => {
5188
5027
  const objectScale = import_lodash7.default.clamp(
5189
- 20 - 1 * this.camera.getZoom(),
5028
+ 20 - 1 * currentView.zoom,
5190
5029
  1,
5191
5030
  1.05
5192
5031
  );
@@ -5239,6 +5078,7 @@ var IndoorMap = class extends EventTarget {
5239
5078
  MARKER_LAYER_NAME,
5240
5079
  NONIMDF_FEATURE_TYPES,
5241
5080
  ORIGIN_MARKER_ID,
5081
+ OccupantHelpers,
5242
5082
  POI_MARKER_LAYER_NAME,
5243
5083
  QueryObserver,
5244
5084
  USER_LOCATION_ELEMENT_ID,
@@ -5248,7 +5088,8 @@ var IndoorMap = class extends EventTarget {
5248
5088
  createSpriteMaterialByLabelSymbol,
5249
5089
  createStyledUIMarkerElement,
5250
5090
  defaultFeatureQueryOptionsMap,
5251
- fetchFeature,
5091
+ fetchDeliveryApi,
5092
+ fetchPreviewApi,
5252
5093
  getBearingBetweenPoints,
5253
5094
  getCenterFromGeometry,
5254
5095
  getDataClient,
@@ -5265,6 +5106,16 @@ var IndoorMap = class extends EventTarget {
5265
5106
  getRelatedLocationsByOccupant,
5266
5107
  getSuitablyValueBetweenBearings,
5267
5108
  isClickableFeature,
5109
+ isValidCoordinate,
5110
+ isValidLineString,
5111
+ isValidLineStringCoordinates,
5112
+ isValidMultiPolygon,
5113
+ isValidMultiPolygonCoordinates,
5114
+ isValidPoint,
5115
+ isValidPolygon,
5116
+ isValidPolygonCoordinates,
5117
+ matchFilter,
5118
+ matchFilters,
5268
5119
  safeFetchFeature,
5269
5120
  styledFeatureGenerator
5270
5121
  });