venue-js 1.0.0 → 1.1.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -223,7 +223,6 @@ var createPopulator = ({
223
223
  const populateDetail = (detail) => Promise.resolve(detail);
224
224
  const populateFootprint = (footprint) => Promise.resolve(footprint);
225
225
  const populateGeofence = (geofence) => Promise.resolve(geofence);
226
- const populateOpening = (opening) => Promise.resolve(opening);
227
226
  const populateRelationship = (relationship) => Promise.resolve(relationship);
228
227
  const populatePrivilege = (privilege) => Promise.resolve(privilege);
229
228
  const populateEvent = (event) => Promise.resolve(event);
@@ -299,8 +298,11 @@ var createPopulator = ({
299
298
  const unit = units.find(
300
299
  (unit2) => unit2.properties.category === "walkway" && unit2.properties.level_id === kiosk.properties.level_id && (0, import_boolean_within.booleanWithin)(kiosk, unit2)
301
300
  );
302
- const sections = await internalFilterByType("section");
303
- const section = sections.find((section2) => (0, import_boolean_within.booleanWithin)(anchor, section2));
301
+ let section = null;
302
+ if (anchor) {
303
+ const sections = await internalFilterByType("section");
304
+ section = sections.find((section2) => (0, import_boolean_within.booleanWithin)(anchor, section2));
305
+ }
304
306
  return {
305
307
  ...kiosk,
306
308
  properties: {
@@ -369,6 +371,18 @@ var createPopulator = ({
369
371
  }
370
372
  };
371
373
  };
374
+ const populateOpening = async (opening) => {
375
+ const venue = await internalFindById(opening.properties.venue_id);
376
+ const level = await internalFindById(opening.properties.level_id);
377
+ return {
378
+ ...opening,
379
+ properties: {
380
+ venue,
381
+ level: await populateLevel(level),
382
+ ordinal: level.properties.ordinal
383
+ }
384
+ };
385
+ };
372
386
  const populateSection = async (section) => {
373
387
  const venue = await internalFindById(section.properties.venue_id);
374
388
  const level = await internalFindById(section.properties.level_id);
@@ -386,17 +400,21 @@ var createPopulator = ({
386
400
  const venue = await internalFindById(unit.properties.venue_id);
387
401
  const level = await internalFindById(unit.properties.level_id);
388
402
  const sections = await internalFilterByType("section");
389
- const section = sections.find((section2) => (0, import_boolean_within.booleanWithin)(unit, section2));
390
- return {
391
- ...unit,
392
- properties: {
393
- ...unit.properties,
394
- venue,
395
- ordinal: level.properties.ordinal,
396
- level: await populateLevel(level),
397
- section: section ? await populateSection(section) : null
398
- }
399
- };
403
+ try {
404
+ const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => (0, import_boolean_within.booleanWithin)(unit, section2)) : null;
405
+ return {
406
+ ...unit,
407
+ properties: {
408
+ ...unit.properties,
409
+ venue,
410
+ ordinal: level.properties.ordinal,
411
+ level: await populateLevel(level),
412
+ section: section ? await populateSection(section) : null
413
+ }
414
+ };
415
+ } catch (err) {
416
+ console.log(`error finding section `, { unit, sections });
417
+ }
400
418
  };
401
419
  const populateVenue = (venue) => {
402
420
  return Promise.resolve(venue);
@@ -439,6 +457,26 @@ var createPopulator = ({
439
457
  };
440
458
  };
441
459
 
460
+ // src/data/utils/match-filters.ts
461
+ function isInFilter(filter) {
462
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
463
+ }
464
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
465
+ function matchFilter(value, filter) {
466
+ if (Array.isArray(value)) {
467
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
468
+ return value.includes(filter);
469
+ } else {
470
+ if (isInFilter(filter)) return filter.$in.includes(value);
471
+ return value === filter;
472
+ }
473
+ }
474
+ function matchFilters(item, filters) {
475
+ return Object.entries(filters).every(([key, filter]) => {
476
+ return matchFilter(item.properties[key], filter);
477
+ });
478
+ }
479
+
442
480
  // src/data/getDataClient.ts
443
481
  var getDataClient = (options) => {
444
482
  const observers = /* @__PURE__ */ new Map();
@@ -514,7 +552,12 @@ var getDataClient = (options) => {
514
552
  queryKey: [featureType, "list", params],
515
553
  queryFn: async () => {
516
554
  const features = await internalFilterByType(featureType);
517
- return params.populate === true ? await Promise.all(features.map((f) => populator[featureType](f))) : features;
555
+ const filters = params.filters ?? {};
556
+ let result = features;
557
+ if (params.filters) {
558
+ result = features.filter((f) => matchFilters(f, filters));
559
+ }
560
+ return params.populate === true ? await Promise.all(result.map((f) => populator[featureType](f))) : result;
518
561
  },
519
562
  ...options2 ?? {}
520
563
  });
@@ -557,9 +600,9 @@ var getDataClient = (options) => {
557
600
  };
558
601
 
559
602
  // src/IndoorMap/IndoorMap.ts
560
- var import_maptalks8 = require("maptalks");
603
+ var import_maptalks_gl = require("maptalks-gl");
561
604
  var import_tween2 = __toESM(require("@tweenjs/tween.js"));
562
- var import_lodash6 = __toESM(require("lodash"));
605
+ var import_lodash7 = __toESM(require("lodash"));
563
606
 
564
607
  // ../../node_modules/@turf/helpers/dist/esm/index.js
565
608
  var earthRadius = 63710088e-1;
@@ -638,7 +681,7 @@ function isNumber(num) {
638
681
 
639
682
  // src/IndoorMap/IndoorMap.ts
640
683
  var import_distance = __toESM(require("@turf/distance"));
641
- var import_center3 = __toESM(require("@turf/center"));
684
+ var import_center4 = __toESM(require("@turf/center"));
642
685
 
643
686
  // ../../node_modules/@turf/meta/dist/esm/index.js
644
687
  function coordEach(geojson, callback, excludeWrapCoord) {
@@ -760,13 +803,12 @@ function bbox(geojson, options = {}) {
760
803
  });
761
804
  return result;
762
805
  }
763
- var turf_bbox_default = bbox;
806
+ var index_default = bbox;
764
807
 
765
808
  // src/IndoorMap/IndoorMap.ts
766
809
  var import_transform_scale = __toESM(require("@turf/transform-scale"));
767
810
  var import_bbox_polygon = __toESM(require("@turf/bbox-polygon"));
768
- var import_three9 = require("three");
769
- var import_maptalks9 = require("maptalks.three");
811
+ var import_three8 = require("three");
770
812
 
771
813
  // src/IndoorMap/constants.ts
772
814
  var defaultLayerOption = { enableAltitude: true };
@@ -1485,10 +1527,8 @@ var GeometryType = {
1485
1527
  var ORDINAL_HEIGHT = 0;
1486
1528
  var VENUE_Z_INDEX = 0;
1487
1529
  var LEVEL_Z_INDEX = 2;
1488
- var UNIT_Z_INDEX = 3;
1489
1530
  var FIXTURE_Z_INDEX = 4;
1490
1531
  var DECORATION_Z_INDEX = 4;
1491
- var KIOSK_Z_INDEX = 5;
1492
1532
  var OPENING_Z_INDEX = 3;
1493
1533
  var SECTION_Z_INDEX = 6;
1494
1534
  var USER_LOCATION_Z_INDEX = 99;
@@ -1576,77 +1616,6 @@ var SPRITE_HIGHLIGHT_MARKER_FEATURE = SPRITE_MARKER_FEATURE.map(
1576
1616
  );
1577
1617
  var OCCUPANT_TEXT_MARKER_CLASSNAME = "mtk-occupant-text-marker";
1578
1618
  var getAltitude = (properties) => Math.max(0, properties.ordinal * ORDINAL_HEIGHT || 0);
1579
- var createRoomUnit = (feature2, style, options) => {
1580
- const { geometry, id, properties } = feature2;
1581
- const { allowOverride, inheritFillColorToLine } = options;
1582
- const symbolStyle = { ...style };
1583
- if (allowOverride) import_lodash4.default.merge(symbolStyle, properties.style);
1584
- if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1585
- return new GeometryType[geometry.type](geometry.coordinates, {
1586
- properties: {
1587
- id,
1588
- feature_type: "unit",
1589
- category: properties.category,
1590
- altitude: getAltitude(properties)
1591
- },
1592
- symbol: symbolStyle,
1593
- defaultSymbol: symbolStyle
1594
- });
1595
- };
1596
- var createAmenityUnit = (feature2, style, options = {}) => {
1597
- const { geometry, id, properties } = feature2;
1598
- const { allowOverride, inheritFillColorToLine } = options;
1599
- const symbolStyle = { ...style };
1600
- if (allowOverride) import_lodash4.default.merge(symbolStyle, properties.style);
1601
- if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1602
- const area = new GeometryType[geometry.type](geometry.coordinates, {
1603
- properties: {
1604
- id,
1605
- feature_type: "unit",
1606
- category: properties.category,
1607
- altitude: getAltitude(properties)
1608
- },
1609
- symbol: symbolStyle,
1610
- defaultSymbol: symbolStyle
1611
- });
1612
- return area;
1613
- };
1614
- var createNonpublicUnit = (feature2, style, options = {}) => {
1615
- const { geometry, id, properties } = feature2;
1616
- const { allowOverride, inheritFillColorToLine } = options;
1617
- const symbolStyle = { ...style };
1618
- if (allowOverride) import_lodash4.default.merge(symbolStyle, properties.style);
1619
- if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1620
- return new GeometryType[geometry.type](geometry.coordinates, {
1621
- properties: {
1622
- id,
1623
- feature_type: "unit",
1624
- category: properties.category,
1625
- altitude: getAltitude(properties)
1626
- },
1627
- symbol: {
1628
- ...style
1629
- }
1630
- });
1631
- };
1632
- var createWalkwayUnit = (feature2, style, options) => {
1633
- const { geometry, id, properties } = feature2;
1634
- const { allowOverride, inheritFillColorToLine } = options;
1635
- const symbolStyle = { ...style };
1636
- if (allowOverride) import_lodash4.default.merge(symbolStyle, properties.style);
1637
- if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1638
- return new GeometryType[geometry.type](geometry.coordinates, {
1639
- properties: {
1640
- id,
1641
- feature_type: "unit",
1642
- category: properties.category,
1643
- altitude: getAltitude(properties)
1644
- },
1645
- symbol: {
1646
- ...symbolStyle
1647
- }
1648
- });
1649
- };
1650
1619
  var createWaterFixture = (feature2, style, options = {}) => {
1651
1620
  const { geometry, properties } = feature2;
1652
1621
  const { allowOverride, inheritFillColorToLine, zIndex } = options;
@@ -2198,62 +2167,6 @@ var styledFeatureGenerator = (mapTheme) => {
2198
2167
  zIndex: LEVEL_Z_INDEX
2199
2168
  });
2200
2169
  },
2201
- createUnit: (feature2) => {
2202
- const {
2203
- feature_type,
2204
- properties: { category }
2205
- } = feature2;
2206
- const elementStyle = getElementSymbol(`${feature_type}.${category}`);
2207
- const options = getElementOptions(`${feature_type}.${category}`);
2208
- const zIndex = UNIT_Z_INDEX;
2209
- switch (feature2.properties.category) {
2210
- case "room":
2211
- case "terrace":
2212
- case "unenclosedarea":
2213
- case "vegetation":
2214
- case "unspecified":
2215
- case "recreation":
2216
- return createRoomUnit(feature2, elementStyle, options).setZIndex(
2217
- zIndex
2218
- );
2219
- case "firstaid":
2220
- case "restroom":
2221
- case "restroom.female":
2222
- case "restroom.male":
2223
- case "escalator":
2224
- case "elevator":
2225
- case "stairs":
2226
- case "stairs.emergencyexit":
2227
- case "parking":
2228
- case "smokingarea":
2229
- case "mothersroom":
2230
- case "privatelounge":
2231
- case "shuttle":
2232
- case "fieldofplay":
2233
- return createAmenityUnit(feature2, elementStyle, options).setZIndex(
2234
- zIndex
2235
- );
2236
- case "nonpublic":
2237
- case "structure":
2238
- case "brick":
2239
- case "concrete":
2240
- case "drywall":
2241
- case "glass":
2242
- case "wood":
2243
- case "column":
2244
- case "opentobelow":
2245
- return createNonpublicUnit(feature2, elementStyle, options).setZIndex(
2246
- zIndex
2247
- );
2248
- case "walkway":
2249
- case "footbridge":
2250
- return createWalkwayUnit(feature2, elementStyle, options).setZIndex(
2251
- zIndex - 1
2252
- );
2253
- default:
2254
- break;
2255
- }
2256
- },
2257
2170
  createMarker: (feature2) => {
2258
2171
  try {
2259
2172
  const { geometry, properties } = feature2;
@@ -2438,32 +2351,6 @@ var styledFeatureGenerator = (mapTheme) => {
2438
2351
  symbol
2439
2352
  });
2440
2353
  },
2441
- createKiosk: (feature2) => {
2442
- const { geometry, feature_type, properties, id } = feature2;
2443
- const {
2444
- properties: { category }
2445
- } = feature2;
2446
- const elementStyle = getElementSymbol(`${feature_type}.${category}`);
2447
- const options = getElementOptions(
2448
- `${feature_type}.${category}.geometry.options`
2449
- );
2450
- const { allowOverride, inheritFillColorToLine } = options;
2451
- const symbolStyle = { ...elementStyle };
2452
- if (allowOverride) import_lodash4.default.merge(symbolStyle, properties.style);
2453
- if (inheritFillColorToLine)
2454
- symbolStyle.lineColor = symbolStyle.polygonFill;
2455
- return new GeometryType[geometry.type](geometry.coordinates, {
2456
- properties: {
2457
- id,
2458
- feature_type,
2459
- category: "kiosk",
2460
- altitude: getAltitude(properties)
2461
- },
2462
- symbol: symbolStyle,
2463
- defaultSymbol: symbolStyle,
2464
- zIndex: KIOSK_Z_INDEX
2465
- });
2466
- },
2467
2354
  createSection: (feature2) => {
2468
2355
  const { properties, feature_type } = feature2;
2469
2356
  const { category } = properties;
@@ -2836,43 +2723,6 @@ var styledFeatureGenerator = (mapTheme) => {
2836
2723
  markerProperties
2837
2724
  );
2838
2725
  },
2839
- create3DUnit: async (unit, threeLayer) => {
2840
- const { id, feature_type, properties } = unit;
2841
- const { category, ordinal, model3d } = properties;
2842
- const modelProperty = {
2843
- id,
2844
- feature_type,
2845
- category,
2846
- ordinal
2847
- };
2848
- const center2 = (0, import_center2.default)(unit);
2849
- const coordinate = import_lodash4.default.get(center2, "geometry.coordinates");
2850
- const models = await create3DModels(
2851
- model3d,
2852
- coordinate,
2853
- modelProperty,
2854
- threeLayer
2855
- );
2856
- return models;
2857
- },
2858
- create3DKiosk: async (kiosk, threeLayer) => {
2859
- const { id, feature_type, properties } = kiosk;
2860
- const { ordinal, model3d } = properties;
2861
- const modelProperty = {
2862
- id,
2863
- feature_type,
2864
- ordinal
2865
- };
2866
- const center2 = (0, import_center2.default)(kiosk);
2867
- const coordinate = import_lodash4.default.get(center2, "geometry.coordinates");
2868
- const models = await create3DModels(
2869
- model3d,
2870
- coordinate,
2871
- modelProperty,
2872
- threeLayer
2873
- );
2874
- return models;
2875
- },
2876
2726
  createVenue3DModel: async (venue, threeLayer) => {
2877
2727
  const { id, feature_type, properties } = venue;
2878
2728
  const { category, model3d } = properties;
@@ -2951,52 +2801,6 @@ var styledFeatureGenerator = (mapTheme) => {
2951
2801
  );
2952
2802
  return object;
2953
2803
  },
2954
- createExtrudedKiosk: (kiosk, threeLayer, options) => {
2955
- const extrudeHeight = import_lodash4.default.get(options, "height");
2956
- if (!extrudeHeight) return;
2957
- const kioskProperty = getFeatureProperties(kiosk);
2958
- const options3d = {
2959
- offset: -0.1,
2960
- altitude: import_lodash4.default.get(options, "altitude", 0)
2961
- };
2962
- const color = kioskProperty.defaultColor;
2963
- if (color === "transparent") return;
2964
- const material = new import_three5.MeshLambertMaterial({
2965
- color,
2966
- transparent: true
2967
- });
2968
- const object = createExtrudePolygon(
2969
- kiosk.geometry,
2970
- threeLayer,
2971
- material,
2972
- extrudeHeight,
2973
- kioskProperty,
2974
- options3d
2975
- );
2976
- return object;
2977
- },
2978
- createExtrudedLevel: (level, threeLayer, options) => {
2979
- const extrudeHeight = import_lodash4.default.get(options, "height", 0);
2980
- if (!extrudeHeight) return;
2981
- const levelProperty = getFeatureProperties(level);
2982
- const options3d = { offset: 0 };
2983
- const color = levelProperty?.defaultColor || "#808080";
2984
- if (color === "transparent" || import_lodash4.default.isEmpty(level?.geometry?.coordinates))
2985
- return;
2986
- const material = new import_three5.MeshLambertMaterial({
2987
- color,
2988
- transparent: true
2989
- });
2990
- const object = createExtrudePolygon(
2991
- level.geometry,
2992
- threeLayer,
2993
- material,
2994
- extrudeHeight,
2995
- levelProperty,
2996
- options3d
2997
- );
2998
- return object;
2999
- },
3000
2804
  createAmbientLight: (config) => {
3001
2805
  const { color: colorString = "0xffffff", intensity = 1 } = config;
3002
2806
  const color = parseInt(colorString, 16);
@@ -3256,175 +3060,252 @@ var CameraManager = class {
3256
3060
  };
3257
3061
  };
3258
3062
 
3259
- // src/IndoorMap/renderer/Element3DRenderer.ts
3260
- var maptalks5 = __toESM(require("maptalks"));
3063
+ // src/IndoorMap/renderer/RendererManager.ts
3064
+ var import_min = __toESM(require("lodash/min"));
3065
+ var import_center3 = require("@turf/center");
3066
+ var import_maptalks8 = require("maptalks.three");
3067
+ var THREE3 = __toESM(require("three"));
3068
+
3069
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3070
+ var maptalks4 = __toESM(require("maptalks"));
3261
3071
  var THREE2 = __toESM(require("three"));
3262
- var import_maptalks7 = require("maptalks.three");
3072
+ var import_GLTFLoader2 = require("three/examples/jsm/loaders/GLTFLoader");
3073
+ var import_DRACOLoader = require("three/examples/jsm/loaders/DRACOLoader");
3263
3074
  var import_buffer2 = __toESM(require("@turf/buffer"));
3264
- var import_three8 = require("three");
3265
3075
 
3266
- // src/IndoorMap/object3d/Escalator.ts
3267
- var maptalks4 = __toESM(require("maptalks"));
3268
- var import_maptalks6 = require("maptalks.three");
3076
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3077
+ var element3DRendererOptions = {
3078
+ unit: {
3079
+ default: { color: "#ffffff", height: 4 },
3080
+ byCategory: {
3081
+ walkway: { color: "#cccccc", height: 0.1 },
3082
+ terrace: { color: "#cccccc", height: 0.1 },
3083
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3084
+ nonpublic: { color: "#999999", height: 0.3 },
3085
+ escalator: { height: 0.2 },
3086
+ room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3087
+ }
3088
+ },
3089
+ kiosk: {
3090
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3091
+ },
3092
+ fixture: {
3093
+ default: { color: "#ffffff", height: 0.5 },
3094
+ byCategory: {
3095
+ water: { color: "#ACD7EC", height: 0.1 },
3096
+ vegetation: { color: "#91C499", height: 0.5 }
3097
+ }
3098
+ }
3099
+ };
3100
+
3101
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3102
+ var import_maptalks6 = require("maptalks");
3269
3103
  var THREE = __toESM(require("three"));
3270
- var import_d3plus_shape2 = require("d3plus-shape");
3271
- var import_lodash_es2 = require("lodash-es");
3272
- var defaultRectAngleToCalc2 = (0, import_lodash_es2.range)(-90, 90, 2);
3273
- var Escalator = class extends import_maptalks6.BaseObject {
3274
- layer;
3275
- constructor(feature2, opts, layer) {
3104
+ var import_maptalks7 = require("maptalks.three");
3105
+ var import_lodash6 = require("lodash");
3106
+
3107
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3108
+ var interpolateStops = ({ stops }, zoom) => {
3109
+ if (zoom <= stops[0][0]) return stops[0][1];
3110
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3111
+ for (let i = 0; i < stops.length - 1; i++) {
3112
+ const [z1, v1] = stops[i];
3113
+ const [z2, v2] = stops[i + 1];
3114
+ if (zoom >= z1 && zoom <= z2) {
3115
+ const t = (zoom - z1) / (z2 - z1);
3116
+ return v1 + t * (v2 - v1);
3117
+ }
3118
+ }
3119
+ };
3120
+
3121
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3122
+ var OPTIONS4 = {
3123
+ // Texture options
3124
+ text: "",
3125
+ textAlign: "center",
3126
+ color: "#ffffff",
3127
+ fontFamily: "sans-serif",
3128
+ fontSize: 28,
3129
+ fontWeight: 400,
3130
+ background: "rgba(0, 0, 0, 0.2)",
3131
+ lineHeight: 32,
3132
+ padding: 8,
3133
+ strokeColor: "#000000",
3134
+ strokeWidth: 6,
3135
+ strokeStyle: "round",
3136
+ // Sprite options
3137
+ /* Overall scale multiplier */
3138
+ scale: 1,
3139
+ altitude: 0,
3140
+ opacity: 1
3141
+ };
3142
+ var TextSpriteMarker = class extends import_maptalks7.BaseObject {
3143
+ #altitudeOffset = 0;
3144
+ constructor(coordinate, options, layer, properties = {}) {
3145
+ options = import_maptalks6.Util.extend({}, OPTIONS4, options, { layer });
3276
3146
  super();
3277
- this._initOptions({});
3278
- this.layer = layer;
3147
+ this._coordinate = new import_maptalks6.Coordinate(coordinate);
3148
+ this._initOptions(options);
3279
3149
  this._createGroup();
3280
- const startAltitude = feature2.properties.ordinal * HEIGHT_METER;
3281
- const endAltitude = startAltitude + 0.5 * HEIGHT_METER;
3282
- this.buildMesh(feature2.geometry.coordinates[0], {
3283
- startAltitude,
3284
- endAltitude
3150
+ this.properties = { ...properties };
3151
+ const sprite = this._createSprite();
3152
+ this.getObject3d().add(sprite);
3153
+ this._updatePosition();
3154
+ this.type = "TextSpriteMarker";
3155
+ }
3156
+ getOptions() {
3157
+ return super.getOptions();
3158
+ }
3159
+ _createSprite() {
3160
+ const options = this.getOptions();
3161
+ const texture = this._createTextTexture(options.text, options);
3162
+ const material = new THREE.SpriteMaterial({
3163
+ map: texture,
3164
+ transparent: true,
3165
+ alphaTest: 0.1
3285
3166
  });
3286
- if (opts.props) this.setProperties(opts.props);
3167
+ const sprite = new THREE.Sprite(material);
3168
+ const w = texture.image.width;
3169
+ const h = texture.image.height;
3170
+ const base = 1 / 16;
3171
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3172
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3173
+ this.#altitudeOffset = Math.max(
3174
+ h * base * options.scale * 0.5,
3175
+ 0.05
3176
+ // minimum lift in world units
3177
+ );
3178
+ return sprite;
3287
3179
  }
3288
- buildMesh(coordinates, { startAltitude, endAltitude }) {
3289
- const rect = (0, import_d3plus_shape2.largestRect)(coordinates, {
3290
- cache: true,
3291
- angle: defaultRectAngleToCalc2
3180
+ _createTextTexture(text, options = {}) {
3181
+ const {
3182
+ padding,
3183
+ fontSize,
3184
+ fontFamily,
3185
+ fontWeight,
3186
+ lineHeight,
3187
+ background,
3188
+ color,
3189
+ textAlign,
3190
+ strokeColor,
3191
+ strokeWidth,
3192
+ maxWidth
3193
+ } = options || {};
3194
+ const canvas = document.createElement("canvas");
3195
+ const ctx = canvas.getContext("2d");
3196
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3197
+ const paragraphs = String(text).split("\n");
3198
+ const wrappedLines = [];
3199
+ paragraphs.forEach((paragraph) => {
3200
+ if ((0, import_lodash6.isNil)(maxWidth) || isNaN(maxWidth)) {
3201
+ wrappedLines.push(paragraph);
3202
+ return;
3203
+ }
3204
+ const words = paragraph.split(/\s+/);
3205
+ let currentLine = "";
3206
+ words.forEach((word) => {
3207
+ const testLine = currentLine ? currentLine + " " + word : word;
3208
+ const testWidth = ctx.measureText(testLine).width;
3209
+ if (testWidth > maxWidth && currentLine) {
3210
+ wrappedLines.push(currentLine);
3211
+ currentLine = word;
3212
+ } else {
3213
+ currentLine = testLine;
3214
+ }
3215
+ });
3216
+ if (currentLine) {
3217
+ wrappedLines.push(currentLine);
3218
+ }
3292
3219
  });
3293
- const [p0, p1, p2, p3] = rect.points;
3294
- const startHeight = this.layer.altitudeToVector3(
3295
- startAltitude,
3296
- startAltitude
3297
- ).x;
3298
- const endHeight = this.layer.altitudeToVector3(endAltitude, endAltitude).x;
3299
- const anchorV = this.layer.coordinateToVector3(
3300
- new maptalks4.Coordinate(p0[0], p0[1]),
3301
- startHeight
3302
- );
3303
- const toLocal = (coord, alt) => {
3304
- const v = this.layer.coordinateToVector3(
3305
- new maptalks4.Coordinate(coord[0], coord[1]),
3306
- alt
3307
- );
3308
- return v.sub(anchorV);
3309
- };
3310
- const v0 = toLocal(p0, startHeight);
3311
- const v1 = toLocal(p1, endHeight);
3312
- const v2 = toLocal(p2, endHeight);
3313
- const v3 = toLocal(p3, startHeight);
3314
- const geom = new THREE.BufferGeometry();
3315
- const positions = new Float32Array([
3316
- v0.x,
3317
- v0.y,
3318
- v0.z,
3319
- v1.x,
3320
- v1.y,
3321
- v1.z,
3322
- v2.x,
3323
- v2.y,
3324
- v2.z,
3325
- v0.x,
3326
- v0.y,
3327
- v0.z,
3328
- v2.x,
3329
- v2.y,
3330
- v2.z,
3331
- v3.x,
3332
- v3.y,
3333
- v3.z
3334
- ]);
3335
- geom.setAttribute("position", new THREE.BufferAttribute(positions, 3));
3336
- const uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1]);
3337
- geom.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
3338
- geom.computeVertexNormals();
3339
- const mat = new THREE.MeshLambertMaterial({
3340
- color: 11184810,
3341
- // top
3342
- emissive: 0,
3343
- side: THREE.DoubleSide
3344
- // visible from both sides (escalators are thin)
3220
+ const lines = wrappedLines.length ? wrappedLines : [""];
3221
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3222
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3223
+ const finalHeight = lineHeight * lines.length + padding * 2;
3224
+ canvas.width = finalWidth;
3225
+ canvas.height = finalHeight;
3226
+ const ctx2 = canvas.getContext("2d");
3227
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3228
+ ctx2.textAlign = textAlign;
3229
+ if (background && background !== "transparent") {
3230
+ ctx2.fillStyle = background;
3231
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3232
+ }
3233
+ lines.forEach((line, i) => {
3234
+ const y = padding + lineHeight * (i + 0.8);
3235
+ let x = padding;
3236
+ if (textAlign === "center") x = canvas.width / 2;
3237
+ if (textAlign === "right" || textAlign === "end")
3238
+ x = canvas.width - padding;
3239
+ if (strokeWidth > 0) {
3240
+ ctx2.lineWidth = strokeWidth;
3241
+ ctx2.lineJoin = "round";
3242
+ ctx2.miterLimit = 2;
3243
+ ctx2.strokeStyle = strokeColor;
3244
+ ctx2.strokeText(line, x, y);
3245
+ }
3246
+ ctx2.fillStyle = color;
3247
+ ctx2.fillText(line, x, y);
3345
3248
  });
3346
- this._createMesh(geom, mat);
3347
- this.getObject3d().position.copy(anchorV);
3249
+ const texture = new THREE.CanvasTexture(canvas);
3250
+ texture.needsUpdate = true;
3251
+ texture.minFilter = THREE.LinearFilter;
3252
+ return texture;
3253
+ }
3254
+ _updatePosition() {
3255
+ const options = this.getOptions();
3256
+ const layer = options.layer;
3257
+ if (!layer) return;
3258
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3259
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3260
+ const position = layer.coordinateToVector3(this._coordinate, z);
3261
+ (0, import_lodash6.set)(this.properties, "default.position", position);
3262
+ this.getObject3d().position.copy(position);
3263
+ }
3264
+ _animation() {
3265
+ const layer = this.getLayer();
3266
+ if (!this.isAdd || !layer) return;
3267
+ if (this._visible === true) {
3268
+ const zoom = layer.map.getZoom();
3269
+ const object3d = this.getObject3d();
3270
+ const { opacity } = this.getOptions();
3271
+ let opacityValue;
3272
+ if (typeof opacity === "number") {
3273
+ opacityValue = opacity ?? 1;
3274
+ } else if (Array.isArray(opacity.stops)) {
3275
+ opacityValue = interpolateStops(opacity, zoom);
3276
+ } else {
3277
+ throw new Error(`Unknown opacity value ${opacity}`);
3278
+ }
3279
+ const visible = opacityValue > 0.5;
3280
+ object3d.visible = visible;
3281
+ }
3282
+ }
3283
+ setText(text) {
3284
+ const options = this.getOptions();
3285
+ options.text = text;
3286
+ const newSprite = this._createSprite();
3287
+ const group = this.getObject3d();
3288
+ group.children.forEach((child) => group.remove(child));
3289
+ group.add(newSprite);
3290
+ this._updatePosition();
3291
+ }
3292
+ setAltitude(altitude) {
3293
+ const bottomHeight = this.options.bottomHeight ?? 0;
3294
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3348
3295
  }
3349
3296
  };
3350
3297
 
3351
- // src/IndoorMap/renderer/Element3DRenderer/utils/svg2material.ts
3352
- var import_three7 = require("three");
3353
- var svgToDataURL = (svgString, scaleFactor = 1) => {
3354
- const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3355
- const url = URL.createObjectURL(svgBlob);
3356
- const img = new Image();
3357
- return new Promise((resolve, reject) => {
3358
- img.onload = function() {
3359
- const newWidth = img.width * scaleFactor;
3360
- const newHeight = img.height * scaleFactor;
3361
- const canvas = document.createElement("canvas");
3362
- canvas.width = newWidth;
3363
- canvas.height = newHeight;
3364
- const ctx = canvas.getContext("2d");
3365
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
3366
- const pngDataUrl = canvas.toDataURL("image/png");
3367
- resolve(pngDataUrl);
3368
- };
3369
- img.onerror = function(error) {
3370
- reject(error);
3371
- };
3372
- img.src = url;
3373
- });
3374
- };
3375
- var createSVGPathFromMarkerSymbol2 = (style) => {
3376
- const {
3377
- markerWidth = 24,
3378
- markerDx = 0,
3379
- markerDy = 0,
3380
- // markerFill,
3381
- markerPath,
3382
- fill = "#000000"
3383
- } = style;
3384
- const scale2 = markerWidth / 24;
3385
- const strokeWidth = 2;
3386
- const halfStrokeWidth = 0.5 * strokeWidth;
3387
- if (Array.isArray(markerPath)) {
3388
- return markerPath.map(
3389
- ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3390
- );
3391
- }
3392
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3393
- };
3394
- var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3395
- const material = new import_three7.SpriteMaterial();
3396
- try {
3397
- const [base, icon] = labelSymbol ?? [{}, {}];
3398
- const { markerWidth: baseWidth = 24 } = base;
3399
- const { markerWidth: iconWidth = 24 } = icon;
3400
- const viewBoxDimension = Math.max(baseWidth, iconWidth);
3401
- const baseSVG = createSVGPathFromMarkerSymbol2(base);
3402
- const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3403
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3404
- const textureLoader = new import_three7.TextureLoader();
3405
- const scaleFactor = 200 / 24;
3406
- svgToDataURL(svg, scaleFactor).then((png) => {
3407
- const texture = textureLoader.load(png, () => {
3408
- material.map = texture;
3409
- material.needsUpdate = true;
3410
- });
3411
- });
3412
- } catch (error) {
3413
- console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3414
- }
3415
- return material;
3416
- };
3417
-
3418
- // src/IndoorMap/renderer/Element3DRenderer.ts
3419
- var DEFAULT_POLYGON_OPTION = {
3420
- color: "#FFFFFF",
3421
- offset: 0,
3422
- altitude: 0
3298
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3299
+ var DEFAULT_POLYGON_OPTION = {
3300
+ color: "#FFFFFF",
3301
+ offset: 0,
3302
+ altitude: 0
3423
3303
  };
3424
3304
  var HEIGHT_METER = 4;
3305
+ var MULTIORDINAL_HEIGHT_METER = 9;
3425
3306
  var getGeometryOption = (feature2, options) => {
3426
3307
  try {
3427
- const option = options[feature2.feature_type];
3308
+ const option = options[feature2.feature_type] ?? element3DRendererOptions[feature2.feature_type];
3428
3309
  const category = feature2.properties.category;
3429
3310
  return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION;
3430
3311
  } catch (err) {
@@ -3435,34 +3316,20 @@ var Element3DRenderer = class extends EventTarget {
3435
3316
  options;
3436
3317
  map;
3437
3318
  threeLayer;
3438
- materialByColorMap;
3439
- materialByKey;
3319
+ dracoLoader;
3440
3320
  lineMaterial;
3321
+ materialByColorMap;
3322
+ markerRenderer;
3441
3323
  // Renderer is Ready
3442
3324
  isReady = false;
3443
- constructor(map, options) {
3325
+ constructor(map, options, layer) {
3444
3326
  super();
3445
3327
  this.options = options;
3446
3328
  this.map = map;
3447
- this.threeLayer = new import_maptalks7.ThreeLayer("elements", {
3448
- forceRenderOnMoving: true,
3449
- forceRenderOnRotating: true
3450
- });
3451
- const _this = this;
3452
- this.threeLayer.prepareToDraw = function(gl, scene, camera) {
3453
- const ambientLight = new THREE2.AmbientLight(16777215, 0.3);
3454
- scene.add(ambientLight);
3455
- const dirColor = 16777215;
3456
- const dllight = new THREE2.DirectionalLight(dirColor, 0.8);
3457
- dllight.position.set(0, -10, 10).normalize();
3458
- scene.add(dllight);
3459
- const hemi = new THREE2.HemisphereLight(16777215, 4473924, 0.4);
3460
- scene.add(hemi);
3461
- this.isReady = true;
3462
- _this.dispatchEvent(new CustomEvent("threelayer:ready"));
3463
- };
3329
+ this.dracoLoader = new import_DRACOLoader.DRACOLoader();
3330
+ this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
3464
3331
  this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3465
- this.threeLayer.addTo(this.map);
3332
+ this.threeLayer = layer;
3466
3333
  this.render();
3467
3334
  }
3468
3335
  animation() {
@@ -3477,80 +3344,56 @@ var Element3DRenderer = class extends EventTarget {
3477
3344
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3478
3345
  const existingMaterial = this.materialByColorMap.get(color);
3479
3346
  if (existingMaterial) return existingMaterial;
3480
- const created = new import_three8.MeshLambertMaterial({ color, transparent: true });
3347
+ const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3481
3348
  created.toneMapped = false;
3482
3349
  this.materialByColorMap.set(color, created);
3483
3350
  return created;
3484
3351
  }
3485
- getOrCreateIconMaterial(key) {
3486
- if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3487
- const existingMaterial = this.materialByKey.get(key);
3488
- if (existingMaterial) return existingMaterial;
3489
- const baseSymbol = {
3490
- markerType: "path",
3491
- markerPath: [
3492
- {
3493
- path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3494
- fill: "#ff0000"
3495
- }
3496
- ],
3497
- markerPathWidth: 24,
3498
- markerPathHeight: 24
3499
- };
3500
- const markerSymbol = {
3501
- markerType: "path",
3502
- markerPath: [],
3503
- // TODO: Get Path by featureType.category
3504
- // 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" }],
3505
- markerPathWidth: 24,
3506
- markerPathHeight: 24,
3507
- markerWidth: 24,
3508
- markerHeight: 24,
3509
- markerDy: 1.5,
3510
- markerDx: 1.5
3511
- };
3512
- const created = createSpriteMaterialByLabelSymbol2([
3513
- baseSymbol,
3514
- markerSymbol
3515
- ]);
3516
- this.materialByKey.set(key, created);
3517
- return created;
3518
- }
3519
3352
  createGeometry = (feature2) => {
3520
- const options = getGeometryOption(feature2, this.options);
3521
- const offset = options?.offset ?? 0;
3353
+ const {
3354
+ offset = 0,
3355
+ height: heightOptions,
3356
+ bottomHeight: bottomHeightOptions,
3357
+ color: colorOptions,
3358
+ ...options
3359
+ } = getGeometryOption(feature2, this.options);
3360
+ const _this = this;
3522
3361
  const createPolygon = (geometry, feature3) => {
3523
3362
  const [outerRing, ...innerRings] = geometry.coordinates;
3524
3363
  const offsetFeature = offset !== 0 ? (0, import_buffer2.default)(geometry, offset, { units: "meters" }) : feature3;
3525
- const color = options.color ?? feature3.properties.style.polygonFill ?? "#ffffff";
3364
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3526
3365
  if (color === "transparent") return;
3527
3366
  const material = this.getOrCreateMaterialByColor(color);
3528
3367
  const altitude = feature3.properties.ordinal * HEIGHT_METER;
3529
- const bottomHeight = options.bottomHeight ?? 0;
3530
- const polygon = this.threeLayer.toExtrudePolygon(
3368
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3369
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3370
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3531
3371
  offsetFeature,
3532
- { asynchronous: true, ...options, altitude },
3372
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3533
3373
  material
3534
3374
  );
3375
+ extrudedPolygon.on("click", (e) => {
3376
+ console.log(e.target.options.polygon.id);
3377
+ });
3535
3378
  const topLineStrings = [
3536
- new maptalks5.LineString(outerRing),
3537
- ...innerRings.map((innerRing) => new maptalks5.LineString(innerRing))
3379
+ new maptalks4.LineString(outerRing),
3380
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3538
3381
  ];
3539
3382
  const topLines = this.threeLayer.toLines(
3540
3383
  topLineStrings,
3541
- { altitude: altitude + options.height + 1e-3, bottomHeight, interactive: false },
3384
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3542
3385
  this.lineMaterial
3543
3386
  );
3544
3387
  const bottomLineStrings = [
3545
- new maptalks5.LineString(outerRing),
3546
- ...innerRings.map((innerRing) => new maptalks5.LineString(innerRing))
3388
+ new maptalks4.LineString(outerRing),
3389
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3547
3390
  ];
3548
3391
  const bottomLines = this.threeLayer.toLines(
3549
3392
  bottomLineStrings,
3550
3393
  { altitude, bottomHeight, interactive: false },
3551
3394
  this.lineMaterial
3552
3395
  );
3553
- return [polygon, topLines, bottomLines];
3396
+ return [extrudedPolygon, topLines, bottomLines];
3554
3397
  };
3555
3398
  try {
3556
3399
  switch (feature2.geometry.type) {
@@ -3573,49 +3416,111 @@ var Element3DRenderer = class extends EventTarget {
3573
3416
  console.log(`error createGeometry`, { feature: feature2, options });
3574
3417
  }
3575
3418
  };
3576
- createMarker = (coordinates, ordinal, label) => {
3577
- const options = {
3578
- scale: 0.05,
3579
- altitude: ordinal * HEIGHT_METER,
3580
- // highlight: highlightOptions,
3581
- interactive: true
3582
- };
3583
- const material = this.getOrCreateIconMaterial(
3584
- "amenity.escalator"
3585
- );
3586
- const marker = new SpriteMarker(
3587
- coordinates,
3588
- options,
3589
- material,
3590
- this.threeLayer,
3591
- {}
3419
+ async createEscalator(f, coordinate, options) {
3420
+ const { direction: dir, angle } = options;
3421
+ const model = await this.loadModel3d({
3422
+ url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
3423
+ properties: {
3424
+ rotation: {
3425
+ x: 0.5 * Math.PI,
3426
+ // Rotate the model up (new_escalator.glb)
3427
+ y: 0,
3428
+ z: 0
3429
+ },
3430
+ position: { x: 0, y: 0, z: 0 },
3431
+ scale: 0.01
3432
+ }
3433
+ });
3434
+ model.rotation.y += dir === "up" ? Math.PI + angle : angle;
3435
+ const box = new THREE2.Box3().setFromObject(model);
3436
+ const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
3437
+ 1 * (box.min.x + box.max.x),
3438
+ 1 * (box.min.y + box.max.y),
3439
+ 0.6 * box.max.z
3592
3440
  );
3593
- this.threeLayer.addMesh([marker]);
3594
- return marker;
3595
- };
3441
+ const pivot = new THREE2.Group();
3442
+ pivot.add(model);
3443
+ model.position.sub(pivotPoint);
3444
+ model.updateMatrixWorld(true);
3445
+ const altitude = f.properties.ordinal * HEIGHT_METER;
3446
+ const baseObjectModel = this.threeLayer.toModel(pivot, {
3447
+ coordinate,
3448
+ altitude
3449
+ });
3450
+ this.threeLayer.addMesh(baseObjectModel);
3451
+ return baseObjectModel;
3452
+ }
3453
+ async createTree(coordinate, ordinal) {
3454
+ const model = await this.loadModel3d({
3455
+ url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
3456
+ properties: {
3457
+ rotation: {
3458
+ x: 0.5 * Math.PI,
3459
+ // Rotate the model up (new_escalator.glb)
3460
+ y: 0,
3461
+ z: 0
3462
+ },
3463
+ position: { x: 0, y: 0, z: 0 },
3464
+ scale: 0.01
3465
+ }
3466
+ });
3467
+ const altitude = ordinal * HEIGHT_METER;
3468
+ const baseObjectModel = this.threeLayer.toModel(model, {
3469
+ coordinate,
3470
+ altitude
3471
+ });
3472
+ this.threeLayer.addMesh(baseObjectModel);
3473
+ return baseObjectModel;
3474
+ }
3596
3475
  createElement(f) {
3597
3476
  switch (f.feature_type) {
3598
- case "unit": {
3599
- switch (f.properties.category) {
3600
- case "escalator": {
3601
- const mesh = new Escalator(
3602
- f,
3603
- {
3604
- startAltitude: 0,
3605
- endAltitude: 0.06
3606
- },
3607
- this.threeLayer
3608
- );
3609
- this.threeLayer.addMesh([mesh]);
3610
- return [mesh];
3611
- }
3612
- }
3613
- break;
3614
- }
3615
3477
  default:
3616
3478
  return null;
3617
3479
  }
3618
3480
  }
3481
+ showElements(elements, ordinalDiff = 0) {
3482
+ elements.forEach((element) => {
3483
+ element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER);
3484
+ element.show();
3485
+ });
3486
+ }
3487
+ hideElements(elements, ordinalDiff = 0) {
3488
+ elements.forEach((element) => {
3489
+ try {
3490
+ element.hide();
3491
+ } catch (err) {
3492
+ console.log(`cannot hide`, err, element);
3493
+ }
3494
+ });
3495
+ }
3496
+ async loadModel3d(model3d) {
3497
+ const loader = new import_GLTFLoader2.GLTFLoader();
3498
+ loader.setDRACOLoader(this.dracoLoader);
3499
+ const { url, properties: modelProperties } = model3d;
3500
+ const gltf = await loader.loadAsync(url);
3501
+ const model = gltf.scene;
3502
+ model.rotation.x = modelProperties.rotation.x;
3503
+ model.rotation.y = modelProperties.rotation.y;
3504
+ model.position.x = modelProperties.position.x;
3505
+ model.position.y = modelProperties.position.y;
3506
+ model.position.z = modelProperties.position.z;
3507
+ const scale2 = modelProperties.scale;
3508
+ model.scale.set(scale2, scale2, scale2);
3509
+ return model;
3510
+ }
3511
+ createMarker = (coordinates, ordinal, text) => {
3512
+ const options = {
3513
+ // scale: 0.05,
3514
+ // altitude: ordinal * HEIGHT_METER,
3515
+ text
3516
+ // interactive: true,
3517
+ };
3518
+ const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
3519
+ this.threeLayer.addMesh([marker]);
3520
+ return marker;
3521
+ };
3522
+ removeMarker = () => {
3523
+ };
3619
3524
  render() {
3620
3525
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3621
3526
  if (this.threeLayer._needsUpdate) {
@@ -3625,9 +3530,34 @@ var Element3DRenderer = class extends EventTarget {
3625
3530
  }
3626
3531
  };
3627
3532
 
3628
- // src/IndoorMap/renderer/Element2DRenderer.ts
3629
- var maptalks6 = __toESM(require("maptalks"));
3630
- var OCCUPANT_TEXT_MARKER_CLASSNAME2 = "mtk-occupant-text-marker";
3533
+ // src/IndoorMap/renderer/2d/Element2DRenderer.ts
3534
+ var maptalks5 = __toESM(require("maptalks"));
3535
+
3536
+ // src/IndoorMap/renderer/2d/element2DRendererOptions.ts
3537
+ var element2DRendererOptions = {
3538
+ unit: {
3539
+ default: { symbol: { polygonFill: "#cccccc" } },
3540
+ byCategory: {
3541
+ room: { symbol: { polygonFill: "#fff" } },
3542
+ walkway: { symbol: { polygonFill: "#efefef", lineColor: "#dadada", lineWidth: 2 } },
3543
+ terrace: { symbol: { polygonFill: "#efefef" } },
3544
+ unenclosedarea: { symbol: { polygonFill: "#fff" } },
3545
+ nonpublic: { symbol: { polygonFill: "#999999" } }
3546
+ }
3547
+ },
3548
+ kiosk: {
3549
+ default: {}
3550
+ },
3551
+ fixture: {
3552
+ default: { symbol: { polygonFill: "#ffffff" } },
3553
+ byCategory: {
3554
+ water: { symbol: { polygonFill: "#ACD7EC" } },
3555
+ vegetation: { symbol: { polygonFill: "#91C499" } }
3556
+ }
3557
+ }
3558
+ };
3559
+
3560
+ // src/IndoorMap/renderer/2d/Element2DRenderer.ts
3631
3561
  var DEFAULT_POLYGON_OPTION2 = {
3632
3562
  zIndex: 0,
3633
3563
  symbol: {
@@ -3637,6 +3567,7 @@ var DEFAULT_POLYGON_OPTION2 = {
3637
3567
  lineWidth: 2
3638
3568
  }
3639
3569
  };
3570
+ var MULTIORDINAL_HEIGHT_METER2 = 10;
3640
3571
  var getGeometryProperties = (feature2) => ({
3641
3572
  // Core
3642
3573
  type: "Feature",
@@ -3646,11 +3577,11 @@ var getGeometryProperties = (feature2) => ({
3646
3577
  // Extra
3647
3578
  feature_type: feature2.feature_type,
3648
3579
  category: feature2.properties.category,
3649
- name: feature2.properties.name.en
3580
+ name: feature2.properties.name?.en
3650
3581
  });
3651
3582
  var getGeometryOption2 = (feature2, options) => {
3652
3583
  try {
3653
- const option = options[feature2.feature_type];
3584
+ const option = options[feature2.feature_type] ?? element2DRendererOptions[feature2.feature_type];
3654
3585
  const category = feature2.properties.category;
3655
3586
  return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION2;
3656
3587
  } catch (err) {
@@ -3667,18 +3598,17 @@ var Element2DRenderer = class extends EventTarget {
3667
3598
  super();
3668
3599
  this.options = options;
3669
3600
  this.map = map;
3670
- this.elementLayer = new maptalks6.VectorLayer("elements");
3601
+ this.elementLayer = new maptalks5.VectorLayer("elements");
3671
3602
  this.elementLayer.addTo(this.map);
3672
- this.markerLayer = new maptalks6.VectorLayer("markers");
3603
+ this.markerLayer = new maptalks5.VectorLayer("markers");
3673
3604
  this.markerLayer.addTo(this.map);
3674
3605
  this.isReady = true;
3675
- this.dispatchEvent(new CustomEvent("renderer:ready"));
3676
3606
  }
3677
3607
  createGeometry = (imdfFeature) => {
3678
3608
  const feature2 = getGeometryProperties(imdfFeature);
3679
3609
  const { symbol, ...options } = getGeometryOption2(imdfFeature, this.options);
3680
3610
  const altitude = feature2.properties.ordinal * 10;
3681
- const geometry = maptalks6.Geometry.fromJSON({
3611
+ const geometry = maptalks5.Geometry.fromJSON({
3682
3612
  feature: feature2,
3683
3613
  symbol,
3684
3614
  options: {
@@ -3689,42 +3619,235 @@ var Element2DRenderer = class extends EventTarget {
3689
3619
  });
3690
3620
  if (Array.isArray(geometry)) {
3691
3621
  geometry.forEach((g) => g.addTo(this.elementLayer));
3692
- return new maptalks6.GeometryCollection(geometry);
3622
+ return new maptalks5.GeometryCollection(geometry);
3693
3623
  } else {
3694
3624
  geometry.addTo(this.elementLayer);
3695
3625
  return geometry;
3696
3626
  }
3697
3627
  };
3698
- createMarker = (coordinates, ordinal, label) => {
3699
- const createStyledUIMarkerElement2 = ({ style: style2, textContent, className }) => {
3700
- const element = document.createElement("div");
3701
- for (const key in style2) {
3702
- element.style[key] = style2[key];
3703
- }
3704
- element.className = className;
3705
- element.textContent = textContent;
3706
- return element.outerHTML;
3707
- };
3708
- const style = {};
3628
+ async createEscalator(f, coordinates) {
3629
+ return Promise.resolve(null);
3630
+ }
3631
+ async createTree(f, coordinates) {
3632
+ return Promise.resolve(null);
3633
+ }
3634
+ createElement = (imdfFeature) => {
3635
+ switch (imdfFeature.feature_type) {
3636
+ default:
3637
+ return null;
3638
+ }
3639
+ };
3640
+ showElements(elements, ordinalDiff = 0) {
3641
+ elements.forEach((element) => {
3642
+ element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER2);
3643
+ element.show();
3644
+ });
3645
+ }
3646
+ hideElements(elements, ordinalDiff = 0) {
3647
+ elements.forEach((element) => {
3648
+ element.hide();
3649
+ });
3650
+ }
3651
+ };
3652
+
3653
+ // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
3654
+ var maptalks6 = __toESM(require("maptalks"));
3655
+ var Marker2DRenderer = class extends EventTarget {
3656
+ isReady = false;
3657
+ map;
3658
+ markerLayer;
3659
+ constructor(map) {
3660
+ super();
3661
+ }
3662
+ createMarker = (coordinates, ordinal, content) => {
3709
3663
  const marker = new maptalks6.ui.UIMarker(coordinates, {
3710
- content: createStyledUIMarkerElement2({
3711
- style,
3712
- textContent: label,
3713
- className: OCCUPANT_TEXT_MARKER_CLASSNAME2
3714
- }),
3664
+ content,
3715
3665
  collision: true,
3716
- collisionFadeIn: true
3717
- // altitude: getAltitude(f.properties) + markerHeight,
3666
+ collisionFadeIn: true,
3667
+ altitude: 0
3718
3668
  });
3719
3669
  marker.addTo(this.map);
3720
3670
  return marker;
3721
3671
  };
3722
- createElement = (imdfFeature) => {
3723
- switch (imdfFeature.feature_type) {
3724
- default:
3725
- return null;
3726
- }
3672
+ removeMarker = (marker) => {
3673
+ marker.remove();
3727
3674
  };
3675
+ showMarkers(elements, ordinalDiff = 0) {
3676
+ }
3677
+ hideMarkers(elements, ordinalDiff = 0) {
3678
+ }
3679
+ };
3680
+
3681
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3682
+ var maptalks7 = __toESM(require("maptalks"));
3683
+
3684
+ // src/IndoorMap/renderer/utils/svg2material.ts
3685
+ var import_three7 = require("three");
3686
+ var svgToDataURL = (svgString, scaleFactor = 1) => {
3687
+ const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3688
+ const url = URL.createObjectURL(svgBlob);
3689
+ const img = new Image();
3690
+ return new Promise((resolve, reject) => {
3691
+ img.onload = function() {
3692
+ const newWidth = img.width * scaleFactor;
3693
+ const newHeight = img.height * scaleFactor;
3694
+ const canvas = document.createElement("canvas");
3695
+ canvas.width = newWidth;
3696
+ canvas.height = newHeight;
3697
+ const ctx = canvas.getContext("2d");
3698
+ ctx.drawImage(img, 0, 0, newWidth, newHeight);
3699
+ const pngDataUrl = canvas.toDataURL("image/png");
3700
+ resolve(pngDataUrl);
3701
+ };
3702
+ img.onerror = function(error) {
3703
+ reject(error);
3704
+ };
3705
+ img.src = url;
3706
+ });
3707
+ };
3708
+ var createSVGPathFromMarkerSymbol2 = (style) => {
3709
+ const {
3710
+ markerWidth = 24,
3711
+ markerDx = 0,
3712
+ markerDy = 0,
3713
+ // markerFill,
3714
+ markerPath,
3715
+ fill = "#000000"
3716
+ } = style;
3717
+ const scale2 = markerWidth / 24;
3718
+ const strokeWidth = 2;
3719
+ const halfStrokeWidth = 0.5 * strokeWidth;
3720
+ if (Array.isArray(markerPath)) {
3721
+ return markerPath.map(
3722
+ ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3723
+ );
3724
+ }
3725
+ return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3726
+ };
3727
+ var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3728
+ const material = new import_three7.SpriteMaterial();
3729
+ try {
3730
+ const [base, icon] = labelSymbol ?? [{}, {}];
3731
+ const { markerWidth: baseWidth = 24 } = base;
3732
+ const { markerWidth: iconWidth = 24 } = icon;
3733
+ const viewBoxDimension = Math.max(baseWidth, iconWidth);
3734
+ const baseSVG = createSVGPathFromMarkerSymbol2(base);
3735
+ const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3736
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3737
+ const textureLoader = new import_three7.TextureLoader();
3738
+ const scaleFactor = 200 / 24;
3739
+ svgToDataURL(svg, scaleFactor).then((png) => {
3740
+ const texture = textureLoader.load(png, () => {
3741
+ material.map = texture;
3742
+ material.needsUpdate = true;
3743
+ });
3744
+ });
3745
+ } catch (error) {
3746
+ console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3747
+ }
3748
+ return material;
3749
+ };
3750
+
3751
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3752
+ var HEIGHT_METER2 = 4;
3753
+ var MULTIORDINAL_HEIGHT_METER3 = 9;
3754
+ var Marker3DRenderer = class extends EventTarget {
3755
+ isReady = false;
3756
+ threeLayer;
3757
+ map;
3758
+ materialByKey;
3759
+ constructor(map, options, layer) {
3760
+ super();
3761
+ this.map = map;
3762
+ this.threeLayer = layer;
3763
+ }
3764
+ createTextMarker = (position, ordinal, label, options) => {
3765
+ const combinedOptions = {
3766
+ altitude: ordinal * HEIGHT_METER2,
3767
+ text: label,
3768
+ ...options ?? {}
3769
+ };
3770
+ const [lng, lat] = position;
3771
+ const marker = new TextSpriteMarker(new maptalks7.Coordinate(lng, lat), combinedOptions, this.threeLayer);
3772
+ this.threeLayer.addMesh([marker]);
3773
+ return marker;
3774
+ };
3775
+ createImageMarker = () => {
3776
+ };
3777
+ createMarker = (coordinates, ordinal, label, options) => {
3778
+ return this.createTextMarker(coordinates, ordinal, label, options);
3779
+ };
3780
+ removeMarker = (marker) => {
3781
+ marker.remove();
3782
+ };
3783
+ showMarkers(elements, ordinalDiff = 0) {
3784
+ elements.forEach((element) => {
3785
+ element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER3);
3786
+ element.show();
3787
+ });
3788
+ }
3789
+ hideMarkers(elements, ordinalDiff = 0) {
3790
+ elements.forEach((element) => {
3791
+ try {
3792
+ element.hide();
3793
+ } catch (err) {
3794
+ console.log(`cannot hide`, err, element);
3795
+ }
3796
+ });
3797
+ }
3798
+ /** Marker */
3799
+ getOrCreateIconMaterial(key) {
3800
+ if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3801
+ const existingMaterial = this.materialByKey.get(key);
3802
+ if (existingMaterial) return existingMaterial;
3803
+ const baseSymbol = {
3804
+ markerType: "path",
3805
+ markerPath: [
3806
+ {
3807
+ path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3808
+ fill: "#ff0000"
3809
+ }
3810
+ ],
3811
+ markerPathWidth: 24,
3812
+ markerPathHeight: 24
3813
+ };
3814
+ const markerSymbol = {
3815
+ markerType: "path",
3816
+ markerPath: [],
3817
+ // TODO: Get Path by featureType.category
3818
+ // markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
3819
+ markerPathWidth: 24,
3820
+ markerPathHeight: 24,
3821
+ markerWidth: 24,
3822
+ markerHeight: 24,
3823
+ markerDy: 1.5,
3824
+ markerDx: 1.5
3825
+ };
3826
+ const created = createSpriteMaterialByLabelSymbol2([
3827
+ baseSymbol,
3828
+ markerSymbol
3829
+ ]);
3830
+ this.materialByKey.set(key, created);
3831
+ return created;
3832
+ }
3833
+ };
3834
+
3835
+ // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
3836
+ var getLineCenter = (line) => {
3837
+ let x = 0, y = 0;
3838
+ for (const [lx, ly] of line) {
3839
+ x += lx;
3840
+ y += ly;
3841
+ }
3842
+ const len = line.length;
3843
+ return [x / len, y / len];
3844
+ };
3845
+ var angleBetweenLineStrings = (line1, line2) => {
3846
+ const [x1, y1] = getLineCenter(line1);
3847
+ const [x2, y2] = getLineCenter(line2);
3848
+ const dx = x2 - x1;
3849
+ const dy = y2 - y1;
3850
+ return Math.atan2(dy, dx);
3728
3851
  };
3729
3852
 
3730
3853
  // src/IndoorMap/renderer/RendererManager.ts
@@ -3735,25 +3858,48 @@ var RendererManager = class extends EventTarget {
3735
3858
  #dataClient;
3736
3859
  /** Elements: Responsible for converting feature info elements and add to map */
3737
3860
  elementRenderer;
3861
+ markerRenderer;
3738
3862
  elementsMap;
3739
3863
  elementsByOrdinal;
3740
- constructor(map, options) {
3864
+ currentOrdinals;
3865
+ markersMap;
3866
+ markersByOrdinal;
3867
+ constructor(map, dataClient, options) {
3741
3868
  super();
3742
3869
  this.map = map;
3743
3870
  this.options = options;
3744
3871
  this.elementsMap = /* @__PURE__ */ new Map();
3745
3872
  this.elementsByOrdinal = /* @__PURE__ */ new Map();
3746
- this.elementRenderer = options.type === "2D" ? new Element2DRenderer(map, options.elements) : new Element3DRenderer(map, options.elements);
3747
- }
3748
- set dataClient(value) {
3749
- this.#dataClient = value;
3750
- if (this.elementRenderer.isReady) {
3751
- this.#createElements();
3752
- } else {
3753
- this.elementRenderer.addEventListener("threelayer:ready", (e) => {
3754
- this.dispatchEvent(new CustomEvent("renderermanager:ready"));
3755
- this.#createElements();
3873
+ this.markersMap = /* @__PURE__ */ new Map();
3874
+ this.markersByOrdinal = /* @__PURE__ */ new Map();
3875
+ this.#dataClient = dataClient;
3876
+ if (options.type === "3D") {
3877
+ const threeLayer = new import_maptalks8.ThreeLayer("elements", {
3878
+ forceRenderOnMoving: true,
3879
+ forceRenderOnRotating: true
3756
3880
  });
3881
+ const _this = this;
3882
+ threeLayer.prepareToDraw = function(gl, scene, camera) {
3883
+ const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3884
+ scene.add(ambientLight);
3885
+ const dirColor = 16777215;
3886
+ const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3887
+ dllight.position.set(0, -10, 10).normalize();
3888
+ scene.add(dllight);
3889
+ const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3890
+ scene.add(hemi);
3891
+ _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
3892
+ _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3893
+ if (typeof options.onRendererReady === "function") {
3894
+ options.onRendererReady();
3895
+ }
3896
+ _this.#createElements();
3897
+ };
3898
+ threeLayer.addTo(this.map);
3899
+ } else {
3900
+ this.elementRenderer = new Element2DRenderer(map, options.elements);
3901
+ this.markerRenderer = new Marker2DRenderer(map);
3902
+ this.#createElements();
3757
3903
  }
3758
3904
  }
3759
3905
  getElementsByOrdinal = (ordinal) => {
@@ -3761,19 +3907,46 @@ var RendererManager = class extends EventTarget {
3761
3907
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3762
3908
  return this.elementsByOrdinal.get(ordinal);
3763
3909
  };
3910
+ getMarkersByOrdinal = (ordinal) => {
3911
+ const exist = this.markersByOrdinal.get(ordinal);
3912
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
3913
+ return this.markersByOrdinal.get(ordinal);
3914
+ };
3915
+ addElementsToManager = (id, elements, ordinal) => {
3916
+ this.elementsMap.set(id, elements);
3917
+ elements.forEach((el) => {
3918
+ this.getElementsByOrdinal(ordinal).push(el);
3919
+ });
3920
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3921
+ if (inOrdinal) {
3922
+ this.elementRenderer.showElements(elements, ordinal);
3923
+ } else {
3924
+ this.elementRenderer.hideElements(elements, ordinal);
3925
+ }
3926
+ };
3927
+ addMarkersToManager = (id, markers, ordinal) => {
3928
+ this.markersMap.set(id, markers);
3929
+ markers.forEach((el) => {
3930
+ this.getMarkersByOrdinal(ordinal).push(el);
3931
+ });
3932
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3933
+ if (inOrdinal) {
3934
+ this.markerRenderer.showMarkers(markers, ordinal);
3935
+ } else {
3936
+ this.markerRenderer.hideMarkers(markers, ordinal);
3937
+ }
3938
+ };
3764
3939
  async #createElements() {
3765
3940
  const levels = await this.#dataClient.filterByType("level", {
3766
3941
  populate: true
3767
3942
  });
3943
+ const relationships = await this.#dataClient.filterByType("relationship");
3768
3944
  const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
3769
3945
  fixtures.forEach((fixture) => {
3770
3946
  const element = this.elementRenderer.createGeometry(fixture);
3771
3947
  if (element) {
3772
3948
  const _elements = Array.isArray(element) ? element : [element];
3773
- _elements.forEach((el) => {
3774
- this.elementsMap.set(fixture.id, el);
3775
- this.getElementsByOrdinal(fixture.properties.level.properties.ordinal).push(el);
3776
- });
3949
+ this.addElementsToManager(fixture.id, _elements, fixture.properties.level.properties.ordinal);
3777
3950
  }
3778
3951
  });
3779
3952
  const units = await this.#dataClient.filterByType("unit", {
@@ -3785,10 +3958,7 @@ var RendererManager = class extends EventTarget {
3785
3958
  const element = this.elementRenderer.createGeometry(unit);
3786
3959
  if (element) {
3787
3960
  const _elements = Array.isArray(element) ? element : [element];
3788
- _elements.forEach((el) => {
3789
- this.elementsMap.set(unit.id, el);
3790
- this.getElementsByOrdinal(unit.properties.level.properties.ordinal).push(el);
3791
- });
3961
+ this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
3792
3962
  }
3793
3963
  });
3794
3964
  const kiosks = await this.#dataClient.filterByType("kiosk", {
@@ -3798,32 +3968,85 @@ var RendererManager = class extends EventTarget {
3798
3968
  const element = this.elementRenderer.createGeometry(kiosk);
3799
3969
  if (element) {
3800
3970
  const _elements = Array.isArray(element) ? element : [element];
3801
- _elements.forEach((el) => {
3802
- this.elementsMap.set(kiosk.id, el);
3803
- this.getElementsByOrdinal(kiosk.properties.level.properties.ordinal).push(el);
3804
- });
3971
+ this.addElementsToManager(kiosk.id, _elements, kiosk.properties.level.properties.ordinal);
3805
3972
  }
3806
3973
  });
3974
+ const escalators = units.filter((u) => u.properties.category === "escalator");
3975
+ for (const escalator of escalators) {
3976
+ try {
3977
+ const escalatorRelationships = relationships.filter((r) => (r.properties?.intermediary || []).some((inter) => inter.id === escalator.id));
3978
+ if (escalatorRelationships.length === 0) {
3979
+ throw new Error("Cannot find escalator relationship");
3980
+ }
3981
+ if (escalatorRelationships.length > 1) {
3982
+ throw new Error("Found more than one relationship");
3983
+ }
3984
+ const thisOrdinal = escalator.properties.ordinal;
3985
+ const relationship = escalatorRelationships[0];
3986
+ const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
3987
+ const bothOpenings = await Promise.all(
3988
+ bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
3989
+ );
3990
+ const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
3991
+ const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
3992
+ const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
3993
+ const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
3994
+ const escalatorEntryPoint = (0, import_center3.center)(thisLevelOpening).geometry.coordinates;
3995
+ const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
3996
+ if (element) {
3997
+ const _elements = Array.isArray(element) ? element : [element];
3998
+ this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
3999
+ }
4000
+ } catch (err) {
4001
+ console.log(`cannot create escalator`, err);
4002
+ }
4003
+ }
4004
+ this.changeLevelByOrdinal(this.currentOrdinals);
3807
4005
  this.dispatchEvent(new CustomEvent("renderermanager:elements_created"));
3808
4006
  }
3809
4007
  changeLevelByOrdinal(targetOrdinal) {
3810
- for (const [ordinal, elements] of this.elementsByOrdinal) {
3811
- const inOrdinal = targetOrdinal === null ? true : Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
3812
- if (inOrdinal) {
3813
- elements.forEach((element, i) => {
3814
- element.show();
3815
- });
3816
- } else {
3817
- elements.forEach((element) => {
3818
- element.hide();
3819
- });
4008
+ this.currentOrdinals = targetOrdinal;
4009
+ if (targetOrdinal === null) {
4010
+ const baseOrdinal = 0;
4011
+ for (const [ordinal, elements] of this.elementsByOrdinal) {
4012
+ this.elementRenderer.showElements(elements, ordinal - baseOrdinal);
4013
+ }
4014
+ for (const [ordinal, markers] of this.markersByOrdinal) {
4015
+ this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
4016
+ }
4017
+ } else {
4018
+ const baseOrdinal = Array.isArray(targetOrdinal) ? (0, import_min.default)(targetOrdinal) : targetOrdinal;
4019
+ for (const [ordinal, elements] of this.elementsByOrdinal) {
4020
+ const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
4021
+ if (inOrdinal) {
4022
+ this.elementRenderer.showElements(elements, ordinal - baseOrdinal);
4023
+ } else {
4024
+ this.elementRenderer.hideElements(elements, ordinal - baseOrdinal);
4025
+ }
4026
+ }
4027
+ for (const [ordinal, markers] of this.markersByOrdinal) {
4028
+ const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
4029
+ if (inOrdinal) {
4030
+ this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
4031
+ } else {
4032
+ this.markerRenderer.hideMarkers(markers, ordinal - baseOrdinal);
4033
+ }
3820
4034
  }
3821
4035
  }
3822
4036
  }
3823
- createMarker(coordinate, ordinal, label) {
3824
- const marker = this.elementRenderer.createMarker(coordinate, ordinal, label);
3825
- this.elementsMap.set(label, marker);
3826
- this.getElementsByOrdinal(ordinal).push(marker);
4037
+ /**
4038
+ * ========================================================================
4039
+ * Markers
4040
+ * ======================================================================== */
4041
+ createMarker(coordinate, ordinal, text, options) {
4042
+ const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
4043
+ const markerId = `${this.markersMap.size + 1}`;
4044
+ this.addMarkersToManager(markerId, [marker], ordinal);
4045
+ }
4046
+ clearMarkers() {
4047
+ for (const [markerId, marker] of this.markersMap) {
4048
+ this.markerRenderer.removeMarker(marker);
4049
+ }
3827
4050
  }
3828
4051
  };
3829
4052
 
@@ -3892,13 +4115,14 @@ var IndoorMap = class extends EventTarget {
3892
4115
  onMapLoading,
3893
4116
  pixelRatio,
3894
4117
  locale
3895
- } = import_lodash6.default.merge({}, defaultOptions, options);
3896
- this.map = new import_maptalks8.Map(elementId, {
4118
+ } = import_lodash7.default.merge({}, defaultOptions, options);
4119
+ this.map = new import_maptalks_gl.Map(elementId, {
3897
4120
  attribution: false,
3898
4121
  center: INITIAL_CENTER,
3899
4122
  zoom: INITIAL_ZOOM,
3900
4123
  clickTimeThreshold: 600,
3901
- baseLayer: new import_maptalks8.TileLayer("base", {
4124
+ centerCross: options.centerCross ?? false,
4125
+ baseLayer: new import_maptalks_gl.TileLayer("base", {
3902
4126
  urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
3903
4127
  subdomains: ["a", "b", "c", "d"],
3904
4128
  opacity: 1,
@@ -3909,13 +4133,7 @@ var IndoorMap = class extends EventTarget {
3909
4133
  }),
3910
4134
  layers: []
3911
4135
  });
3912
- this.rendererManager = new RendererManager(this.map, options.renderer);
3913
- this.rendererManager.addEventListener("renderermanager:ready", (e) => {
3914
- this.dispatchEvent(new CustomEvent("renderer:ready"));
3915
- });
3916
- this.rendererManager.addEventListener("renderermanager:elements_created", (e) => {
3917
- this.dispatchEvent(new CustomEvent("renderer:elements_created"));
3918
- });
4136
+ this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
3919
4137
  this.camera = new CameraManager(this.map);
3920
4138
  this.locale = locale;
3921
4139
  this.pixelRatio = pixelRatio;
@@ -3928,12 +4146,14 @@ var IndoorMap = class extends EventTarget {
3928
4146
  set dataClient(value) {
3929
4147
  this.#dataClient = value;
3930
4148
  this.#dataClient.filterByType("venue").then((venues) => {
3931
- const venueCenters = (0, import_center3.default)(featureCollection(venues));
4149
+ const venueCenters = (0, import_center4.default)(featureCollection(venues));
3932
4150
  const [x, y] = venueCenters.geometry.coordinates;
3933
- const center2 = new import_maptalks8.Coordinate(x, y);
4151
+ const center2 = new import_maptalks_gl.Coordinate(x, y);
3934
4152
  this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
3935
4153
  });
3936
- this.rendererManager.dataClient = this.#dataClient;
4154
+ }
4155
+ on(eventName, handler) {
4156
+ this.map.on(eventName, handler);
3937
4157
  }
3938
4158
  /**
3939
4159
  * Events
@@ -3941,7 +4161,7 @@ var IndoorMap = class extends EventTarget {
3941
4161
  handleMapClick = ({ coordinate }) => {
3942
4162
  const { x, y } = coordinate;
3943
4163
  console.log(
3944
- `[Coordinates]: x: ${import_lodash6.default.round(x, 8)} y: ${import_lodash6.default.round(
4164
+ `[Coordinates]: x: ${import_lodash7.default.round(x, 8)} y: ${import_lodash7.default.round(
3945
4165
  y,
3946
4166
  8
3947
4167
  )}, [Bearing]: ${this.map.getBearing()}, [Pitch]: ${this.map.getPitch()}`
@@ -4050,69 +4270,37 @@ var IndoorMap = class extends EventTarget {
4050
4270
  const scene = this.threeLayer.getScene();
4051
4271
  if (scene) {
4052
4272
  scene.children = scene.children.filter(
4053
- (children) => children instanceof import_three9.PerspectiveCamera
4273
+ (children) => children instanceof import_three8.PerspectiveCamera
4054
4274
  );
4055
4275
  }
4056
4276
  }
4057
- #createLayers() {
4058
- const map = this.map;
4059
- if (!this.ordinals || this.ordinals.length === 0) return;
4060
- LAYERS.forEach((layerKey) => {
4061
- const layerID = layerKey;
4062
- const option = LAYER_OPTIONS[layerKey];
4063
- const layer = new import_maptalks8.VectorLayer(layerID, option);
4064
- map.addLayer(layer);
4065
- });
4066
- const threeLayer = new import_maptalks9.ThreeLayer("t_building", {
4067
- forceRenderOnMoving: true,
4068
- forceRenderOnRotating: true
4069
- });
4070
- this.threeLayer = threeLayer;
4071
- threeLayer.addTo(this.map);
4072
- }
4073
- #initMapElements() {
4074
- this.#createLayers();
4075
- const threeLayer = this.threeLayer;
4076
- if (threeLayer) {
4077
- this.threeLayer.prepareToDraw = async (gl, scene, camera) => {
4078
- await this.#createElements();
4079
- };
4080
- }
4081
- }
4082
4277
  handleClickElement = (e) => {
4083
4278
  if (this.#isClicked) return;
4084
4279
  this.#isClicked = true;
4085
4280
  const onClickElement = this.#onClickElement;
4086
- if (!import_lodash6.default.isFunction(onClickElement)) return;
4281
+ if (!import_lodash7.default.isFunction(onClickElement)) return;
4087
4282
  this.#onClickElement(e);
4088
4283
  this.#isClicked = false;
4089
4284
  };
4090
4285
  setCenter(center2, padding) {
4091
4286
  this.map.setCenter(center2, padding);
4092
4287
  }
4093
- async #createElements() {
4288
+ async #legacy_createElements() {
4094
4289
  const {
4095
4290
  // 2D
4096
4291
  createVenue,
4097
- createLevel,
4098
- createUnit,
4099
4292
  createOpening,
4100
4293
  createSection,
4101
4294
  createFixture,
4102
- createKiosk,
4103
4295
  createOccupant,
4104
4296
  createDecoration,
4105
4297
  // 3D
4106
4298
  create3DFootprint,
4107
4299
  create3DGroundLabel,
4108
4300
  create3DBillboard,
4109
- create3DUnit,
4110
- create3DKiosk,
4111
4301
  createVenue3DModel,
4112
4302
  createExtrudedUnit,
4113
- createExtrudedLevel,
4114
4303
  create3DFixture,
4115
- createExtrudedKiosk,
4116
4304
  create3DAmenityMarker,
4117
4305
  create3DOccupantAmenityMarker,
4118
4306
  create3DOpeningMarker,
@@ -4128,7 +4316,7 @@ var IndoorMap = class extends EventTarget {
4128
4316
  const {
4129
4317
  ambientLight: ambientLightConfig = {},
4130
4318
  directionalLight: directionalLightConfig = {}
4131
- } = import_lodash6.default.get(this.#mapConfig, "light", {
4319
+ } = import_lodash7.default.get(this.#mapConfig, "light", {
4132
4320
  ambientLight: {},
4133
4321
  directionalLight: {}
4134
4322
  });
@@ -4140,16 +4328,16 @@ var IndoorMap = class extends EventTarget {
4140
4328
  for (const feature2 of this.#features) {
4141
4329
  try {
4142
4330
  const { feature_type: featureType, properties, id } = feature2;
4143
- const layerName = import_lodash6.default.get(
4331
+ const layerName = import_lodash7.default.get(
4144
4332
  LAYER_FEATURE_TYPE_OBJ,
4145
4333
  featureType,
4146
4334
  featureType
4147
4335
  );
4148
4336
  const layer = this.map.getLayer(layerName);
4149
4337
  let geometry;
4150
- const category = import_lodash6.default.get(feature2, "properties.category");
4151
- const extrudeConfig = import_lodash6.default.get(this.#mapConfig, "extrude");
4152
- const textMarkerType = import_lodash6.default.get(
4338
+ const category = import_lodash7.default.get(feature2, "properties.category");
4339
+ const extrudeConfig = import_lodash7.default.get(this.#mapConfig, "extrude");
4340
+ const textMarkerType = import_lodash7.default.get(
4153
4341
  this.#mapConfig,
4154
4342
  "text_marker_type",
4155
4343
  "ui-marker"
@@ -4169,53 +4357,6 @@ var IndoorMap = class extends EventTarget {
4169
4357
  });
4170
4358
  break;
4171
4359
  }
4172
- case "level": {
4173
- const extrudedLevel = createExtrudedLevel(
4174
- feature2,
4175
- this.threeLayer,
4176
- featureExtrudeConfig
4177
- );
4178
- if (extrudedLevel) {
4179
- extrudedLevel.on("click", this.handleClickElement);
4180
- object3ds.push(extrudedLevel);
4181
- } else {
4182
- geometry = createLevel(feature2).addTo(layer);
4183
- }
4184
- break;
4185
- }
4186
- case "unit": {
4187
- const models = await create3DUnit(feature2, this.threeLayer);
4188
- models.forEach((model) => {
4189
- model.on("click", this.handleClickElement);
4190
- object3ds.push(model);
4191
- this.#glbObjects.push(model);
4192
- });
4193
- const locatedLevel = feature2?.properties?.level;
4194
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4195
- extrudeConfig,
4196
- locatedLevel
4197
- );
4198
- const levelHeight = levelExtrudeConfig?.height ?? 0;
4199
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4200
- const hasAddedModel3d = models?.length > 0;
4201
- if (hasAddedModel3d || !featureExtrudeConfig) {
4202
- geometry = createUnit(feature2)?.on("click", this.handleClickElement).addTo(layer);
4203
- } else {
4204
- const extrudedUnit = createExtrudedUnit(
4205
- feature2,
4206
- this.threeLayer,
4207
- option
4208
- );
4209
- extrudedUnit.on("click", this.handleClickElement);
4210
- extrudedUnit.on("touchstart", (e) => {
4211
- this.#touchStartTarget = e.target;
4212
- this.#touchStartPoint = e.containerPoint;
4213
- this.map.on("touchend", this.handleMapTouchEnd);
4214
- });
4215
- object3ds.push(extrudedUnit);
4216
- }
4217
- break;
4218
- }
4219
4360
  case "amenity": {
4220
4361
  if (feature2.properties.is_featured) {
4221
4362
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4238,7 +4379,7 @@ var IndoorMap = class extends EventTarget {
4238
4379
  case "opening": {
4239
4380
  switch (category) {
4240
4381
  case "emergencyexit":
4241
- const { geometry: geometry2 } = (0, import_center3.default)(feature2);
4382
+ const { geometry: geometry2 } = (0, import_center4.default)(feature2);
4242
4383
  const markerFeature = {
4243
4384
  ...feature2,
4244
4385
  geometry: geometry2
@@ -4306,7 +4447,7 @@ var IndoorMap = class extends EventTarget {
4306
4447
  textMarkerType,
4307
4448
  extrudeConfig
4308
4449
  });
4309
- if (occupantMarker instanceof import_maptalks8.ui.UIMarker) {
4450
+ if (occupantMarker instanceof import_maptalks_gl.ui.UIMarker) {
4310
4451
  occupantMarker.addTo(this.map);
4311
4452
  } else {
4312
4453
  occupantMarker?.on("click", this.handleClickElement);
@@ -4343,7 +4484,7 @@ var IndoorMap = class extends EventTarget {
4343
4484
  extrudeConfig,
4344
4485
  locatedLevel
4345
4486
  );
4346
- const levelHeight = import_lodash6.default.get(levelExtrudeConfig, "height", 0);
4487
+ const levelHeight = import_lodash7.default.get(levelExtrudeConfig, "height", 0);
4347
4488
  const option = { ...featureExtrudeConfig, altitude: levelHeight };
4348
4489
  const extrudedFixture = createExtrudedUnit(
4349
4490
  feature2,
@@ -4354,34 +4495,6 @@ var IndoorMap = class extends EventTarget {
4354
4495
  }
4355
4496
  break;
4356
4497
  }
4357
- case "kiosk": {
4358
- const models = await create3DKiosk(feature2, this.threeLayer);
4359
- models.forEach((model) => {
4360
- model.on("click", this.handleClickElement);
4361
- object3ds.push(model);
4362
- this.#glbObjects.push(model);
4363
- });
4364
- const locatedLevel = feature2?.properties?.level;
4365
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4366
- extrudeConfig,
4367
- locatedLevel
4368
- );
4369
- const levelHeight = import_lodash6.default.get(levelExtrudeConfig, "height", 0);
4370
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4371
- const hasAddedModel3d = models?.length > 0;
4372
- if (hasAddedModel3d || !featureExtrudeConfig) {
4373
- geometry = createKiosk(feature2)?.on("click", this.handleClickElement).addTo(layer);
4374
- } else {
4375
- const extrudedKiosk = createExtrudedKiosk(
4376
- feature2,
4377
- this.threeLayer,
4378
- option
4379
- );
4380
- extrudedKiosk.on("click", this.handleClickElement);
4381
- object3ds.push(extrudedKiosk);
4382
- }
4383
- break;
4384
- }
4385
4498
  case "footprint": {
4386
4499
  const objects = await create3DFootprint(
4387
4500
  feature2,
@@ -4392,7 +4505,7 @@ var IndoorMap = class extends EventTarget {
4392
4505
  object.on("click", () => {
4393
4506
  const {
4394
4507
  geometry: { coordinates }
4395
- } = (0, import_center3.default)(feature2);
4508
+ } = (0, import_center4.default)(feature2);
4396
4509
  this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4397
4510
  });
4398
4511
  object3ds.push(object);
@@ -4460,7 +4573,6 @@ var IndoorMap = class extends EventTarget {
4460
4573
  );
4461
4574
  }
4462
4575
  });
4463
- this.render();
4464
4576
  this.#elements = elements;
4465
4577
  this.#elementsLoaded = true;
4466
4578
  this.#featuresInitted = true;
@@ -4471,39 +4583,6 @@ var IndoorMap = class extends EventTarget {
4471
4583
  const layer = this.map.getLayer(layerName);
4472
4584
  if (layer) layer.clear();
4473
4585
  };
4474
- #showGeometriesByOrdinal(ordinal) {
4475
- (0, import_lodash6.default)(this.#elements).filter((element) => !!import_lodash6.default.get(element, "geometry")).forEach(({ featureType, geometry, properties }) => {
4476
- const show = ordinal === null || properties?.ordinal === ordinal || featureType === "venue";
4477
- const layerName = import_lodash6.default.get(
4478
- LAYER_FEATURE_TYPE_OBJ,
4479
- featureType,
4480
- featureType
4481
- );
4482
- const layer = this.map.getLayer(layerName);
4483
- if (!layer) return;
4484
- if (geometry instanceof import_maptalks8.ui.UIMarker)
4485
- return show ? geometry?.addTo(this.map) : geometry.remove();
4486
- show ? layer.addGeometry(geometry) : layer.removeGeometry(geometry);
4487
- if (geometry._animPlayer instanceof import_maptalks8.animation.Player) {
4488
- const animPlayer = geometry?._animPlayer;
4489
- show ? animPlayer.play() : animPlayer.cancel();
4490
- }
4491
- });
4492
- }
4493
- #showThreeObjectByOrdinal = (ordinal) => {
4494
- const threeLayer = this.threeLayer;
4495
- const objectsToAdd = [];
4496
- const objects = this.#object3ds || [];
4497
- objects?.forEach((baseObject) => {
4498
- const objectOrdinal = import_lodash6.default.get(baseObject, "properties.ordinal");
4499
- const featureType = import_lodash6.default.get(baseObject, "properties.feature_type");
4500
- const isAdd = import_lodash6.default.get(baseObject, "isAdd");
4501
- const show = Boolean(objectOrdinal === ordinal) || ALWAYS_VISIBLE_FEATURE_TYPES.includes(featureType);
4502
- if (show) return objectsToAdd.push(baseObject);
4503
- if (isAdd) return threeLayer.removeMesh(baseObject);
4504
- });
4505
- threeLayer.addMesh(objectsToAdd);
4506
- };
4507
4586
  /**
4508
4587
  * Change Level & animate to path / geometry / view / etc.
4509
4588
  * ================================== */
@@ -4511,10 +4590,10 @@ var IndoorMap = class extends EventTarget {
4511
4590
  this.rendererManager.changeLevelByOrdinal(ordinal);
4512
4591
  }
4513
4592
  getFeatureExtent = (feature2, scaleFactor = 1) => {
4514
- const [minX, minY, maxX, maxY] = turf_bbox_default(
4515
- (0, import_transform_scale.default)((0, import_bbox_polygon.default)(turf_bbox_default(feature2)), scaleFactor)
4593
+ const [minX, minY, maxX, maxY] = index_default(
4594
+ (0, import_transform_scale.default)((0, import_bbox_polygon.default)(index_default(feature2)), scaleFactor)
4516
4595
  );
4517
- return new import_maptalks8.Extent(minX, minY, maxX, maxY);
4596
+ return new import_maptalks_gl.Extent(minX, minY, maxX, maxY);
4518
4597
  };
4519
4598
  getExtentCenter = (extent) => {
4520
4599
  return extent.getCenter();
@@ -4548,19 +4627,19 @@ var IndoorMap = class extends EventTarget {
4548
4627
  };
4549
4628
  getLineStringBearing = (feature2) => {
4550
4629
  const { geometry } = feature2;
4551
- const path = new import_maptalks8.LineString(geometry.coordinates);
4630
+ const path = new import_maptalks_gl.LineString(geometry.coordinates);
4552
4631
  return getBearingBetweenPoints(
4553
4632
  path.getFirstCoordinate(),
4554
4633
  path.getLastCoordinate()
4555
4634
  );
4556
4635
  };
4557
4636
  //map animation
4558
- addAnimations(animation2) {
4559
- this.#animationsToRun.push(animation2);
4637
+ addAnimations(animation) {
4638
+ this.#animationsToRun.push(animation);
4560
4639
  }
4561
4640
  removeAnimationById(id) {
4562
4641
  this.#animationsToRun = this.#animationsToRun.filter(
4563
- (animation2) => animation2.id !== id
4642
+ (animation) => animation.id !== id
4564
4643
  );
4565
4644
  }
4566
4645
  clearAnimations() {
@@ -4571,21 +4650,21 @@ var IndoorMap = class extends EventTarget {
4571
4650
  * ========================================= */
4572
4651
  // TODO: To consider if we should use setter `set hilightElementIds` instead?
4573
4652
  setHighlightElementIds(targetElementIds, options = {}) {
4574
- const highlight3DOptions = import_lodash6.default.merge(
4653
+ const highlight3DOptions = import_lodash7.default.merge(
4575
4654
  {},
4576
4655
  DEFAULT_HIGHLIGHT_OPTIONS,
4577
- import_lodash6.default.get(options, "highlight3DOptions", {})
4656
+ import_lodash7.default.get(options, "highlight3DOptions", {})
4578
4657
  );
4579
- const highlight2DOptions = import_lodash6.default.merge(
4658
+ const highlight2DOptions = import_lodash7.default.merge(
4580
4659
  {},
4581
4660
  DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4582
- import_lodash6.default.get(options, "highlight2DOptions", {})
4661
+ import_lodash7.default.get(options, "highlight2DOptions", {})
4583
4662
  );
4584
4663
  this.setHighlightedObject(targetElementIds, highlight3DOptions);
4585
4664
  return this.setHighlight2DElementIds(targetElementIds, highlight2DOptions);
4586
4665
  }
4587
4666
  setHighlight2DElementIds(targetElementIds, options = {}) {
4588
- const { defaultMarker, symbolSet } = import_lodash6.default.merge(
4667
+ const { defaultMarker, symbolSet } = import_lodash7.default.merge(
4589
4668
  {},
4590
4669
  DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4591
4670
  options
@@ -4597,7 +4676,7 @@ var IndoorMap = class extends EventTarget {
4597
4676
  getHilighPolygonalSymbol,
4598
4677
  getHighlightMarkerSymbol
4599
4678
  } = this.#styler;
4600
- const extrudeConfig = import_lodash6.default.get(this.#mapConfig, "extrude");
4679
+ const extrudeConfig = import_lodash7.default.get(this.#mapConfig, "extrude");
4601
4680
  const elementToHilights = targetElementIds.map(
4602
4681
  (elemId) => this.#elements[elemId] || this.#elements[`${LAST_USER_LOCATION_ELEMENT_ID_PREFIX}${elemId}`]
4603
4682
  ).filter((elem) => elem);
@@ -4608,7 +4687,7 @@ var IndoorMap = class extends EventTarget {
4608
4687
  if (!hilightLayer) return;
4609
4688
  const defaultSymbol = getHilighPolygonalSymbol(geometry.type);
4610
4689
  const definedSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4611
- const symbol = import_lodash6.default.isEmpty(definedSymbol) ? defaultSymbol : definedSymbol;
4690
+ const symbol = import_lodash7.default.isEmpty(definedSymbol) ? defaultSymbol : definedSymbol;
4612
4691
  switch (geometry.type) {
4613
4692
  case "MultiPolygon":
4614
4693
  case "Polygon": {
@@ -4663,9 +4742,9 @@ var IndoorMap = class extends EventTarget {
4663
4742
  }
4664
4743
  clearHighlightElements() {
4665
4744
  this.#clearAllElementOnLayerByName(HIGHLIGHT_LAYER_NAME);
4666
- (0, import_lodash6.default)(this.#highlightElementIds).map((elemId) => this.#elements[elemId]?.geometry).compact().forEach((geometry) => {
4667
- if (geometry instanceof import_maptalks8.ui.UIMarker) return;
4668
- if (geometry instanceof import_maptalks8.Marker) {
4745
+ (0, import_lodash7.default)(this.#highlightElementIds).map((elemId) => this.#elements[elemId]?.geometry).compact().forEach((geometry) => {
4746
+ if (geometry instanceof import_maptalks_gl.ui.UIMarker) return;
4747
+ if (geometry instanceof import_maptalks_gl.Marker) {
4669
4748
  this.showGeometryByElementId(geometry.properties.id);
4670
4749
  return;
4671
4750
  }
@@ -4681,7 +4760,7 @@ var IndoorMap = class extends EventTarget {
4681
4760
  this.#highlightElementIds = [];
4682
4761
  }
4683
4762
  setHighlightedObject(targetObjectIds, options = {}) {
4684
- const { symbolSet } = import_lodash6.default.merge({}, DEFAULT_HIGHLIGHT_OPTIONS, options);
4763
+ const { symbolSet } = import_lodash7.default.merge({}, DEFAULT_HIGHLIGHT_OPTIONS, options);
4685
4764
  const {
4686
4765
  getElementSymbol,
4687
4766
  getHilighPolygonalSymbol,
@@ -4693,8 +4772,8 @@ var IndoorMap = class extends EventTarget {
4693
4772
  );
4694
4773
  const defaultSymbol = getHilighPolygonalSymbol("Polygon");
4695
4774
  const targetSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4696
- const { polygonFill: color } = import_lodash6.default.isEmpty(targetSymbol) ? defaultSymbol : targetSymbol;
4697
- const amenityHighlightMode = import_lodash6.default.get(
4775
+ const { polygonFill: color } = import_lodash7.default.isEmpty(targetSymbol) ? defaultSymbol : targetSymbol;
4776
+ const amenityHighlightMode = import_lodash7.default.get(
4698
4777
  this.#mapConfig,
4699
4778
  "amenity_highlight_mode",
4700
4779
  ""
@@ -4710,7 +4789,7 @@ var IndoorMap = class extends EventTarget {
4710
4789
  if (obj instanceof SpriteMarker) {
4711
4790
  if (amenityHighlightMode === "2DMarker") {
4712
4791
  const hilight2DLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4713
- const extrudeConfig = import_lodash6.default.get(this.#mapConfig, "extrude");
4792
+ const extrudeConfig = import_lodash7.default.get(this.#mapConfig, "extrude");
4714
4793
  obj.hide();
4715
4794
  const { properties: featureProperties } = obj;
4716
4795
  createHighlight2DAmenityMarkerFrom3DMarker(
@@ -4731,7 +4810,7 @@ var IndoorMap = class extends EventTarget {
4731
4810
  }
4732
4811
  clearHighlightObject() {
4733
4812
  this.#highlightObjectControllers.forEach((controller) => {
4734
- if (import_lodash6.default.isFunction(controller?.clear)) controller.clear();
4813
+ if (import_lodash7.default.isFunction(controller?.clear)) controller.clear();
4735
4814
  });
4736
4815
  this.#highlightObjectIds.forEach((objIds) => {
4737
4816
  const objects = this.threeLayer?.getBaseObjects();
@@ -4770,15 +4849,15 @@ var IndoorMap = class extends EventTarget {
4770
4849
  }
4771
4850
  }
4772
4851
  updateUserLocationSymbolByLocale(locale) {
4773
- const userLocationGeometry = import_lodash6.default.get(
4852
+ const userLocationGeometry = import_lodash7.default.get(
4774
4853
  this.#elements,
4775
4854
  `${USER_LOCATION_ELEMENT_ID}.geometry`
4776
4855
  );
4777
4856
  if (!userLocationGeometry) return;
4778
4857
  const currentSymbol = userLocationGeometry.getSymbol();
4779
4858
  const localeSymbolToUpdate = currentSymbol.map((symbol) => {
4780
- const localeSymbol = import_lodash6.default.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || import_lodash6.default.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
4781
- if (!import_lodash6.default.isPlainObject(localeSymbol)) return symbol;
4859
+ const localeSymbol = import_lodash7.default.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || import_lodash7.default.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
4860
+ if (!import_lodash7.default.isPlainObject(localeSymbol)) return symbol;
4782
4861
  return {
4783
4862
  ...symbol,
4784
4863
  ...localeSymbol
@@ -4852,14 +4931,14 @@ var IndoorMap = class extends EventTarget {
4852
4931
  * END of User Location
4853
4932
  ****************************/
4854
4933
  showGeometryByElementId = (elementId) => {
4855
- const geometry = import_lodash6.default.get(
4934
+ const geometry = import_lodash7.default.get(
4856
4935
  this.#elements,
4857
4936
  `${elementId}.geometry`
4858
4937
  );
4859
4938
  if (geometry) geometry.show();
4860
4939
  };
4861
4940
  hideGeometryByElementId = (elementId) => {
4862
- const geometry = import_lodash6.default.get(this.#elements, `${elementId}.geometry`);
4941
+ const geometry = import_lodash7.default.get(this.#elements, `${elementId}.geometry`);
4863
4942
  if (geometry) geometry.hide();
4864
4943
  };
4865
4944
  setSpriteMarkersOpacity = (opacity = 1) => {
@@ -4906,13 +4985,13 @@ var IndoorMap = class extends EventTarget {
4906
4985
  const line = lineStrings[i];
4907
4986
  const coords = line.geometry.coordinates;
4908
4987
  const prevLine = lineStrings[i - 1];
4909
- const firstCoord = import_lodash6.default.first(coords);
4988
+ const firstCoord = import_lodash7.default.first(coords);
4910
4989
  const isFirstLine = i === 0;
4911
4990
  if (isFirstLine) {
4912
4991
  accLine.push(...coords);
4913
4992
  continue;
4914
4993
  }
4915
- const prevLastCoord = import_lodash6.default.last(prevLine.geometry.coordinates);
4994
+ const prevLastCoord = import_lodash7.default.last(prevLine.geometry.coordinates);
4916
4995
  const isNearby = (0, import_distance.default)(point(firstCoord), point(prevLastCoord)) < distance;
4917
4996
  if (!isNearby) {
4918
4997
  const remainingLines = lineStrings.slice(i);
@@ -4933,8 +5012,8 @@ var IndoorMap = class extends EventTarget {
4933
5012
  create3DStepPath
4934
5013
  } = this.#styler;
4935
5014
  const routeMarkerLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4936
- const linesByOrdinal = (0, import_lodash6.default)(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
4937
- const joinedLines = (0, import_lodash6.default)(linesByOrdinal).reduce((acc, lines, key) => {
5015
+ const linesByOrdinal = (0, import_lodash7.default)(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5016
+ const joinedLines = (0, import_lodash7.default)(linesByOrdinal).reduce((acc, lines, key) => {
4938
5017
  const joined = this.combineNearbyLineStrings(lines, {
4939
5018
  properties: { ordinal: +key }
4940
5019
  });
@@ -4962,14 +5041,14 @@ var IndoorMap = class extends EventTarget {
4962
5041
  stepElement = createOriginMarker(stepGeometry).addTo(routeMarkerLayer);
4963
5042
  break;
4964
5043
  case "destination-marker":
4965
- const extrudeConfig = import_lodash6.default.get(this.#mapConfig, "extrude");
5044
+ const extrudeConfig = import_lodash7.default.get(this.#mapConfig, "extrude");
4966
5045
  if (destinationFeature.feature_type === "occupant") {
4967
- const stepId = import_lodash6.default.get(stepGeometry, "id");
5046
+ const stepId = import_lodash7.default.get(stepGeometry, "id");
4968
5047
  const normalizedDestinationFeature = {
4969
5048
  ...destinationFeature,
4970
5049
  id: stepId
4971
5050
  };
4972
- const logoUrl = import_lodash6.default.get(
5051
+ const logoUrl = import_lodash7.default.get(
4973
5052
  normalizedDestinationFeature,
4974
5053
  "properties.logo.url"
4975
5054
  );
@@ -5014,15 +5093,15 @@ var IndoorMap = class extends EventTarget {
5014
5093
  const routeMarkerLayer = this.map.getLayer(
5015
5094
  HIGHLIGHT_LAYER_NAME
5016
5095
  );
5017
- const originMarkerGeometry = import_lodash6.default.get(
5096
+ const originMarkerGeometry = import_lodash7.default.get(
5018
5097
  this.#elements,
5019
5098
  `${ORIGIN_MARKER_ID}.geometry`
5020
5099
  );
5021
- const destinationMarkerGeometry = import_lodash6.default.get(
5100
+ const destinationMarkerGeometry = import_lodash7.default.get(
5022
5101
  this.#elements,
5023
5102
  `${DESTINATION_MARKER_ID}.geometry`
5024
5103
  );
5025
- const geometriesToRemove = import_lodash6.default.compact([
5104
+ const geometriesToRemove = import_lodash7.default.compact([
5026
5105
  originMarkerGeometry,
5027
5106
  destinationMarkerGeometry
5028
5107
  ]);
@@ -5033,7 +5112,7 @@ var IndoorMap = class extends EventTarget {
5033
5112
  (obj) => !(obj instanceof NavigationPath)
5034
5113
  );
5035
5114
  const objects = this.#navigationGeometries || {};
5036
- import_lodash6.default.forEach(objects, (obj) => {
5115
+ import_lodash7.default.forEach(objects, (obj) => {
5037
5116
  if (!obj) return;
5038
5117
  this.#navigationGeometries[obj.properties.id] = null;
5039
5118
  obj.remove();
@@ -5072,10 +5151,10 @@ var IndoorMap = class extends EventTarget {
5072
5151
  zoom: map.getZoom()
5073
5152
  };
5074
5153
  const finalView = {
5075
- bearing: import_lodash6.default.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5076
- center: import_lodash6.default.isNil(targetView.center) ? map.getCenter() : targetView.center,
5077
- pitch: import_lodash6.default.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5078
- zoom: import_lodash6.default.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5154
+ bearing: import_lodash7.default.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5155
+ center: import_lodash7.default.isNil(targetView.center) ? map.getCenter() : targetView.center,
5156
+ pitch: import_lodash7.default.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5157
+ zoom: import_lodash7.default.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5079
5158
  };
5080
5159
  map.setView(finalView);
5081
5160
  const projectedTargetCenter = map.coordinateToContainerPoint(finalView.center).add(right / 2 - left / 2, bottom / 2 - top / 2);
@@ -5096,7 +5175,7 @@ var IndoorMap = class extends EventTarget {
5096
5175
  this.threeLayer.redraw();
5097
5176
  }
5098
5177
  if (this.threeLayer) {
5099
- const objectOpacity = import_lodash6.default.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5178
+ const objectOpacity = import_lodash7.default.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5100
5179
  this.#objects.forEach((object) => {
5101
5180
  object.getObject3d().traverse((child) => {
5102
5181
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5106,7 +5185,7 @@ var IndoorMap = class extends EventTarget {
5106
5185
  });
5107
5186
  if (this.#billboardObjects) {
5108
5187
  this.#billboardObjects.forEach((object) => {
5109
- const objectScale = import_lodash6.default.clamp(
5188
+ const objectScale = import_lodash7.default.clamp(
5110
5189
  20 - 1 * this.camera.getZoom(),
5111
5190
  1,
5112
5191
  1.05
@@ -5115,7 +5194,7 @@ var IndoorMap = class extends EventTarget {
5115
5194
  });
5116
5195
  }
5117
5196
  if (this.#isLayersFadingOnZoom) {
5118
- const layerOpacity = import_lodash6.default.clamp(1 - objectOpacity, 0, 1);
5197
+ const layerOpacity = import_lodash7.default.clamp(1 - objectOpacity, 0, 1);
5119
5198
  LAYERS.forEach((layerKey) => {
5120
5199
  const layer = this.map.getLayer(layerKey);
5121
5200
  if (layer) layer.setOpacity(layerOpacity);
@@ -5190,5 +5269,4 @@ var IndoorMap = class extends EventTarget {
5190
5269
  styledFeatureGenerator
5191
5270
  });
5192
5271
  //! Use outerHTML to return HTML string instead of element object to avoid DOM event warnings from Maptalks.js.
5193
- //! Prevent animating geometry from stopping after being removed and re-added to the layer.
5194
5272
  //# sourceMappingURL=index.js.map