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.mjs CHANGED
@@ -1,3 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
1
7
  // src/data/index.ts
2
8
  import { QueryObserver as QueryObserver2 } from "@tanstack/query-core";
3
9
 
@@ -79,7 +85,7 @@ var defaultFeatureQueryOptionsMap = {
79
85
  };
80
86
 
81
87
  // src/data/api/delivery-project.ts
82
- async function fetchFeature(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
88
+ async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
83
89
  switch (featureType) {
84
90
  case "label":
85
91
  case "element": {
@@ -113,20 +119,193 @@ async function fetchFeature(projectId, apiKey, featureType, baseUrl = DEFAULT_BA
113
119
  }
114
120
  }
115
121
  }
116
- var safeFetchFeature = async (projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) => {
122
+ async function fetchPreviewApi(projectId, previewToken, featureType, baseUrl = DEFAULT_BASE_URL) {
123
+ switch (featureType) {
124
+ case "label":
125
+ case "element": {
126
+ const pluralFeatureType = `${featureType}s`;
127
+ const res = await fetch(
128
+ `${baseUrl}/preview/projects/${projectId}/${pluralFeatureType}.geojson`,
129
+ {
130
+ headers: {
131
+ Authorization: `Bearer ${previewToken}`
132
+ }
133
+ }
134
+ );
135
+ if (res.status !== 200) return [];
136
+ const items = await res.json();
137
+ return items;
138
+ }
139
+ case "sponsored-content": {
140
+ const res = await fetch(
141
+ `${baseUrl}/preview/projects/${projectId}/sponsored-content.json`,
142
+ {
143
+ headers: {
144
+ Authorization: `Bearer ${previewToken}`
145
+ }
146
+ }
147
+ );
148
+ if (res.status !== 200) return [];
149
+ const jsonRes = await res.json();
150
+ const items = jsonRes.data;
151
+ return items.map((item) => ({
152
+ id: item.id,
153
+ ...item.attributes
154
+ }));
155
+ }
156
+ default: {
157
+ const res = await fetch(
158
+ `${baseUrl}/preview/projects/${projectId}/imdf/${featureType}.geojson`,
159
+ {
160
+ headers: {
161
+ Authorization: `Bearer ${previewToken}`
162
+ }
163
+ }
164
+ );
165
+ if (res.status !== 200) return [];
166
+ const collections = await res.json();
167
+ return collections.features;
168
+ }
169
+ }
170
+ }
171
+ var safeFetchFeature = async (featureType, params) => {
172
+ const mode = params.mode ?? "delivery";
173
+ const projectId = params.projectId;
174
+ const apiKey = params.apiKey;
175
+ const previewToken = params.previewToken;
176
+ const baseUrl = params.baseUrl ?? DEFAULT_BASE_URL;
117
177
  try {
118
- const result = await fetchFeature(
119
- projectId,
120
- apiKey,
121
- featureType,
122
- baseUrl
123
- );
178
+ let result = [];
179
+ if (mode === "delivery") {
180
+ result = await fetchDeliveryApi(
181
+ projectId,
182
+ apiKey,
183
+ featureType,
184
+ baseUrl
185
+ );
186
+ } else if (mode === "preview") {
187
+ result = await fetchPreviewApi(
188
+ projectId,
189
+ previewToken,
190
+ featureType,
191
+ baseUrl
192
+ );
193
+ }
124
194
  return result ?? [];
125
195
  } catch (e) {
126
196
  return Promise.resolve([]);
127
197
  }
128
198
  };
129
199
 
200
+ // src/data/utils/geometry-validator.ts
201
+ var isValidCoordinate = (point2) => {
202
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
203
+ };
204
+ function isValidLinearRingCoordinates(ring) {
205
+ if (ring.length < 4) {
206
+ return false;
207
+ }
208
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
209
+ }
210
+ var isValidPolygonCoordinates = (polygon) => {
211
+ if (Array.isArray(polygon[0]) && (polygon[0].length === 0 || typeof polygon[0][0] === "number")) {
212
+ return isValidLinearRingCoordinates(polygon);
213
+ }
214
+ if (Array.isArray(polygon) && polygon.length > 0 && Array.isArray(polygon[0])) {
215
+ if (!isValidLinearRingCoordinates(polygon[0])) {
216
+ return false;
217
+ }
218
+ for (let i = 1; i < polygon.length; i++) {
219
+ if (!isValidLinearRingCoordinates(polygon[i])) {
220
+ return false;
221
+ }
222
+ }
223
+ return true;
224
+ }
225
+ return false;
226
+ };
227
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
228
+ return multipolygon.every(isValidPolygonCoordinates);
229
+ };
230
+ var isValidLineStringCoordinates = (lineString2) => {
231
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
232
+ return false;
233
+ }
234
+ const firstPoint = lineString2[0];
235
+ const lastPoint = lineString2[lineString2.length - 1];
236
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
237
+ return false;
238
+ }
239
+ return lineString2.every(isValidCoordinate);
240
+ };
241
+ var isValidMultiPolygon = (geometry) => {
242
+ const { type, coordinates } = geometry;
243
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
244
+ };
245
+ var isValidPolygon = (geometry) => {
246
+ const { type, coordinates } = geometry;
247
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
248
+ };
249
+ var isValidLineString = (geometry) => {
250
+ const { type, coordinates } = geometry;
251
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
252
+ };
253
+ var isValidPoint = (geometry) => {
254
+ const { type, coordinates } = geometry;
255
+ return type === "Point" && isValidCoordinate(coordinates);
256
+ };
257
+
258
+ // src/data/utils/match-filters.ts
259
+ function isInFilter(filter) {
260
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
261
+ }
262
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
263
+ function matchFilter(value, filter) {
264
+ if (Array.isArray(value)) {
265
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
266
+ return value.includes(filter);
267
+ } else {
268
+ if (isInFilter(filter)) return filter.$in.includes(value);
269
+ return value === filter;
270
+ }
271
+ }
272
+ function matchFilters(item, filters) {
273
+ return Object.entries(filters).every(([key, filter]) => {
274
+ return matchFilter(item.properties[key], filter);
275
+ });
276
+ }
277
+
278
+ // src/data/utils/occupant-helper.ts
279
+ var occupant_helper_exports = {};
280
+ __export(occupant_helper_exports, {
281
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
282
+ getOccupantMainLocation: () => getOccupantMainLocation,
283
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
284
+ });
285
+ import _compact from "lodash/compact";
286
+ var getOccupantMainLocation = (occupant) => {
287
+ return occupant.properties.kiosk || occupant.properties.unit;
288
+ };
289
+ var getOccupantCorrelatedLocations = (occupant) => {
290
+ const allCorrelatedLocations = [
291
+ ...occupant.properties.units,
292
+ ...occupant.properties.kiosks
293
+ ];
294
+ return _compact(allCorrelatedLocations);
295
+ };
296
+ var getOccupantMarkerLocations = (occupant, options) => {
297
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
298
+ const mainLocation = getOccupantMainLocation(occupant);
299
+ const mainLocationLevel = mainLocation?.properties?.level_id;
300
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
301
+ if (placementType === "ALL_LOCATIONS") {
302
+ return _compact([mainLocation, ...allCorrelatedLocations]);
303
+ }
304
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
305
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
306
+ return _compact([mainLocation, ...onePerLevelLocations]);
307
+ };
308
+
130
309
  // src/data/getDataClient.ts
131
310
  import {
132
311
  QueryClient,
@@ -285,8 +464,8 @@ var createPopulator = ({
285
464
  venue,
286
465
  promotions,
287
466
  privileges,
288
- kiosk,
289
- unit,
467
+ kiosk: kiosk ? await populateKiosk(kiosk) : null,
468
+ unit: unit ? await populateUnit(unit) : null,
290
469
  kiosks: await Promise.all(kiosks.map(populateKiosk)),
291
470
  units: await Promise.all(units.map(populateUnit))
292
471
  }
@@ -378,42 +557,26 @@ var createPopulator = ({
378
557
  };
379
558
  };
380
559
 
381
- // src/data/utils/match-filters.ts
382
- function isInFilter(filter) {
383
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
384
- }
385
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
386
- function matchFilter(value, filter) {
387
- if (Array.isArray(value)) {
388
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
389
- return value.includes(filter);
390
- } else {
391
- if (isInFilter(filter)) return filter.$in.includes(value);
392
- return value === filter;
393
- }
394
- }
395
- function matchFilters(item, filters) {
396
- return Object.entries(filters).every(([key, filter]) => {
397
- return matchFilter(item.properties[key], filter);
398
- });
399
- }
400
-
401
560
  // src/data/getDataClient.ts
402
561
  var getDataClient = (options) => {
403
562
  const observers = /* @__PURE__ */ new Map();
404
563
  const queryClient = options.queryClient ?? new QueryClient();
405
- const { projectId, apiKey, baseUrl } = options;
564
+ const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
406
565
  if (!projectId)
407
566
  throw new Error(
408
567
  "Cannot create VenueDataClient. Reason: `projectId` is missing"
409
568
  );
410
- if (!apiKey)
569
+ if (mode === "delivery" && !apiKey)
411
570
  throw new Error(
412
571
  "Cannot create VenueDataClient. Reason: `apiKey` is missing"
413
572
  );
573
+ if (mode === "preview" && !previewToken)
574
+ throw new Error(
575
+ "Cannot create VenueDataClient. Reason: `previewToken` is missing"
576
+ );
414
577
  const createDeliveryApiQueryOptions = (featureType) => ({
415
578
  queryKey: ["_deliveryapi", featureType],
416
- queryFn: () => safeFetchFeature(projectId, apiKey, featureType, baseUrl)
579
+ queryFn: () => safeFetchFeature(featureType, { mode, projectId, apiKey, previewToken, baseUrl })
417
580
  });
418
581
  const internalFilterByType = async (featureType) => {
419
582
  try {
@@ -525,11 +688,13 @@ import {
525
688
  ui as ui3,
526
689
  Map as Map2,
527
690
  TileLayer,
528
- Extent,
529
691
  LineString as LineString3,
530
692
  Marker as Marker2,
531
- Coordinate as Coordinate4
693
+ Coordinate as Coordinate4,
694
+ GroupGLLayer,
695
+ GLTFLayer
532
696
  } from "maptalks-gl";
697
+ import "@maptalks/transcoders.draco";
533
698
  import TWEEN2 from "@tweenjs/tween.js";
534
699
  import _6 from "lodash";
535
700
 
@@ -611,133 +776,8 @@ function isNumber(num) {
611
776
  // src/IndoorMap/IndoorMap.ts
612
777
  import turfDistance from "@turf/distance";
613
778
  import turfCenter3 from "@turf/center";
614
-
615
- // ../../node_modules/@turf/meta/dist/esm/index.js
616
- function coordEach(geojson, callback, excludeWrapCoord) {
617
- if (geojson === null) return;
618
- 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;
619
- for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
620
- geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
621
- isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
622
- stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
623
- for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
624
- var multiFeatureIndex = 0;
625
- var geometryIndex = 0;
626
- geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
627
- if (geometry === null) continue;
628
- coords = geometry.coordinates;
629
- var geomType = geometry.type;
630
- wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
631
- switch (geomType) {
632
- case null:
633
- break;
634
- case "Point":
635
- if (callback(
636
- coords,
637
- coordIndex,
638
- featureIndex,
639
- multiFeatureIndex,
640
- geometryIndex
641
- ) === false)
642
- return false;
643
- coordIndex++;
644
- multiFeatureIndex++;
645
- break;
646
- case "LineString":
647
- case "MultiPoint":
648
- for (j = 0; j < coords.length; j++) {
649
- if (callback(
650
- coords[j],
651
- coordIndex,
652
- featureIndex,
653
- multiFeatureIndex,
654
- geometryIndex
655
- ) === false)
656
- return false;
657
- coordIndex++;
658
- if (geomType === "MultiPoint") multiFeatureIndex++;
659
- }
660
- if (geomType === "LineString") multiFeatureIndex++;
661
- break;
662
- case "Polygon":
663
- case "MultiLineString":
664
- for (j = 0; j < coords.length; j++) {
665
- for (k = 0; k < coords[j].length - wrapShrink; k++) {
666
- if (callback(
667
- coords[j][k],
668
- coordIndex,
669
- featureIndex,
670
- multiFeatureIndex,
671
- geometryIndex
672
- ) === false)
673
- return false;
674
- coordIndex++;
675
- }
676
- if (geomType === "MultiLineString") multiFeatureIndex++;
677
- if (geomType === "Polygon") geometryIndex++;
678
- }
679
- if (geomType === "Polygon") multiFeatureIndex++;
680
- break;
681
- case "MultiPolygon":
682
- for (j = 0; j < coords.length; j++) {
683
- geometryIndex = 0;
684
- for (k = 0; k < coords[j].length; k++) {
685
- for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
686
- if (callback(
687
- coords[j][k][l],
688
- coordIndex,
689
- featureIndex,
690
- multiFeatureIndex,
691
- geometryIndex
692
- ) === false)
693
- return false;
694
- coordIndex++;
695
- }
696
- geometryIndex++;
697
- }
698
- multiFeatureIndex++;
699
- }
700
- break;
701
- case "GeometryCollection":
702
- for (j = 0; j < geometry.geometries.length; j++)
703
- if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
704
- return false;
705
- break;
706
- default:
707
- throw new Error("Unknown Geometry Type");
708
- }
709
- }
710
- }
711
- }
712
-
713
- // ../../node_modules/@turf/bbox/dist/esm/index.js
714
- function bbox(geojson, options = {}) {
715
- if (geojson.bbox != null && true !== options.recompute) {
716
- return geojson.bbox;
717
- }
718
- const result = [Infinity, Infinity, -Infinity, -Infinity];
719
- coordEach(geojson, (coord) => {
720
- if (result[0] > coord[0]) {
721
- result[0] = coord[0];
722
- }
723
- if (result[1] > coord[1]) {
724
- result[1] = coord[1];
725
- }
726
- if (result[2] < coord[0]) {
727
- result[2] = coord[0];
728
- }
729
- if (result[3] < coord[1]) {
730
- result[3] = coord[1];
731
- }
732
- });
733
- return result;
734
- }
735
- var index_default = bbox;
736
-
737
- // src/IndoorMap/IndoorMap.ts
738
- import scale from "@turf/transform-scale";
739
- import bboxPolygon from "@turf/bbox-polygon";
740
779
  import { PerspectiveCamera } from "three";
780
+ import { ThreeLayer as ThreeLayer4 } from "maptalks.three";
741
781
 
742
782
  // src/IndoorMap/constants.ts
743
783
  var defaultLayerOption = { enableAltitude: true };
@@ -1759,18 +1799,6 @@ var loadModel3d = (model3d, coordinate, threeLayer) => {
1759
1799
  );
1760
1800
  });
1761
1801
  };
