venue-js 1.2.0-next.1 → 1.2.0-next.11

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
 
@@ -191,6 +197,115 @@ var safeFetchFeature = async (featureType, params) => {
191
197
  }
192
198
  };
193
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
+
194
309
  // src/data/getDataClient.ts
195
310
  import {
196
311
  QueryClient,
@@ -349,8 +464,8 @@ var createPopulator = ({
349
464
  venue,
350
465
  promotions,
351
466
  privileges,
352
- kiosk,
353
- unit,
467
+ kiosk: kiosk ? await populateKiosk(kiosk) : null,
468
+ unit: unit ? await populateUnit(unit) : null,
354
469
  kiosks: await Promise.all(kiosks.map(populateKiosk)),
355
470
  units: await Promise.all(units.map(populateUnit))
356
471
  }
@@ -442,26 +557,6 @@ var createPopulator = ({
442
557
  };
443
558
  };
444
559
 
445
- // src/data/utils/match-filters.ts
446
- function isInFilter(filter) {
447
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
448
- }
449
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
450
- function matchFilter(value, filter) {
451
- if (Array.isArray(value)) {
452
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
453
- return value.includes(filter);
454
- } else {
455
- if (isInFilter(filter)) return filter.$in.includes(value);
456
- return value === filter;
457
- }
458
- }
459
- function matchFilters(item, filters) {
460
- return Object.entries(filters).every(([key, filter]) => {
461
- return matchFilter(item.properties[key], filter);
462
- });
463
- }
464
-
465
560
  // src/data/getDataClient.ts
466
561
  var getDataClient = (options) => {
467
562
  const observers = /* @__PURE__ */ new Map();
@@ -590,16 +685,16 @@ var getDataClient = (options) => {
590
685
 
591
686
  // src/IndoorMap/IndoorMap.ts
592
687
  import {
593
- ui as ui3,
594
688
  Map as Map2,
595
689
  TileLayer,
596
- Extent,
597
690
  LineString as LineString3,
598
- Marker as Marker2,
599
- Coordinate as Coordinate4
691
+ Coordinate as Coordinate4,
692
+ GroupGLLayer,
693
+ GLTFLayer
600
694
  } from "maptalks-gl";
601
- import TWEEN2 from "@tweenjs/tween.js";
602
- import _6 from "lodash";
695
+ import "@maptalks/transcoders.draco";
696
+ import TWEEN from "@tweenjs/tween.js";
697
+ import _5 from "lodash";
603
698
 
604
699
  // ../../node_modules/@turf/helpers/dist/esm/index.js
605
700
  var earthRadius = 63710088e-1;
@@ -679,133 +774,8 @@ function isNumber(num) {
679
774
  // src/IndoorMap/IndoorMap.ts
680
775
  import turfDistance from "@turf/distance";
681
776
  import turfCenter3 from "@turf/center";
682
-
683
- // ../../node_modules/@turf/meta/dist/esm/index.js
684
- function coordEach(geojson, callback, excludeWrapCoord) {
685
- if (geojson === null) return;
686
- 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;
687
- for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
688
- geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
689
- isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
690
- stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
691
- for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
692
- var multiFeatureIndex = 0;
693
- var geometryIndex = 0;
694
- geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
695
- if (geometry === null) continue;
696
- coords = geometry.coordinates;
697
- var geomType = geometry.type;
698
- wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
699
- switch (geomType) {
700
- case null:
701
- break;
702
- case "Point":
703
- if (callback(
704
- coords,
705
- coordIndex,
706
- featureIndex,
707
- multiFeatureIndex,
708
- geometryIndex
709
- ) === false)
710
- return false;
711
- coordIndex++;
712
- multiFeatureIndex++;
713
- break;
714
- case "LineString":
715
- case "MultiPoint":
716
- for (j = 0; j < coords.length; j++) {
717
- if (callback(
718
- coords[j],
719
- coordIndex,
720
- featureIndex,
721
- multiFeatureIndex,
722
- geometryIndex
723
- ) === false)
724
- return false;
725
- coordIndex++;
726
- if (geomType === "MultiPoint") multiFeatureIndex++;
727
- }
728
- if (geomType === "LineString") multiFeatureIndex++;
729
- break;
730
- case "Polygon":
731
- case "MultiLineString":
732
- for (j = 0; j < coords.length; j++) {
733
- for (k = 0; k < coords[j].length - wrapShrink; k++) {
734
- if (callback(
735
- coords[j][k],
736
- coordIndex,
737
- featureIndex,
738
- multiFeatureIndex,
739
- geometryIndex
740
- ) === false)
741
- return false;
742
- coordIndex++;
743
- }
744
- if (geomType === "MultiLineString") multiFeatureIndex++;
745
- if (geomType === "Polygon") geometryIndex++;
746
- }
747
- if (geomType === "Polygon") multiFeatureIndex++;
748
- break;
749
- case "MultiPolygon":
750
- for (j = 0; j < coords.length; j++) {
751
- geometryIndex = 0;
752
- for (k = 0; k < coords[j].length; k++) {
753
- for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
754
- if (callback(
755
- coords[j][k][l],
756
- coordIndex,
757
- featureIndex,
758
- multiFeatureIndex,
759
- geometryIndex
760
- ) === false)
761
- return false;
762
- coordIndex++;
763
- }
764
- geometryIndex++;
765
- }
766
- multiFeatureIndex++;
767
- }
768
- break;
769
- case "GeometryCollection":
770
- for (j = 0; j < geometry.geometries.length; j++)
771
- if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
772
- return false;
773
- break;
774
- default:
775
- throw new Error("Unknown Geometry Type");
776
- }
777
- }
778
- }
779
- }
780
-
781
- // ../../node_modules/@turf/bbox/dist/esm/index.js
782
- function bbox(geojson, options = {}) {
783
- if (geojson.bbox != null && true !== options.recompute) {
784
- return geojson.bbox;
785
- }
786
- const result = [Infinity, Infinity, -Infinity, -Infinity];
787
- coordEach(geojson, (coord) => {
788
- if (result[0] > coord[0]) {
789
- result[0] = coord[0];
790
- }
791
- if (result[1] > coord[1]) {
792
- result[1] = coord[1];
793
- }
794
- if (result[2] < coord[0]) {
795
- result[2] = coord[0];
796
- }
797
- if (result[3] < coord[1]) {
798
- result[3] = coord[1];
799
- }
800
- });
801
- return result;
802
- }
803
- var index_default = bbox;
804
-
805
- // src/IndoorMap/IndoorMap.ts
806
- import scale from "@turf/transform-scale";
807
- import bboxPolygon from "@turf/bbox-polygon";
808
777
  import { PerspectiveCamera } from "three";
778
+ import { ThreeLayer as ThreeLayer4 } from "maptalks.three";
809
779
 
810
780
  // src/IndoorMap/constants.ts
811
781
  var defaultLayerOption = { enableAltitude: true };
@@ -823,7 +793,6 @@ var GEOLOCATION = "geolocation";
823
793
  var ORIGIN_MARKER = "origin-marker";
824
794
  var DESTINATION_MARKER = "destination-marker";
825
795
  var DECORATION = "decoration";
826
- var ALWAYS_VISIBLE_FEATURE_TYPES = [VENUE, FOOTPRINT];
827
796
  var BASE_LAYER_NAME = "base";
828
797
  var POI_MARKER_LAYER_NAME = "poi";
829
798
  var MARKER_LAYER_NAME = "marker";
@@ -835,13 +804,6 @@ var USER_LOCATION_ELEMENT_ID = "user_location";
835
804
  var LAST_USER_LOCATION_ELEMENT_ID_PREFIX = "last_user_location-";
836
805
  var LOCALE_SYMBOL_KEY = "locale_symbol";
837
806
  var DEFAULT_LOCALE = "en";
838
- var DEFAULT_HIGHLIGHT_OPTIONS = {
839
- symbolSet: null
840
- };
841
- var DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS = {
842
- symbolSet: null,
843
- defaultMarker: false
844
- };
845
807
  var LAYERS = [
846
808
  BASE_LAYER_NAME,
847
809
  POI_MARKER_LAYER_NAME,
@@ -1827,18 +1789,6 @@ var loadModel3d = (model3d, coordinate, threeLayer) => {
1827
1789
  );
1828
1790
  });
1829
1791
  };
1830
- var create3DModels = async (models, defaultCoordinate, properties, threeLayer) => {
1831
- let modelObjs = [];
1832
- for (let j = 0; j < models.length; j++) {
1833
- const model = models[j];
1834
- const positionCoord = _4.get(model, "properties.position");
1835
- const coord = positionCoord || defaultCoordinate;
1836
- const object = await loadModel3d(model, coord, threeLayer);
1837
- object.properties = properties;
1838
- modelObjs.push(object);
1839
- }
1840
- return modelObjs;
1841
- };
1842
1792
  var createExtrudePolygon = (geometry, threeLayer, material, height, properties = {}, options) => {
1843
1793
  const { offset = 0, altitude = 0 } = options;
1844
1794
  const offsetGeometry = turfBuffer(geometry, offset, { units: "meters" });
@@ -2746,44 +2696,6 @@ var styledFeatureGenerator = (mapTheme) => {
2746
2696
  markerProperties
2747
2697
  );
2748
2698
  },
2749
- createVenue3DModel: async (venue, threeLayer) => {
2750
- const { id, feature_type, properties } = venue;
2751
- const { category, model3d } = properties;
2752
- const modelProperty = {
2753
- id,
2754
- feature_type,
2755
- category
2756
- };
2757
- const center2 = turfCenter(venue);
2758
- const centerCoord = _4.get(center2, "geometry.coordinates");
2759
- const modelPosition = _4.get(model3d, "properties.position", centerCoord);
2760
- const models = await create3DModels(
2761
- model3d,
2762
- modelPosition,
2763
- modelProperty,
2764
- threeLayer
2765
- );
2766
- return models;
2767
- },
2768
- create3DFixture: async (fixture, threeLayer) => {
2769
- const { id, feature_type, properties } = fixture;
2770
- const { category, ordinal, model3d } = properties;
2771
- const modelProperty = {
2772
- id,
2773
- feature_type,
2774
- category,
2775
- ordinal
2776
- };
2777
- const center2 = turfCenter(fixture);
2778
- const coordinate = _4.get(center2, "geometry.coordinates");
2779
- const models = await create3DModels(
2780
- model3d,
2781
- coordinate,
2782
- modelProperty,
2783
- threeLayer
2784
- );
2785
- return models;
2786
- },
2787
2699
  createExtrudedUnit: (unit, threeLayer, options) => {
2788
2700
  const extrudeHeight = _4.get(options, "height");
2789
2701
  if (!extrudeHeight) return;
@@ -2823,24 +2735,6 @@ var styledFeatureGenerator = (mapTheme) => {
2823
2735
  options3d
2824
2736
  );
2825
2737
  return object;
2826
- },
2827
- createAmbientLight: (config) => {
2828
- const { color: colorString = "0xffffff", intensity = 1 } = config;
2829
- const color = parseInt(colorString, 16);
2830
- const ambientLight = new AmbientLight(color, intensity);
2831
- return ambientLight;
2832
- },
2833
- createDirectionalLight: (config) => {
2834
- const {
2835
- color: colorString = "0xffffff",
2836
- intensity = 1,
2837
- position: positionString = [0, 0, 0]
2838
- } = config;
2839
- const color = parseInt(colorString, 16);
2840
- const [x, y, z] = positionString;
2841
- const light = new DirectionalLight(color, intensity);
2842
- light.position.set(x, y, z).normalize();
2843
- return light;
2844
2738
  }
2845
2739
  };
2846
2740
  };
@@ -2970,351 +2864,230 @@ var getSuitablyValueBetweenBearings = (newBearing, currentBearing) => {
2970
2864
  return newBearing;
2971
2865
  };
2972
2866
 
2973
- // src/IndoorMap/utils/createHighlightElement.ts
2974
- import { Color as Color2 } from "three";
2975
- import _5 from "lodash";
2976
- import TWEEN from "@tweenjs/tween.js";
2977
- var DEFAULT_ALTITUDE_FACTOR = 0.5;
2978
- var createHighlighBillboardController = (obj, { altitudeFactor = DEFAULT_ALTITUDE_FACTOR } = {}) => {
2979
- const controller = { start: () => {
2980
- }, clear: () => {
2981
- } };
2982
- if (!(obj instanceof Billboard)) return controller;
2983
- const altitude = obj.properties.default.altitude;
2984
- const newAltitude = _5.clamp(altitude * altitudeFactor, 0, altitude);
2985
- const tween = new TWEEN.Tween({ altitude }).to({ altitude: newAltitude }, 800).easing(TWEEN.Easing.Quartic.Out).onUpdate((newUpdate) => {
2986
- obj.setLineHeight(newUpdate.altitude);
2987
- });
2988
- controller.start = () => {
2989
- tween.start();
2990
- };
2991
- controller.clear = () => {
2992
- tween.stop().to({ altitude }, 1600).startFromCurrentValues();
2993
- };
2994
- return controller;
2995
- };
2996
- var createHighlighExtrudeObjectController = (obj, { color }) => {
2997
- const controller = { start: () => {
2998
- }, clear: () => {
2999
- } };
3000
- if (obj?.type !== "ExtrudePolygon" || _5.isNil(obj?.object3d?.material?.color) || _5.isNil(color))
3001
- return controller;
3002
- controller.start = () => {
3003
- obj.object3d.material.color = new Color2(color);
3004
- };
3005
- controller.clear = () => {
3006
- const objectDefaultColor = _5.get(obj, "properties.defaultColor");
3007
- obj.object3d.material.color = new Color2(objectDefaultColor);
3008
- };
3009
- return controller;
3010
- };
3011
-
3012
2867
  // src/IndoorMap/camera/CameraManager.ts
3013
- var ZOOM_OUT_LEVEL = 21;
3014
- var ZOOM_IN_LEVEL = 24;
3015
- var CameraManager = class {
3016
- map;
3017
- constructor(map, options) {
3018
- this.map = map;
3019
- if (options?.defaultView) {
3020
- this.setView(options?.defaultView);
3021
- }
3022
- }
3023
- /** Private method */
3024
- #animateflyTo(viewOptions = {}, options = {}, callbackOption = () => {
3025
- }) {
3026
- const { start, end } = {
3027
- start: (frame) => {
3028
- },
3029
- end: (frame) => {
3030
- },
3031
- ...callbackOption
3032
- };
3033
- this.map.flyTo(viewOptions, options, (frame) => {
3034
- if (frame.state.playState === "running" && frame.state.progress === 0)
3035
- start(frame);
3036
- if (frame.state.playState === "finished") end(frame);
3037
- });
3038
- }
3039
- /** Public methods */
3040
- getView = () => {
3041
- return this.map.getView();
3042
- };
3043
- getZoom = () => {
3044
- return this.map.getView().zoom;
3045
- };
3046
- setView = (value) => {
3047
- this.map.setView(value);
3048
- };
3049
- flyTo = (center2, options = {}) => {
3050
- const currentView = this.getView();
3051
- const {
3052
- zoom = ZOOM_OUT_LEVEL,
3053
- pitch = 60,
3054
- duration = 600,
3055
- easing = "out",
3056
- bearing = currentView.bearing
3057
- } = options;
3058
- this.#animateflyTo(
3059
- {
3060
- center: center2,
3061
- zoom,
3062
- pitch,
3063
- bearing
3064
- },
3065
- { duration, easing }
3066
- );
3067
- };
3068
- flyToAndZoomIn = (centerPoint, options = {}) => {
3069
- const {
3070
- zoom = ZOOM_IN_LEVEL,
3071
- pitch = 60,
3072
- duration = 600,
3073
- easing = "out"
3074
- } = options;
3075
- this.#animateflyTo(
3076
- {
3077
- center: centerPoint,
3078
- zoom,
3079
- pitch
3080
- },
3081
- { duration, easing }
3082
- );
3083
- };
3084
- };
2868
+ import { Extent } from "maptalks";
3085
2869
 
3086
- // src/IndoorMap/renderer/RendererManager.ts
3087
- import _min from "lodash/min";
3088
- import { center as turfCenter2 } from "@turf/center";
3089
- import { ThreeLayer as ThreeLayer3 } from "maptalks.three";
3090
- import * as THREE3 from "three";
3091
-
3092
- // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3093
- import * as maptalks4 from "maptalks";
3094
- import * as THREE2 from "three";
3095
- import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader";
3096
- import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
3097
- import turfBuffer2 from "@turf/buffer";
3098
-
3099
- // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3100
- var element3DRendererOptions = {
3101
- unit: {
3102
- default: { color: "#ffffff", height: 4 },
3103
- byCategory: {
3104
- walkway: { color: "#cccccc", height: 0.1 },
3105
- terrace: { color: "#cccccc", height: 0.1 },
3106
- unenclosedarea: { color: "#cccccc", height: 0.2 },
3107
- nonpublic: { color: "#999999", height: 0.3 },
3108
- escalator: { height: 0.2 },
3109
- room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3110
- }
3111
- },
3112
- kiosk: {
3113
- default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3114
- },
3115
- fixture: {
3116
- default: { color: "#ffffff", height: 0.5 },
3117
- byCategory: {
3118
- water: { color: "#ACD7EC", height: 0.1 },
3119
- vegetation: { color: "#91C499", height: 0.5 }
2870
+ // ../../node_modules/@turf/meta/dist/esm/index.js
2871
+ function coordEach(geojson, callback, excludeWrapCoord) {
2872
+ if (geojson === null) return;
2873
+ 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;
2874
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2875
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2876
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2877
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2878
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2879
+ var multiFeatureIndex = 0;
2880
+ var geometryIndex = 0;
2881
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2882
+ if (geometry === null) continue;
2883
+ coords = geometry.coordinates;
2884
+ var geomType = geometry.type;
2885
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2886
+ switch (geomType) {
2887
+ case null:
2888
+ break;
2889
+ case "Point":
2890
+ if (callback(
2891
+ coords,
2892
+ coordIndex,
2893
+ featureIndex,
2894
+ multiFeatureIndex,
2895
+ geometryIndex
2896
+ ) === false)
2897
+ return false;
2898
+ coordIndex++;
2899
+ multiFeatureIndex++;
2900
+ break;
2901
+ case "LineString":
2902
+ case "MultiPoint":
2903
+ for (j = 0; j < coords.length; j++) {
2904
+ if (callback(
2905
+ coords[j],
2906
+ coordIndex,
2907
+ featureIndex,
2908
+ multiFeatureIndex,
2909
+ geometryIndex
2910
+ ) === false)
2911
+ return false;
2912
+ coordIndex++;
2913
+ if (geomType === "MultiPoint") multiFeatureIndex++;
2914
+ }
2915
+ if (geomType === "LineString") multiFeatureIndex++;
2916
+ break;
2917
+ case "Polygon":
2918
+ case "MultiLineString":
2919
+ for (j = 0; j < coords.length; j++) {
2920
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2921
+ if (callback(
2922
+ coords[j][k],
2923
+ coordIndex,
2924
+ featureIndex,
2925
+ multiFeatureIndex,
2926
+ geometryIndex
2927
+ ) === false)
2928
+ return false;
2929
+ coordIndex++;
2930
+ }
2931
+ if (geomType === "MultiLineString") multiFeatureIndex++;
2932
+ if (geomType === "Polygon") geometryIndex++;
2933
+ }
2934
+ if (geomType === "Polygon") multiFeatureIndex++;
2935
+ break;
2936
+ case "MultiPolygon":
2937
+ for (j = 0; j < coords.length; j++) {
2938
+ geometryIndex = 0;
2939
+ for (k = 0; k < coords[j].length; k++) {
2940
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2941
+ if (callback(
2942
+ coords[j][k][l],
2943
+ coordIndex,
2944
+ featureIndex,
2945
+ multiFeatureIndex,
2946
+ geometryIndex
2947
+ ) === false)
2948
+ return false;
2949
+ coordIndex++;
2950
+ }
2951
+ geometryIndex++;
2952
+ }
2953
+ multiFeatureIndex++;
2954
+ }
2955
+ break;
2956
+ case "GeometryCollection":
2957
+ for (j = 0; j < geometry.geometries.length; j++)
2958
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2959
+ return false;
2960
+ break;
2961
+ default:
2962
+ throw new Error("Unknown Geometry Type");
2963
+ }
3120
2964
  }
3121
2965
  }
3122
- };
3123
-
3124
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3125
- import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3126
- import * as THREE from "three";
3127
- import { BaseObject as BaseObject5 } from "maptalks.three";
3128
- import { isNil, set } from "lodash";
2966
+ }
3129
2967
 