1762
- var create3DModels = async (models, defaultCoordinate, properties, threeLayer) => {
1763
- let modelObjs = [];
1764
- for (let j = 0; j < models.length; j++) {
1765
- const model = models[j];
1766
- const positionCoord = _4.get(model, "properties.position");
1767
- const coord = positionCoord || defaultCoordinate;
1768
- const object = await loadModel3d(model, coord, threeLayer);
1769
- object.properties = properties;
1770
- modelObjs.push(object);
1771
- }
1772
- return modelObjs;
1773
- };
1774
1802
  var createExtrudePolygon = (geometry, threeLayer, material, height, properties = {}, options) => {
1775
1803
  const { offset = 0, altitude = 0 } = options;
1776
1804
  const offsetGeometry = turfBuffer(geometry, offset, { units: "meters" });
@@ -2678,44 +2706,6 @@ var styledFeatureGenerator = (mapTheme) => {
2678
2706
  markerProperties
2679
2707
  );
2680
2708
  },
2681
- createVenue3DModel: async (venue, threeLayer) => {
2682
- const { id, feature_type, properties } = venue;
2683
- const { category, model3d } = properties;
2684
- const modelProperty = {
2685
- id,
2686
- feature_type,
2687
- category
2688
- };
2689
- const center2 = turfCenter(venue);
2690
- const centerCoord = _4.get(center2, "geometry.coordinates");
2691
- const modelPosition = _4.get(model3d, "properties.position", centerCoord);
2692
- const models = await create3DModels(
2693
- model3d,
2694
- modelPosition,
2695
- modelProperty,
2696
- threeLayer
2697
- );
2698
- return models;
2699
- },
2700
- create3DFixture: async (fixture, threeLayer) => {
2701
- const { id, feature_type, properties } = fixture;
2702
- const { category, ordinal, model3d } = properties;
2703
- const modelProperty = {
2704
- id,
2705
- feature_type,
2706
- category,
2707
- ordinal
2708
- };
2709
- const center2 = turfCenter(fixture);
2710
- const coordinate = _4.get(center2, "geometry.coordinates");
2711
- const models = await create3DModels(
2712
- model3d,
2713
- coordinate,
2714
- modelProperty,
2715
- threeLayer
2716
- );
2717
- return models;
2718
- },
2719
2709
  createExtrudedUnit: (unit, threeLayer, options) => {
2720
2710
  const extrudeHeight = _4.get(options, "height");
2721
2711
  if (!extrudeHeight) return;
@@ -2755,24 +2745,6 @@ var styledFeatureGenerator = (mapTheme) => {
2755
2745
  options3d
2756
2746
  );
2757
2747
  return object;
2758
- },
2759
- createAmbientLight: (config) => {
2760
- const { color: colorString = "0xffffff", intensity = 1 } = config;
2761
- const color = parseInt(colorString, 16);
2762
- const ambientLight = new AmbientLight(color, intensity);
2763
- return ambientLight;
2764
- },
2765
- createDirectionalLight: (config) => {
2766
- const {
2767
- color: colorString = "0xffffff",
2768
- intensity = 1,
2769
- position: positionString = [0, 0, 0]
2770
- } = config;
2771
- const color = parseInt(colorString, 16);
2772
- const [x, y, z] = positionString;
2773
- const light = new DirectionalLight(color, intensity);
2774
- light.position.set(x, y, z).normalize();
2775
- return light;
2776
2748
  }
2777
2749
  };
2778
2750
  };
@@ -2942,311 +2914,229 @@ var createHighlighExtrudeObjectController = (obj, { color }) => {
2942
2914
  };
2943
2915
 
2944
2916
  // src/IndoorMap/camera/CameraManager.ts
2945
- var ZOOM_OUT_LEVEL = 21;
2946
- var ZOOM_IN_LEVEL = 24;
2947
- var CameraManager = class {
2948
- map;
2917
+ import { Extent } from "maptalks";
2918
+
2919
+ // ../../node_modules/@turf/meta/dist/esm/index.js
2920
+ function coordEach(geojson, callback, excludeWrapCoord) {
2921
+ if (geojson === null) return;
2922
+ 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;
2923
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2924
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2925
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2926
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2927
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2928
+ var multiFeatureIndex = 0;
2929
+ var geometryIndex = 0;
2930
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2931
+ if (geometry === null) continue;
2932
+ coords = geometry.coordinates;
2933
+ var geomType = geometry.type;
2934
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2935
+ switch (geomType) {
2936
+ case null:
2937
+ break;
2938
+ case "Point":
2939
+ if (callback(
2940
+ coords,
2941
+ coordIndex,
2942
+ featureIndex,
2943
+ multiFeatureIndex,
2944
+ geometryIndex
2945
+ ) === false)
2946
+ return false;
2947
+ coordIndex++;
2948
+ multiFeatureIndex++;
2949
+ break;
2950
+ case "LineString":
2951
+ case "MultiPoint":
2952
+ for (j = 0; j < coords.length; j++) {
2953
+ if (callback(
2954
+ coords[j],
2955
+ coordIndex,
2956
+ featureIndex,
2957
+ multiFeatureIndex,
2958
+ geometryIndex
2959
+ ) === false)
2960
+ return false;
2961
+ coordIndex++;
2962
+ if (geomType === "MultiPoint") multiFeatureIndex++;
2963
+ }
2964
+ if (geomType === "LineString") multiFeatureIndex++;
2965
+ break;
2966
+ case "Polygon":
2967
+ case "MultiLineString":
2968
+ for (j = 0; j < coords.length; j++) {
2969
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2970
+ if (callback(
2971
+ coords[j][k],
2972
+ coordIndex,
2973
+ featureIndex,
2974
+ multiFeatureIndex,
2975
+ geometryIndex
2976
+ ) === false)
2977
+ return false;
2978
+ coordIndex++;
2979
+ }
2980
+ if (geomType === "MultiLineString") multiFeatureIndex++;
2981
+ if (geomType === "Polygon") geometryIndex++;
2982
+ }
2983
+ if (geomType === "Polygon") multiFeatureIndex++;
2984
+ break;
2985
+ case "MultiPolygon":
2986
+ for (j = 0; j < coords.length; j++) {
2987
+ geometryIndex = 0;
2988
+ for (k = 0; k < coords[j].length; k++) {
2989
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2990
+ if (callback(
2991
+ coords[j][k][l],
2992
+ coordIndex,
2993
+ featureIndex,
2994
+ multiFeatureIndex,
2995
+ geometryIndex
2996
+ ) === false)
2997
+ return false;
2998
+ coordIndex++;
2999
+ }
3000
+ geometryIndex++;
3001
+ }
3002
+ multiFeatureIndex++;
3003
+ }
3004
+ break;
3005
+ case "GeometryCollection":
3006
+ for (j = 0; j < geometry.geometries.length; j++)
3007
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
3008
+ return false;
3009
+ break;
3010
+ default:
3011
+ throw new Error("Unknown Geometry Type");
3012
+ }
3013
+ }
3014
+ }
3015
+ }
3016
+
3017
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
3018
+ function bbox(geojson, options = {}) {
3019
+ if (geojson.bbox != null && true !== options.recompute) {
3020
+ return geojson.bbox;
3021
+ }
3022
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
3023
+ coordEach(geojson, (coord) => {
3024
+ if (result[0] > coord[0]) {
3025
+ result[0] = coord[0];
3026
+ }
3027
+ if (result[1] > coord[1]) {
3028
+ result[1] = coord[1];
3029
+ }
3030
+ if (result[2] < coord[0]) {
3031
+ result[2] = coord[0];
3032
+ }
3033
+ if (result[3] < coord[1]) {
3034
+ result[3] = coord[1];
3035
+ }
3036
+ });
3037
+ return result;
3038
+ }
3039
+ var index_default = bbox;
3040
+
3041
+ // src/IndoorMap/camera/CameraManager.ts
3042
+ import scale from "@turf/transform-scale";
3043
+ import bboxPolygon from "@turf/bbox-polygon";
3044
+ var CameraManager = class {
3045
+ map;
2949
3046
  constructor(map, options) {
2950
3047
  this.map = map;
2951
3048
  if (options?.defaultView) {
2952
3049
  this.setView(options?.defaultView);
2953
3050
  }
2954
3051
  }
2955
- /** Private method */
2956
- #animateflyTo(viewOptions = {}, options = {}, callbackOption = () => {
2957
- }) {
2958
- const { start, end } = {
2959
- start: (frame) => {
2960
- },
2961
- end: (frame) => {
2962
- },
2963
- ...callbackOption
2964
- };
2965
- this.map.flyTo(viewOptions, options, (frame) => {
2966
- if (frame.state.playState === "running" && frame.state.progress === 0)
2967
- start(frame);
2968
- if (frame.state.playState === "finished") end(frame);
2969
- });
2970
- }
2971
3052
  /** Public methods */
2972
3053
  getView = () => {
2973
3054
  return this.map.getView();
2974
3055
  };
2975
- getZoom = () => {
2976
- return this.map.getView().zoom;
2977
- };
2978
3056
  setView = (value) => {
2979
- this.map.setView(value);
2980
- };
2981
- flyTo = (center2, options = {}) => {
2982
- const currentView = this.getView();
2983
- const {
2984
- zoom = ZOOM_OUT_LEVEL,
2985
- pitch = 60,
2986
- duration = 600,
2987
- easing = "out",
2988
- bearing = currentView.bearing
2989
- } = options;
2990
- this.#animateflyTo(
2991
- {
2992
- center: center2,
2993
- zoom,
2994
- pitch,
2995
- bearing
2996
- },
2997
- { duration, easing }
2998
- );
3057
+ if (this.map && Object.keys(value).length !== 0) {
3058
+ this.map.setView(value);
3059
+ }
2999
3060
  };
3000
- flyToAndZoomIn = (centerPoint, options = {}) => {
3001
- const {
3002
- zoom = ZOOM_IN_LEVEL,
3003
- pitch = 60,
3004
- duration = 600,
3005
- easing = "out"
3006
- } = options;
3007
- this.#animateflyTo(
3008
- {
3009
- center: centerPoint,
3010
- zoom,
3011
- pitch
3012
- },
3013
- { duration, easing }
3014
- );
3061
+ animateTo = (view, options = {}, step) => {
3062
+ this.map.animateTo(view, options, step);
3015
3063
  };