3130
- // src/IndoorMap/renderer/utils/interpolateStops.ts
3131
- var interpolateStops = ({ stops }, zoom) => {
3132
- if (zoom <= stops[0][0]) return stops[0][1];
3133
- if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3134
- for (let i = 0; i < stops.length - 1; i++) {
3135
- const [z1, v1] = stops[i];
3136
- const [z2, v2] = stops[i + 1];
3137
- if (zoom >= z1 && zoom <= z2) {
3138
- const t = (zoom - z1) / (z2 - z1);
3139
- return v1 + t * (v2 - v1);
3140
- }
2968
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
2969
+ function bbox(geojson, options = {}) {
2970
+ if (geojson.bbox != null && true !== options.recompute) {
2971
+ return geojson.bbox;
3141
2972
  }
3142
- };
2973
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
2974
+ coordEach(geojson, (coord) => {
2975
+ if (result[0] > coord[0]) {
2976
+ result[0] = coord[0];
2977
+ }
2978
+ if (result[1] > coord[1]) {
2979
+ result[1] = coord[1];
2980
+ }
2981
+ if (result[2] < coord[0]) {
2982
+ result[2] = coord[0];
2983
+ }
2984
+ if (result[3] < coord[1]) {
2985
+ result[3] = coord[1];
2986
+ }
2987
+ });
2988
+ return result;
2989
+ }
2990
+ var index_default = bbox;
3143
2991
 
3144
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3145
- var OPTIONS4 = {
3146
- // Texture options
3147
- text: "",
3148
- textAlign: "center",
3149
- color: "#ffffff",
3150
- fontFamily: "sans-serif",
3151
- fontSize: 28,
3152
- fontWeight: 400,
3153
- background: "rgba(0, 0, 0, 0.2)",
3154
- lineHeight: 32,
3155
- padding: 8,
3156
- strokeColor: "#000000",
3157
- strokeWidth: 6,
3158
- strokeStyle: "round",
3159
- // Sprite options
3160
- /* Overall scale multiplier */
3161
- scale: 1,
3162
- altitude: 0,
3163
- opacity: 1
3164
- };
3165
- var TextSpriteMarker = class extends BaseObject5 {
3166
- #altitudeOffset = 0;
3167
- constructor(coordinate, options, layer, properties = {}) {
3168
- options = Util4.extend({}, OPTIONS4, options, { layer });
3169
- super();
3170
- this._coordinate = new Coordinate2(coordinate);
3171
- this._initOptions(options);
3172
- this._createGroup();
3173
- this.properties = { ...properties };
3174
- const sprite = this._createSprite();
3175
- this.getObject3d().add(sprite);
3176
- this._updatePosition();
3177
- this.type = "TextSpriteMarker";
3178
- }
3179
- getOptions() {
3180
- return super.getOptions();
3181
- }
3182
- _createSprite() {
3183
- const options = this.getOptions();
3184
- const texture = this._createTextTexture(options.text, options);
3185
- const material = new THREE.SpriteMaterial({
3186
- map: texture,
3187
- transparent: true,
3188
- alphaTest: 0.1
3189
- });
3190
- const sprite = new THREE.Sprite(material);
3191
- const w = texture.image.width;
3192
- const h = texture.image.height;
3193
- const base = 1 / 16;
3194
- const normalizedScale = options.scale / this.getMap().getGLRes();
3195
- sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3196
- this.#altitudeOffset = Math.max(
3197
- h * base * options.scale * 0.5,
3198
- 0.05
3199
- // minimum lift in world units
3200
- );
3201
- return sprite;
3202
- }
3203
- _createTextTexture(text, options = {}) {
3204
- const {
3205
- padding,
3206
- fontSize,
3207
- fontFamily,
3208
- fontWeight,
3209
- lineHeight,
3210
- background,
3211
- color,
3212
- textAlign,
3213
- strokeColor,
3214
- strokeWidth,
3215
- maxWidth
3216
- } = options || {};
3217
- const canvas = document.createElement("canvas");
3218
- const ctx = canvas.getContext("2d");
3219
- ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3220
- const paragraphs = String(text).split("\n");
3221
- const wrappedLines = [];
3222
- paragraphs.forEach((paragraph) => {
3223
- if (isNil(maxWidth) || isNaN(maxWidth)) {
3224
- wrappedLines.push(paragraph);
3225
- return;
3226
- }
3227
- const words = paragraph.split(/\s+/);
3228
- let currentLine = "";
3229
- words.forEach((word) => {
3230
- const testLine = currentLine ? currentLine + " " + word : word;
3231
- const testWidth = ctx.measureText(testLine).width;
3232
- if (testWidth > maxWidth && currentLine) {
3233
- wrappedLines.push(currentLine);
3234
- currentLine = word;
3235
- } else {
3236
- currentLine = testLine;
3237
- }
3238
- });
3239
- if (currentLine) {
3240
- wrappedLines.push(currentLine);
3241
- }
3242
- });
3243
- const lines = wrappedLines.length ? wrappedLines : [""];
3244
- const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3245
- const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3246
- const finalHeight = lineHeight * lines.length + padding * 2;
3247
- canvas.width = finalWidth;
3248
- canvas.height = finalHeight;
3249
- const ctx2 = canvas.getContext("2d");
3250
- ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3251
- ctx2.textAlign = textAlign;
3252
- if (background && background !== "transparent") {
3253
- ctx2.fillStyle = background;
3254
- ctx2.fillRect(0, 0, canvas.width, canvas.height);
2992
+ // src/IndoorMap/camera/CameraManager.ts
2993
+ import scale from "@turf/transform-scale";
2994
+ import bboxPolygon from "@turf/bbox-polygon";
2995
+ var CameraManager = class {
2996
+ map;
2997
+ constructor(map, options) {
2998
+ this.map = map;
2999
+ if (options?.defaultView) {
3000
+ this.setView(options?.defaultView);
3255
3001
  }
3256
- lines.forEach((line, i) => {
3257
- const y = padding + lineHeight * (i + 0.8);
3258
- let x = padding;
3259
- if (textAlign === "center") x = canvas.width / 2;
3260
- if (textAlign === "right" || textAlign === "end")
3261
- x = canvas.width - padding;
3262
- if (strokeWidth > 0) {
3263
- ctx2.lineWidth = strokeWidth;
3264
- ctx2.lineJoin = "round";
3265
- ctx2.miterLimit = 2;
3266
- ctx2.strokeStyle = strokeColor;
3267
- ctx2.strokeText(line, x, y);
3268
- }
3269
- ctx2.fillStyle = color;
3270
- ctx2.fillText(line, x, y);
3271
- });
3272
- const texture = new THREE.CanvasTexture(canvas);
3273
- texture.needsUpdate = true;
3274
- texture.minFilter = THREE.LinearFilter;
3275
- return texture;
3276
3002
  }
3277
- _updatePosition() {
3278
- const options = this.getOptions();
3279
- const layer = options.layer;
3280
- if (!layer) return;
3281
- const altitude = (options.altitude || 0) + this.#altitudeOffset;
3282
- const z = layer.altitudeToVector3(altitude, altitude).x;
3283
- const position = layer.coordinateToVector3(this._coordinate, z);
3284
- set(this.properties, "default.position", position);
3285
- this.getObject3d().position.copy(position);
3003
+ /** Public methods */
3004
+ getView = () => {
3005
+ return this.map.getView();
3006
+ };
3007
+ setView = (value) => {
3008
+ if (this.map && Object.keys(value).length !== 0) {
3009
+ this.map.setView(value);
3010
+ }
3011
+ };
3012
+ animateTo = (view, options = {}, step) => {
3013
+ this.map.animateTo(view, options, step);
3014
+ };
3015
+ setMaxExtent(extent) {
3016
+ return this.map.setMaxExtent(extent);
3286
3017
  }
3287
- _animation() {
3288
- const layer = this.getLayer();
3289
- if (!this.isAdd || !layer) return;
3290
- if (this._visible === true) {
3291
- const zoom = layer.map.getZoom();
3292
- const object3d = this.getObject3d();
3293
- const { opacity } = this.getOptions();
3294
- let opacityValue;
3295
- if (typeof opacity === "number") {
3296
- opacityValue = opacity ?? 1;
3297
- } else if (Array.isArray(opacity.stops)) {
3298
- opacityValue = interpolateStops(opacity, zoom);
3299
- } else {
3300
- throw new Error(`Unknown opacity value ${opacity}`);
3301
- }
3302
- const visible = opacityValue > 0.5;
3303
- object3d.visible = visible;
3018
+ getFeatureExtent = (feature2, scaleFactor = 1) => {
3019
+ const [minX, minY, maxX, maxY] = index_default(
3020
+ scale(bboxPolygon(index_default(feature2)), scaleFactor)
3021
+ );
3022
+ return new Extent(minX, minY, maxX, maxY);
3023
+ };
3024
+ getExtentZoom = (extent, options = {
3025
+ isFraction: false,
3026
+ padding: {
3027
+ paddingLeft: 0,
3028
+ paddingRight: 0,
3029
+ paddingTop: 0,
3030
+ paddingBottom: 0
3304
3031
  }
3032
+ }) => {
3033
+ const { isFraction = false, padding } = options;
3034
+ return this.map.getFitZoom(extent, isFraction, padding);
3035
+ };
3036
+ set maxZoom(value) {
3037
+ this.map.setMaxZoom(value);
3038
+ const spatialReference = {
3039
+ projection: "EPSG:3857",
3040
+ resolutions: (function() {
3041
+ const resolutions = [];
3042
+ const d = 2 * 6378137 * Math.PI;
3043
+ for (let i = 0; i < value; i++) {
3044
+ resolutions[i] = d / (256 * Math.pow(2, i));
3045
+ }
3046
+ return resolutions;
3047
+ })()
3048
+ };
3049
+ this.map.setSpatialReference(spatialReference);
3305
3050
  }
3306
- setText(text) {
3307
- const options = this.getOptions();
3308
- options.text = text;
3309
- const newSprite = this._createSprite();
3310
- const group = this.getObject3d();
3311
- group.children.forEach((child) => group.remove(child));
3312
- group.add(newSprite);
3313
- this._updatePosition();
3051
+ set minZoom(value) {
3052
+ this.map.setMinZoom(value);
3314
3053
  }
3315
- setAltitude(altitude) {
3316
- const bottomHeight = this.options.bottomHeight ?? 0;
3317
- return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3054
+ };
3055
+
3056
+ // src/IndoorMap/renderer/RendererManager.ts
3057
+ import _isFunction from "lodash/isFunction";
3058
+ import _min from "lodash/min";
3059
+ import { center as turfCenter2 } from "@turf/center";
3060
+ import * as THREE3 from "three";
3061
+
3062
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3063
+ import * as maptalks4 from "maptalks-gl";
3064
+ import * as THREE from "three";
3065
+ import { BaseObject as BaseObject5 } from "maptalks.three";
3066
+ import turfBuffer2 from "@turf/buffer";
3067
+
3068
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3069
+ var element3DRendererOptions = {
3070
+ unit: {
3071
+ default: { color: "#ffffff", height: 4 },
3072
+ byCategory: {
3073
+ walkway: { color: "#cccccc", height: 0.1 },
3074
+ terrace: { color: "#cccccc", height: 0.1 },
3075
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3076
+ nonpublic: { color: "#999999", height: 0.3 },
3077
+ escalator: { height: 0.2 },
3078
+ parking: { height: 0.1 },
3079
+ room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3080
+ }
3081
+ },
3082
+ kiosk: {
3083
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3084
+ },
3085
+ fixture: {
3086
+ default: { color: "#ffffff", height: 0.5 },
3087
+ byCategory: {
3088
+ water: { color: "#ACD7EC", height: 0.1 },
3089
+ vegetation: { color: "#91C499", height: 0.5 }
3090
+ }
3318
3091
  }
3319
3092
  };
3320
3093
 
@@ -3338,21 +3111,22 @@ var getGeometryOption = (feature2, options) => {
3338
3111
  var Element3DRenderer = class extends EventTarget {
3339
3112
  options;
3340
3113
  map;
3114
+ gltfLayer;
3341
3115
  threeLayer;
3342
- dracoLoader;
3116
+ scene;
3117
+ // private dracoLoader: DRACOLoader
3343
3118
  lineMaterial;
3344
3119
  materialByColorMap;
3345
- markerRenderer;
3346
3120
  // Renderer is Ready
3347
3121
  isReady = false;
3348
- constructor(map, options, layer) {
3122
+ constructor(map, options) {
3349
3123
  super();
3350
3124
  this.options = options;
3351
3125
  this.map = map;
3352
- this.dracoLoader = new DRACOLoader();
3353
- this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
3354
- this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3355
- this.threeLayer = layer;
3126
+ const groupLayer = this.map.getLayer("group");
3127
+ this.threeLayer = groupLayer.getLayer("three");
3128
+ this.gltfLayer = groupLayer.getLayer("gltf");
3129
+ this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
3356
3130
  this.render();
3357
3131
  }
3358
3132
  animation() {
@@ -3367,7 +3141,7 @@ var Element3DRenderer = class extends EventTarget {
3367
3141
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3368
3142
  const existingMaterial = this.materialByColorMap.get(color);
3369
3143
  if (existingMaterial) return existingMaterial;
3370
- const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3144
+ const created = new THREE.MeshLambertMaterial({ color, transparent: true });
3371
3145
  created.toneMapped = false;
3372
3146
  this.materialByColorMap.set(color, created);
3373
3147
  return created;
@@ -3382,46 +3156,48 @@ var Element3DRenderer = class extends EventTarget {
3382
3156
  } = getGeometryOption(feature2, this.options);
3383
3157
  const _this = this;
3384
3158
  const createPolygon = (geometry, feature3) => {
3385
- const [outerRing, ...innerRings] = geometry.coordinates;
3386
- const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3387
- const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3388
- if (color === "transparent") return;
3389
- const material = this.getOrCreateMaterialByColor(color);
3390
- const altitude = feature3.properties.ordinal * HEIGHT_METER;
3391
- const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3392
- const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3393
- const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3394
- offsetFeature,
3395
- { asynchronous: true, ...options, height, bottomHeight, altitude },
3396
- material
3397
- );
3398
- extrudedPolygon.on("click", (e) => {
3399
- console.log(e.target.options.polygon.id);
3400
- });
3401
- const topLineStrings = [
3402
- new maptalks4.LineString(outerRing),
3403
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3404
- ];
3405
- const topLines = this.threeLayer.toLines(
3406
- topLineStrings,
3407
- { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3408
- this.lineMaterial
3409
- );
3410
- const bottomLineStrings = [
3411
- new maptalks4.LineString(outerRing),
3412
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3413
- ];
3414
- const bottomLines = this.threeLayer.toLines(
3415
- bottomLineStrings,
3416
- { altitude, bottomHeight, interactive: false },
3417
- this.lineMaterial
3418
- );
3419
- return [extrudedPolygon, topLines, bottomLines];
3159
+ try {
3160
+ const [outerRing, ...innerRings] = geometry.coordinates;
3161
+ const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3162
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3163
+ if (color === "transparent") return;
3164
+ const material = this.getOrCreateMaterialByColor(color);
3165
+ const altitude = 0;
3166
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3167
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3168
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3169
+ offsetFeature,
3170
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3171
+ material
3172
+ );
3173
+ const topLineStrings = [
3174
+ new maptalks4.LineString(outerRing),
3175
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3176
+ ];
3177
+ const topLines = this.threeLayer.toLines(
3178
+ topLineStrings,
3179
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3180
+ this.lineMaterial
3181
+ );
3182
+ const bottomLineStrings = [
3183
+ new maptalks4.LineString(outerRing),
3184
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3185
+ ];
3186
+ const bottomLines = this.threeLayer.toLines(
3187
+ bottomLineStrings,
3188
+ { altitude, bottomHeight, interactive: false },
3189
+ this.lineMaterial
3190
+ );
3191
+ return [extrudedPolygon, topLines, bottomLines];
3192
+ } catch (err) {
3193
+ return [];
3194
+ }
3420
3195
  };
3421
3196
  try {
3422
3197
  switch (feature2.geometry.type) {
3423
3198
  case "MultiPolygon": {
3424
3199
  const { coordinates } = feature2.geometry;
3200
+ if (!coordinates) return [];
3425
3201
  const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3426
3202
  const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3427
3203
  this.threeLayer.addMesh(meshes);
@@ -3430,70 +3206,47 @@ var Element3DRenderer = class extends EventTarget {
3430
3206
  return multiMeshes;
3431
3207
  }
3432
3208
  case "Polygon": {
3209
+ const { coordinates } = feature2.geometry;
3210
+ if (!coordinates) return [];
3433
3211
  const meshes = createPolygon(feature2.geometry, feature2);
3434
3212
  this.threeLayer.addMesh(meshes);
3435
3213
  return meshes;
3436
3214
  }
3437
3215
  }
3438
3216
  } catch (err) {
3439
- console.log(`error createGeometry`, { feature: feature2, options });
3217
+ console.log(`error createGeometry`, err, { feature: feature2, options });
3440
3218
  }
3441
3219
  };
3442
3220
  async createEscalator(f, coordinate, options) {
3221
+ const model = {
3222
+ url: "https://cdn.venue.in.th/static/glb/escalator.glb",
3223
+ size: 4.4
3224
+ };
3443
3225
  const { direction: dir, angle } = options;
3444
- const model = await this.loadModel3d({
3445
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
3446
- properties: {
3447
- rotation: {
3448
- x: 0.5 * Math.PI,
3449
- // Rotate the model up (new_escalator.glb)
3450
- y: 0,
3451
- z: 0
3452
- },
3453
- position: { x: 0, y: 0, z: 0 },
3454
- scale: 0.01
3226
+ const rotationZ = dir === "up" ? 180 + angle : angle;
3227
+ var escalatorMarker = new maptalks4.GLTFMarker(coordinate, {
3228
+ symbol: {
3229
+ url: model.url,
3230
+ rotationZ,
3231
+ translationX: dir === "up" ? 0 : model.size * Math.cos(Math.PI * rotationZ / 180),
3232
+ translationY: dir === "up" ? 0 : model.size * Math.sin(Math.PI * rotationZ / 180),
3233
+ translationZ: dir === "up" ? -0.05 * model.size : -0.5 * model.size
3455
3234
  }
3456
3235
  });
3457
- model.rotation.y += dir === "up" ? Math.PI + angle : angle;
3458
- const box = new THREE2.Box3().setFromObject(model);
3459
- const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
3460
- 1 * (box.min.x + box.max.x),
3461
- 1 * (box.min.y + box.max.y),
3462
- 0.6 * box.max.z
3463
- );
3464
- const pivot = new THREE2.Group();
3465
- pivot.add(model);
3466
- model.position.sub(pivotPoint);
3467
- model.updateMatrixWorld(true);
3468
- const altitude = f.properties.ordinal * HEIGHT_METER;
3469
- const baseObjectModel = this.threeLayer.toModel(pivot, {
3470
- coordinate,
3471
- altitude
3472
- });
3473
- this.threeLayer.addMesh(baseObjectModel);
3474
- return baseObjectModel;
3236
+ escalatorMarker.addTo(this.gltfLayer);
3237
+ return escalatorMarker;
3475
3238
  }
3476
3239
  async createTree(coordinate, ordinal) {
3477
- const model = await this.loadModel3d({
3478
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
3479
- properties: {
3480
- rotation: {
3481
- x: 0.5 * Math.PI,
3482
- // Rotate the model up (new_escalator.glb)
3483
- y: 0,
3484
- z: 0
3485
- },
3486
- position: { x: 0, y: 0, z: 0 },
3487
- scale: 0.01
3240
+ const treeMarker = new maptalks4.GLTFMarker(coordinate, {
3241
+ symbol: {
3242
+ url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb"
3488
3243
  }
3489
3244
  });
3490
- const altitude = ordinal * HEIGHT_METER;
3491
- const baseObjectModel = this.threeLayer.toModel(model, {
3492
- coordinate,
3493
- altitude
3494
- });
3495
- this.threeLayer.addMesh(baseObjectModel);
3496
- return baseObjectModel;
3245
+ treeMarker.addTo(this.gltfLayer);
3246
+ return treeMarker;
3247
+ }
3248
+ async createBuilding(coordinate, ordinal) {
3249
+ return Promise.resolve(null);
3497
3250
  }
3498
3251
  createElement(f) {
3499
3252
  switch (f.feature_type) {
@@ -3516,34 +3269,34 @@ var Element3DRenderer = class extends EventTarget {
3516
3269
  }
3517
3270
  });
3518
3271
  }
3519
- async loadModel3d(model3d) {
3520
- const loader = new GLTFLoader2();
3521
- loader.setDRACOLoader(this.dracoLoader);
3522
- const { url, properties: modelProperties } = model3d;
3523
- const gltf = await loader.loadAsync(url);
3524
- const model = gltf.scene;
3525
- model.rotation.x = modelProperties.rotation.x;
3526
- model.rotation.y = modelProperties.rotation.y;
3527
- model.position.x = modelProperties.position.x;
3528
- model.position.y = modelProperties.position.y;
3529
- model.position.z = modelProperties.position.z;
3530
- const scale2 = modelProperties.scale;
3531
- model.scale.set(scale2, scale2, scale2);
3532
- return model;
3533
- }
3534
- createMarker = (coordinates, ordinal, text) => {
3535
- const options = {
3536
- // scale: 0.05,
3537
- // altitude: ordinal * HEIGHT_METER,
3538
- text
3539
- // interactive: true,
3540
- };
3541
- const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
3542
- this.threeLayer.addMesh([marker]);
3543
- return marker;
3544
- };
3545
- removeMarker = () => {
3546
- };
3272
+ createHighlightController(element) {
3273
+ if (!(element instanceof BaseObject5)) {
3274
+ return null;
3275
+ }
3276
+ switch (element.type) {
3277
+ case "ExtrudePolygon": {
3278
+ const mesh = element.getObject3d();
3279
+ const originalMaterial = mesh.material;
3280
+ const highlightMaterial = this.getOrCreateMaterialByColor("#ff0000");
3281
+ return {
3282
+ start: () => {
3283
+ mesh.material = highlightMaterial;
3284
+ },
3285
+ clear: () => {
3286
+ mesh.material = originalMaterial;
3287
+ }
3288
+ };
3289
+ }
3290
+ default: {
3291
+ return {
3292
+ start() {
3293
+ },
3294
+ clear() {
3295
+ }
3296
+ };
3297
+ }
3298
+ }
3299
+ }
3547
3300
  render() {
3548
3301
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3549
3302
  if (this.threeLayer._needsUpdate) {
@@ -3651,7 +3404,10 @@ var Element2DRenderer = class extends EventTarget {
3651
3404
  async createEscalator(f, coordinates) {
3652
3405
  return Promise.resolve(null);
3653
3406
  }
3654
- async createTree(f, coordinates) {
3407
+ async createTree(coordinates) {
3408
+ return Promise.resolve(null);
3409
+ }
3410
+ async createBuilding(coordinate, ordinal) {
3655
3411
  return Promise.resolve(null);
3656
3412
  }
3657
3413
  createElement = (imdfFeature) => {
@@ -3671,6 +3427,15 @@ var Element2DRenderer = class extends EventTarget {
3671
3427
  element.hide();
3672
3428
  });
3673
3429
  }
3430
+ createHighlightController(element) {
3431
+ if (!(element instanceof maptalks5.Geometry)) return null;
3432
+ return {
3433
+ start() {
3434
+ },
3435
+ clear() {
3436
+ }
3437
+ };
3438
+ }
3674
3439
  };
3675
3440
 
3676
3441
  // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
@@ -3681,6 +3446,7 @@ var Marker2DRenderer = class extends EventTarget {
3681
3446
  markerLayer;
3682
3447
  constructor(map) {
3683
3448
  super();
3449
+ this.map = map;
3684
3450
  }
3685
3451
  createMarker = (coordinates, ordinal, content) => {
3686
3452
  const marker = new maptalks6.ui.UIMarker(coordinates, {
@@ -3702,73 +3468,203 @@ var Marker2DRenderer = class extends EventTarget {
3702
3468
  };
3703
3469
 
3704
3470
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3705
- import * as maptalks7 from "maptalks";
3471
+ import * as maptalks7 from "maptalks-gl";
3706
3472
 
3707
- // src/IndoorMap/renderer/utils/svg2material.ts
3708
- import { SpriteMaterial as SpriteMaterial5, TextureLoader as TextureLoader3 } from "three";
3709
- var svgToDataURL = (svgString, scaleFactor = 1) => {
3710
- const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3711
- const url = URL.createObjectURL(svgBlob);
3712
- const img = new Image();
3713
- return new Promise((resolve, reject) => {
3714
- img.onload = function() {
3715
- const newWidth = img.width * scaleFactor;
3716
- const newHeight = img.height * scaleFactor;
3717
- const canvas = document.createElement("canvas");
3718
- canvas.width = newWidth;
3719
- canvas.height = newHeight;
3720
- const ctx = canvas.getContext("2d");
3721
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
3722
- const pngDataUrl = canvas.toDataURL("image/png");
3723
- resolve(pngDataUrl);
3724
- };
3725
- img.onerror = function(error) {
3726
- reject(error);
3727
- };
3728
- img.src = url;
3729
- });
3473
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3474
+ import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3475
+ import * as THREE2 from "three";
3476
+ import { BaseObject as BaseObject6 } from "maptalks.three";
3477
+ import { isNil, set } from "lodash";
3478
+
3479
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3480
+ var interpolateStops = ({ stops }, zoom) => {
3481
+ if (zoom <= stops[0][0]) return stops[0][1];
3482
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3483
+ for (let i = 0; i < stops.length - 1; i++) {
3484
+ const [z1, v1] = stops[i];
3485
+ const [z2, v2] = stops[i + 1];
3486
+ if (zoom >= z1 && zoom <= z2) {
3487
+ const t = (zoom - z1) / (z2 - z1);
3488
+ return v1 + t * (v2 - v1);
3489
+ }
3490
+ }
3730
3491
  };
3731
- var createSVGPathFromMarkerSymbol2 = (style) => {
3732
- const {
3733
- markerWidth = 24,
3734
- markerDx = 0,
3735
- markerDy = 0,
3736
- // markerFill,
3737
- markerPath,
3738
- fill = "#000000"
3739
- } = style;
3740
- const scale2 = markerWidth / 24;
3741
- const strokeWidth = 2;
3742
- const halfStrokeWidth = 0.5 * strokeWidth;
3743
- if (Array.isArray(markerPath)) {
3744
- return markerPath.map(
3745
- ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3492
+
3493
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3494
+ var OPTIONS4 = {
3495
+ // Texture options
3496
+ text: "",
3497
+ textAlign: "center",
3498
+ color: "#ffffff",
3499
+ fontFamily: "sans-serif",
3500
+ fontSize: 28,
3501
+ fontWeight: 400,
3502
+ background: "transparent",
3503
+ lineHeight: 32,
3504
+ padding: 8,
3505
+ strokeColor: "#000000",
3506
+ strokeWidth: 3,
3507
+ strokeStyle: "round",
3508
+ // Sprite options
3509
+ /* Overall scale multiplier */
3510
+ scale: 1,
3511
+ altitude: 0,
3512
+ opacity: 1
3513
+ };
3514
+ var TextSpriteMarker = class extends BaseObject6 {
3515
+ #altitudeOffset = 0;
3516
+ constructor(coordinate, options, layer, properties = {}) {
3517
+ options = Util4.extend({}, OPTIONS4, options, { layer });
3518
+ super();
3519
+ this._coordinate = new Coordinate2(coordinate);
3520
+ this._initOptions(options);
3521
+ this._createGroup();
3522
+ this.properties = { ...properties };
3523
+ const sprite = this._createSprite();
3524
+ this.getObject3d().add(sprite);
3525
+ this._updatePosition();
3526
+ this.type = "TextSpriteMarker";
3527
+ }
3528
+ getOptions() {
3529
+ return super.getOptions();
3530
+ }
3531
+ _createSprite() {
3532
+ const options = this.getOptions();
3533
+ const texture = this._createTextTexture(options.text, options);
3534
+ const material = new THREE2.SpriteMaterial({
3535
+ map: texture,
3536
+ transparent: true,
3537
+ alphaTest: 0.1
3538
+ });
3539
+ const sprite = new THREE2.Sprite(material);
3540
+ const w = texture.image.width;
3541
+ const h = texture.image.height;
3542
+ const base = 1 / 16;
3543
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3544
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3545
+ this.#altitudeOffset = Math.max(
3546
+ h * base * options.scale * 0.5,
3547
+ 0.05
3548
+ // minimum lift in world units
3746
3549
  );
3550
+ return sprite;
3747
3551
  }
3748
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3749
- };
3750
- var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3751
- const material = new SpriteMaterial5();
3752
- try {
3753
- const [base, icon] = labelSymbol ?? [{}, {}];
3754
- const { markerWidth: baseWidth = 24 } = base;
3755
- const { markerWidth: iconWidth = 24 } = icon;
3756
- const viewBoxDimension = Math.max(baseWidth, iconWidth);
3757
- const baseSVG = createSVGPathFromMarkerSymbol2(base);
3758
- const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3759
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3760
- const textureLoader = new TextureLoader3();
3761
- const scaleFactor = 200 / 24;
3762
- svgToDataURL(svg, scaleFactor).then((png) => {
3763
- const texture = textureLoader.load(png, () => {
3764
- material.map = texture;
3765
- material.needsUpdate = true;
3552
+ _createTextTexture(text, options = {}) {
3553
+ const {
3554
+ padding,
3555
+ fontSize,
3556
+ fontFamily,
3557
+ fontWeight,
3558
+ lineHeight,
3559
+ background,
3560
+ color,
3561
+ textAlign,
3562
+ strokeColor,
3563
+ strokeWidth,
3564
+ maxWidth
3565
+ } = options || {};
3566
+ const canvas = document.createElement("canvas");
3567
+ const ctx = canvas.getContext("2d");
3568
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3569
+ const paragraphs = String(text).split("\n");
3570
+ const wrappedLines = [];
3571
+ paragraphs.forEach((paragraph) => {
3572
+ if (isNil(maxWidth) || isNaN(maxWidth)) {
3573
+ wrappedLines.push(paragraph);
3574
+ return;
3575
+ }
3576
+ const words = paragraph.split(/\s+/);
3577
+ let currentLine = "";
3578
+ words.forEach((word) => {
3579
+ const testLine = currentLine ? currentLine + " " + word : word;
3580
+ const testWidth = ctx.measureText(testLine).width;
3581
+ if (testWidth > maxWidth && currentLine) {
3582
+ wrappedLines.push(currentLine);
3583
+ currentLine = word;
3584
+ } else {
3585
+ currentLine = testLine;
3586
+ }
3766
3587
  });
3588
+ if (currentLine) {
3589
+ wrappedLines.push(currentLine);
3590
+ }
3591
+ });
3592
+ const lines = wrappedLines.length ? wrappedLines : [""];
3593
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3594
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3595
+ const finalHeight = lineHeight * lines.length + padding * 2;
3596
+ canvas.width = finalWidth;
3597
+ canvas.height = finalHeight;
3598
+ const ctx2 = canvas.getContext("2d");
3599
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3600
+ ctx2.textAlign = textAlign;
3601
+ if (background && background !== "transparent") {
3602
+ ctx2.fillStyle = background;
3603
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3604
+ }
3605
+ lines.forEach((line, i) => {
3606
+ const y = padding + lineHeight * (i + 0.8);
3607
+ let x = padding;
3608
+ if (textAlign === "center") x = canvas.width / 2;
3609
+ if (textAlign === "right" || textAlign === "end")
3610
+ x = canvas.width - padding;
3611
+ if (strokeWidth > 0) {
3612
+ ctx2.lineWidth = strokeWidth;
3613
+ ctx2.lineJoin = "round";
3614
+ ctx2.miterLimit = 2;
3615
+ ctx2.strokeStyle = strokeColor;
3616
+ ctx2.strokeText(line, x, y);
3617
+ }
3618
+ ctx2.fillStyle = color;
3619
+ ctx2.fillText(line, x, y);
3767
3620
  });
3768
- } catch (error) {
3769
- console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3621
+ const texture = new THREE2.CanvasTexture(canvas);
3622
+ texture.needsUpdate = true;
3623
+ texture.minFilter = THREE2.LinearFilter;
3624
+ return texture;
3625
+ }
3626
+ _updatePosition() {
3627
+ const options = this.getOptions();
3628
+ const layer = options.layer;
3629
+ if (!layer) return;
3630
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3631
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3632
+ const position = layer.coordinateToVector3(this._coordinate, z);
3633
+ set(this.properties, "default.position", position);
3634
+ this.getObject3d().position.copy(position);
3635
+ }
3636
+ _animation() {
3637
+ const layer = this.getLayer();
3638
+ if (!this.isAdd || !layer) return;
3639
+ if (this._visible === true) {
3640
+ const zoom = layer.map.getZoom();
3641
+ const object3d = this.getObject3d();
3642
+ const { opacity } = this.getOptions();
3643
+ let opacityValue;
3644
+ if (typeof opacity === "number") {
3645
+ opacityValue = opacity ?? 1;
3646
+ } else if (Array.isArray(opacity.stops)) {
3647
+ opacityValue = interpolateStops(opacity, zoom);
3648
+ } else {
3649
+ throw new Error(`Unknown opacity value ${opacity}`);
3650
+ }
3651
+ const visible = opacityValue > 0.5;
3652
+ object3d.visible = visible;
3653
+ }
3654
+ }
3655
+ setText(text) {
3656
+ const options = this.getOptions();
3657
+ options.text = text;
3658
+ const newSprite = this._createSprite();
3659
+ const group = this.getObject3d();
3660
+ group.children.forEach((child) => group.remove(child));
3661
+ group.add(newSprite);
3662
+ this._updatePosition();
3663
+ }
3664
+ setAltitude(altitude) {
3665
+ const bottomHeight = this.options.bottomHeight ?? 0;
3666
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3770
3667
  }
3771
- return material;
3772
3668
  };
3773
3669
 
3774
3670
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
@@ -3819,40 +3715,41 @@ var Marker3DRenderer = class extends EventTarget {
3819
3715
  });
3820
3716
  }
3821
3717
  /** Marker */
3822
- getOrCreateIconMaterial(key) {
3823
- if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3824
- const existingMaterial = this.materialByKey.get(key);
3825
- if (existingMaterial) return existingMaterial;
3826
- const baseSymbol = {
3827
- markerType: "path",
3828
- markerPath: [
3829
- {
3830
- path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3831
- fill: "#ff0000"
3832
- }
3833
- ],
3834
- markerPathWidth: 24,
3835
- markerPathHeight: 24
3836
- };
3837
- const markerSymbol = {
3838
- markerType: "path",
3839
- markerPath: [],
3840
- // TODO: Get Path by featureType.category
3841
- // 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" }],
3842
- markerPathWidth: 24,
3843
- markerPathHeight: 24,
3844
- markerWidth: 24,
3845
- markerHeight: 24,
3846
- markerDy: 1.5,
3847
- markerDx: 1.5
3848
- };
3849
- const created = createSpriteMaterialByLabelSymbol2([
3850
- baseSymbol,
3851
- markerSymbol
3852
- ]);
3853
- this.materialByKey.set(key, created);
3854
- return created;
3855
- }
3718
+ // getOrCreateIconMaterial(key) {
3719
+ // if (!this.materialByKey) this.materialByKey = new Map()
3720
+ // const existingMaterial = this.materialByKey.get(key)
3721
+ // if (existingMaterial) return existingMaterial
3722
+ // // Create new
3723
+ // const baseSymbol: maptalks.Path = {
3724
+ // markerType: "path",
3725
+ // markerPath: [
3726
+ // {
3727
+ // path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3728
+ // fill: "#ff0000",
3729
+ // },
3730
+ // ],
3731
+ // markerPathWidth: 24,
3732
+ // markerPathHeight: 24
3733
+ // }
3734
+ // const markerSymbol: maptalks.PathMarkerSymbol = {
3735
+ // markerType: "path",
3736
+ // markerPath: [],
3737
+ // // TODO: Get Path by featureType.category
3738
+ // // 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" }],
3739
+ // markerPathWidth: 24,
3740
+ // markerPathHeight: 24,
3741
+ // markerWidth: 24,
3742
+ // markerHeight: 24,
3743
+ // markerDy: 1.5,
3744
+ // markerDx: 1.5,
3745
+ // }
3746
+ // const created = createSpriteMaterialByLabelSymbol([
3747
+ // baseSymbol,
3748
+ // markerSymbol,
3749
+ // ])
3750
+ // this.materialByKey.set(key, created)
3751
+ // return created
3752
+ // }
3856
3753
  };
3857
3754
 
3858
3755
  // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
@@ -3874,11 +3771,17 @@ var angleBetweenLineStrings = (line1, line2) => {
3874
3771
  };
3875
3772
 
3876
3773
  // src/IndoorMap/renderer/RendererManager.ts
3774
+ function delay(ms) {
3775
+ return new Promise((resolve) => setTimeout(resolve, ms));
3776
+ }
3877
3777
  var RendererManager = class extends EventTarget {
3878
3778
  map;
3879
3779
  options;
3880
3780
  // Client for fetching data
3881
3781
  #dataClient;
3782
+ #isClicked = false;
3783
+ #onClickElement = (e) => {
3784
+ };
3882
3785
  /** Elements: Responsible for converting feature info elements and add to map */
3883
3786
  elementRenderer;
3884
3787
  markerRenderer;
@@ -3887,6 +3790,7 @@ var RendererManager = class extends EventTarget {
3887
3790
  currentOrdinals;
3888
3791
  markersMap;
3889
3792
  markersByOrdinal;
3793
+ highlightControllers = [];
3890
3794
  constructor(map, dataClient, options) {
3891
3795
  super();
3892
3796
  this.map = map;
@@ -3896,48 +3800,52 @@ var RendererManager = class extends EventTarget {
3896
3800
  this.markersMap = /* @__PURE__ */ new Map();
3897
3801
  this.markersByOrdinal = /* @__PURE__ */ new Map();
3898
3802
  this.#dataClient = dataClient;
3803
+ const _this = this;
3899
3804
  if (options.type === "3D") {
3900
- const threeLayer = new ThreeLayer3("elements", {
3901
- forceRenderOnMoving: true,
3902
- forceRenderOnRotating: true
3903
- });
3904
- const _this = this;
3805
+ const groupLayer = this.map.getLayer("group");
3806
+ const threeLayer = groupLayer.getLayer("three");
3905
3807
  threeLayer.prepareToDraw = function(gl, scene, camera) {
3906
3808
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3907
3809
  scene.add(ambientLight);
3908
3810
  const dirColor = 16777215;
3909
3811
  const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3910
- dllight.position.set(0, -10, 10).normalize();
3812
+ dllight.position.set(0, -10, 20).normalize();
3911
3813
  scene.add(dllight);
3912
3814
  const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3913
3815
  scene.add(hemi);
3914
- _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
3816
+ _this.elementRenderer = new Element3DRenderer(map, options.elements);
3915
3817
  _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3916
3818
  if (typeof options.onRendererReady === "function") {
3917
3819
  options.onRendererReady();
3918
3820
  }
3919
3821
  _this.#createElements();
3920
3822
  };
3921
- threeLayer.addTo(this.map);
3922
3823
  } else {
3923
3824
  this.elementRenderer = new Element2DRenderer(map, options.elements);
3924
3825
  this.markerRenderer = new Marker2DRenderer(map);
3925
3826
  this.#createElements();
3926
3827
  }
3927
3828
  }
3829
+ set onClickElement(func) {
3830
+ this.#onClickElement = func;
3831
+ }
3832
+ handleClickElement = (e) => {
3833
+ if (this.#isClicked) return;
3834
+ this.#isClicked = true;
3835
+ const onClickElement = this.#onClickElement;
3836
+ if (!_isFunction(onClickElement)) return;
3837
+ this.#onClickElement(e);
3838
+ this.#isClicked = false;
3839
+ };
3928
3840
  getElementsByOrdinal = (ordinal) => {
3929
3841
  const exist = this.elementsByOrdinal.get(ordinal);
3930
3842
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3931
3843
  return this.elementsByOrdinal.get(ordinal);
3932
3844
  };
3933
- getMarkersByOrdinal = (ordinal) => {
3934
- const exist = this.markersByOrdinal.get(ordinal);
3935
- if (!exist) this.markersByOrdinal.set(ordinal, []);
3936
- return this.markersByOrdinal.get(ordinal);
3937
- };
3938
3845
  addElementsToManager = (id, elements, ordinal) => {
3939
3846
  this.elementsMap.set(id, elements);
3940
3847
  elements.forEach((el) => {
3848
+ el.on("click", (e) => this.handleClickElement(id));
3941
3849
  this.getElementsByOrdinal(ordinal).push(el);
3942
3850
  });
3943
3851
  const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
@@ -3947,19 +3855,8 @@ var RendererManager = class extends EventTarget {
3947
3855
  this.elementRenderer.hideElements(elements, ordinal);
3948
3856
  }
3949
3857
  };
3950
- addMarkersToManager = (id, markers, ordinal) => {
3951
- this.markersMap.set(id, markers);
3952
- markers.forEach((el) => {
3953
- this.getMarkersByOrdinal(ordinal).push(el);
3954
- });
3955
- const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3956
- if (inOrdinal) {
3957
- this.markerRenderer.showMarkers(markers, ordinal);
3958
- } else {
3959
- this.markerRenderer.hideMarkers(markers, ordinal);
3960
- }
3961
- };
3962
3858
  async #createElements() {
3859
+ await delay(this.options.delayBeforeCreateElements ?? 0);
3963
3860
  const levels = await this.#dataClient.filterByType("level", {
3964
3861
  populate: true
3965
3862
  });
@@ -4006,13 +3903,15 @@ var RendererManager = class extends EventTarget {
4006
3903
  }
4007
3904
  const thisOrdinal = escalator.properties.ordinal;
4008
3905
  const relationship = escalatorRelationships[0];
3906
+ if (!relationship.properties.origin?.id) throw new Error(`relationship (id=${relationship.id}) - origin not exists`);
3907
+ if (!relationship.properties.destination?.id) throw new Error(`relationship (id=${relationship.id}) - destination not exists`);
4009
3908
  const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
4010
3909
  const bothOpenings = await Promise.all(
4011
3910
  bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
4012
3911
  );
4013
3912
  const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
4014
3913
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
4015
- const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
3914
+ const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4016
3915
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
4017
3916
  const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
4018
3917
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
@@ -4021,7 +3920,7 @@ var RendererManager = class extends EventTarget {
4021
3920
  this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
4022
3921
  }
4023
3922
  } catch (err) {
4024
- console.log(`cannot create escalator`, err);
3923
+ console.warn(`cannot create escalator`, err.message);
4025
3924
  }
4026
3925
  }
4027
3926
  this.changeLevelByOrdinal(this.currentOrdinals);
@@ -4057,14 +3956,48 @@ var RendererManager = class extends EventTarget {
4057
3956
  }
4058
3957
  }
4059
3958
  }
3959
+ highlightElements = (elemIds, options) => {
3960
+ const { reset = true } = options ?? {};
3961
+ if (reset) {
3962
+ this.clearHighlightElements();
3963
+ }
3964
+ const elements = elemIds.map((id) => this.elementsMap.get(id)).flat();
3965
+ elements.forEach((element) => {
3966
+ const controller = this.elementRenderer.createHighlightController(element);
3967
+ controller.start();
3968
+ this.highlightControllers.push(controller);
3969
+ });
3970
+ };
3971
+ clearHighlightElements = () => {
3972
+ this.highlightControllers.forEach((controller) => {
3973
+ if (_isFunction(controller?.clear)) controller.clear();
3974
+ });
3975
+ };
4060
3976
  /**
4061
3977
  * ========================================================================
4062
3978
  * Markers
4063
3979
  * ======================================================================== */
3980
+ _getMarkersByOrdinal = (ordinal) => {
3981
+ const exist = this.markersByOrdinal.get(ordinal);
3982
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
3983
+ return this.markersByOrdinal.get(ordinal);
3984
+ };
3985
+ _addMarkersToManager = (id, markers, ordinal) => {
3986
+ this.markersMap.set(id, markers);
3987
+ markers.forEach((el) => {
3988
+ this._getMarkersByOrdinal(ordinal).push(el);
3989
+ });
3990
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3991
+ if (inOrdinal) {
3992
+ this.markerRenderer.showMarkers(markers, ordinal);
3993
+ } else {
3994
+ this.markerRenderer.hideMarkers(markers, ordinal);
3995
+ }
3996
+ };
4064
3997
  createMarker(coordinate, ordinal, text, options) {
4065
3998
  const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
4066
3999
  const markerId = `${this.markersMap.size + 1}`;
4067
- this.addMarkersToManager(markerId, [marker], ordinal);
4000
+ this._addMarkersToManager(markerId, [marker], ordinal);
4068
4001
  }
4069
4002
  clearMarkers() {
4070
4003
  for (const [markerId, marker] of this.markersMap) {
@@ -4079,9 +4012,11 @@ var INITIAL_ZOOM = 18.5;
4079
4012
  var CLICK_TOLERANCE = 20;
4080
4013
  var defaultOptions = {
4081
4014
  pixelRatio: 1,
4015
+ interactions: true,
4082
4016
  locale: DEFAULT_LOCALE
4083
4017
  };
4084
4018
  var IndoorMap = class extends EventTarget {
4019
+ options;
4085
4020
  //TODO: refac functions; let them do only 1 thing in a function
4086
4021
  /** Note: "#" means private variables */
4087
4022
  #styler = null;
@@ -4133,18 +4068,31 @@ var IndoorMap = class extends EventTarget {
4133
4068
  };
4134
4069
  constructor(elementId, options) {
4135
4070
  super();
4071
+ const combinedOptions = _5.merge({}, defaultOptions, options);
4072
+ this.options = options;
4136
4073
  const {
4137
4074
  onMapReady,
4138
4075
  onMapLoading,
4139
4076
  pixelRatio,
4140
4077
  locale
4141
- } = _6.merge({}, defaultOptions, options);
4078
+ } = combinedOptions;
4142
4079
  this.map = new Map2(elementId, {
4143
4080
  attribution: false,
4081
+ // Temporart set, not really default view
4082
+ // Default view is set in camera manager
4144
4083
  center: INITIAL_CENTER,
4145
4084
  zoom: INITIAL_ZOOM,
4146
4085
  clickTimeThreshold: 600,
4147
4086
  centerCross: options.centerCross ?? false,
4087
+ ...options.interactions === false ? {
4088
+ draggable: false,
4089
+ dragPan: false,
4090
+ dragRotate: false,
4091
+ dragPitch: false,
4092
+ scrollWheelZoom: false,
4093
+ touchZoom: false,
4094
+ doubleClickZoom: false
4095
+ } : {},
4148
4096
  baseLayer: new TileLayer("base", {
4149
4097
  urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
4150
4098
  subdomains: ["a", "b", "c", "d"],
@@ -4156,8 +4104,16 @@ var IndoorMap = class extends EventTarget {
4156
4104
  }),
4157
4105
  layers: []
4158
4106
  });
4107
+ const groupLayer = new GroupGLLayer("group", [], {}).addTo(this.map);
4108
+ const threeLayer = new ThreeLayer4("three", {
4109
+ forceRenderOnMoving: true,
4110
+ forceRenderOnRotating: true
4111
+ });
4112
+ groupLayer.addLayer(threeLayer);
4113
+ const gltfLayer = new GLTFLayer("gltf");
4114
+ groupLayer.addLayer(gltfLayer);
4159
4115
  this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
4160
- this.camera = new CameraManager(this.map);
4116
+ this.camera = new CameraManager(this.map, options.camera);
4161
4117
  this.locale = locale;
4162
4118
  this.pixelRatio = pixelRatio;
4163
4119
  this.onMapReady = onMapReady;
@@ -4168,23 +4124,25 @@ var IndoorMap = class extends EventTarget {
4168
4124
  }
4169
4125
  set dataClient(value) {
4170
4126
  this.#dataClient = value;
4171
- this.#dataClient.filterByType("venue").then((venues) => {
4172
- const venueCenters = turfCenter3(featureCollection(venues));
4173
- const [x, y] = venueCenters.geometry.coordinates;
4174
- const center2 = new Coordinate4(x, y);
4175
- this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4176
- });
4177
- }
4178
- on(eventName, handler) {
4179
- this.map.on(eventName, handler);
4127
+ if (!this.options.camera?.defaultView?.center) {
4128
+ this.#dataClient.filterByType("venue").then((venues) => {
4129
+ const venueCenters = turfCenter3(featureCollection(venues));
4130
+ const [x, y] = venueCenters.geometry.coordinates;
4131
+ const center2 = new Coordinate4(x, y);
4132
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4133
+ });
4134
+ }
4180
4135
  }
4181
4136
  /**
4182
4137
  * Events
4183
4138
  */
4139
+ on(eventName, handler) {
4140
+ this.map.on(eventName, handler);
4141
+ }
4184
4142
  handleMapClick = ({ coordinate }) => {
4185
4143
  const { x, y } = coordinate;
4186
4144
  console.log(
4187
- `[Coordinates]: x: ${_6.round(x, 8)} y: ${_6.round(
4145
+ `[Coordinates]: x: ${_5.round(x, 8)} y: ${_5.round(
4188
4146
  y,
4189
4147
  8
4190
4148
  )}, [Bearing]: ${this.map.getBearing()}, [Pitch]: ${this.map.getPitch()}`
@@ -4236,40 +4194,12 @@ var IndoorMap = class extends EventTarget {
4236
4194
  this.map.off("moveend", this.#findAndSetVenueInView);
4237
4195
  }
4238
4196
  }
4239
- get ordinals() {
4240
- return this.#ordinals || [];
4241
- }
4242
- set ordinals(value) {
4243
- if (!Array.isArray(value)) throw new Error("ordinals must be Array");
4244
- this.#ordinals = value;
4245
- }
4246
4197
  set billboards(value) {
4247
4198
  this.#billboards = value;
4248
4199
  }
4249
- set mapConfig(value) {
4250
- this.#mapConfig = value;
4251
- }
4252
4200
  set mapDecorations(value) {
4253
4201
  this.#mapDecorations = value;
4254
4202
  }
4255
- set maxZoom(value) {
4256
- this.map.setMaxZoom(value);
4257
- const spatialReference = {
4258
- projection: "EPSG:3857",
4259
- resolutions: (function() {
4260
- const resolutions = [];
4261
- const d = 2 * 6378137 * Math.PI;
4262
- for (let i = 0; i < value; i++) {
4263
- resolutions[i] = d / (256 * Math.pow(2, i));
4264
- }
4265
- return resolutions;
4266
- })()
4267
- };
4268
- this.map.setSpatialReference(spatialReference);
4269
- }
4270
- set minZoom(value) {
4271
- this.map.setMinZoom(value);
4272
- }
4273
4203
  set groundLabels(value) {
4274
4204
  this.#groundLabels = value;
4275
4205
  }
@@ -4277,7 +4207,7 @@ var IndoorMap = class extends EventTarget {
4277
4207
  this.map.setDevicePixelRatio(value);
4278
4208
  }
4279
4209
  set onClickElement(func) {
4280
- this.#onClickElement = func;
4210
+ this.rendererManager.onClickElement = func;
4281
4211
  }
4282
4212
  set locale(value) {
4283
4213
  this.#locale = value || defaultOptions.locale;
@@ -4301,13 +4231,10 @@ var IndoorMap = class extends EventTarget {
4301
4231
  if (this.#isClicked) return;
4302
4232
  this.#isClicked = true;
4303
4233
  const onClickElement = this.#onClickElement;
4304
- if (!_6.isFunction(onClickElement)) return;
4234
+ if (!_5.isFunction(onClickElement)) return;
4305
4235
  this.#onClickElement(e);
4306
4236
  this.#isClicked = false;
4307
4237
  };
4308
- setCenter(center2, padding) {
4309
- this.map.setCenter(center2, padding);
4310
- }
4311
4238
  async #legacy_createElements() {
4312
4239
  const {
4313
4240
  // 2D
@@ -4321,46 +4248,27 @@ var IndoorMap = class extends EventTarget {
4321
4248
  create3DFootprint,
4322
4249
  create3DGroundLabel,
4323
4250
  create3DBillboard,
4324
- createVenue3DModel,
4325
4251
  createExtrudedUnit,
4326
- create3DFixture,
4327
4252
  create3DAmenityMarker,
4328
4253
  create3DOccupantAmenityMarker,
4329
4254
  create3DOpeningMarker,
4330
- createOccupantGroundLabel,
4331
- // Light
4332
- createAmbientLight,
4333
- createDirectionalLight
4255
+ createOccupantGroundLabel
4334
4256
  } = this.#styler;
4335
4257
  let elements = {};
4336
4258
  let object3ds = [];
4337
- const scene = this.threeLayer.getScene();
4338
- if (scene) {
4339
- const {
4340
- ambientLight: ambientLightConfig = {},
4341
- directionalLight: directionalLightConfig = {}
4342
- } = _6.get(this.#mapConfig, "light", {
4343
- ambientLight: {},
4344
- directionalLight: {}
4345
- });
4346
- const ambientLight = createAmbientLight(ambientLightConfig);
4347
- scene.add(ambientLight);
4348
- const light = createDirectionalLight(directionalLightConfig);
4349
- scene.add(light);
4350
- }
4351
4259
  for (const feature2 of this.#features) {
4352
4260
  try {
4353
4261
  const { feature_type: featureType, properties, id } = feature2;
4354
- const layerName = _6.get(
4262
+ const layerName = _5.get(
4355
4263
  LAYER_FEATURE_TYPE_OBJ,
4356
4264
  featureType,
4357
4265
  featureType
4358
4266
  );
4359
4267
  const layer = this.map.getLayer(layerName);
4360
4268
  let geometry;
4361
- const category = _6.get(feature2, "properties.category");
4362
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4363
- const textMarkerType = _6.get(
4269
+ const category = _5.get(feature2, "properties.category");
4270
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
4271
+ const textMarkerType = _5.get(
4364
4272
  this.#mapConfig,
4365
4273
  "text_marker_type",
4366
4274
  "ui-marker"
@@ -4370,16 +4278,6 @@ var IndoorMap = class extends EventTarget {
4370
4278
  feature2
4371
4279
  );
4372
4280
  switch (featureType) {
4373
- case "venue": {
4374
- geometry = createVenue(feature2).addTo(layer);
4375
- const models = await createVenue3DModel(feature2, this.threeLayer);
4376
- models.forEach((model) => {
4377
- model.on("click", this.handleClickElement);
4378
- object3ds.push(model);
4379
- this.#venueObjects.push(model);
4380
- });
4381
- break;
4382
- }
4383
4281
  case "amenity": {
4384
4282
  if (feature2.properties.is_featured) {
4385
4283
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4423,127 +4321,6 @@ var IndoorMap = class extends EventTarget {
4423
4321
  geometry = createSection(feature2)?.addTo(layer);
4424
4322
  break;
4425
4323
  }
4426
- case "occupant": {
4427
- switch (category) {
4428
- // Create only marker if it is amenity occupant
4429
- case "currencyexchange":
4430
- case "donationcenter":
4431
- case "postoffice":
4432
- const markerFeature = {
4433
- ...feature2,
4434
- geometry: feature2.properties?.anchor?.geometry
4435
- };
4436
- const marker3d = create3DOccupantAmenityMarker(
4437
- markerFeature,
4438
- this.threeLayer,
4439
- extrudeConfig
4440
- )?.on("click", this.handleClickElement);
4441
- object3ds.push(marker3d);
4442
- break;
4443
- default: {
4444
- const { kiosk, anchor } = feature2.properties;
4445
- const { unit } = anchor.properties;
4446
- let mainLocation = kiosk || unit || null;
4447
- const relatedLocations = [
4448
- ...feature2.properties.units,
4449
- ...feature2.properties.kiosks
4450
- ].filter((f) => f.properties.ordinal !== properties.ordinal);
4451
- const occupantLocations = [mainLocation, ...relatedLocations];
4452
- const renderType = feature2.properties.render_type;
4453
- occupantLocations.forEach((location, index) => {
4454
- const isMainLocation = index === 0;
4455
- if (renderType === "Label") {
4456
- const occupantGroundLabel = createOccupantGroundLabel(
4457
- feature2,
4458
- location,
4459
- { textMarkerType, extrudeConfig },
4460
- this.threeLayer
4461
- );
4462
- if (occupantGroundLabel instanceof GroundLabel) {
4463
- occupantGroundLabel.on("click", this.handleClickElement);
4464
- occupantGroundLabel.addTo(this.threeLayer);
4465
- object3ds.push(occupantGroundLabel);
4466
- this.#groundObjects.push(occupantGroundLabel);
4467
- }
4468
- } else {
4469
- const occupantMarker = createOccupant(feature2, location, {
4470
- textMarkerType,
4471
- extrudeConfig
4472
- });
4473
- if (occupantMarker instanceof ui3.UIMarker) {
4474
- occupantMarker.addTo(this.map);
4475
- } else {
4476
- occupantMarker?.on("click", this.handleClickElement);
4477
- occupantMarker?.addTo(layer);
4478
- }
4479
- if (isMainLocation) {
4480
- geometry = occupantMarker;
4481
- } else {
4482
- elements[`${feature2.id}_${index}`] = {
4483
- geometry: occupantMarker,
4484
- properties: location.properties,
4485
- featureType: "occupant",
4486
- feature: feature2
4487
- };
4488
- }
4489
- }
4490
- });
4491
- }
4492
- }
4493
- break;
4494
- }
4495
- case "fixture": {
4496
- const models = await create3DFixture(feature2, this.threeLayer);
4497
- models.forEach((model) => {
4498
- model.on("click", this.handleClickElement);
4499
- object3ds.push(model);
4500
- this.#glbObjects.push(model);
4501
- });
4502
- if (!featureExtrudeConfig) {
4503
- geometry = createFixture(feature2)?.addTo(layer);
4504
- } else {
4505
- const locatedLevel = feature2?.properties?.level;
4506
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4507
- extrudeConfig,
4508
- locatedLevel
4509
- );
4510
- const levelHeight = _6.get(levelExtrudeConfig, "height", 0);
4511
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4512
- const extrudedFixture = createExtrudedUnit(
4513
- feature2,
4514
- this.threeLayer,
4515
- option
4516
- );
4517
- object3ds.push(extrudedFixture);
4518
- }
4519
- break;
4520
- }
4521
- case "footprint": {
4522
- const objects = await create3DFootprint(
4523
- feature2,
4524
- this.threeLayer,
4525
- featureExtrudeConfig
4526
- );
4527
- objects.forEach((object) => {
4528
- object.on("click", () => {
4529
- const {
4530
- geometry: { coordinates }
4531
- } = turfCenter3(feature2);
4532
- this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4533
- });
4534
- object3ds.push(object);
4535
- this.#objects.push(object);
4536
- });
4537
- if (feature2.properties.logo) {
4538
- const footprintMarker = create3DBillboard(
4539
- feature2,
4540
- this.threeLayer
4541
- );
4542
- object3ds.push(footprintMarker);
4543
- this.#billboardObjects.push(footprintMarker);
4544
- }
4545
- break;
4546
- }
4547
4324
  default:
4548
4325
  break;
4549
4326
  }
@@ -4612,27 +4389,6 @@ var IndoorMap = class extends EventTarget {
4612
4389
  changeLevelByOrdinal(ordinal) {
4613
4390
  this.rendererManager.changeLevelByOrdinal(ordinal);
4614
4391
  }
4615
- getFeatureExtent = (feature2, scaleFactor = 1) => {
4616
- const [minX, minY, maxX, maxY] = index_default(
4617
- scale(bboxPolygon(index_default(feature2)), scaleFactor)
4618
- );
4619
- return new Extent(minX, minY, maxX, maxY);
4620
- };
4621
- getExtentCenter = (extent) => {
4622
- return extent.getCenter();
4623
- };
4624
- getExtentZoom = (extent, options = {
4625
- isFraction: false,
4626
- padding: {
4627
- paddingLeft: 0,
4628
- paddingRight: 0,
4629
- paddingTop: 0,
4630
- paddingBottom: 0
4631
- }
4632
- }) => {
4633
- const { isFraction = false, padding } = options;
4634
- return this.map.getFitZoom(extent, isFraction, padding);
4635
- };
4636
4392
  findVenueInView = () => {
4637
4393
  const mapCenter = this.map.getCenter();
4638
4394
  const result = this.#venues.reduce((closest, venue) => {
@@ -4645,9 +4401,6 @@ var IndoorMap = class extends EventTarget {
4645
4401
  }, null);
4646
4402
  return result;
4647
4403
  };
4648
- flyTo = (center2, options) => {
4649
- this.camera.flyTo(center2, options);
4650
- };
4651
4404
  getLineStringBearing = (feature2) => {
4652
4405
  const { geometry } = feature2;
4653
4406
  const path = new LineString3(geometry.coordinates);
@@ -4668,186 +4421,6 @@ var IndoorMap = class extends EventTarget {
4668
4421
  clearAnimations() {
4669
4422
  this.#animationsToRun = [];
4670
4423
  }
4671
- /**
4672
- * Hilighting Elements
4673
- * ========================================= */
4674
- // TODO: To consider if we should use setter `set hilightElementIds` instead?
4675
- setHighlightElementIds(targetElementIds, options = {}) {
4676
- const highlight3DOptions = _6.merge(
4677
- {},
4678
- DEFAULT_HIGHLIGHT_OPTIONS,
4679
- _6.get(options, "highlight3DOptions", {})
4680
- );
4681
- const highlight2DOptions = _6.merge(
4682
- {},
4683
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4684
- _6.get(options, "highlight2DOptions", {})
4685
- );
4686
- this.setHighlightedObject(targetElementIds, highlight3DOptions);
4687
- return this.setHighlight2DElementIds(targetElementIds, highlight2DOptions);
4688
- }
4689
- setHighlight2DElementIds(targetElementIds, options = {}) {
4690
- const { defaultMarker, symbolSet } = _6.merge(
4691
- {},
4692
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4693
- options
4694
- );
4695
- const {
4696
- createMarker,
4697
- createHighlightOccupantMarker,
4698
- getElementSymbol,
4699
- getHilighPolygonalSymbol,
4700
- getHighlightMarkerSymbol
4701
- } = this.#styler;
4702
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4703
- const elementToHilights = targetElementIds.map(
4704
- (elemId) => this.#elements[elemId] || this.#elements[`${LAST_USER_LOCATION_ELEMENT_ID_PREFIX}${elemId}`]
4705
- ).filter((elem) => elem);
4706
- elementToHilights.forEach((elem) => {
4707
- const { feature: feature2, geometry } = elem;
4708
- if (!geometry || !feature2) return;
4709
- const hilightLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4710
- if (!hilightLayer) return;
4711
- const defaultSymbol = getHilighPolygonalSymbol(geometry.type);
4712
- const definedSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4713
- const symbol = _6.isEmpty(definedSymbol) ? defaultSymbol : definedSymbol;
4714
- switch (geometry.type) {
4715
- case "MultiPolygon":
4716
- case "Polygon": {
4717
- geometry?.updateSymbol(symbol);
4718
- break;
4719
- }
4720
- default:
4721
- break;
4722
- }
4723
- switch (feature2.feature_type) {
4724
- case "amenity":
4725
- const highlightedAmenityMarker = definedSymbol || getHighlightMarkerSymbol();
4726
- geometry?.updateSymbol(highlightedAmenityMarker);
4727
- break;
4728
- case "occupant": {
4729
- switch (feature2.properties.category) {
4730
- case "currencyexchange":
4731
- case "donationcenter":
4732
- case "postoffice":
4733
- const highlightedAmenityMarker2 = definedSymbol || getHighlightMarkerSymbol();
4734
- geometry?.updateSymbol(highlightedAmenityMarker2);
4735
- break;
4736
- default:
4737
- if (feature2.properties.render_type === "Logo") {
4738
- this.hideGeometryByElementId(feature2.id);
4739
- }
4740
- createHighlightOccupantMarker(feature2, {
4741
- extrudeConfig,
4742
- symbol: definedSymbol
4743
- }).on("click", this.handleClickElement).addTo(hilightLayer);
4744
- break;
4745
- }
4746
- break;
4747
- }
4748
- case "opening":
4749
- break;
4750
- default:
4751
- if (defaultMarker) createMarker(feature2).addTo(hilightLayer);
4752
- break;
4753
- }
4754
- });
4755
- this.#highlightElementIds = targetElementIds;
4756
- if (elementToHilights.length === 0) return;
4757
- return featureCollection(
4758
- elementToHilights.map(({ feature: feature2 }) => {
4759
- const { geometry } = feature2;
4760
- if (feature2.feature_type === "occupant")
4761
- return feature(feature2?.properties?.anchor?.geometry);
4762
- return feature(geometry);
4763
- })
4764
- );
4765
- }
4766
- clearHighlightElements() {
4767
- this.#clearAllElementOnLayerByName(HIGHLIGHT_LAYER_NAME);
4768
- _6(this.#highlightElementIds).map((elemId) => this.#elements[elemId]?.geometry).compact().forEach((geometry) => {
4769
- if (geometry instanceof ui3.UIMarker) return;
4770
- if (geometry instanceof Marker2) {
4771
- this.showGeometryByElementId(geometry.properties.id);
4772
- return;
4773
- }
4774
- try {
4775
- const defaultSymbol = geometry.options.defaultSymbol;
4776
- geometry.updateSymbol(defaultSymbol);
4777
- } catch (err) {
4778
- console.log(
4779
- `error cannot return to defaultSymbol, check if "defaultSymbol" exists in element creation function`
4780
- );
4781
- }
4782
- });
4783
- this.#highlightElementIds = [];
4784
- }
4785
- setHighlightedObject(targetObjectIds, options = {}) {
4786
- const { symbolSet } = _6.merge({}, DEFAULT_HIGHLIGHT_OPTIONS, options);
4787
- const {
4788
- getElementSymbol,
4789
- getHilighPolygonalSymbol,
4790
- createHighlight2DAmenityMarkerFrom3DMarker
4791
- } = this.#styler;
4792
- const objects = this.threeLayer?.getBaseObjects();
4793
- const objectsToHighlight = objects.filter(
4794
- ({ properties }) => targetObjectIds.includes(properties?.id)
4795
- );
4796
- const defaultSymbol = getHilighPolygonalSymbol("Polygon");
4797
- const targetSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4798
- const { polygonFill: color } = _6.isEmpty(targetSymbol) ? defaultSymbol : targetSymbol;
4799
- const amenityHighlightMode = _6.get(
4800
- this.#mapConfig,
4801
- "amenity_highlight_mode",
4802
- ""
4803
- );
4804
- objectsToHighlight.forEach((obj) => {
4805
- if (obj.type === "ExtrudePolygon") {
4806
- const newController = createHighlighExtrudeObjectController(obj, {
4807
- color
4808
- });
4809
- newController.start();
4810
- this.#highlightObjectControllers.push(newController);
4811
- }
4812
- if (obj instanceof SpriteMarker) {
4813
- if (amenityHighlightMode === "2DMarker") {
4814
- const hilight2DLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4815
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4816
- obj.hide();
4817
- const { properties: featureProperties } = obj;
4818
- createHighlight2DAmenityMarkerFrom3DMarker(
4819
- featureProperties,
4820
- extrudeConfig
4821
- ).on("click", this.handleClickElement).addTo(hilight2DLayer);
4822
- } else {
4823
- obj.highlight();
4824
- }
4825
- }
4826
- if (obj instanceof Billboard) {
4827
- const newController = createHighlighBillboardController(obj);
4828
- newController.start();
4829
- this.#highlightObjectControllers.push(newController);
4830
- }
4831
- });
4832
- this.#highlightObjectIds = targetObjectIds;
4833
- }
4834
- clearHighlightObject() {
4835
- this.#highlightObjectControllers.forEach((controller) => {
4836
- if (_6.isFunction(controller?.clear)) controller.clear();
4837
- });
4838
- this.#highlightObjectIds.forEach((objIds) => {
4839
- const objects = this.threeLayer?.getBaseObjects();
4840
- const objectToResetHighlight = objects.find(
4841
- ({ properties }) => objIds.includes(properties?.id)
4842
- );
4843
- if (objectToResetHighlight instanceof SpriteMarker) {
4844
- objectToResetHighlight.show();
4845
- objectToResetHighlight.removeHighlight();
4846
- }
4847
- });
4848
- this.#highlightObjectControllers = [];
4849
- this.#highlightObjectIds = [];
4850
- }
4851
4424
  /**
4852
4425
  * User Location
4853
4426
  ****************************/
@@ -4872,15 +4445,15 @@ var IndoorMap = class extends EventTarget {
4872
4445
  }
4873
4446
  }
4874
4447
  updateUserLocationSymbolByLocale(locale) {
4875
- const userLocationGeometry = _6.get(
4448
+ const userLocationGeometry = _5.get(
4876
4449
  this.#elements,
4877
4450
  `${USER_LOCATION_ELEMENT_ID}.geometry`
4878
4451
  );
4879
4452
  if (!userLocationGeometry) return;
4880
4453
  const currentSymbol = userLocationGeometry.getSymbol();
4881
4454
  const localeSymbolToUpdate = currentSymbol.map((symbol) => {
4882
- const localeSymbol = _6.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _6.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
4883
- if (!_6.isPlainObject(localeSymbol)) return symbol;
4455
+ const localeSymbol = _5.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _5.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
4456
+ if (!_5.isPlainObject(localeSymbol)) return symbol;
4884
4457
  return {
4885
4458
  ...symbol,
4886
4459
  ...localeSymbol
@@ -4954,14 +4527,14 @@ var IndoorMap = class extends EventTarget {
4954
4527
  * END of User Location
4955
4528
  ****************************/
4956
4529
  showGeometryByElementId = (elementId) => {
4957
- const geometry = _6.get(
4530
+ const geometry = _5.get(
4958
4531
  this.#elements,
4959
4532
  `${elementId}.geometry`
4960
4533
  );
4961
4534
  if (geometry) geometry.show();
4962
4535
  };
4963
4536
  hideGeometryByElementId = (elementId) => {
4964
- const geometry = _6.get(this.#elements, `${elementId}.geometry`);
4537
+ const geometry = _5.get(this.#elements, `${elementId}.geometry`);
4965
4538
  if (geometry) geometry.hide();
4966
4539
  };
4967
4540
  setSpriteMarkersOpacity = (opacity = 1) => {
@@ -5008,13 +4581,13 @@ var IndoorMap = class extends EventTarget {
5008
4581
  const line = lineStrings[i];
5009
4582
  const coords = line.geometry.coordinates;
5010
4583
  const prevLine = lineStrings[i - 1];
5011
- const firstCoord = _6.first(coords);
4584
+ const firstCoord = _5.first(coords);
5012
4585
  const isFirstLine = i === 0;
5013
4586
  if (isFirstLine) {
5014
4587
  accLine.push(...coords);
5015
4588
  continue;
5016
4589
  }
5017
- const prevLastCoord = _6.last(prevLine.geometry.coordinates);
4590
+ const prevLastCoord = _5.last(prevLine.geometry.coordinates);
5018
4591
  const isNearby = turfDistance(point(firstCoord), point(prevLastCoord)) < distance;
5019
4592
  if (!isNearby) {
5020
4593
  const remainingLines = lineStrings.slice(i);
@@ -5035,8 +4608,8 @@ var IndoorMap = class extends EventTarget {
5035
4608
  create3DStepPath
5036
4609
  } = this.#styler;
5037
4610
  const routeMarkerLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
5038
- const linesByOrdinal = _6(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5039
- const joinedLines = _6(linesByOrdinal).reduce((acc, lines, key) => {
4611
+ const linesByOrdinal = _5(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
4612
+ const joinedLines = _5(linesByOrdinal).reduce((acc, lines, key) => {
5040
4613
  const joined = this.combineNearbyLineStrings(lines, {
5041
4614
  properties: { ordinal: +key }
5042
4615
  });
@@ -5064,14 +4637,14 @@ var IndoorMap = class extends EventTarget {
5064
4637
  stepElement = createOriginMarker(stepGeometry).addTo(routeMarkerLayer);
5065
4638
  break;
5066
4639
  case "destination-marker":
5067
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4640
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
5068
4641
  if (destinationFeature.feature_type === "occupant") {
5069
- const stepId = _6.get(stepGeometry, "id");
4642
+ const stepId = _5.get(stepGeometry, "id");
5070
4643
  const normalizedDestinationFeature = {
5071
4644
  ...destinationFeature,
5072
4645
  id: stepId
5073
4646
  };
5074
- const logoUrl = _6.get(
4647
+ const logoUrl = _5.get(
5075
4648
  normalizedDestinationFeature,
5076
4649
  "properties.logo.url"
5077
4650
  );
@@ -5116,15 +4689,15 @@ var IndoorMap = class extends EventTarget {
5116
4689
  const routeMarkerLayer = this.map.getLayer(
5117
4690
  HIGHLIGHT_LAYER_NAME
5118
4691
  );
5119
- const originMarkerGeometry = _6.get(
4692
+ const originMarkerGeometry = _5.get(
5120
4693
  this.#elements,
5121
4694
  `${ORIGIN_MARKER_ID}.geometry`
5122
4695
  );
5123
- const destinationMarkerGeometry = _6.get(
4696
+ const destinationMarkerGeometry = _5.get(
5124
4697
  this.#elements,
5125
4698
  `${DESTINATION_MARKER_ID}.geometry`
5126
4699
  );
5127
- const geometriesToRemove = _6.compact([
4700
+ const geometriesToRemove = _5.compact([
5128
4701
  originMarkerGeometry,
5129
4702
  destinationMarkerGeometry
5130
4703
  ]);
@@ -5135,7 +4708,7 @@ var IndoorMap = class extends EventTarget {
5135
4708
  (obj) => !(obj instanceof NavigationPath)
5136
4709
  );
5137
4710
  const objects = this.#navigationGeometries || {};
5138
- _6.forEach(objects, (obj) => {
4711
+ _5.forEach(objects, (obj) => {
5139
4712
  if (!obj) return;
5140
4713
  this.#navigationGeometries[obj.properties.id] = null;
5141
4714
  obj.remove();
@@ -5163,33 +4736,6 @@ var IndoorMap = class extends EventTarget {
5163
4736
  /**
5164
4737
  * render (frame)
5165
4738
  */
5166
- getTargetViewCenter = (targetView, options = { offset: { top: 0, left: 0, right: 0, bottom: 0 } }) => {
5167
- const map = this.map;
5168
- const { offset } = options;
5169
- const { top = 0, left = 0, right = 0, bottom = 0 } = offset;
5170
- const originalState = {
5171
- bearing: map.getBearing(),
5172
- center: map.getCenter(),
5173
- pitch: map.getPitch(),
5174
- zoom: map.getZoom()
5175
- };
5176
- const finalView = {
5177
- bearing: _6.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5178
- center: _6.isNil(targetView.center) ? map.getCenter() : targetView.center,
5179
- pitch: _6.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5180
- zoom: _6.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5181
- };
5182
- map.setView(finalView);
5183
- const projectedTargetCenter = map.coordinateToContainerPoint(finalView.center).add(right / 2 - left / 2, bottom / 2 - top / 2);
5184
- const adjustedTargetCenter = map.containerPointToCoordinate(
5185
- projectedTargetCenter
5186
- );
5187
- map.setView(originalState);
5188
- return adjustedTargetCenter;
5189
- };
5190
- setMaxExtent(extent) {
5191
- return this.map.setMaxExtent(extent);
5192
- }
5193
4739
  render() {
5194
4740
  const view = this.map.getView();
5195
4741
  const currBearing = view.bearing;
@@ -5198,7 +4744,8 @@ var IndoorMap = class extends EventTarget {
5198
4744
  this.threeLayer.redraw();
5199
4745
  }
5200
4746
  if (this.threeLayer) {
5201
- const objectOpacity = _6.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
4747
+ const currentView = this.camera.getView();
4748
+ const objectOpacity = _5.clamp(38 - 2 * currentView.zoom, 0, 1);
5202
4749
  this.#objects.forEach((object) => {
5203
4750
  object.getObject3d().traverse((child) => {
5204
4751
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5208,8 +4755,8 @@ var IndoorMap = class extends EventTarget {
5208
4755
  });
5209
4756
  if (this.#billboardObjects) {
5210
4757
  this.#billboardObjects.forEach((object) => {
5211
- const objectScale = _6.clamp(
5212
- 20 - 1 * this.camera.getZoom(),
4758
+ const objectScale = _5.clamp(
4759
+ 20 - 1 * currentView.zoom,
5213
4760
  1,
5214
4761
  1.05
5215
4762
  );
@@ -5217,7 +4764,7 @@ var IndoorMap = class extends EventTarget {
5217
4764
  });
5218
4765
  }
5219
4766
  if (this.#isLayersFadingOnZoom) {
5220
- const layerOpacity = _6.clamp(1 - objectOpacity, 0, 1);
4767
+ const layerOpacity = _5.clamp(1 - objectOpacity, 0, 1);
5221
4768
  LAYERS.forEach((layerKey) => {
5222
4769
  const layer = this.map.getLayer(layerKey);
5223
4770
  if (layer) layer.setOpacity(layerOpacity);
@@ -5236,18 +4783,15 @@ var IndoorMap = class extends EventTarget {
5236
4783
  });
5237
4784
  }
5238
4785
  this.#animationsToRun.forEach(({ callback }) => callback(this));
5239
- TWEEN2.update();
4786
+ TWEEN.update();
5240
4787
  requestAnimationFrame(this.render.bind(this));
5241
4788
  }
5242
4789
  };
5243
4790
  export {
5244
4791
  ALL_FEATURE_TYPES,
5245
- ALWAYS_VISIBLE_FEATURE_TYPES,
5246
4792
  BASE_LAYER_NAME,
5247
4793
  DEFAULT_BASE_URL,
5248
- DEFAULT_HIGHLIGHT_OPTIONS,
5249
4794
  DEFAULT_LOCALE,
5250
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
5251
4795
  DESTINATION_MARKER_ID,
5252
4796
  GEOJSON_FEATURE_TYPES,
5253
4797
  HIGHLIGHT_LAYER_NAME,
@@ -5261,6 +4805,7 @@ export {
5261
4805
  MARKER_LAYER_NAME,
5262
4806
  NONIMDF_FEATURE_TYPES,
5263
4807
  ORIGIN_MARKER_ID,
4808
+ occupant_helper_exports as OccupantHelpers,
5264
4809
  POI_MARKER_LAYER_NAME,
5265
4810
  QueryObserver2 as QueryObserver,
5266
4811
  USER_LOCATION_ELEMENT_ID,
@@ -5288,6 +4833,16 @@ export {
5288
4833
  getRelatedLocationsByOccupant,
5289
4834
  getSuitablyValueBetweenBearings,
5290
4835
  isClickableFeature,
4836
+ isValidCoordinate,
4837
+ isValidLineString,
4838
+ isValidLineStringCoordinates,
4839
+ isValidMultiPolygon,
4840
+ isValidMultiPolygonCoordinates,
4841
+ isValidPoint,
4842
+ isValidPolygon,
4843
+ isValidPolygonCoordinates,
4844
+ matchFilter,
4845
+ matchFilters,
5291
4846
  safeFetchFeature,
5292
4847
  styledFeatureGenerator
5293
4848
  };