3016
- };
3017
-
3018
- // src/IndoorMap/renderer/RendererManager.ts
3019
- import _min from "lodash/min";
3020
- import { center as turfCenter2 } from "@turf/center";
3021
- import { ThreeLayer as ThreeLayer3 } from "maptalks.three";
3022
- import * as THREE3 from "three";
3023
-
3024
- // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3025
- import * as maptalks4 from "maptalks";
3026
- import * as THREE2 from "three";
3027
- import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader";
3028
- import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
3029
- import turfBuffer2 from "@turf/buffer";
3030
-
3031
- // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3032
- var element3DRendererOptions = {
3033
- unit: {
3034
- default: { color: "#ffffff", height: 4 },
3035
- byCategory: {
3036
- walkway: { color: "#cccccc", height: 0.1 },
3037
- terrace: { color: "#cccccc", height: 0.1 },
3038
- unenclosedarea: { color: "#cccccc", height: 0.2 },
3039
- nonpublic: { color: "#999999", height: 0.3 },
3040
- escalator: { height: 0.2 },
3041
- room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3042
- }
3043
- },
3044
- kiosk: {
3045
- default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3046
- },
3047
- fixture: {
3048
- default: { color: "#ffffff", height: 0.5 },
3049
- byCategory: {
3050
- water: { color: "#ACD7EC", height: 0.1 },
3051
- vegetation: { color: "#91C499", height: 0.5 }
3052
- }
3053
- }
3054
- };
3055
-
3056
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3057
- import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3058
- import * as THREE from "three";
3059
- import { BaseObject as BaseObject5 } from "maptalks.three";
3060
- import { isNil, set } from "lodash";
3061
-
3062
- // src/IndoorMap/renderer/utils/interpolateStops.ts
3063
- var interpolateStops = ({ stops }, zoom) => {
3064
- if (zoom <= stops[0][0]) return stops[0][1];
3065
- if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3066
- for (let i = 0; i < stops.length - 1; i++) {
3067
- const [z1, v1] = stops[i];
3068
- const [z2, v2] = stops[i + 1];
3069
- if (zoom >= z1 && zoom <= z2) {
3070
- const t = (zoom - z1) / (z2 - z1);
3071
- return v1 + t * (v2 - v1);
3072
- }
3073
- }
3074
- };
3075
-
3076
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3077
- var OPTIONS4 = {
3078
- // Texture options
3079
- text: "",
3080
- textAlign: "center",
3081
- color: "#ffffff",
3082
- fontFamily: "sans-serif",
3083
- fontSize: 28,
3084
- fontWeight: 400,
3085
- background: "rgba(0, 0, 0, 0.2)",
3086
- lineHeight: 32,
3087
- padding: 8,
3088
- strokeColor: "#000000",
3089
- strokeWidth: 6,
3090
- strokeStyle: "round",
3091
- // Sprite options
3092
- /* Overall scale multiplier */
3093
- scale: 1,
3094
- altitude: 0,
3095
- opacity: 1
3096
- };
3097
- var TextSpriteMarker = class extends BaseObject5 {
3098
- #altitudeOffset = 0;
3099
- constructor(coordinate, options, layer, properties = {}) {
3100
- options = Util4.extend({}, OPTIONS4, options, { layer });
3101
- super();
3102
- this._coordinate = new Coordinate2(coordinate);
3103
- this._initOptions(options);
3104
- this._createGroup();
3105
- this.properties = { ...properties };
3106
- const sprite = this._createSprite();
3107
- this.getObject3d().add(sprite);
3108
- this._updatePosition();
3109
- this.type = "TextSpriteMarker";
3110
- }
3111
- getOptions() {
3112
- return super.getOptions();
3064
+ setMaxExtent(extent) {
3065
+ return this.map.setMaxExtent(extent);
3113
3066
  }
3114
- _createSprite() {
3115
- const options = this.getOptions();
3116
- const texture = this._createTextTexture(options.text, options);
3117
- const material = new THREE.SpriteMaterial({
3118
- map: texture,
3119
- transparent: true,
3120
- alphaTest: 0.1
3121
- });
3122
- const sprite = new THREE.Sprite(material);
3123
- const w = texture.image.width;
3124
- const h = texture.image.height;
3125
- const base = 1 / 16;
3126
- const normalizedScale = options.scale / this.getMap().getGLRes();
3127
- sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3128
- this.#altitudeOffset = Math.max(
3129
- h * base * options.scale * 0.5,
3130
- 0.05
3131
- // minimum lift in world units
3067
+ getFeatureExtent = (feature2, scaleFactor = 1) => {
3068
+ const [minX, minY, maxX, maxY] = index_default(
3069
+ scale(bboxPolygon(index_default(feature2)), scaleFactor)
3132
3070
  );
3133
- return sprite;
3134
- }
3135
- _createTextTexture(text, options = {}) {
3136
- const {
3137
- padding,
3138
- fontSize,
3139
- fontFamily,
3140
- fontWeight,
3141
- lineHeight,
3142
- background,
3143
- color,
3144
- textAlign,
3145
- strokeColor,
3146
- strokeWidth,
3147
- maxWidth
3148
- } = options || {};
3149
- const canvas = document.createElement("canvas");
3150
- const ctx = canvas.getContext("2d");
3151
- ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3152
- const paragraphs = String(text).split("\n");
3153
- const wrappedLines = [];
3154
- paragraphs.forEach((paragraph) => {
3155
- if (isNil(maxWidth) || isNaN(maxWidth)) {
3156
- wrappedLines.push(paragraph);
3157
- return;
3158
- }
3159
- const words = paragraph.split(/\s+/);
3160
- let currentLine = "";
3161
- words.forEach((word) => {
3162
- const testLine = currentLine ? currentLine + " " + word : word;
3163
- const testWidth = ctx.measureText(testLine).width;
3164
- if (testWidth > maxWidth && currentLine) {
3165
- wrappedLines.push(currentLine);
3166
- currentLine = word;
3167
- } else {
3168
- currentLine = testLine;
3169
- }
3170
- });
3171
- if (currentLine) {
3172
- wrappedLines.push(currentLine);
3173
- }
3174
- });
3175
- const lines = wrappedLines.length ? wrappedLines : [""];
3176
- const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3177
- const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3178
- const finalHeight = lineHeight * lines.length + padding * 2;
3179
- canvas.width = finalWidth;
3180
- canvas.height = finalHeight;
3181
- const ctx2 = canvas.getContext("2d");
3182
- ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3183
- ctx2.textAlign = textAlign;
3184
- if (background && background !== "transparent") {
3185
- ctx2.fillStyle = background;
3186
- ctx2.fillRect(0, 0, canvas.width, canvas.height);
3187
- }
3188
- lines.forEach((line, i) => {
3189
- const y = padding + lineHeight * (i + 0.8);
3190
- let x = padding;
3191
- if (textAlign === "center") x = canvas.width / 2;
3192
- if (textAlign === "right" || textAlign === "end")
3193
- x = canvas.width - padding;
3194
- if (strokeWidth > 0) {
3195
- ctx2.lineWidth = strokeWidth;
3196
- ctx2.lineJoin = "round";
3197
- ctx2.miterLimit = 2;
3198
- ctx2.strokeStyle = strokeColor;
3199
- ctx2.strokeText(line, x, y);
3200
- }
3201
- ctx2.fillStyle = color;
3202
- ctx2.fillText(line, x, y);
3203
- });
3204
- const texture = new THREE.CanvasTexture(canvas);
3205
- texture.needsUpdate = true;
3206
- texture.minFilter = THREE.LinearFilter;
3207
- return texture;
3208
- }
3209
- _updatePosition() {
3210
- const options = this.getOptions();
3211
- const layer = options.layer;
3212
- if (!layer) return;
3213
- const altitude = (options.altitude || 0) + this.#altitudeOffset;
3214
- const z = layer.altitudeToVector3(altitude, altitude).x;
3215
- const position = layer.coordinateToVector3(this._coordinate, z);
3216
- set(this.properties, "default.position", position);
3217
- this.getObject3d().position.copy(position);
3218
- }
3219
- _animation() {
3220
- const layer = this.getLayer();
3221
- if (!this.isAdd || !layer) return;
3222
- if (this._visible === true) {
3223
- const zoom = layer.map.getZoom();
3224
- const object3d = this.getObject3d();
3225
- const { opacity } = this.getOptions();
3226
- let opacityValue;
3227
- if (typeof opacity === "number") {
3228
- opacityValue = opacity ?? 1;
3229
- } else if (Array.isArray(opacity.stops)) {
3230
- opacityValue = interpolateStops(opacity, zoom);
3231
- } else {
3232
- throw new Error(`Unknown opacity value ${opacity}`);
3233
- }
3234
- const visible = opacityValue > 0.5;
3235
- object3d.visible = visible;
3071
+ return new Extent(minX, minY, maxX, maxY);
3072
+ };
3073
+ getExtentZoom = (extent, options = {
3074
+ isFraction: false,
3075
+ padding: {
3076
+ paddingLeft: 0,
3077
+ paddingRight: 0,
3078
+ paddingTop: 0,
3079
+ paddingBottom: 0
3236
3080
  }
3081
+ }) => {
3082
+ const { isFraction = false, padding } = options;
3083
+ return this.map.getFitZoom(extent, isFraction, padding);
3084
+ };
3085
+ set maxZoom(value) {
3086
+ this.map.setMaxZoom(value);
3087
+ const spatialReference = {
3088
+ projection: "EPSG:3857",
3089
+ resolutions: (function() {
3090
+ const resolutions = [];
3091
+ const d = 2 * 6378137 * Math.PI;
3092
+ for (let i = 0; i < value; i++) {
3093
+ resolutions[i] = d / (256 * Math.pow(2, i));
3094
+ }
3095
+ return resolutions;
3096
+ })()
3097
+ };
3098
+ this.map.setSpatialReference(spatialReference);
3237
3099
  }
3238
- setText(text) {
3239
- const options = this.getOptions();
3240
- options.text = text;
3241
- const newSprite = this._createSprite();
3242
- const group = this.getObject3d();
3243
- group.children.forEach((child) => group.remove(child));
3244
- group.add(newSprite);
3245
- this._updatePosition();
3100
+ set minZoom(value) {
3101
+ this.map.setMinZoom(value);
3246
3102
  }
3247
- setAltitude(altitude) {
3248
- const bottomHeight = this.options.bottomHeight ?? 0;
3249
- return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3103
+ };
3104
+
3105
+ // src/IndoorMap/renderer/RendererManager.ts
3106
+ import _isFunction from "lodash/isFunction";
3107
+ import _min from "lodash/min";
3108
+ import { center as turfCenter2 } from "@turf/center";
3109
+ import * as THREE3 from "three";
3110
+
3111
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3112
+ import * as maptalks4 from "maptalks-gl";
3113
+ import * as THREE from "three";
3114
+ import { BaseObject as BaseObject5 } from "maptalks.three";
3115
+ import turfBuffer2 from "@turf/buffer";
3116
+
3117
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3118
+ var element3DRendererOptions = {
3119
+ unit: {
3120
+ default: { color: "#ffffff", height: 4 },
3121
+ byCategory: {
3122
+ walkway: { color: "#cccccc", height: 0.1 },
3123
+ terrace: { color: "#cccccc", height: 0.1 },
3124
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3125
+ nonpublic: { color: "#999999", height: 0.3 },
3126
+ escalator: { height: 0.2 },
3127
+ parking: { height: 0.1 },
3128
+ room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3129
+ }
3130
+ },
3131
+ kiosk: {
3132
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3133
+ },
3134
+ fixture: {
3135
+ default: { color: "#ffffff", height: 0.5 },
3136
+ byCategory: {
3137
+ water: { color: "#ACD7EC", height: 0.1 },
3138
+ vegetation: { color: "#91C499", height: 0.5 }
3139
+ }
3250
3140
  }
3251
3141
  };
3252
3142
 
@@ -3270,21 +3160,22 @@ var getGeometryOption = (feature2, options) => {
3270
3160
  var Element3DRenderer = class extends EventTarget {
3271
3161
  options;
3272
3162
  map;
3163
+ gltfLayer;
3273
3164
  threeLayer;
3274
- dracoLoader;
3165
+ scene;
3166
+ // private dracoLoader: DRACOLoader
3275
3167
  lineMaterial;
3276
3168
  materialByColorMap;
3277
- markerRenderer;
3278
3169
  // Renderer is Ready
3279
3170
  isReady = false;
3280
- constructor(map, options, layer) {
3171
+ constructor(map, options) {
3281
3172
  super();
3282
3173
  this.options = options;
3283
3174
  this.map = map;
3284
- this.dracoLoader = new DRACOLoader();
3285
- this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
3286
- this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3287
- this.threeLayer = layer;
3175
+ const groupLayer = this.map.getLayer("group");
3176
+ this.threeLayer = groupLayer.getLayer("three");
3177
+ this.gltfLayer = groupLayer.getLayer("gltf");
3178
+ this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
3288
3179
  this.render();
3289
3180
  }
3290
3181
  animation() {
@@ -3299,7 +3190,7 @@ var Element3DRenderer = class extends EventTarget {
3299
3190
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3300
3191
  const existingMaterial = this.materialByColorMap.get(color);
3301
3192
  if (existingMaterial) return existingMaterial;
3302
- const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3193
+ const created = new THREE.MeshLambertMaterial({ color, transparent: true });
3303
3194
  created.toneMapped = false;
3304
3195
  this.materialByColorMap.set(color, created);
3305
3196
  return created;
@@ -3314,46 +3205,48 @@ var Element3DRenderer = class extends EventTarget {
3314
3205
  } = getGeometryOption(feature2, this.options);
3315
3206
  const _this = this;
3316
3207
  const createPolygon = (geometry, feature3) => {
3317
- const [outerRing, ...innerRings] = geometry.coordinates;
3318
- const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3319
- const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3320
- if (color === "transparent") return;
3321
- const material = this.getOrCreateMaterialByColor(color);
3322
- const altitude = feature3.properties.ordinal * HEIGHT_METER;
3323
- const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3324
- const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3325
- const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3326
- offsetFeature,
3327
- { asynchronous: true, ...options, height, bottomHeight, altitude },
3328
- material
3329
- );
3330
- extrudedPolygon.on("click", (e) => {
3331
- console.log(e.target.options.polygon.id);
3332
- });
3333
- const topLineStrings = [
3334
- new maptalks4.LineString(outerRing),
3335
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3336
- ];
3337
- const topLines = this.threeLayer.toLines(
3338
- topLineStrings,
3339
- { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3340
- this.lineMaterial
3341
- );
3342
- const bottomLineStrings = [
3343
- new maptalks4.LineString(outerRing),
3344
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3345
- ];
3346
- const bottomLines = this.threeLayer.toLines(
3347
- bottomLineStrings,
3348
- { altitude, bottomHeight, interactive: false },
3349
- this.lineMaterial
3350
- );
3351
- return [extrudedPolygon, topLines, bottomLines];
3208
+ try {
3209
+ const [outerRing, ...innerRings] = geometry.coordinates;
3210
+ const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3211
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3212
+ if (color === "transparent") return;
3213
+ const material = this.getOrCreateMaterialByColor(color);
3214
+ const altitude = 0;
3215
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3216
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3217
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3218
+ offsetFeature,
3219
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3220
+ material
3221
+ );
3222
+ const topLineStrings = [
3223
+ new maptalks4.LineString(outerRing),
3224
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3225
+ ];
3226
+ const topLines = this.threeLayer.toLines(
3227
+ topLineStrings,
3228
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3229
+ this.lineMaterial
3230
+ );
3231
+ const bottomLineStrings = [
3232
+ new maptalks4.LineString(outerRing),
3233
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3234
+ ];
3235
+ const bottomLines = this.threeLayer.toLines(
3236
+ bottomLineStrings,
3237
+ { altitude, bottomHeight, interactive: false },
3238
+ this.lineMaterial
3239
+ );
3240
+ return [extrudedPolygon, topLines, bottomLines];
3241
+ } catch (err) {
3242
+ return [];
3243
+ }
3352
3244
  };
3353
3245
  try {
3354
3246
  switch (feature2.geometry.type) {
3355
3247
  case "MultiPolygon": {
3356
3248
  const { coordinates } = feature2.geometry;
3249
+ if (!coordinates) return [];
3357
3250
  const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3358
3251
  const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3359
3252
  this.threeLayer.addMesh(meshes);
@@ -3362,70 +3255,47 @@ var Element3DRenderer = class extends EventTarget {
3362
3255
  return multiMeshes;
3363
3256
  }
3364
3257
  case "Polygon": {
3258
+ const { coordinates } = feature2.geometry;
3259
+ if (!coordinates) return [];
3365
3260
  const meshes = createPolygon(feature2.geometry, feature2);
3366
3261
  this.threeLayer.addMesh(meshes);
3367
3262
  return meshes;
3368
3263
  }
3369
3264
  }
3370
3265
  } catch (err) {
3371
- console.log(`error createGeometry`, { feature: feature2, options });
3266
+ console.log(`error createGeometry`, err, { feature: feature2, options });
3372
3267
  }
3373
3268
  };
3374
3269
  async createEscalator(f, coordinate, options) {
3270
+ const model = {
3271
+ url: "https://cdn.venue.in.th/static/glb/escalator.glb",
3272
+ size: 4.4
3273
+ };
3375
3274
  const { direction: dir, angle } = options;
3376
- const model = await this.loadModel3d({
3377
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
3378
- properties: {
3379
- rotation: {
3380
- x: 0.5 * Math.PI,
3381
- // Rotate the model up (new_escalator.glb)
3382
- y: 0,
3383
- z: 0
3384
- },
3385
- position: { x: 0, y: 0, z: 0 },
3386
- scale: 0.01
3275
+ const rotationZ = dir === "up" ? 180 + angle : angle;
3276
+ var escalatorMarker = new maptalks4.GLTFMarker(coordinate, {
3277
+ symbol: {
3278
+ url: model.url,
3279
+ rotationZ,
3280
+ translationX: dir === "up" ? 0 : model.size * Math.cos(Math.PI * rotationZ / 180),
3281
+ translationY: dir === "up" ? 0 : model.size * Math.sin(Math.PI * rotationZ / 180),
3282
+ translationZ: dir === "up" ? -0.05 * model.size : -0.5 * model.size
3387
3283
  }
3388
3284
  });
3389
- model.rotation.y += dir === "up" ? Math.PI + angle : angle;
3390
- const box = new THREE2.Box3().setFromObject(model);
3391
- const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
3392
- 1 * (box.min.x + box.max.x),
3393
- 1 * (box.min.y + box.max.y),
3394
- 0.6 * box.max.z
3395
- );
3396
- const pivot = new THREE2.Group();
3397
- pivot.add(model);
3398
- model.position.sub(pivotPoint);
3399
- model.updateMatrixWorld(true);
3400
- const altitude = f.properties.ordinal * HEIGHT_METER;
3401
- const baseObjectModel = this.threeLayer.toModel(pivot, {
3402
- coordinate,
3403
- altitude
3404
- });
3405
- this.threeLayer.addMesh(baseObjectModel);
3406
- return baseObjectModel;
3285
+ escalatorMarker.addTo(this.gltfLayer);
3286
+ return escalatorMarker;
3407
3287
  }
3408
3288
  async createTree(coordinate, ordinal) {
3409
- const model = await this.loadModel3d({
3410
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
3411
- properties: {
3412
- rotation: {
3413
- x: 0.5 * Math.PI,
3414
- // Rotate the model up (new_escalator.glb)
3415
- y: 0,
3416
- z: 0
3417
- },
3418
- position: { x: 0, y: 0, z: 0 },
3419
- scale: 0.01
3289
+ const treeMarker = new maptalks4.GLTFMarker(coordinate, {
3290
+ symbol: {
3291
+ url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb"
3420
3292
  }
3421
3293
  });
3422
- const altitude = ordinal * HEIGHT_METER;
3423
- const baseObjectModel = this.threeLayer.toModel(model, {
3424
- coordinate,
3425
- altitude
3426
- });
3427
- this.threeLayer.addMesh(baseObjectModel);
3428
- return baseObjectModel;
3294
+ treeMarker.addTo(this.gltfLayer);
3295
+ return treeMarker;
3296
+ }
3297
+ async createBuilding(coordinate, ordinal) {
3298
+ return Promise.resolve(null);
3429
3299
  }
3430
3300
  createElement(f) {
3431
3301
  switch (f.feature_type) {
@@ -3448,34 +3318,34 @@ var Element3DRenderer = class extends EventTarget {
3448
3318
  }
3449
3319
  });
3450
3320
  }
3451
- async loadModel3d(model3d) {
3452
- const loader = new GLTFLoader2();
3453
- loader.setDRACOLoader(this.dracoLoader);
3454
- const { url, properties: modelProperties } = model3d;
3455
- const gltf = await loader.loadAsync(url);
3456
- const model = gltf.scene;
3457
- model.rotation.x = modelProperties.rotation.x;
3458
- model.rotation.y = modelProperties.rotation.y;
3459
- model.position.x = modelProperties.position.x;
3460
- model.position.y = modelProperties.position.y;
3461
- model.position.z = modelProperties.position.z;
3462
- const scale2 = modelProperties.scale;
3463
- model.scale.set(scale2, scale2, scale2);
3464
- return model;
3465
- }
3466
- createMarker = (coordinates, ordinal, text) => {
3467
- const options = {
3468
- // scale: 0.05,
3469
- // altitude: ordinal * HEIGHT_METER,
3470
- text
3471
- // interactive: true,
3472
- };
3473
- const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
3474
- this.threeLayer.addMesh([marker]);
3475
- return marker;
3476
- };
3477
- removeMarker = () => {
3478
- };
3321
+ createHighlightController(element) {
3322
+ if (!(element instanceof BaseObject5)) {
3323
+ return null;
3324
+ }
3325
+ switch (element.type) {
3326
+ case "ExtrudePolygon": {
3327
+ const mesh = element.getObject3d();
3328
+ const originalMaterial = mesh.material;
3329
+ const highlightMaterial = this.getOrCreateMaterialByColor("#ff0000");
3330
+ return {
3331
+ start: () => {
3332
+ mesh.material = highlightMaterial;
3333
+ },
3334
+ clear: () => {
3335
+ mesh.material = originalMaterial;
3336
+ }
3337
+ };
3338
+ }
3339
+ default: {
3340
+ return {
3341
+ start() {
3342
+ },
3343
+ clear() {
3344
+ }
3345
+ };
3346
+ }
3347
+ }
3348
+ }
3479
3349
  render() {
3480
3350
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3481
3351
  if (this.threeLayer._needsUpdate) {
@@ -3583,7 +3453,10 @@ var Element2DRenderer = class extends EventTarget {
3583
3453
  async createEscalator(f, coordinates) {
3584
3454
  return Promise.resolve(null);
3585
3455
  }
3586
- async createTree(f, coordinates) {
3456
+ async createTree(coordinates) {
3457
+ return Promise.resolve(null);
3458
+ }
3459
+ async createBuilding(coordinate, ordinal) {
3587
3460
  return Promise.resolve(null);
3588
3461
  }
3589
3462
  createElement = (imdfFeature) => {
@@ -3603,6 +3476,15 @@ var Element2DRenderer = class extends EventTarget {
3603
3476
  element.hide();
3604
3477
  });
3605
3478
  }
3479
+ createHighlightController(element) {
3480
+ if (!(element instanceof maptalks5.Geometry)) return null;
3481
+ return {
3482
+ start() {
3483
+ },
3484
+ clear() {
3485
+ }
3486
+ };
3487
+ }
3606
3488
  };
3607
3489
 
3608
3490
  // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
@@ -3613,6 +3495,7 @@ var Marker2DRenderer = class extends EventTarget {
3613
3495
  markerLayer;
3614
3496
  constructor(map) {
3615
3497
  super();
3498
+ this.map = map;
3616
3499
  }
3617
3500
  createMarker = (coordinates, ordinal, content) => {
3618
3501
  const marker = new maptalks6.ui.UIMarker(coordinates, {
@@ -3621,86 +3504,216 @@ var Marker2DRenderer = class extends EventTarget {
3621
3504
  collisionFadeIn: true,
3622
3505
  altitude: 0
3623
3506
  });
3624
- marker.addTo(this.map);
3625
- return marker;
3626
- };
3627
- removeMarker = (marker) => {
3628
- marker.remove();
3629
- };
3630
- showMarkers(elements, ordinalDiff = 0) {
3507
+ marker.addTo(this.map);
3508
+ return marker;
3509
+ };
3510
+ removeMarker = (marker) => {
3511
+ marker.remove();
3512
+ };
3513
+ showMarkers(elements, ordinalDiff = 0) {
3514
+ }
3515
+ hideMarkers(elements, ordinalDiff = 0) {
3516
+ }
3517
+ };
3518
+
3519
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3520
+ import * as maptalks7 from "maptalks-gl";
3521
+
3522
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3523
+ import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3524
+ import * as THREE2 from "three";
3525
+ import { BaseObject as BaseObject6 } from "maptalks.three";
3526
+ import { isNil, set } from "lodash";
3527
+
3528
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3529
+ var interpolateStops = ({ stops }, zoom) => {
3530
+ if (zoom <= stops[0][0]) return stops[0][1];
3531
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3532
+ for (let i = 0; i < stops.length - 1; i++) {
3533
+ const [z1, v1] = stops[i];
3534
+ const [z2, v2] = stops[i + 1];
3535
+ if (zoom >= z1 && zoom <= z2) {
3536
+ const t = (zoom - z1) / (z2 - z1);
3537
+ return v1 + t * (v2 - v1);
3538
+ }
3539
+ }
3540
+ };
3541
+
3542
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3543
+ var OPTIONS4 = {
3544
+ // Texture options
3545
+ text: "",
3546
+ textAlign: "center",
3547
+ color: "#ffffff",
3548
+ fontFamily: "sans-serif",
3549
+ fontSize: 28,
3550
+ fontWeight: 400,
3551
+ background: "transparent",
3552
+ lineHeight: 32,
3553
+ padding: 8,
3554
+ strokeColor: "#000000",
3555
+ strokeWidth: 3,
3556
+ strokeStyle: "round",
3557
+ // Sprite options
3558
+ /* Overall scale multiplier */
3559
+ scale: 1,
3560
+ altitude: 0,
3561
+ opacity: 1
3562
+ };
3563
+ var TextSpriteMarker = class extends BaseObject6 {
3564
+ #altitudeOffset = 0;
3565
+ constructor(coordinate, options, layer, properties = {}) {
3566
+ options = Util4.extend({}, OPTIONS4, options, { layer });
3567
+ super();
3568
+ this._coordinate = new Coordinate2(coordinate);
3569
+ this._initOptions(options);
3570
+ this._createGroup();
3571
+ this.properties = { ...properties };
3572
+ const sprite = this._createSprite();
3573
+ this.getObject3d().add(sprite);
3574
+ this._updatePosition();
3575
+ this.type = "TextSpriteMarker";
3576
+ }
3577
+ getOptions() {
3578
+ return super.getOptions();
3579
+ }
3580
+ _createSprite() {
3581
+ const options = this.getOptions();
3582
+ const texture = this._createTextTexture(options.text, options);
3583
+ const material = new THREE2.SpriteMaterial({
3584
+ map: texture,
3585
+ transparent: true,
3586
+ alphaTest: 0.1
3587
+ });
3588
+ const sprite = new THREE2.Sprite(material);
3589
+ const w = texture.image.width;
3590
+ const h = texture.image.height;
3591
+ const base = 1 / 16;
3592
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3593
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3594
+ this.#altitudeOffset = Math.max(
3595
+ h * base * options.scale * 0.5,
3596
+ 0.05
3597
+ // minimum lift in world units
3598
+ );
3599
+ return sprite;
3600
+ }
3601
+ _createTextTexture(text, options = {}) {
3602
+ const {
3603
+ padding,
3604
+ fontSize,
3605
+ fontFamily,
3606
+ fontWeight,
3607
+ lineHeight,
3608
+ background,
3609
+ color,
3610
+ textAlign,
3611
+ strokeColor,
3612
+ strokeWidth,
3613
+ maxWidth
3614
+ } = options || {};
3615
+ const canvas = document.createElement("canvas");
3616
+ const ctx = canvas.getContext("2d");
3617
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3618
+ const paragraphs = String(text).split("\n");
3619
+ const wrappedLines = [];
3620
+ paragraphs.forEach((paragraph) => {
3621
+ if (isNil(maxWidth) || isNaN(maxWidth)) {
3622
+ wrappedLines.push(paragraph);
3623
+ return;
3624
+ }
3625
+ const words = paragraph.split(/\s+/);
3626
+ let currentLine = "";
3627
+ words.forEach((word) => {
3628
+ const testLine = currentLine ? currentLine + " " + word : word;
3629
+ const testWidth = ctx.measureText(testLine).width;
3630
+ if (testWidth > maxWidth && currentLine) {
3631
+ wrappedLines.push(currentLine);
3632
+ currentLine = word;
3633
+ } else {
3634
+ currentLine = testLine;
3635
+ }
3636
+ });
3637
+ if (currentLine) {
3638
+ wrappedLines.push(currentLine);
3639
+ }
3640
+ });
3641
+ const lines = wrappedLines.length ? wrappedLines : [""];
3642
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3643
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3644
+ const finalHeight = lineHeight * lines.length + padding * 2;
3645
+ canvas.width = finalWidth;
3646
+ canvas.height = finalHeight;
3647
+ const ctx2 = canvas.getContext("2d");
3648
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3649
+ ctx2.textAlign = textAlign;
3650
+ if (background && background !== "transparent") {
3651
+ ctx2.fillStyle = background;
3652
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3653
+ }
3654
+ lines.forEach((line, i) => {
3655
+ const y = padding + lineHeight * (i + 0.8);
3656
+ let x = padding;
3657
+ if (textAlign === "center") x = canvas.width / 2;
3658
+ if (textAlign === "right" || textAlign === "end")
3659
+ x = canvas.width - padding;
3660
+ if (strokeWidth > 0) {
3661
+ ctx2.lineWidth = strokeWidth;
3662
+ ctx2.lineJoin = "round";
3663
+ ctx2.miterLimit = 2;
3664
+ ctx2.strokeStyle = strokeColor;
3665
+ ctx2.strokeText(line, x, y);
3666
+ }
3667
+ ctx2.fillStyle = color;
3668
+ ctx2.fillText(line, x, y);
3669
+ });
3670
+ const texture = new THREE2.CanvasTexture(canvas);
3671
+ texture.needsUpdate = true;
3672
+ texture.minFilter = THREE2.LinearFilter;
3673
+ return texture;
3631
3674
  }
3632
- hideMarkers(elements, ordinalDiff = 0) {
3675
+ _updatePosition() {
3676
+ const options = this.getOptions();
3677
+ const layer = options.layer;
3678
+ if (!layer) return;
3679
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3680
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3681
+ const position = layer.coordinateToVector3(this._coordinate, z);
3682
+ set(this.properties, "default.position", position);
3683
+ this.getObject3d().position.copy(position);
3633
3684
  }
3634
- };
3635
-
3636
- // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3637
- import * as maptalks7 from "maptalks";
3638
-
3639
- // src/IndoorMap/renderer/utils/svg2material.ts
3640
- import { SpriteMaterial as SpriteMaterial5, TextureLoader as TextureLoader3 } from "three";
3641
- var svgToDataURL = (svgString, scaleFactor = 1) => {
3642
- const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3643
- const url = URL.createObjectURL(svgBlob);
3644
- const img = new Image();
3645
- return new Promise((resolve, reject) => {
3646
- img.onload = function() {
3647
- const newWidth = img.width * scaleFactor;
3648
- const newHeight = img.height * scaleFactor;
3649
- const canvas = document.createElement("canvas");
3650
- canvas.width = newWidth;
3651
- canvas.height = newHeight;
3652
- const ctx = canvas.getContext("2d");
3653
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
3654
- const pngDataUrl = canvas.toDataURL("image/png");
3655
- resolve(pngDataUrl);
3656
- };
3657
- img.onerror = function(error) {
3658
- reject(error);
3659
- };
3660
- img.src = url;
3661
- });
3662
- };
3663
- var createSVGPathFromMarkerSymbol2 = (style) => {
3664
- const {
3665
- markerWidth = 24,
3666
- markerDx = 0,
3667
- markerDy = 0,
3668
- // markerFill,
3669
- markerPath,
3670
- fill = "#000000"
3671
- } = style;
3672
- const scale2 = markerWidth / 24;
3673
- const strokeWidth = 2;
3674
- const halfStrokeWidth = 0.5 * strokeWidth;
3675
- if (Array.isArray(markerPath)) {
3676
- return markerPath.map(
3677
- ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3678
- );
3685
+ _animation() {
3686
+ const layer = this.getLayer();
3687
+ if (!this.isAdd || !layer) return;
3688
+ if (this._visible === true) {
3689
+ const zoom = layer.map.getZoom();
3690
+ const object3d = this.getObject3d();
3691
+ const { opacity } = this.getOptions();
3692
+ let opacityValue;
3693
+ if (typeof opacity === "number") {
3694
+ opacityValue = opacity ?? 1;
3695
+ } else if (Array.isArray(opacity.stops)) {
3696
+ opacityValue = interpolateStops(opacity, zoom);
3697
+ } else {
3698
+ throw new Error(`Unknown opacity value ${opacity}`);
3699
+ }
3700
+ const visible = opacityValue > 0.5;
3701
+ object3d.visible = visible;
3702
+ }
3679
3703
  }
3680
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3681
- };
3682
- var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3683
- const material = new SpriteMaterial5();
3684
- try {
3685
- const [base, icon] = labelSymbol ?? [{}, {}];
3686
- const { markerWidth: baseWidth = 24 } = base;
3687
- const { markerWidth: iconWidth = 24 } = icon;
3688
- const viewBoxDimension = Math.max(baseWidth, iconWidth);
3689
- const baseSVG = createSVGPathFromMarkerSymbol2(base);
3690
- const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3691
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3692
- const textureLoader = new TextureLoader3();
3693
- const scaleFactor = 200 / 24;
3694
- svgToDataURL(svg, scaleFactor).then((png) => {
3695
- const texture = textureLoader.load(png, () => {
3696
- material.map = texture;
3697
- material.needsUpdate = true;
3698
- });
3699
- });
3700
- } catch (error) {
3701
- console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3704
+ setText(text) {
3705
+ const options = this.getOptions();
3706
+ options.text = text;
3707
+ const newSprite = this._createSprite();
3708
+ const group = this.getObject3d();
3709
+ group.children.forEach((child) => group.remove(child));
3710
+ group.add(newSprite);
3711
+ this._updatePosition();
3712
+ }
3713
+ setAltitude(altitude) {
3714
+ const bottomHeight = this.options.bottomHeight ?? 0;
3715
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3702
3716
  }
3703
- return material;
3704
3717
  };
3705
3718
 
3706
3719
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
@@ -3751,40 +3764,41 @@ var Marker3DRenderer = class extends EventTarget {
3751
3764
  });
3752
3765
  }
3753
3766
  /** Marker */
3754
- getOrCreateIconMaterial(key) {
3755
- if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3756
- const existingMaterial = this.materialByKey.get(key);
3757
- if (existingMaterial) return existingMaterial;
3758
- const baseSymbol = {
3759
- markerType: "path",
3760
- markerPath: [
3761
- {
3762
- path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3763
- fill: "#ff0000"
3764
- }
3765
- ],
3766
- markerPathWidth: 24,
3767
- markerPathHeight: 24
3768
- };
3769
- const markerSymbol = {
3770
- markerType: "path",
3771
- markerPath: [],
3772
- // TODO: Get Path by featureType.category
3773
- // 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" }],
3774
- markerPathWidth: 24,
3775
- markerPathHeight: 24,
3776
- markerWidth: 24,
3777
- markerHeight: 24,
3778
- markerDy: 1.5,
3779
- markerDx: 1.5
3780
- };
3781
- const created = createSpriteMaterialByLabelSymbol2([
3782
- baseSymbol,
3783
- markerSymbol
3784
- ]);
3785
- this.materialByKey.set(key, created);
3786
- return created;
3787
- }
3767
+ // getOrCreateIconMaterial(key) {
3768
+ // if (!this.materialByKey) this.materialByKey = new Map()
3769
+ // const existingMaterial = this.materialByKey.get(key)
3770
+ // if (existingMaterial) return existingMaterial
3771
+ // // Create new
3772
+ // const baseSymbol: maptalks.Path = {
3773
+ // markerType: "path",
3774
+ // markerPath: [
3775
+ // {
3776
+ // path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3777
+ // fill: "#ff0000",
3778
+ // },
3779
+ // ],
3780
+ // markerPathWidth: 24,
3781
+ // markerPathHeight: 24
3782
+ // }
3783
+ // const markerSymbol: maptalks.PathMarkerSymbol = {
3784
+ // markerType: "path",
3785
+ // markerPath: [],
3786
+ // // TODO: Get Path by featureType.category
3787
+ // // 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" }],
3788
+ // markerPathWidth: 24,
3789
+ // markerPathHeight: 24,
3790
+ // markerWidth: 24,
3791
+ // markerHeight: 24,
3792
+ // markerDy: 1.5,
3793
+ // markerDx: 1.5,
3794
+ // }
3795
+ // const created = createSpriteMaterialByLabelSymbol([
3796
+ // baseSymbol,
3797
+ // markerSymbol,
3798
+ // ])
3799
+ // this.materialByKey.set(key, created)
3800
+ // return created
3801
+ // }
3788
3802
  };
3789
3803
 
3790
3804
  // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
@@ -3806,11 +3820,17 @@ var angleBetweenLineStrings = (line1, line2) => {
3806
3820
  };
3807
3821
 
3808
3822
  // src/IndoorMap/renderer/RendererManager.ts
3823
+ function delay(ms) {
3824
+ return new Promise((resolve) => setTimeout(resolve, ms));
3825
+ }
3809
3826
  var RendererManager = class extends EventTarget {
3810
3827
  map;
3811
3828
  options;
3812
3829
  // Client for fetching data
3813
3830
  #dataClient;
3831
+ #isClicked = false;
3832
+ #onClickElement = (e) => {
3833
+ };
3814
3834
  /** Elements: Responsible for converting feature info elements and add to map */
3815
3835
  elementRenderer;
3816
3836
  markerRenderer;
@@ -3819,6 +3839,7 @@ var RendererManager = class extends EventTarget {
3819
3839
  currentOrdinals;
3820
3840
  markersMap;
3821
3841
  markersByOrdinal;
3842
+ highlightControllers = [];
3822
3843
  constructor(map, dataClient, options) {
3823
3844
  super();
3824
3845
  this.map = map;
@@ -3828,48 +3849,52 @@ var RendererManager = class extends EventTarget {
3828
3849
  this.markersMap = /* @__PURE__ */ new Map();
3829
3850
  this.markersByOrdinal = /* @__PURE__ */ new Map();
3830
3851
  this.#dataClient = dataClient;
3852
+ const _this = this;
3831
3853
  if (options.type === "3D") {
3832
- const threeLayer = new ThreeLayer3("elements", {
3833
- forceRenderOnMoving: true,
3834
- forceRenderOnRotating: true
3835
- });
3836
- const _this = this;
3854
+ const groupLayer = this.map.getLayer("group");
3855
+ const threeLayer = groupLayer.getLayer("three");
3837
3856
  threeLayer.prepareToDraw = function(gl, scene, camera) {
3838
3857
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3839
3858
  scene.add(ambientLight);
3840
3859
  const dirColor = 16777215;
3841
3860
  const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3842
- dllight.position.set(0, -10, 10).normalize();
3861
+ dllight.position.set(0, -10, 20).normalize();
3843
3862
  scene.add(dllight);
3844
3863
  const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3845
3864
  scene.add(hemi);
3846
- _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
3865
+ _this.elementRenderer = new Element3DRenderer(map, options.elements);
3847
3866
  _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3848
3867
  if (typeof options.onRendererReady === "function") {
3849
3868
  options.onRendererReady();
3850
3869
  }
3851
3870
  _this.#createElements();
3852
3871
  };
3853
- threeLayer.addTo(this.map);
3854
3872
  } else {
3855
3873
  this.elementRenderer = new Element2DRenderer(map, options.elements);
3856
3874
  this.markerRenderer = new Marker2DRenderer(map);
3857
3875
  this.#createElements();
3858
3876
  }
3859
3877
  }
3878
+ set onClickElement(func) {
3879
+ this.#onClickElement = func;
3880
+ }
3881
+ handleClickElement = (e) => {
3882
+ if (this.#isClicked) return;
3883
+ this.#isClicked = true;
3884
+ const onClickElement = this.#onClickElement;
3885
+ if (!_isFunction(onClickElement)) return;
3886
+ this.#onClickElement(e);
3887
+ this.#isClicked = false;
3888
+ };
3860
3889
  getElementsByOrdinal = (ordinal) => {
3861
3890
  const exist = this.elementsByOrdinal.get(ordinal);
3862
3891
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3863
3892
  return this.elementsByOrdinal.get(ordinal);
3864
3893
  };
3865
- getMarkersByOrdinal = (ordinal) => {
3866
- const exist = this.markersByOrdinal.get(ordinal);
3867
- if (!exist) this.markersByOrdinal.set(ordinal, []);
3868
- return this.markersByOrdinal.get(ordinal);
3869
- };
3870
3894
  addElementsToManager = (id, elements, ordinal) => {
3871
3895
  this.elementsMap.set(id, elements);
3872
3896
  elements.forEach((el) => {
3897
+ el.on("click", (e) => this.handleClickElement(id));
3873
3898
  this.getElementsByOrdinal(ordinal).push(el);
3874
3899
  });
3875
3900
  const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
@@ -3879,19 +3904,8 @@ var RendererManager = class extends EventTarget {
3879
3904
  this.elementRenderer.hideElements(elements, ordinal);
3880
3905
  }
3881
3906
  };
3882
- addMarkersToManager = (id, markers, ordinal) => {
3883
- this.markersMap.set(id, markers);
3884
- markers.forEach((el) => {
3885
- this.getMarkersByOrdinal(ordinal).push(el);
3886
- });
3887
- const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3888
- if (inOrdinal) {
3889
- this.markerRenderer.showMarkers(markers, ordinal);
3890
- } else {
3891
- this.markerRenderer.hideMarkers(markers, ordinal);
3892
- }
3893
- };
3894
3907
  async #createElements() {
3908
+ await delay(this.options.delayBeforeCreateElements ?? 0);
3895
3909
  const levels = await this.#dataClient.filterByType("level", {
3896
3910
  populate: true
3897
3911
  });
@@ -3938,13 +3952,15 @@ var RendererManager = class extends EventTarget {
3938
3952
  }
3939
3953
  const thisOrdinal = escalator.properties.ordinal;
3940
3954
  const relationship = escalatorRelationships[0];
3955
+ if (!relationship.properties.origin?.id) throw new Error(`relationship (id=${relationship.id}) - origin not exists`);
3956
+ if (!relationship.properties.destination?.id) throw new Error(`relationship (id=${relationship.id}) - destination not exists`);
3941
3957
  const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
3942
3958
  const bothOpenings = await Promise.all(
3943
3959
  bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
3944
3960
  );
3945
3961
  const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
3946
3962
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
3947
- const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
3963
+ const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
3948
3964
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
3949
3965
  const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
3950
3966
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
@@ -3953,7 +3969,7 @@ var RendererManager = class extends EventTarget {
3953
3969
  this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
3954
3970
  }
3955
3971
  } catch (err) {
3956
- console.log(`cannot create escalator`, err);
3972
+ console.warn(`cannot create escalator`, err.message);
3957
3973
  }
3958
3974
  }
3959
3975
  this.changeLevelByOrdinal(this.currentOrdinals);
@@ -3989,14 +4005,48 @@ var RendererManager = class extends EventTarget {
3989
4005
  }
3990
4006
  }
3991
4007
  }
4008
+ highlightElements = (elemIds, options) => {
4009
+ const { reset = true } = options ?? {};
4010
+ if (reset) {
4011
+ this.clearHighlightElements();
4012
+ }
4013
+ const elements = elemIds.map((id) => this.elementsMap.get(id)).flat();
4014
+ elements.forEach((element) => {
4015
+ const controller = this.elementRenderer.createHighlightController(element);
4016
+ controller.start();
4017
+ this.highlightControllers.push(controller);
4018
+ });
4019
+ };
4020
+ clearHighlightElements = () => {
4021
+ this.highlightControllers.forEach((controller) => {
4022
+ if (_isFunction(controller?.clear)) controller.clear();
4023
+ });
4024
+ };
3992
4025
  /**
3993
4026
  * ========================================================================
3994
4027
  * Markers
3995
4028
  * ======================================================================== */
4029
+ _getMarkersByOrdinal = (ordinal) => {
4030
+ const exist = this.markersByOrdinal.get(ordinal);
4031
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
4032
+ return this.markersByOrdinal.get(ordinal);
4033
+ };
4034
+ _addMarkersToManager = (id, markers, ordinal) => {
4035
+ this.markersMap.set(id, markers);
4036
+ markers.forEach((el) => {
4037
+ this._getMarkersByOrdinal(ordinal).push(el);
4038
+ });
4039
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
4040
+ if (inOrdinal) {
4041
+ this.markerRenderer.showMarkers(markers, ordinal);
4042
+ } else {
4043
+ this.markerRenderer.hideMarkers(markers, ordinal);
4044
+ }
4045
+ };
3996
4046
  createMarker(coordinate, ordinal, text, options) {
3997
4047
  const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
3998
4048
  const markerId = `${this.markersMap.size + 1}`;
3999
- this.addMarkersToManager(markerId, [marker], ordinal);
4049
+ this._addMarkersToManager(markerId, [marker], ordinal);
4000
4050
  }
4001
4051
  clearMarkers() {
4002
4052
  for (const [markerId, marker] of this.markersMap) {
@@ -4014,6 +4064,7 @@ var defaultOptions = {
4014
4064
  locale: DEFAULT_LOCALE
4015
4065
  };
4016
4066
  var IndoorMap = class extends EventTarget {
4067
+ options;
4017
4068
  //TODO: refac functions; let them do only 1 thing in a function
4018
4069
  /** Note: "#" means private variables */
4019
4070
  #styler = null;
@@ -4065,14 +4116,18 @@ var IndoorMap = class extends EventTarget {
4065
4116
  };
4066
4117
  constructor(elementId, options) {
4067
4118
  super();
4119
+ const combinedOptions = _6.merge({}, defaultOptions, options);
4120
+ this.options = options;
4068
4121
  const {
4069
4122
  onMapReady,
4070
4123
  onMapLoading,
4071
4124
  pixelRatio,
4072
4125
  locale
4073
- } = _6.merge({}, defaultOptions, options);
4126
+ } = combinedOptions;
4074
4127
  this.map = new Map2(elementId, {
4075
4128
  attribution: false,
4129
+ // Temporart set, not really default view
4130
+ // Default view is set in camera manager
4076
4131
  center: INITIAL_CENTER,
4077
4132
  zoom: INITIAL_ZOOM,
4078
4133
  clickTimeThreshold: 600,
@@ -4088,8 +4143,16 @@ var IndoorMap = class extends EventTarget {
4088
4143
  }),
4089
4144
  layers: []
4090
4145
  });
4146
+ const groupLayer = new GroupGLLayer("group", [], {}).addTo(this.map);
4147
+ const threeLayer = new ThreeLayer4("three", {
4148
+ forceRenderOnMoving: true,
4149
+ forceRenderOnRotating: true
4150
+ });
4151
+ groupLayer.addLayer(threeLayer);
4152
+ const gltfLayer = new GLTFLayer("gltf");
4153
+ groupLayer.addLayer(gltfLayer);
4091
4154
  this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
4092
- this.camera = new CameraManager(this.map);
4155
+ this.camera = new CameraManager(this.map, options.camera);
4093
4156
  this.locale = locale;
4094
4157
  this.pixelRatio = pixelRatio;
4095
4158
  this.onMapReady = onMapReady;
@@ -4100,19 +4163,21 @@ var IndoorMap = class extends EventTarget {
4100
4163
  }
4101
4164
  set dataClient(value) {
4102
4165
  this.#dataClient = value;
4103
- this.#dataClient.filterByType("venue").then((venues) => {
4104
- const venueCenters = turfCenter3(featureCollection(venues));
4105
- const [x, y] = venueCenters.geometry.coordinates;
4106
- const center2 = new Coordinate4(x, y);
4107
- this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4108
- });
4109
- }
4110
- on(eventName, handler) {
4111
- this.map.on(eventName, handler);
4166
+ if (!this.options.camera?.defaultView?.center) {
4167
+ this.#dataClient.filterByType("venue").then((venues) => {
4168
+ const venueCenters = turfCenter3(featureCollection(venues));
4169
+ const [x, y] = venueCenters.geometry.coordinates;
4170
+ const center2 = new Coordinate4(x, y);
4171
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4172
+ });
4173
+ }
4112
4174
  }
4113
4175
  /**
4114
4176
  * Events
4115
4177
  */
4178
+ on(eventName, handler) {
4179
+ this.map.on(eventName, handler);
4180
+ }
4116
4181
  handleMapClick = ({ coordinate }) => {
4117
4182
  const { x, y } = coordinate;
4118
4183
  console.log(
@@ -4168,40 +4233,12 @@ var IndoorMap = class extends EventTarget {
4168
4233
  this.map.off("moveend", this.#findAndSetVenueInView);
4169
4234
  }
4170
4235
  }
4171
- get ordinals() {
4172
- return this.#ordinals || [];
4173
- }
4174
- set ordinals(value) {
4175
- if (!Array.isArray(value)) throw new Error("ordinals must be Array");
4176
- this.#ordinals = value;
4177
- }
4178
4236
  set billboards(value) {
4179
4237
  this.#billboards = value;
4180
4238
  }
4181
- set mapConfig(value) {
4182
- this.#mapConfig = value;
4183
- }
4184
4239
  set mapDecorations(value) {
4185
4240
  this.#mapDecorations = value;
4186
4241
  }
4187
- set maxZoom(value) {
4188
- this.map.setMaxZoom(value);
4189
- const spatialReference = {
4190
- projection: "EPSG:3857",
4191
- resolutions: (function() {
4192
- const resolutions = [];
4193
- const d = 2 * 6378137 * Math.PI;
4194
- for (let i = 0; i < value; i++) {
4195
- resolutions[i] = d / (256 * Math.pow(2, i));
4196
- }
4197
- return resolutions;
4198
- })()
4199
- };
4200
- this.map.setSpatialReference(spatialReference);
4201
- }
4202
- set minZoom(value) {
4203
- this.map.setMinZoom(value);
4204
- }
4205
4242
  set groundLabels(value) {
4206
4243
  this.#groundLabels = value;
4207
4244
  }
@@ -4209,7 +4246,7 @@ var IndoorMap = class extends EventTarget {
4209
4246
  this.map.setDevicePixelRatio(value);
4210
4247
  }
4211
4248
  set onClickElement(func) {
4212
- this.#onClickElement = func;
4249
+ this.rendererManager.onClickElement = func;
4213
4250
  }
4214
4251
  set locale(value) {
4215
4252
  this.#locale = value || defaultOptions.locale;
@@ -4237,9 +4274,6 @@ var IndoorMap = class extends EventTarget {
4237
4274
  this.#onClickElement(e);
4238
4275
  this.#isClicked = false;
4239
4276
  };
4240
- setCenter(center2, padding) {
4241
- this.map.setCenter(center2, padding);
4242
- }
4243
4277
  async #legacy_createElements() {
4244
4278
  const {
4245
4279
  // 2D
@@ -4253,33 +4287,14 @@ var IndoorMap = class extends EventTarget {
4253
4287
  create3DFootprint,
4254
4288
  create3DGroundLabel,
4255
4289
  create3DBillboard,
4256
- createVenue3DModel,
4257
4290
  createExtrudedUnit,
4258
- create3DFixture,
4259
4291
  create3DAmenityMarker,
4260
4292
  create3DOccupantAmenityMarker,
4261
4293
  create3DOpeningMarker,
4262
- createOccupantGroundLabel,
4263
- // Light
4264
- createAmbientLight,
4265
- createDirectionalLight
4294
+ createOccupantGroundLabel
4266
4295
  } = this.#styler;
4267
4296
  let elements = {};
4268
4297
  let object3ds = [];
4269
- const scene = this.threeLayer.getScene();
4270
- if (scene) {
4271
- const {
4272
- ambientLight: ambientLightConfig = {},
4273
- directionalLight: directionalLightConfig = {}
4274
- } = _6.get(this.#mapConfig, "light", {
4275
- ambientLight: {},
4276
- directionalLight: {}
4277
- });
4278
- const ambientLight = createAmbientLight(ambientLightConfig);
4279
- scene.add(ambientLight);
4280
- const light = createDirectionalLight(directionalLightConfig);
4281
- scene.add(light);
4282
- }
4283
4298
  for (const feature2 of this.#features) {
4284
4299
  try {
4285
4300
  const { feature_type: featureType, properties, id } = feature2;
@@ -4302,16 +4317,6 @@ var IndoorMap = class extends EventTarget {
4302
4317
  feature2
4303
4318
  );
4304
4319
  switch (featureType) {
4305
- case "venue": {
4306
- geometry = createVenue(feature2).addTo(layer);
4307
- const models = await createVenue3DModel(feature2, this.threeLayer);
4308
- models.forEach((model) => {
4309
- model.on("click", this.handleClickElement);
4310
- object3ds.push(model);
4311
- this.#venueObjects.push(model);
4312
- });
4313
- break;
4314
- }
4315
4320
  case "amenity": {
4316
4321
  if (feature2.properties.is_featured) {
4317
4322
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4355,127 +4360,6 @@ var IndoorMap = class extends EventTarget {
4355
4360
  geometry = createSection(feature2)?.addTo(layer);
4356
4361
  break;
4357
4362
  }
4358
- case "occupant": {
4359
- switch (category) {
4360
- // Create only marker if it is amenity occupant
4361
- case "currencyexchange":
4362
- case "donationcenter":
4363
- case "postoffice":
4364
- const markerFeature = {
4365
- ...feature2,
4366
- geometry: feature2.properties?.anchor?.geometry
4367
- };
4368
- const marker3d = create3DOccupantAmenityMarker(
4369
- markerFeature,
4370
- this.threeLayer,
4371
- extrudeConfig
4372
- )?.on("click", this.handleClickElement);
4373
- object3ds.push(marker3d);
4374
- break;
4375
- default: {
4376
- const { kiosk, anchor } = feature2.properties;
4377
- const { unit } = anchor.properties;
4378
- let mainLocation = kiosk || unit || null;
4379
- const relatedLocations = [
4380
- ...feature2.properties.units,
4381
- ...feature2.properties.kiosks
4382
- ].filter((f) => f.properties.ordinal !== properties.ordinal);
4383
- const occupantLocations = [mainLocation, ...relatedLocations];
4384
- const renderType = feature2.properties.render_type;
4385
- occupantLocations.forEach((location, index) => {
4386
- const isMainLocation = index === 0;
4387
- if (renderType === "Label") {
4388
- const occupantGroundLabel = createOccupantGroundLabel(
4389
- feature2,
4390
- location,
4391
- { textMarkerType, extrudeConfig },
4392
- this.threeLayer
4393
- );
4394
- if (occupantGroundLabel instanceof GroundLabel) {
4395
- occupantGroundLabel.on("click", this.handleClickElement);
4396
- occupantGroundLabel.addTo(this.threeLayer);
4397
- object3ds.push(occupantGroundLabel);
4398
- this.#groundObjects.push(occupantGroundLabel);
4399
- }
4400
- } else {
4401
- const occupantMarker = createOccupant(feature2, location, {
4402
- textMarkerType,
4403
- extrudeConfig
4404
- });
4405
- if (occupantMarker instanceof ui3.UIMarker) {
4406
- occupantMarker.addTo(this.map);
4407
- } else {
4408
- occupantMarker?.on("click", this.handleClickElement);
4409
- occupantMarker?.addTo(layer);
4410
- }
4411
- if (isMainLocation) {
4412
- geometry = occupantMarker;
4413
- } else {
4414
- elements[`${feature2.id}_${index}`] = {
4415
- geometry: occupantMarker,
4416
- properties: location.properties,
4417
- featureType: "occupant",
4418
- feature: feature2
4419
- };
4420
- }
4421
- }
4422
- });
4423
- }
4424
- }
4425
- break;
4426
- }
4427
- case "fixture": {
4428
- const models = await create3DFixture(feature2, this.threeLayer);
4429
- models.forEach((model) => {
4430
- model.on("click", this.handleClickElement);
4431
- object3ds.push(model);
4432
- this.#glbObjects.push(model);
4433
- });
4434
- if (!featureExtrudeConfig) {
4435
- geometry = createFixture(feature2)?.addTo(layer);
4436
- } else {
4437
- const locatedLevel = feature2?.properties?.level;
4438
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4439
- extrudeConfig,
4440
- locatedLevel
4441
- );
4442
- const levelHeight = _6.get(levelExtrudeConfig, "height", 0);
4443
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4444
- const extrudedFixture = createExtrudedUnit(
4445
- feature2,
4446
- this.threeLayer,
4447
- option
4448
- );
4449
- object3ds.push(extrudedFixture);
4450
- }
4451
- break;
4452
- }
4453
- case "footprint": {
4454
- const objects = await create3DFootprint(
4455
- feature2,
4456
- this.threeLayer,
4457
- featureExtrudeConfig
4458
- );
4459
- objects.forEach((object) => {
4460
- object.on("click", () => {
4461
- const {
4462
- geometry: { coordinates }
4463
- } = turfCenter3(feature2);
4464
- this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4465
- });
4466
- object3ds.push(object);
4467
- this.#objects.push(object);
4468
- });
4469
- if (feature2.properties.logo) {
4470
- const footprintMarker = create3DBillboard(
4471
- feature2,
4472
- this.threeLayer
4473
- );
4474
- object3ds.push(footprintMarker);
4475
- this.#billboardObjects.push(footprintMarker);
4476
- }
4477
- break;
4478
- }
4479
4363
  default:
4480
4364
  break;
4481
4365
  }
@@ -4544,27 +4428,6 @@ var IndoorMap = class extends EventTarget {
4544
4428
  changeLevelByOrdinal(ordinal) {
4545
4429
  this.rendererManager.changeLevelByOrdinal(ordinal);
4546
4430
  }
4547
- getFeatureExtent = (feature2, scaleFactor = 1) => {
4548
- const [minX, minY, maxX, maxY] = index_default(
4549
- scale(bboxPolygon(index_default(feature2)), scaleFactor)
4550
- );
4551
- return new Extent(minX, minY, maxX, maxY);
4552
- };
4553
- getExtentCenter = (extent) => {
4554
- return extent.getCenter();
4555
- };
4556
- getExtentZoom = (extent, options = {
4557
- isFraction: false,
4558
- padding: {
4559
- paddingLeft: 0,
4560
- paddingRight: 0,
4561
- paddingTop: 0,
4562
- paddingBottom: 0
4563
- }
4564
- }) => {
4565
- const { isFraction = false, padding } = options;
4566
- return this.map.getFitZoom(extent, isFraction, padding);
4567
- };
4568
4431
  findVenueInView = () => {
4569
4432
  const mapCenter = this.map.getCenter();
4570
4433
  const result = this.#venues.reduce((closest, venue) => {
@@ -4577,9 +4440,6 @@ var IndoorMap = class extends EventTarget {
4577
4440
  }, null);
4578
4441
  return result;
4579
4442
  };
4580
- flyTo = (center2, options) => {
4581
- this.camera.flyTo(center2, options);
4582
- };
4583
4443
  getLineStringBearing = (feature2) => {
4584
4444
  const { geometry } = feature2;
4585
4445
  const path = new LineString3(geometry.coordinates);
@@ -5095,33 +4955,6 @@ var IndoorMap = class extends EventTarget {
5095
4955
  /**
5096
4956
  * render (frame)
5097
4957
  */
5098
- getTargetViewCenter = (targetView, options = { offset: { top: 0, left: 0, right: 0, bottom: 0 } }) => {
5099
- const map = this.map;
5100
- const { offset } = options;
5101
- const { top = 0, left = 0, right = 0, bottom = 0 } = offset;
5102
- const originalState = {
5103
- bearing: map.getBearing(),
5104
- center: map.getCenter(),
5105
- pitch: map.getPitch(),
5106
- zoom: map.getZoom()
5107
- };
5108
- const finalView = {
5109
- bearing: _6.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5110
- center: _6.isNil(targetView.center) ? map.getCenter() : targetView.center,
5111
- pitch: _6.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5112
- zoom: _6.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5113
- };
5114
- map.setView(finalView);
5115
- const projectedTargetCenter = map.coordinateToContainerPoint(finalView.center).add(right / 2 - left / 2, bottom / 2 - top / 2);
5116
- const adjustedTargetCenter = map.containerPointToCoordinate(
5117
- projectedTargetCenter
5118
- );
5119
- map.setView(originalState);
5120
- return adjustedTargetCenter;
5121
- };
5122
- setMaxExtent(extent) {
5123
- return this.map.setMaxExtent(extent);
5124
- }
5125
4958
  render() {
5126
4959
  const view = this.map.getView();
5127
4960
  const currBearing = view.bearing;
@@ -5130,7 +4963,8 @@ var IndoorMap = class extends EventTarget {
5130
4963
  this.threeLayer.redraw();
5131
4964
  }
5132
4965
  if (this.threeLayer) {
5133
- const objectOpacity = _6.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
4966
+ const currentView = this.camera.getView();
4967
+ const objectOpacity = _6.clamp(38 - 2 * currentView.zoom, 0, 1);
5134
4968
  this.#objects.forEach((object) => {
5135
4969
  object.getObject3d().traverse((child) => {
5136
4970
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5141,7 +4975,7 @@ var IndoorMap = class extends EventTarget {
5141
4975
  if (this.#billboardObjects) {
5142
4976
  this.#billboardObjects.forEach((object) => {
5143
4977
  const objectScale = _6.clamp(
5144
- 20 - 1 * this.camera.getZoom(),
4978
+ 20 - 1 * currentView.zoom,
5145
4979
  1,
5146
4980
  1.05
5147
4981
  );
@@ -5193,6 +5027,7 @@ export {
5193
5027
  MARKER_LAYER_NAME,
5194
5028
  NONIMDF_FEATURE_TYPES,
5195
5029
  ORIGIN_MARKER_ID,
5030
+ occupant_helper_exports as OccupantHelpers,
5196
5031
  POI_MARKER_LAYER_NAME,
5197
5032
  QueryObserver2 as QueryObserver,
5198
5033
  USER_LOCATION_ELEMENT_ID,
@@ -5202,7 +5037,8 @@ export {
5202
5037
  createSpriteMaterialByLabelSymbol,
5203
5038
  createStyledUIMarkerElement,
5204
5039
  defaultFeatureQueryOptionsMap,
5205
- fetchFeature,
5040
+ fetchDeliveryApi,
5041
+ fetchPreviewApi,
5206
5042
  getBearingBetweenPoints,
5207
5043
  getCenterFromGeometry,
5208
5044
  getDataClient,
@@ -5219,6 +5055,16 @@ export {
5219
5055
  getRelatedLocationsByOccupant,
5220
5056
  getSuitablyValueBetweenBearings,
5221
5057
  isClickableFeature,
5058
+ isValidCoordinate,
5059
+ isValidLineString,
5060
+ isValidLineStringCoordinates,
5061
+ isValidMultiPolygon,
5062
+ isValidMultiPolygonCoordinates,
5063
+ isValidPoint,
5064
+ isValidPolygon,
5065
+ isValidPolygonCoordinates,
5066
+ matchFilter,
5067
+ matchFilters,
5222
5068
  safeFetchFeature,
5223
5069
  styledFeatureGenerator
5224
5070
  };