venue-js 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,3 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
1
7
  // src/data/index.ts
2
8
  import { QueryObserver as QueryObserver2 } from "@tanstack/query-core";
3
9
 
@@ -75,7 +81,8 @@ var defaultFeatureQueryOptionsMap = {
75
81
  // refresh every 5 min
76
82
  },
77
83
  element: {},
78
- page: {}
84
+ page: {},
85
+ model3d: {}
79
86
  };
80
87
 
81
88
  // src/data/api/delivery-project.ts
@@ -91,6 +98,14 @@ async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAUL
91
98
  const items = await res.json();
92
99
  return items;
93
100
  }
101
+ case "model3d": {
102
+ const res = await fetch(
103
+ `${baseUrl}/delivery/projects/${projectId}/${featureType}.geojson?api-key=${apiKey}`
104
+ );
105
+ if (res.status !== 200) return [];
106
+ const items = await res.json();
107
+ return items.features;
108
+ }
94
109
  case "sponsored-content": {
95
110
  const res = await fetch(
96
111
  `${baseUrl}/delivery/projects/${projectId}/sponsored-content.json?api-key=${apiKey}`
@@ -191,6 +206,115 @@ var safeFetchFeature = async (featureType, params) => {
191
206
  }
192
207
  };
193
208
 
209
+ // src/data/utils/geometry-validator.ts
210
+ var isValidCoordinate = (point2) => {
211
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
212
+ };
213
+ function isValidLinearRingCoordinates(ring) {
214
+ if (ring.length < 4) {
215
+ return false;
216
+ }
217
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
218
+ }
219
+ var isValidPolygonCoordinates = (polygon2) => {
220
+ if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
221
+ return isValidLinearRingCoordinates(polygon2);
222
+ }
223
+ if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
224
+ if (!isValidLinearRingCoordinates(polygon2[0])) {
225
+ return false;
226
+ }
227
+ for (let i = 1; i < polygon2.length; i++) {
228
+ if (!isValidLinearRingCoordinates(polygon2[i])) {
229
+ return false;
230
+ }
231
+ }
232
+ return true;
233
+ }
234
+ return false;
235
+ };
236
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
237
+ return multipolygon.every(isValidPolygonCoordinates);
238
+ };
239
+ var isValidLineStringCoordinates = (lineString2) => {
240
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
241
+ return false;
242
+ }
243
+ const firstPoint = lineString2[0];
244
+ const lastPoint = lineString2[lineString2.length - 1];
245
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
246
+ return false;
247
+ }
248
+ return lineString2.every(isValidCoordinate);
249
+ };
250
+ var isValidMultiPolygon = (geometry) => {
251
+ const { type, coordinates } = geometry;
252
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
253
+ };
254
+ var isValidPolygon = (geometry) => {
255
+ const { type, coordinates } = geometry;
256
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
257
+ };
258
+ var isValidLineString = (geometry) => {
259
+ const { type, coordinates } = geometry;
260
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
261
+ };
262
+ var isValidPoint = (geometry) => {
263
+ const { type, coordinates } = geometry;
264
+ return type === "Point" && isValidCoordinate(coordinates);
265
+ };
266
+
267
+ // src/data/utils/match-filters.ts
268
+ function isInFilter(filter) {
269
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
270
+ }
271
+ var someIntersect = (a, b) => a.some((v2) => b.includes(v2));
272
+ function matchFilter(value, filter) {
273
+ if (Array.isArray(value)) {
274
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
275
+ return value.includes(filter);
276
+ } else {
277
+ if (isInFilter(filter)) return filter.$in.includes(value);
278
+ return value === filter;
279
+ }
280
+ }
281
+ function matchFilters(item, filters) {
282
+ return Object.entries(filters).every(([key, filter]) => {
283
+ return matchFilter(item.properties[key], filter);
284
+ });
285
+ }
286
+
287
+ // src/data/utils/occupant-helper.ts
288
+ var occupant_helper_exports = {};
289
+ __export(occupant_helper_exports, {
290
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
291
+ getOccupantMainLocation: () => getOccupantMainLocation,
292
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
293
+ });
294
+ import { compact } from "lodash-es";
295
+ var getOccupantMainLocation = (occupant) => {
296
+ return occupant.properties.kiosk || occupant.properties.unit;
297
+ };
298
+ var getOccupantCorrelatedLocations = (occupant) => {
299
+ const allCorrelatedLocations = [
300
+ ...occupant.properties.units,
301
+ ...occupant.properties.kiosks
302
+ ];
303
+ return compact(allCorrelatedLocations);
304
+ };
305
+ var getOccupantMarkerLocations = (occupant, options) => {
306
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
307
+ const mainLocation = getOccupantMainLocation(occupant);
308
+ const mainLocationLevel = mainLocation?.properties?.level_id;
309
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
310
+ if (placementType === "ALL_LOCATIONS") {
311
+ return compact([mainLocation, ...allCorrelatedLocations]);
312
+ }
313
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
314
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
315
+ return compact([mainLocation, ...onePerLevelLocations]);
316
+ };
317
+
194
318
  // src/data/getDataClient.ts
195
319
  import {
196
320
  QueryClient,
@@ -349,8 +473,8 @@ var createPopulator = ({
349
473
  venue,
350
474
  promotions,
351
475
  privileges,
352
- kiosk,
353
- unit,
476
+ kiosk: kiosk ? await populateKiosk(kiosk) : null,
477
+ unit: unit ? await populateUnit(unit) : null,
354
478
  kiosks: await Promise.all(kiosks.map(populateKiosk)),
355
479
  units: await Promise.all(units.map(populateUnit))
356
480
  }
@@ -442,26 +566,6 @@ var createPopulator = ({
442
566
  };
443
567
  };
444
568
 
445
- // src/data/utils/match-filters.ts
446
- function isInFilter(filter) {
447
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
448
- }
449
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
450
- function matchFilter(value, filter) {
451
- if (Array.isArray(value)) {
452
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
453
- return value.includes(filter);
454
- } else {
455
- if (isInFilter(filter)) return filter.$in.includes(value);
456
- return value === filter;
457
- }
458
- }
459
- function matchFilters(item, filters) {
460
- return Object.entries(filters).every(([key, filter]) => {
461
- return matchFilter(item.properties[key], filter);
462
- });
463
- }
464
-
465
569
  // src/data/getDataClient.ts
466
570
  var getDataClient = (options) => {
467
571
  const observers = /* @__PURE__ */ new Map();
@@ -590,16 +694,16 @@ var getDataClient = (options) => {
590
694
 
591
695
  // src/IndoorMap/IndoorMap.ts
592
696
  import {
593
- ui as ui3,
594
697
  Map as Map2,
595
698
  TileLayer,
596
- Extent,
597
699
  LineString as LineString3,
598
- Marker as Marker2,
599
- Coordinate as Coordinate4
700
+ Coordinate as Coordinate4,
701
+ GroupGLLayer,
702
+ GLTFLayer
600
703
  } from "maptalks-gl";
601
- import TWEEN2 from "@tweenjs/tween.js";
602
- import _6 from "lodash";
704
+ import "@maptalks/transcoders.draco";
705
+ import TWEEN from "@tweenjs/tween.js";
706
+ import _5 from "lodash";
603
707
 
604
708
  // ../../node_modules/@turf/helpers/dist/esm/index.js
605
709
  var earthRadius = 63710088e-1;
@@ -651,6 +755,28 @@ function point(coordinates, properties, options = {}) {
651
755
  };
652
756
  return feature(geom, properties, options);
653
757
  }
758
+ function polygon(coordinates, properties, options = {}) {
759
+ for (const ring of coordinates) {
760
+ if (ring.length < 4) {
761
+ throw new Error(
762
+ "Each LinearRing of a Polygon must have 4 or more Positions."
763
+ );
764
+ }
765
+ if (ring[ring.length - 1].length !== ring[0].length) {
766
+ throw new Error("First and last Position are not equivalent.");
767
+ }
768
+ for (let j = 0; j < ring[ring.length - 1].length; j++) {
769
+ if (ring[ring.length - 1][j] !== ring[0][j]) {
770
+ throw new Error("First and last Position are not equivalent.");
771
+ }
772
+ }
773
+ }
774
+ const geom = {
775
+ type: "Polygon",
776
+ coordinates
777
+ };
778
+ return feature(geom, properties, options);
779
+ }
654
780
  function lineString(coordinates, properties, options = {}) {
655
781
  if (coordinates.length < 2) {
656
782
  throw new Error("coordinates must be an array of two or more positions");
@@ -672,6 +798,13 @@ function featureCollection(features, options = {}) {
672
798
  fc.features = features;
673
799
  return fc;
674
800
  }
801
+ function multiPoint(coordinates, properties, options = {}) {
802
+ const geom = {
803
+ type: "MultiPoint",
804
+ coordinates
805
+ };
806
+ return feature(geom, properties, options);
807
+ }
675
808
  function isNumber(num) {
676
809
  return !isNaN(num) && num !== null && !Array.isArray(num);
677
810
  }
@@ -679,133 +812,8 @@ function isNumber(num) {
679
812
  // src/IndoorMap/IndoorMap.ts
680
813
  import turfDistance from "@turf/distance";
681
814
  import turfCenter3 from "@turf/center";
682
-
683
- // ../../node_modules/@turf/meta/dist/esm/index.js
684
- function coordEach(geojson, callback, excludeWrapCoord) {
685
- if (geojson === null) return;
686
- var j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", stop = isFeatureCollection ? geojson.features.length : 1;
687
- for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
688
- geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
689
- isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
690
- stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
691
- for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
692
- var multiFeatureIndex = 0;
693
- var geometryIndex = 0;
694
- geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
695
- if (geometry === null) continue;
696
- coords = geometry.coordinates;
697
- var geomType = geometry.type;
698
- wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
699
- switch (geomType) {
700
- case null:
701
- break;
702
- case "Point":
703
- if (callback(
704
- coords,
705
- coordIndex,
706
- featureIndex,
707
- multiFeatureIndex,
708
- geometryIndex
709
- ) === false)
710
- return false;
711
- coordIndex++;
712
- multiFeatureIndex++;
713
- break;
714
- case "LineString":
715
- case "MultiPoint":
716
- for (j = 0; j < coords.length; j++) {
717
- if (callback(
718
- coords[j],
719
- coordIndex,
720
- featureIndex,
721
- multiFeatureIndex,
722
- geometryIndex
723
- ) === false)
724
- return false;
725
- coordIndex++;
726
- if (geomType === "MultiPoint") multiFeatureIndex++;
727
- }
728
- if (geomType === "LineString") multiFeatureIndex++;
729
- break;
730
- case "Polygon":
731
- case "MultiLineString":
732
- for (j = 0; j < coords.length; j++) {
733
- for (k = 0; k < coords[j].length - wrapShrink; k++) {
734
- if (callback(
735
- coords[j][k],
736
- coordIndex,
737
- featureIndex,
738
- multiFeatureIndex,
739
- geometryIndex
740
- ) === false)
741
- return false;
742
- coordIndex++;
743
- }
744
- if (geomType === "MultiLineString") multiFeatureIndex++;
745
- if (geomType === "Polygon") geometryIndex++;
746
- }
747
- if (geomType === "Polygon") multiFeatureIndex++;
748
- break;
749
- case "MultiPolygon":
750
- for (j = 0; j < coords.length; j++) {
751
- geometryIndex = 0;
752
- for (k = 0; k < coords[j].length; k++) {
753
- for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
754
- if (callback(
755
- coords[j][k][l],
756
- coordIndex,
757
- featureIndex,
758
- multiFeatureIndex,
759
- geometryIndex
760
- ) === false)
761
- return false;
762
- coordIndex++;
763
- }
764
- geometryIndex++;
765
- }
766
- multiFeatureIndex++;
767
- }
768
- break;
769
- case "GeometryCollection":
770
- for (j = 0; j < geometry.geometries.length; j++)
771
- if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
772
- return false;
773
- break;
774
- default:
775
- throw new Error("Unknown Geometry Type");
776
- }
777
- }
778
- }
779
- }
780
-
781
- // ../../node_modules/@turf/bbox/dist/esm/index.js
782
- function bbox(geojson, options = {}) {
783
- if (geojson.bbox != null && true !== options.recompute) {
784
- return geojson.bbox;
785
- }
786
- const result = [Infinity, Infinity, -Infinity, -Infinity];
787
- coordEach(geojson, (coord) => {
788
- if (result[0] > coord[0]) {
789
- result[0] = coord[0];
790
- }
791
- if (result[1] > coord[1]) {
792
- result[1] = coord[1];
793
- }
794
- if (result[2] < coord[0]) {
795
- result[2] = coord[0];
796
- }
797
- if (result[3] < coord[1]) {
798
- result[3] = coord[1];
799
- }
800
- });
801
- return result;
802
- }
803
- var index_default = bbox;
804
-
805
- // src/IndoorMap/IndoorMap.ts
806
- import scale from "@turf/transform-scale";
807
- import bboxPolygon from "@turf/bbox-polygon";
808
815
  import { PerspectiveCamera } from "three";
816
+ import { ThreeLayer as ThreeLayer5 } from "maptalks.three";
809
817
 
810
818
  // src/IndoorMap/constants.ts
811
819
  var defaultLayerOption = { enableAltitude: true };
@@ -823,7 +831,6 @@ var GEOLOCATION = "geolocation";
823
831
  var ORIGIN_MARKER = "origin-marker";
824
832
  var DESTINATION_MARKER = "destination-marker";
825
833
  var DECORATION = "decoration";
826
- var ALWAYS_VISIBLE_FEATURE_TYPES = [VENUE, FOOTPRINT];
827
834
  var BASE_LAYER_NAME = "base";
828
835
  var POI_MARKER_LAYER_NAME = "poi";
829
836
  var MARKER_LAYER_NAME = "marker";
@@ -835,13 +842,6 @@ var USER_LOCATION_ELEMENT_ID = "user_location";
835
842
  var LAST_USER_LOCATION_ELEMENT_ID_PREFIX = "last_user_location-";
836
843
  var LOCALE_SYMBOL_KEY = "locale_symbol";
837
844
  var DEFAULT_LOCALE = "en";
838
- var DEFAULT_HIGHLIGHT_OPTIONS = {
839
- symbolSet: null
840
- };
841
- var DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS = {
842
- symbolSet: null,
843
- defaultMarker: false
844
- };
845
845
  var LAYERS = [
846
846
  BASE_LAYER_NAME,
847
847
  POI_MARKER_LAYER_NAME,
@@ -905,11 +905,8 @@ import turfBuffer from "@turf/buffer";
905
905
  import {
906
906
  TextureLoader as TextureLoader2,
907
907
  SpriteMaterial as SpriteMaterial3,
908
- MeshLambertMaterial,
909
- AmbientLight,
910
- DirectionalLight
908
+ MeshLambertMaterial
911
909
  } from "three";
912
- import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
913
910
 
914
911
  // src/IndoorMap/object3d/Billboard.js
915
912
  import * as maptalks from "maptalks";
@@ -949,7 +946,7 @@ var Billboard = class extends BaseObject {
949
946
  this._initOptions(options);
950
947
  const {
951
948
  altitude = OPTIONS.altitude,
952
- scale: scale2 = OPTIONS.scale,
949
+ scale: scale3 = OPTIONS.scale,
953
950
  alphaTest = OPTIONS.alphaTest,
954
951
  legColor = OPTIONS.legColor,
955
952
  showLeg = OPTIONS.showLeg
@@ -983,8 +980,8 @@ var Billboard = class extends BaseObject {
983
980
  const sprite = new Sprite(material);
984
981
  sprite.material.sizeAttenuation = false;
985
982
  sprite.scale.set(
986
- scale2 * naturalWidth / divider,
987
- scale2 * naturalHeight / divider,
983
+ scale3 * naturalWidth / divider,
984
+ scale3 * naturalHeight / divider,
988
985
  1
989
986
  );
990
987
  this.getObject3d().add(sprite);
@@ -993,7 +990,7 @@ var Billboard = class extends BaseObject {
993
990
  const position = layer.coordinateToVector3(coordinate, z);
994
991
  _.set(this.properties, "default.position", position);
995
992
  _.set(this.properties, "default.altitude", altitude);
996
- _.set(this.properties, "default.scale", scale2);
993
+ _.set(this.properties, "default.scale", scale3);
997
994
  this.getObject3d().position.copy(position);
998
995
  }
999
996
  setLineHeight(altitude) {
@@ -1006,319 +1003,25 @@ var Billboard = class extends BaseObject {
1006
1003
  }
1007
1004
  };
1008
1005
 
1009
- // src/IndoorMap/object3d/GroundLabel.ts
1010
- import * as maptalks2 from "maptalks";
1006
+ // src/IndoorMap/object3d/SpriteMarker.ts
1011
1007
  import { BaseObject as BaseObject2 } from "maptalks.three";
1012
- import {
1013
- Texture,
1014
- MeshPhongMaterial,
1015
- PlaneGeometry
1016
- } from "three";
1017
- import { largestRect } from "d3plus-shape";
1018
- import { max, merge, isNumber as isNumber2, isArray, range } from "lodash-es";
1019
- var OPTIONS2 = {
1020
- // Allowing click through and prevent interaction
1021
- interactive: false,
1022
- altitude: 0
1023
- };
1024
- var defaultFlatLabelOptions = {
1025
- fontSize: 14,
1026
- fontFamily: "Manrope",
1027
- fontWeight: 600,
1028
- margin: 0,
1029
- scaleMin: 0.5,
1030
- lineHeight: 1.05,
1031
- scaleStep: 0.05,
1032
- textAlign: "center",
1033
- textBaseline: "middle",
1034
- fillStyle: "#000"
1008
+ import { Sprite as Sprite2, SpriteMaterial as SpriteMaterial2 } from "three";
1009
+ import _2 from "lodash";
1010
+ var DEFAULT_SCALE = 0.05;
1011
+ var DEFAULT_ALTITUDE = 0;
1012
+ var DEFAULT_ALPHATEST = 0.3;
1013
+ var DEFAULT_OPTIONS = {
1014
+ scale: DEFAULT_SCALE,
1015
+ altitude: DEFAULT_ALTITUDE,
1016
+ alphaTest: DEFAULT_ALPHATEST,
1017
+ highlight: {
1018
+ options: {
1019
+ scale: DEFAULT_SCALE * 1.25
1020
+ },
1021
+ material: null
1022
+ }
1035
1023
  };
1036
- var defaultRectAngleToCalc = range(-90, 92, 2);
1037
- var getMaterial = (text, flatLabelOptions) => {
1038
- const options = merge({}, defaultFlatLabelOptions, flatLabelOptions);
1039
- const {
1040
- fontSize: initialFontSize,
1041
- fontFamily,
1042
- fontWeight,
1043
- margin,
1044
- scaleMin,
1045
- scaleStep,
1046
- fillStyle,
1047
- lineHeight,
1048
- textAlign,
1049
- strokeStyle,
1050
- lineWidth,
1051
- textBaseline
1052
- } = options;
1053
- const pixelMultiplier = 4;
1054
- const SIZE = 100 * pixelMultiplier;
1055
- const fontSize = initialFontSize * (pixelMultiplier * 1.25);
1056
- const canvas = document.createElement("canvas");
1057
- canvas.width = canvas.height = SIZE;
1058
- const ctx = canvas.getContext("2d");
1059
- ctx.font = `${fontWeight} ${fontSize}px "${fontFamily}", Arial`;
1060
- ctx.textAlign = textAlign;
1061
- ctx.textBaseline = textBaseline;
1062
- ctx.fillStyle = fillStyle;
1063
- ctx.strokeStyle = strokeStyle;
1064
- ctx.lineWidth = lineWidth;
1065
- const wrapText = (ctx2, text2, maxWidth) => {
1066
- const words = text2.trim().split(/\s+/);
1067
- if (words.length <= 1) return [text2];
1068
- const lines = [];
1069
- const MAX_LINES = 3;
1070
- let currentLine = words[0];
1071
- for (let i = 1; i < words.length; i++) {
1072
- const lineToMeasure = currentLine + " " + words[i];
1073
- if (ctx2.measureText(lineToMeasure).width > maxWidth) {
1074
- lines.push(currentLine);
1075
- currentLine = words[i];
1076
- } else {
1077
- currentLine = lineToMeasure;
1078
- }
1079
- }
1080
- lines.push(currentLine);
1081
- return lines.slice(0, MAX_LINES);
1082
- };
1083
- const hasManualBreaks = text.includes("\n");
1084
- let texts;
1085
- if (hasManualBreaks) {
1086
- texts = text.split(/\n/g);
1087
- } else {
1088
- const maxWidth = SIZE - 2 * margin;
1089
- texts = wrapText(ctx, text, maxWidth);
1090
- }
1091
- let textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
1092
- let scale2 = 1;
1093
- while (scale2 > 0 && textWidth + 2 * margin > SIZE) {
1094
- scale2 -= scaleStep;
1095
- ctx.font = `${fontWeight} ${scale2 * fontSize}px "${fontFamily}", Arial`;
1096
- textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
1097
- }
1098
- const center2 = { x: 0.5 * SIZE, y: 0.5 * SIZE };
1099
- if (scale2 > scaleMin) {
1100
- const totalHeight = texts.length * (fontSize * scale2 * lineHeight);
1101
- const startY = center2.y - totalHeight / 2 + fontSize * scale2 * lineHeight * 0.5;
1102
- texts.forEach((text2, index) => {
1103
- const yOffset = startY + index * (fontSize * scale2 * lineHeight);
1104
- if (strokeStyle && lineWidth) {
1105
- ctx.strokeText(text2, center2.x, yOffset);
1106
- }
1107
- ctx.fillText(text2, center2.x, yOffset);
1108
- });
1109
- }
1110
- const texture = new Texture(canvas);
1111
- texture.needsUpdate = true;
1112
- const material = new MeshPhongMaterial({
1113
- map: texture,
1114
- transparent: true,
1115
- // @ref: https://threejs.org/docs/#api/en/materials/Material.alphaTest
1116
- alphaTest: 0.3
1117
- });
1118
- return material;
1119
- };
1120
- var GroundLabel = class extends BaseObject2 {
1121
- #angle = 0;
1122
- #bearing = 0;
1123
- #text = "";
1124
- #offsetX = 0;
1125
- #offsetY = 0;
1126
- #originalPosition = null;
1127
- #layer = null;
1128
- constructor(bound, options, layer) {
1129
- options = maptalks2.Util.extend({}, OPTIONS2, options, {
1130
- layer,
1131
- coordinate: bound
1132
- });
1133
- const {
1134
- altitude,
1135
- text,
1136
- fontSize,
1137
- fillStyle,
1138
- textAlign,
1139
- fontFamily,
1140
- textBaseline,
1141
- strokeStyle,
1142
- lineWidth,
1143
- angle = defaultRectAngleToCalc,
1144
- maxFontScale,
1145
- offsetX = 0,
1146
- offsetY = 0,
1147
- ...properties
1148
- } = options;
1149
- super();
1150
- this._initOptions(options);
1151
- this.properties = properties;
1152
- this.#offsetX = offsetX;
1153
- this.#offsetY = offsetY;
1154
- this.#layer = layer;
1155
- const material = getMaterial(text, {
1156
- fillStyle,
1157
- fontSize,
1158
- textAlign,
1159
- textBaseline,
1160
- fontFamily,
1161
- strokeStyle,
1162
- lineWidth
1163
- });
1164
- const rectAngles = isArray(angle) ? angle : [angle];
1165
- material.needsUpdate = true;
1166
- const rect = largestRect(bound, {
1167
- cache: true,
1168
- /**
1169
- * Black magic here:
1170
- * For some reason if we allow angle -90 or 90, some polygon will use that angle even if it's wrong angle to use.
1171
- * So we remove -90 and 90 from choices, and use -85 & 85 instead.
1172
- */
1173
- angle: rectAngles
1174
- });
1175
- const { cx, cy, width, angle: calculatedAngle } = rect;
1176
- this.#text = text;
1177
- this.#angle = calculatedAngle;
1178
- const geometry = new PlaneGeometry(1, 1);
1179
- this._createMesh(geometry, material);
1180
- const z = layer.altitudeToVector3(altitude, altitude).x;
1181
- const basePosition = layer.coordinateToVector3({ x: cx, y: cy }, z);
1182
- this.#originalPosition = basePosition.clone();
1183
- const finalPosition = this.#calculateFinalPosition(basePosition);
1184
- const scale2 = width / 6456122659e-13;
1185
- const finalScale = maxFontScale && scale2 > maxFontScale ? maxFontScale : scale2;
1186
- this.getObject3d().scale.set(finalScale, finalScale, finalScale);
1187
- this.getObject3d().position.copy(finalPosition);
1188
- this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
1189
- }
1190
- #calculateFinalPosition(basePosition) {
1191
- if (this.#offsetX === 0 && this.#offsetY === 0) {
1192
- return basePosition;
1193
- }
1194
- const offsetCoordinate = {
1195
- x: this.#offsetX,
1196
- y: this.#offsetY
1197
- };
1198
- const z = this.#layer.altitudeToVector3(0, 0).x;
1199
- const offsetVector = this.#layer.coordinateToVector3(offsetCoordinate, z);
1200
- const zeroVector = this.#layer.coordinateToVector3({ x: 0, y: 0 }, z);
1201
- const worldOffsetX = offsetVector.x - zeroVector.x;
1202
- const worldOffsetY = offsetVector.y - zeroVector.y;
1203
- return {
1204
- x: basePosition.x + worldOffsetX,
1205
- y: basePosition.y + worldOffsetY,
1206
- z: basePosition.z
1207
- };
1208
- }
1209
- #updatePosition() {
1210
- if (this.#originalPosition && this.#layer) {
1211
- const finalPosition = this.#calculateFinalPosition(this.#originalPosition);
1212
- this.getObject3d().position.copy(finalPosition);
1213
- }
1214
- }
1215
- set bearing(value) {
1216
- this.#bearing = value;
1217
- const degree = this.#angle + this.#bearing;
1218
- const angle = degree > 90 || degree < -90 ? this.#angle + 180 : this.#angle;
1219
- this.getObject3d().rotation.z = Math.PI / 180 * angle;
1220
- }
1221
- get angle() {
1222
- return this.#angle;
1223
- }
1224
- get currentAngle() {
1225
- return this.#angle;
1226
- }
1227
- get text() {
1228
- return this.#text;
1229
- }
1230
- get offsetX() {
1231
- return this.#offsetX;
1232
- }
1233
- get offsetY() {
1234
- return this.#offsetY;
1235
- }
1236
- get offset() {
1237
- return { x: this.#offsetX, y: this.#offsetY };
1238
- }
1239
- set offsetX(value) {
1240
- if (isNumber2(value)) {
1241
- this.#offsetX = value;
1242
- this.#updatePosition();
1243
- }
1244
- }
1245
- set offsetY(value) {
1246
- if (isNumber2(value)) {
1247
- this.#offsetY = value;
1248
- this.#updatePosition();
1249
- }
1250
- }
1251
- set angle(newAngle) {
1252
- if (isNumber2(newAngle)) {
1253
- this.#angle = newAngle;
1254
- this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
1255
- }
1256
- }
1257
- setOffset(offsetX, offsetY) {
1258
- if (isNumber2(offsetX) && isNumber2(offsetY)) {
1259
- this.#offsetX = offsetX;
1260
- this.#offsetY = offsetY;
1261
- this.#updatePosition();
1262
- }
1263
- }
1264
- addOffset(deltaX, deltaY) {
1265
- if (isNumber2(deltaX) && isNumber2(deltaY)) {
1266
- this.#offsetX += deltaX;
1267
- this.#offsetY += deltaY;
1268
- this.#updatePosition();
1269
- }
1270
- }
1271
- resetOffset() {
1272
- this.#offsetX = 0;
1273
- this.#offsetY = 0;
1274
- this.#updatePosition();
1275
- }
1276
- moveToPosition(targetX, targetY) {
1277
- if (this.#originalPosition && this.#layer) {
1278
- const currentCenter = this.#layer.vector3ToCoordinate(
1279
- this.#originalPosition
1280
- );
1281
- this.#offsetX = targetX - currentCenter.x;
1282
- this.#offsetY = targetY - currentCenter.y;
1283
- this.#updatePosition();
1284
- }
1285
- }
1286
- updateText(newText, options = {}) {
1287
- this.#text = newText;
1288
- const materialOptions = {
1289
- fillStyle: options.fillStyle || this.properties.fillStyle,
1290
- fontSize: options.fontSize || this.properties.fontSize,
1291
- textAlign: options.textAlign || this.properties.textAlign,
1292
- textBaseline: options.textBaseline || this.properties.textBaseline,
1293
- fontFamily: options.fontFamily || this.properties.fontFamily,
1294
- strokeStyle: options.strokeStyle || this.properties.strokeStyle,
1295
- lineWidth: options.lineWidth || this.properties.lineWidth
1296
- };
1297
- const newMaterial = getMaterial(newText, materialOptions);
1298
- this.getObject3d().material = newMaterial;
1299
- newMaterial.needsUpdate = true;
1300
- }
1301
- };
1302
-
1303
- // src/IndoorMap/object3d/SpriteMarker.ts
1304
- import { BaseObject as BaseObject3 } from "maptalks.three";
1305
- import { Sprite as Sprite2, SpriteMaterial as SpriteMaterial2 } from "three";
1306
- import _2 from "lodash";
1307
- var DEFAULT_SCALE = 0.05;
1308
- var DEFAULT_ALTITUDE = 0;
1309
- var DEFAULT_ALPHATEST = 0.3;
1310
- var DEFAULT_OPTIONS = {
1311
- scale: DEFAULT_SCALE,
1312
- altitude: DEFAULT_ALTITUDE,
1313
- alphaTest: DEFAULT_ALPHATEST,
1314
- highlight: {
1315
- options: {
1316
- scale: DEFAULT_SCALE * 1.25
1317
- },
1318
- material: null
1319
- }
1320
- };
1321
- var SpriteMarker = class extends BaseObject3 {
1024
+ var SpriteMarker = class extends BaseObject2 {
1322
1025
  #default = null;
1323
1026
  #highlight = null;
1324
1027
  constructor(coordinate, options, material, layer, properties) {
@@ -1327,18 +1030,18 @@ var SpriteMarker = class extends BaseObject3 {
1327
1030
  this._createGroup();
1328
1031
  const {
1329
1032
  altitude = DEFAULT_OPTIONS.altitude,
1330
- scale: scale2 = DEFAULT_OPTIONS.scale,
1033
+ scale: scale3 = DEFAULT_OPTIONS.scale,
1331
1034
  highlight = DEFAULT_OPTIONS.highlight,
1332
1035
  alphaTest = DEFAULT_OPTIONS.alphaTest
1333
1036
  } = options;
1334
1037
  this.properties = { ...properties };
1335
1038
  const modifiedAltitude = altitude + 2;
1336
- this.#default = { options: { scale: scale2, altitude: modifiedAltitude }, material };
1039
+ this.#default = { options: { scale: scale3, altitude: modifiedAltitude }, material };
1337
1040
  this.#highlight = _2.merge({}, DEFAULT_OPTIONS.highlight, highlight);
1338
1041
  if (material && material instanceof SpriteMaterial2)
1339
1042
  material.alphaTest = alphaTest;
1340
1043
  const sprite = new Sprite2(material);
1341
- sprite.scale.set(scale2, scale2, scale2);
1044
+ sprite.scale.set(scale3, scale3, scale3);
1342
1045
  const obj3d = this.getObject3d();
1343
1046
  obj3d.add(sprite);
1344
1047
  const z = layer.altitudeToVector3(modifiedAltitude, modifiedAltitude).x;
@@ -1383,10 +1086,10 @@ var SpriteMarker = class extends BaseObject3 {
1383
1086
  };
1384
1087
 
1385
1088
  // src/IndoorMap/object3d/NavigationPath.ts
1386
- import * as maptalks3 from "maptalks";
1387
- import { BaseObject as BaseObject4 } from "maptalks.three";
1089
+ import * as maptalks2 from "maptalks";
1090
+ import { BaseObject as BaseObject3 } from "maptalks.three";
1388
1091
  import { MeshBasicMaterial, ShaderMaterial, Color } from "three";
1389
- var OPTIONS3 = {
1092
+ var OPTIONS2 = {
1390
1093
  altitude: 0
1391
1094
  };
1392
1095
  var DEFAULT_LINE_OPTION = {
@@ -1398,14 +1101,14 @@ var DEFAULT_LINE_EFFECT_OPTION = {
1398
1101
  opacity: 1
1399
1102
  };
1400
1103
  var ENABLE_ANIMATED_PATH = true;
1401
- var NavigationPath = class extends BaseObject4 {
1104
+ var NavigationPath = class extends BaseObject3 {
1402
1105
  constructor(feature2, layer, properties, options, lineOptions = DEFAULT_LINE_OPTION, outlineOption = DEFAULT_LINE_EFFECT_OPTION) {
1403
- options = maptalks3.Util.extend({}, OPTIONS3, options, {
1106
+ options = maptalks2.Util.extend({}, OPTIONS2, options, {
1404
1107
  layer
1405
1108
  });
1406
1109
  super();
1407
1110
  this._initOptions(options);
1408
- const { altitude = OPTIONS3.altitude } = options;
1111
+ const { altitude = OPTIONS2.altitude } = options;
1409
1112
  this.properties = { ...properties };
1410
1113
  this._createGroup();
1411
1114
  const { color: lineColor, opacity: lineOpacity } = lineOptions || DEFAULT_LINE_OPTION;
@@ -1445,7 +1148,7 @@ var NavigationPath = class extends BaseObject4 {
1445
1148
  }
1446
1149
  `
1447
1150
  });
1448
- const pathGeometry = maptalks3.GeoJSON.toGeometry(feature2);
1151
+ const pathGeometry = maptalks2.GeoJSON.toGeometry(feature2);
1449
1152
  const line = layer.toPath(
1450
1153
  pathGeometry,
1451
1154
  {
@@ -1503,8 +1206,8 @@ var createPolygonFromLineString = (geometry) => {
1503
1206
  const right = turfLineOffset(line, -0.3, { units: "meters" });
1504
1207
  const leftCoords = left.geometry.coordinates;
1505
1208
  const rightCoords = right.geometry.coordinates.reverse();
1506
- const polygon = [...leftCoords, ...rightCoords, leftCoords[0]];
1507
- return [polygon];
1209
+ const polygon2 = [...leftCoords, ...rightCoords, leftCoords[0]];
1210
+ return [polygon2];
1508
1211
  };
1509
1212
 
1510
1213
  // src/IndoorMap/utils/svg.ts
@@ -1538,8 +1241,8 @@ var createSVGPathFromMarkerSymbol = (style) => {
1538
1241
  markerFill,
1539
1242
  markerPath
1540
1243
  } = style;
1541
- const scale2 = markerWidth / 24;
1542
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${markerFill}"/>`;
1244
+ const scale3 = markerWidth / 24;
1245
+ return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale3})" fill="${markerFill}"/>`;
1543
1246
  };
1544
1247
 
1545
1248
  // src/IndoorMap/utils/createElements.js
@@ -1680,8 +1383,8 @@ var createObstructionalFixture = (feature2, style = {}, options = {}) => {
1680
1383
  if (allowOverride) _4.merge(symbolStyle, properties.style);
1681
1384
  if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1682
1385
  if (geometry.type === "LineString") {
1683
- const polygon = createPolygonFromLineString(geometry);
1684
- return new GeometryType["Polygon"](polygon, {
1386
+ const polygon2 = createPolygonFromLineString(geometry);
1387
+ return new GeometryType["Polygon"](polygon2, {
1685
1388
  properties: {
1686
1389
  altitude: getAltitude(properties)
1687
1390
  },
@@ -1797,48 +1500,6 @@ var createPedestrianOpening = (feature2, style, options = {}) => {
1797
1500
  console.log(`error creating pedestrian opening:`, feature2);
1798
1501
  }
1799
1502
  };
1800
- var loadModel3d = (model3d, coordinate, threeLayer) => {
1801
- return new Promise((resolve, reject) => {
1802
- const loader = new GLTFLoader();
1803
- const { url, properties: modelProperties } = model3d;
1804
- loader.load(
1805
- url,
1806
- (gltf) => {
1807
- const object3d = gltf.scene;
1808
- object3d.rotation.x = _4.get(modelProperties, "rotation.x");
1809
- object3d.rotation.y = _4.get(modelProperties, "rotation.y");
1810
- object3d.scale.set(..._4.get(modelProperties, "scale") || []);
1811
- const object = threeLayer.toModel(object3d, {
1812
- coordinate
1813
- });
1814
- object.getObject3d().traverse((child) => {
1815
- if (child.isMesh === true) {
1816
- child.material.transparent = true;
1817
- child.material.metalness = 0.1;
1818
- }
1819
- });
1820
- resolve(object);
1821
- },
1822
- (xhr) => {
1823
- },
1824
- (error) => {
1825
- reject(error);
1826
- }
1827
- );
1828
- });
1829
- };
1830
- var create3DModels = async (models, defaultCoordinate, properties, threeLayer) => {
1831
- let modelObjs = [];
1832
- for (let j = 0; j < models.length; j++) {
1833
- const model = models[j];
1834
- const positionCoord = _4.get(model, "properties.position");
1835
- const coord = positionCoord || defaultCoordinate;
1836
- const object = await loadModel3d(model, coord, threeLayer);
1837
- object.properties = properties;
1838
- modelObjs.push(object);
1839
- }
1840
- return modelObjs;
1841
- };
1842
1503
  var createExtrudePolygon = (geometry, threeLayer, material, height, properties = {}, options) => {
1843
1504
  const { offset = 0, altitude = 0 } = options;
1844
1505
  const offsetGeometry = turfBuffer(geometry, offset, { units: "meters" });
@@ -2512,104 +2173,12 @@ var styledFeatureGenerator = (mapTheme) => {
2512
2173
  return null;
2513
2174
  }
2514
2175
  },
2515
- /** Three JS */
2516
- create3DFootprint: async (feature2, threeLayer, options) => {
2517
- const objects = [];
2518
- const extrudeHeight = _4.get(options, "height");
2519
- if (!extrudeHeight) return objects;
2520
- const { properties } = feature2;
2521
- const footprintProperties = getFeatureProperties(feature2);
2522
- const hasModel3ds = Array.isArray(properties.model3d) && properties.model3d.length > 0;
2523
- if (hasModel3ds) {
2524
- const models = properties.model3d;
2525
- const center2 = turfCenter(feature2);
2526
- const coordinate = _4.get(center2, "geometry.coordinates");
2527
- for (const model of models) {
2528
- const object = await loadModel3d(model, coordinate, threeLayer);
2529
- object.properties = footprintProperties;
2530
- objects.push(object);
2531
- }
2532
- } else {
2533
- const color = footprintProperties.defaultColor;
2534
- if (color === "transparent") return;
2535
- const material = new MeshLambertMaterial({
2536
- color,
2537
- transparent: true
2538
- });
2539
- const object = createExtrudePolygon(
2540
- feature2.geometry,
2541
- threeLayer,
2542
- material,
2543
- extrudeHeight,
2544
- footprintProperties,
2545
- {}
2546
- );
2547
- objects.push(object);
2548
- }
2549
- return objects;
2550
- },
2551
- create3DGroundLabel: (label, threeLayer) => {
2552
- const text = label.properties.name;
2553
- const bound = label.geometry.coordinates[0];
2554
- if (_4.isNil(bound)) throw new Error("Invalid coordinates");
2555
- const groundLabelSymbol = getElementSymbol("ground-label");
2556
- const featureSymbol = _4.get(label, "properties", {});
2557
- const groundLabelOptions = _4.merge(
2558
- {},
2559
- { text },
2560
- groundLabelSymbol,
2561
- featureSymbol
2562
- );
2563
- return new GroundLabel(bound, groundLabelOptions, threeLayer);
2564
- },
2565
- createOccupantGroundLabel: (feature2, location, mapConfig, threeLayer) => {
2566
- const text = feature2.properties.name.en;
2567
- const bound = location.geometry.coordinates[0];
2568
- if (_4.isNil(bound)) throw new Error("Invalid coordinates");
2569
- const groundLabelSymbol = getElementSymbol("occupant-flat-label");
2570
- const groundLabelOptions = getElementOptions("occupant-flat-label");
2571
- const baseAltitude = getAltitude(location.properties);
2572
- const extrudeHeight = _4.get(
2573
- mapConfig,
2574
- "extrudeConfig.unit.room.height",
2575
- 0
2576
- );
2577
- const totalAltitude = baseAltitude + extrudeHeight + 0.05;
2578
- const customAngle = _4.get(feature2, "properties.style.angle");
2579
- const offsetX = _4.get(feature2, "properties.style.offsetX", 0);
2580
- const offsetY = _4.get(feature2, "properties.style.offsetY", 0);
2581
- const featureSymbol = {
2582
- name: text,
2583
- ordinal: location.properties.ordinal,
2584
- venue_id: feature2.properties.venue_id
2585
- };
2586
- const mergedGroundLabelOptions = _4.merge(
2587
- {},
2588
- { text },
2589
- groundLabelSymbol,
2590
- groundLabelOptions,
2591
- featureSymbol,
2592
- {
2593
- altitude: totalAltitude,
2594
- offsetX,
2595
- offsetY,
2596
- // set custom angle
2597
- ...!_4.isNil(customAngle) ? { angle: customAngle } : {}
2598
- }
2599
- );
2600
- const groundLabel = new GroundLabel(
2601
- bound,
2602
- mergedGroundLabelOptions,
2603
- threeLayer
2604
- );
2605
- return groundLabel;
2606
- },
2607
2176
  create3DBillboard: (billboard, threeLayer) => {
2608
2177
  const { id, feature_type, properties } = billboard;
2609
2178
  const {
2610
2179
  logo,
2611
2180
  altitude,
2612
- scale: scale2,
2181
+ scale: scale3,
2613
2182
  alphaTest,
2614
2183
  legColor,
2615
2184
  showLeg,
@@ -2623,7 +2192,7 @@ var styledFeatureGenerator = (mapTheme) => {
2623
2192
  };
2624
2193
  const options = {
2625
2194
  altitude,
2626
- scale: scale2,
2195
+ scale: scale3,
2627
2196
  alphaTest,
2628
2197
  legColor,
2629
2198
  showLeg,
@@ -2746,44 +2315,6 @@ var styledFeatureGenerator = (mapTheme) => {
2746
2315
  markerProperties
2747
2316
  );
2748
2317
  },
2749
- createVenue3DModel: async (venue, threeLayer) => {
2750
- const { id, feature_type, properties } = venue;
2751
- const { category, model3d } = properties;
2752
- const modelProperty = {
2753
- id,
2754
- feature_type,
2755
- category
2756
- };
2757
- const center2 = turfCenter(venue);
2758
- const centerCoord = _4.get(center2, "geometry.coordinates");
2759
- const modelPosition = _4.get(model3d, "properties.position", centerCoord);
2760
- const models = await create3DModels(
2761
- model3d,
2762
- modelPosition,
2763
- modelProperty,
2764
- threeLayer
2765
- );
2766
- return models;
2767
- },
2768
- create3DFixture: async (fixture, threeLayer) => {
2769
- const { id, feature_type, properties } = fixture;
2770
- const { category, ordinal, model3d } = properties;
2771
- const modelProperty = {
2772
- id,
2773
- feature_type,
2774
- category,
2775
- ordinal
2776
- };
2777
- const center2 = turfCenter(fixture);
2778
- const coordinate = _4.get(center2, "geometry.coordinates");
2779
- const models = await create3DModels(
2780
- model3d,
2781
- coordinate,
2782
- modelProperty,
2783
- threeLayer
2784
- );
2785
- return models;
2786
- },
2787
2318
  createExtrudedUnit: (unit, threeLayer, options) => {
2788
2319
  const extrudeHeight = _4.get(options, "height");
2789
2320
  if (!extrudeHeight) return;
@@ -2800,10 +2331,10 @@ var styledFeatureGenerator = (mapTheme) => {
2800
2331
  transparent: true
2801
2332
  });
2802
2333
  if (unit.geometry.type === "LineString") {
2803
- const polygon = createPolygonFromLineString(unit.geometry);
2334
+ const polygon2 = createPolygonFromLineString(unit.geometry);
2804
2335
  const geometry = {
2805
2336
  type: "Polygon",
2806
- coordinates: polygon
2337
+ coordinates: polygon2
2807
2338
  };
2808
2339
  return createExtrudePolygon(
2809
2340
  geometry,
@@ -2823,24 +2354,6 @@ var styledFeatureGenerator = (mapTheme) => {
2823
2354
  options3d
2824
2355
  );
2825
2356
  return object;
2826
- },
2827
- createAmbientLight: (config) => {
2828
- const { color: colorString = "0xffffff", intensity = 1 } = config;
2829
- const color = parseInt(colorString, 16);
2830
- const ambientLight = new AmbientLight(color, intensity);
2831
- return ambientLight;
2832
- },
2833
- createDirectionalLight: (config) => {
2834
- const {
2835
- color: colorString = "0xffffff",
2836
- intensity = 1,
2837
- position: positionString = [0, 0, 0]
2838
- } = config;
2839
- const color = parseInt(colorString, 16);
2840
- const [x, y, z] = positionString;
2841
- const light = new DirectionalLight(color, intensity);
2842
- light.position.set(x, y, z).normalize();
2843
- return light;
2844
2357
  }
2845
2358
  };
2846
2359
  };
@@ -2923,9 +2436,9 @@ var getRelatedLocationsByAmenity = (feature2) => {
2923
2436
  var getRelatedLocationIdsByFeature = (feature2) => {
2924
2437
  switch (feature2?.feature_type) {
2925
2438
  case "amenity":
2926
- return getRelatedLocationsByAmenity(feature2).map((v) => v?.id);
2439
+ return getRelatedLocationsByAmenity(feature2).map((v2) => v2?.id);
2927
2440
  case "occupant":
2928
- return getRelatedLocationsByOccupant(feature2).map((v) => v?.id);
2441
+ return getRelatedLocationsByOccupant(feature2).map((v2) => v2?.id);
2929
2442
  default:
2930
2443
  return [];
2931
2444
  }
@@ -2970,48 +2483,134 @@ var getSuitablyValueBetweenBearings = (newBearing, currentBearing) => {
2970
2483
  return newBearing;
2971
2484
  };
2972
2485
 
2973
- // src/IndoorMap/utils/createHighlightElement.ts
2974
- import { Color as Color2 } from "three";
2975
- import _5 from "lodash";
2976
- import TWEEN from "@tweenjs/tween.js";
2977
- var DEFAULT_ALTITUDE_FACTOR = 0.5;
2978
- var createHighlighBillboardController = (obj, { altitudeFactor = DEFAULT_ALTITUDE_FACTOR } = {}) => {
2979
- const controller = { start: () => {
2980
- }, clear: () => {
2981
- } };
2982
- if (!(obj instanceof Billboard)) return controller;
2983
- const altitude = obj.properties.default.altitude;
2984
- const newAltitude = _5.clamp(altitude * altitudeFactor, 0, altitude);
2985
- const tween = new TWEEN.Tween({ altitude }).to({ altitude: newAltitude }, 800).easing(TWEEN.Easing.Quartic.Out).onUpdate((newUpdate) => {
2986
- obj.setLineHeight(newUpdate.altitude);
2486
+ // src/IndoorMap/camera/CameraManager.ts
2487
+ import { Extent } from "maptalks";
2488
+
2489
+ // ../../node_modules/@turf/meta/dist/esm/index.js
2490
+ function coordEach(geojson, callback, excludeWrapCoord) {
2491
+ if (geojson === null) return;
2492
+ var j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", stop = isFeatureCollection ? geojson.features.length : 1;
2493
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2494
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2495
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2496
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2497
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2498
+ var multiFeatureIndex = 0;
2499
+ var geometryIndex = 0;
2500
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2501
+ if (geometry === null) continue;
2502
+ coords = geometry.coordinates;
2503
+ var geomType = geometry.type;
2504
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2505
+ switch (geomType) {
2506
+ case null:
2507
+ break;
2508
+ case "Point":
2509
+ if (callback(
2510
+ coords,
2511
+ coordIndex,
2512
+ featureIndex,
2513
+ multiFeatureIndex,
2514
+ geometryIndex
2515
+ ) === false)
2516
+ return false;
2517
+ coordIndex++;
2518
+ multiFeatureIndex++;
2519
+ break;
2520
+ case "LineString":
2521
+ case "MultiPoint":
2522
+ for (j = 0; j < coords.length; j++) {
2523
+ if (callback(
2524
+ coords[j],
2525
+ coordIndex,
2526
+ featureIndex,
2527
+ multiFeatureIndex,
2528
+ geometryIndex
2529
+ ) === false)
2530
+ return false;
2531
+ coordIndex++;
2532
+ if (geomType === "MultiPoint") multiFeatureIndex++;
2533
+ }
2534
+ if (geomType === "LineString") multiFeatureIndex++;
2535
+ break;
2536
+ case "Polygon":
2537
+ case "MultiLineString":
2538
+ for (j = 0; j < coords.length; j++) {
2539
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2540
+ if (callback(
2541
+ coords[j][k],
2542
+ coordIndex,
2543
+ featureIndex,
2544
+ multiFeatureIndex,
2545
+ geometryIndex
2546
+ ) === false)
2547
+ return false;
2548
+ coordIndex++;
2549
+ }
2550
+ if (geomType === "MultiLineString") multiFeatureIndex++;
2551
+ if (geomType === "Polygon") geometryIndex++;
2552
+ }
2553
+ if (geomType === "Polygon") multiFeatureIndex++;
2554
+ break;
2555
+ case "MultiPolygon":
2556
+ for (j = 0; j < coords.length; j++) {
2557
+ geometryIndex = 0;
2558
+ for (k = 0; k < coords[j].length; k++) {
2559
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2560
+ if (callback(
2561
+ coords[j][k][l],
2562
+ coordIndex,
2563
+ featureIndex,
2564
+ multiFeatureIndex,
2565
+ geometryIndex
2566
+ ) === false)
2567
+ return false;
2568
+ coordIndex++;
2569
+ }
2570
+ geometryIndex++;
2571
+ }
2572
+ multiFeatureIndex++;
2573
+ }
2574
+ break;
2575
+ case "GeometryCollection":
2576
+ for (j = 0; j < geometry.geometries.length; j++)
2577
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2578
+ return false;
2579
+ break;
2580
+ default:
2581
+ throw new Error("Unknown Geometry Type");
2582
+ }
2583
+ }
2584
+ }
2585
+ }
2586
+
2587
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
2588
+ function bbox(geojson, options = {}) {
2589
+ if (geojson.bbox != null && true !== options.recompute) {
2590
+ return geojson.bbox;
2591
+ }
2592
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
2593
+ coordEach(geojson, (coord) => {
2594
+ if (result[0] > coord[0]) {
2595
+ result[0] = coord[0];
2596
+ }
2597
+ if (result[1] > coord[1]) {
2598
+ result[1] = coord[1];
2599
+ }
2600
+ if (result[2] < coord[0]) {
2601
+ result[2] = coord[0];
2602
+ }
2603
+ if (result[3] < coord[1]) {
2604
+ result[3] = coord[1];
2605
+ }
2987
2606
  });
2988
- controller.start = () => {
2989
- tween.start();
2990
- };
2991
- controller.clear = () => {
2992
- tween.stop().to({ altitude }, 1600).startFromCurrentValues();
2993
- };
2994
- return controller;
2995
- };
2996
- var createHighlighExtrudeObjectController = (obj, { color }) => {
2997
- const controller = { start: () => {
2998
- }, clear: () => {
2999
- } };
3000
- if (obj?.type !== "ExtrudePolygon" || _5.isNil(obj?.object3d?.material?.color) || _5.isNil(color))
3001
- return controller;
3002
- controller.start = () => {
3003
- obj.object3d.material.color = new Color2(color);
3004
- };
3005
- controller.clear = () => {
3006
- const objectDefaultColor = _5.get(obj, "properties.defaultColor");
3007
- obj.object3d.material.color = new Color2(objectDefaultColor);
3008
- };
3009
- return controller;
3010
- };
2607
+ return result;
2608
+ }
2609
+ var index_default = bbox;
3011
2610
 
3012
2611
  // src/IndoorMap/camera/CameraManager.ts
3013
- var ZOOM_OUT_LEVEL = 21;
3014
- var ZOOM_IN_LEVEL = 24;
2612
+ import scale from "@turf/transform-scale";
2613
+ import bboxPolygon from "@turf/bbox-polygon";
3015
2614
  var CameraManager = class {
3016
2615
  map;
3017
2616
  constructor(map, options) {
@@ -3020,339 +2619,442 @@ var CameraManager = class {
3020
2619
  this.setView(options?.defaultView);
3021
2620
  }
3022
2621
  }
3023
- /** Private method */
3024
- #animateflyTo(viewOptions = {}, options = {}, callbackOption = () => {
3025
- }) {
3026
- const { start, end } = {
3027
- start: (frame) => {
3028
- },
3029
- end: (frame) => {
3030
- },
3031
- ...callbackOption
3032
- };
3033
- this.map.flyTo(viewOptions, options, (frame) => {
3034
- if (frame.state.playState === "running" && frame.state.progress === 0)
3035
- start(frame);
3036
- if (frame.state.playState === "finished") end(frame);
3037
- });
3038
- }
3039
2622
  /** Public methods */
3040
2623
  getView = () => {
3041
2624
  return this.map.getView();
3042
2625
  };
3043
- getZoom = () => {
3044
- return this.map.getView().zoom;
3045
- };
3046
2626
  setView = (value) => {
3047
- this.map.setView(value);
2627
+ if (this.map && Object.keys(value).length !== 0) {
2628
+ this.map.setView(value);
2629
+ }
3048
2630
  };
3049
- flyTo = (center2, options = {}) => {
3050
- const currentView = this.getView();
3051
- const {
3052
- zoom = ZOOM_OUT_LEVEL,
3053
- pitch = 60,
3054
- duration = 600,
3055
- easing = "out",
3056
- bearing = currentView.bearing
3057
- } = options;
3058
- this.#animateflyTo(
3059
- {
3060
- center: center2,
3061
- zoom,
3062
- pitch,
3063
- bearing
3064
- },
3065
- { duration, easing }
3066
- );
2631
+ animateTo = (view, options = {}, step) => {
2632
+ this.map.animateTo(view, options, step);
3067
2633
  };
3068
- flyToAndZoomIn = (centerPoint, options = {}) => {
3069
- const {
3070
- zoom = ZOOM_IN_LEVEL,
3071
- pitch = 60,
3072
- duration = 600,
3073
- easing = "out"
3074
- } = options;
3075
- this.#animateflyTo(
3076
- {
3077
- center: centerPoint,
3078
- zoom,
3079
- pitch
3080
- },
3081
- { duration, easing }
2634
+ setMaxExtent(extent) {
2635
+ return this.map.setMaxExtent(extent);
2636
+ }
2637
+ getFeatureExtent = (feature2, scaleFactor = 1) => {
2638
+ const [minX, minY, maxX, maxY] = index_default(
2639
+ scale(bboxPolygon(index_default(feature2)), scaleFactor)
3082
2640
  );
2641
+ return new Extent(minX, minY, maxX, maxY);
2642
+ };
2643
+ getExtentZoom = (extent, options = {
2644
+ isFraction: false,
2645
+ padding: {
2646
+ paddingLeft: 0,
2647
+ paddingRight: 0,
2648
+ paddingTop: 0,
2649
+ paddingBottom: 0
2650
+ }
2651
+ }) => {
2652
+ const { isFraction = false, padding } = options;
2653
+ return this.map.getFitZoom(extent, isFraction, padding);
3083
2654
  };
2655
+ set maxZoom(value) {
2656
+ this.map.setMaxZoom(value);
2657
+ const spatialReference = {
2658
+ projection: "EPSG:3857",
2659
+ resolutions: (function() {
2660
+ const resolutions = [];
2661
+ const d = 2 * 6378137 * Math.PI;
2662
+ for (let i = 0; i < value; i++) {
2663
+ resolutions[i] = d / (256 * Math.pow(2, i));
2664
+ }
2665
+ return resolutions;
2666
+ })()
2667
+ };
2668
+ this.map.setSpatialReference(spatialReference);
2669
+ }
2670
+ set minZoom(value) {
2671
+ this.map.setMinZoom(value);
2672
+ }
3084
2673
  };
3085
2674
 
3086
2675
  // src/IndoorMap/renderer/RendererManager.ts
3087
- import _min from "lodash/min";
2676
+ import { min, compact as compact2, isFunction } from "lodash-es";
3088
2677
  import { center as turfCenter2 } from "@turf/center";
3089
- import { ThreeLayer as ThreeLayer3 } from "maptalks.three";
3090
2678
  import * as THREE3 from "three";
3091
2679
 
3092
2680
  // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3093
- import * as maptalks4 from "maptalks";
3094
- import * as THREE2 from "three";
3095
- import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader";
3096
- import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
2681
+ import * as maptalks4 from "maptalks-gl";
2682
+ import * as THREE from "three";
2683
+ import { BaseObject as BaseObject5 } from "maptalks.three";
3097
2684
  import turfBuffer2 from "@turf/buffer";
2685
+ import { cleanCoords } from "@turf/clean-coords";
2686
+ import { polygonToLine } from "@turf/polygon-to-line";
2687
+ import { nearestPointOnLine } from "@turf/nearest-point-on-line";
2688
+ import { length } from "@turf/length";
2689
+ import { along } from "@turf/along";
2690
+ import { pointToLineDistance } from "@turf/point-to-line-distance";
3098
2691
 
3099
- // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3100
- var element3DRendererOptions = {
3101
- unit: {
3102
- default: { color: "#ffffff", height: 4 },
3103
- byCategory: {
3104
- walkway: { color: "#cccccc", height: 0.1 },
3105
- terrace: { color: "#cccccc", height: 0.1 },
3106
- unenclosedarea: { color: "#cccccc", height: 0.2 },
3107
- nonpublic: { color: "#999999", height: 0.3 },
3108
- escalator: { height: 0.2 },
3109
- room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
2692
+ // src/IndoorMap/renderer/3d/objects/GroundLabel.ts
2693
+ import * as maptalks3 from "maptalks-gl";
2694
+ import { BaseObject as BaseObject4 } from "maptalks.three";
2695
+ import {
2696
+ Texture,
2697
+ MeshPhongMaterial,
2698
+ PlaneGeometry
2699
+ } from "three";
2700
+ import { largestRect } from "d3plus-shape";
2701
+ import { max, merge, isNumber as isNumber2, isArray, range } from "lodash-es";
2702
+ var OPTIONS3 = {
2703
+ // Allowing click through and prevent interaction
2704
+ interactive: false,
2705
+ altitude: 0
2706
+ };
2707
+ var defaultFlatLabelOptions = {
2708
+ fontSize: 14,
2709
+ fontFamily: "Manrope",
2710
+ fontWeight: 600,
2711
+ margin: 0,
2712
+ scaleMin: 0.5,
2713
+ lineHeight: 1.05,
2714
+ scaleStep: 0.05,
2715
+ textAlign: "center",
2716
+ textBaseline: "middle",
2717
+ fillStyle: "#000"
2718
+ };
2719
+ var defaultRectAngleToCalc = range(-90, 92, 2);
2720
+ var getMaterial = (text, flatLabelOptions) => {
2721
+ const options = merge({}, defaultFlatLabelOptions, flatLabelOptions);
2722
+ const {
2723
+ fontSize: initialFontSize,
2724
+ fontFamily,
2725
+ fontWeight,
2726
+ margin,
2727
+ scaleMin,
2728
+ scaleStep,
2729
+ fillStyle,
2730
+ lineHeight,
2731
+ textAlign,
2732
+ strokeStyle,
2733
+ lineWidth,
2734
+ textBaseline
2735
+ } = options;
2736
+ const pixelMultiplier = 4;
2737
+ const SIZE = 100 * pixelMultiplier;
2738
+ const fontSize = initialFontSize * (pixelMultiplier * 1.25);
2739
+ const canvas = document.createElement("canvas");
2740
+ canvas.width = canvas.height = SIZE;
2741
+ const ctx = canvas.getContext("2d");
2742
+ ctx.font = `${fontWeight} ${fontSize}px "${fontFamily}", Arial`;
2743
+ ctx.textAlign = textAlign;
2744
+ ctx.textBaseline = textBaseline;
2745
+ ctx.fillStyle = fillStyle;
2746
+ ctx.strokeStyle = strokeStyle;
2747
+ ctx.lineWidth = lineWidth;
2748
+ const wrapText = (ctx2, text2, maxWidth) => {
2749
+ const words = text2.trim().split(/\s+/);
2750
+ if (words.length <= 1) return [text2];
2751
+ const lines = [];
2752
+ const MAX_LINES = 3;
2753
+ let currentLine = words[0];
2754
+ for (let i = 1; i < words.length; i++) {
2755
+ const lineToMeasure = currentLine + " " + words[i];
2756
+ if (ctx2.measureText(lineToMeasure).width > maxWidth) {
2757
+ lines.push(currentLine);
2758
+ currentLine = words[i];
2759
+ } else {
2760
+ currentLine = lineToMeasure;
2761
+ }
3110
2762
  }
3111
- },
3112
- kiosk: {
3113
- default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3114
- },
3115
- fixture: {
3116
- default: { color: "#ffffff", height: 0.5 },
3117
- byCategory: {
3118
- water: { color: "#ACD7EC", height: 0.1 },
3119
- vegetation: { color: "#91C499", height: 0.5 }
2763
+ lines.push(currentLine);
2764
+ return lines.slice(0, MAX_LINES);
2765
+ };
2766
+ const hasManualBreaks = text.includes("\n");
2767
+ let texts;
2768
+ if (hasManualBreaks) {
2769
+ texts = text.split(/\n/g);
2770
+ } else {
2771
+ const maxWidth = SIZE - 2 * margin;
2772
+ texts = wrapText(ctx, text, maxWidth);
2773
+ }
2774
+ let textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
2775
+ let scale3 = 1;
2776
+ while (scale3 > 0 && textWidth + 2 * margin > SIZE) {
2777
+ scale3 -= scaleStep;
2778
+ ctx.font = `${fontWeight} ${scale3 * fontSize}px "${fontFamily}", Arial`;
2779
+ textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
2780
+ }
2781
+ const center2 = { x: 0.5 * SIZE, y: 0.5 * SIZE };
2782
+ if (scale3 > scaleMin) {
2783
+ const totalHeight = texts.length * (fontSize * scale3 * lineHeight);
2784
+ const startY = center2.y - totalHeight / 2 + fontSize * scale3 * lineHeight * 0.5;
2785
+ texts.forEach((text2, index) => {
2786
+ const yOffset = startY + index * (fontSize * scale3 * lineHeight);
2787
+ if (strokeStyle && lineWidth) {
2788
+ ctx.strokeText(text2, center2.x, yOffset);
2789
+ }
2790
+ ctx.fillText(text2, center2.x, yOffset);
2791
+ });
2792
+ }
2793
+ const texture = new Texture(canvas);
2794
+ texture.needsUpdate = true;
2795
+ const material = new MeshPhongMaterial({
2796
+ map: texture,
2797
+ transparent: true,
2798
+ // @ref: https://threejs.org/docs/#api/en/materials/Material.alphaTest
2799
+ alphaTest: 0.3
2800
+ });
2801
+ return material;
2802
+ };
2803
+ var GroundLabel = class extends BaseObject4 {
2804
+ #angle = 0;
2805
+ #bearing = 0;
2806
+ #text = "";
2807
+ #offsetX = 0;
2808
+ #offsetY = 0;
2809
+ #originalPosition = null;
2810
+ #layer = null;
2811
+ constructor(bound, text, options, layer) {
2812
+ options = maptalks3.Util.extend({}, OPTIONS3, options, {
2813
+ layer,
2814
+ coordinate: bound
2815
+ });
2816
+ const {
2817
+ altitude = 0,
2818
+ bottomHeight = 0,
2819
+ fontSize,
2820
+ fillStyle,
2821
+ textAlign,
2822
+ fontFamily,
2823
+ textBaseline,
2824
+ strokeStyle,
2825
+ lineWidth,
2826
+ angle = defaultRectAngleToCalc,
2827
+ maxFontScale,
2828
+ offsetX = 0,
2829
+ offsetY = 0,
2830
+ ...properties
2831
+ } = options;
2832
+ super();
2833
+ this._initOptions(options);
2834
+ this.properties = properties;
2835
+ this.#offsetX = offsetX;
2836
+ this.#offsetY = offsetY;
2837
+ this.#layer = layer;
2838
+ const material = getMaterial(text, {
2839
+ fillStyle,
2840
+ fontSize,
2841
+ textAlign,
2842
+ textBaseline,
2843
+ fontFamily,
2844
+ strokeStyle,
2845
+ lineWidth
2846
+ });
2847
+ const rectAngles = isArray(angle) ? angle : [angle];
2848
+ material.needsUpdate = true;
2849
+ const rect = largestRect(bound, {
2850
+ cache: true,
2851
+ /**
2852
+ * Black magic here:
2853
+ * For some reason if we allow angle -90 or 90, some polygon will use that angle even if it's wrong angle to use.
2854
+ * So we remove -90 and 90 from choices, and use -85 & 85 instead.
2855
+ */
2856
+ angle: rectAngles
2857
+ });
2858
+ const { cx, cy, width, angle: calculatedAngle } = rect;
2859
+ this.#text = text;
2860
+ this.#angle = calculatedAngle;
2861
+ const geometry = new PlaneGeometry(1, 1);
2862
+ this._createMesh(geometry, material);
2863
+ const z = layer.altitudeToVector3(altitude + bottomHeight, altitude + bottomHeight).x;
2864
+ const basePosition = layer.coordinateToVector3([cx, cy], z);
2865
+ this.#originalPosition = basePosition.clone();
2866
+ const finalPosition = this.#calculateFinalPosition(basePosition);
2867
+ const scale3 = width / 6456122659e-13;
2868
+ const finalScale = maxFontScale && scale3 > maxFontScale ? maxFontScale : scale3;
2869
+ this.getObject3d().scale.set(finalScale, finalScale, finalScale);
2870
+ this.getObject3d().position.copy(finalPosition);
2871
+ this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
2872
+ }
2873
+ #calculateFinalPosition(basePosition) {
2874
+ if (this.#offsetX === 0 && this.#offsetY === 0) {
2875
+ return basePosition;
2876
+ }
2877
+ const offsetCoordinate = [this.#offsetX, this.#offsetY];
2878
+ const z = this.#layer.altitudeToVector3(0, 0).x;
2879
+ const offsetVector = this.#layer.coordinateToVector3(offsetCoordinate, z);
2880
+ const zeroVector = this.#layer.coordinateToVector3([0, 0], z);
2881
+ const worldOffsetX = offsetVector.x - zeroVector.x;
2882
+ const worldOffsetY = offsetVector.y - zeroVector.y;
2883
+ return {
2884
+ x: basePosition.x + worldOffsetX,
2885
+ y: basePosition.y + worldOffsetY,
2886
+ z: basePosition.z
2887
+ };
2888
+ }
2889
+ #updatePosition() {
2890
+ if (this.#originalPosition && this.#layer) {
2891
+ const finalPosition = this.#calculateFinalPosition(this.#originalPosition);
2892
+ this.getObject3d().position.copy(finalPosition);
3120
2893
  }
3121
2894
  }
3122
- };
3123
-
3124
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3125
- import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3126
- import * as THREE from "three";
3127
- import { BaseObject as BaseObject5 } from "maptalks.three";
3128
- import { isNil, set } from "lodash";
3129
-
3130
- // src/IndoorMap/renderer/utils/interpolateStops.ts
3131
- var interpolateStops = ({ stops }, zoom) => {
3132
- if (zoom <= stops[0][0]) return stops[0][1];
3133
- if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3134
- for (let i = 0; i < stops.length - 1; i++) {
3135
- const [z1, v1] = stops[i];
3136
- const [z2, v2] = stops[i + 1];
3137
- if (zoom >= z1 && zoom <= z2) {
3138
- const t = (zoom - z1) / (z2 - z1);
3139
- return v1 + t * (v2 - v1);
2895
+ set bearing(value) {
2896
+ this.#bearing = value;
2897
+ const degree = this.#angle + this.#bearing;
2898
+ const angle = degree > 90 || degree < -90 ? this.#angle + 180 : this.#angle;
2899
+ this.getObject3d().rotation.z = Math.PI / 180 * angle;
2900
+ }
2901
+ get angle() {
2902
+ return this.#angle;
2903
+ }
2904
+ get currentAngle() {
2905
+ return this.#angle;
2906
+ }
2907
+ get text() {
2908
+ return this.#text;
2909
+ }
2910
+ get offsetX() {
2911
+ return this.#offsetX;
2912
+ }
2913
+ get offsetY() {
2914
+ return this.#offsetY;
2915
+ }
2916
+ get offset() {
2917
+ return { x: this.#offsetX, y: this.#offsetY };
2918
+ }
2919
+ set offsetX(value) {
2920
+ if (isNumber2(value)) {
2921
+ this.#offsetX = value;
2922
+ this.#updatePosition();
3140
2923
  }
3141
2924
  }
3142
- };
3143
-
3144
- // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3145
- var OPTIONS4 = {
3146
- // Texture options
3147
- text: "",
3148
- textAlign: "center",
3149
- color: "#ffffff",
3150
- fontFamily: "sans-serif",
3151
- fontSize: 28,
3152
- fontWeight: 400,
3153
- background: "rgba(0, 0, 0, 0.2)",
3154
- lineHeight: 32,
3155
- padding: 8,
3156
- strokeColor: "#000000",
3157
- strokeWidth: 6,
3158
- strokeStyle: "round",
3159
- // Sprite options
3160
- /* Overall scale multiplier */
3161
- scale: 1,
3162
- altitude: 0,
3163
- opacity: 1
3164
- };
3165
- var TextSpriteMarker = class extends BaseObject5 {
3166
- #altitudeOffset = 0;
3167
- constructor(coordinate, options, layer, properties = {}) {
3168
- options = Util4.extend({}, OPTIONS4, options, { layer });
3169
- super();
3170
- this._coordinate = new Coordinate2(coordinate);
3171
- this._initOptions(options);
3172
- this._createGroup();
3173
- this.properties = { ...properties };
3174
- const sprite = this._createSprite();
3175
- this.getObject3d().add(sprite);
3176
- this._updatePosition();
3177
- this.type = "TextSpriteMarker";
2925
+ set offsetY(value) {
2926
+ if (isNumber2(value)) {
2927
+ this.#offsetY = value;
2928
+ this.#updatePosition();
2929
+ }
3178
2930
  }
3179
- getOptions() {
3180
- return super.getOptions();
2931
+ set angle(newAngle) {
2932
+ if (isNumber2(newAngle)) {
2933
+ this.#angle = newAngle;
2934
+ this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
2935
+ }
3181
2936
  }
3182
- _createSprite() {
3183
- const options = this.getOptions();
3184
- const texture = this._createTextTexture(options.text, options);
3185
- const material = new THREE.SpriteMaterial({
3186
- map: texture,
3187
- transparent: true,
3188
- alphaTest: 0.1
3189
- });
3190
- const sprite = new THREE.Sprite(material);
3191
- const w = texture.image.width;
3192
- const h = texture.image.height;
3193
- const base = 1 / 16;
3194
- const normalizedScale = options.scale / this.getMap().getGLRes();
3195
- sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3196
- this.#altitudeOffset = Math.max(
3197
- h * base * options.scale * 0.5,
3198
- 0.05
3199
- // minimum lift in world units
3200
- );
3201
- return sprite;
2937
+ setOffset(offsetX, offsetY) {
2938
+ if (isNumber2(offsetX) && isNumber2(offsetY)) {
2939
+ this.#offsetX = offsetX;
2940
+ this.#offsetY = offsetY;
2941
+ this.#updatePosition();
2942
+ }
3202
2943
  }
3203
- _createTextTexture(text, options = {}) {
3204
- const {
3205
- padding,
3206
- fontSize,
3207
- fontFamily,
3208
- fontWeight,
3209
- lineHeight,
3210
- background,
3211
- color,
3212
- textAlign,
3213
- strokeColor,
3214
- strokeWidth,
3215
- maxWidth
3216
- } = options || {};
3217
- const canvas = document.createElement("canvas");
3218
- const ctx = canvas.getContext("2d");
3219
- ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3220
- const paragraphs = String(text).split("\n");
3221
- const wrappedLines = [];
3222
- paragraphs.forEach((paragraph) => {
3223
- if (isNil(maxWidth) || isNaN(maxWidth)) {
3224
- wrappedLines.push(paragraph);
3225
- return;
3226
- }
3227
- const words = paragraph.split(/\s+/);
3228
- let currentLine = "";
3229
- words.forEach((word) => {
3230
- const testLine = currentLine ? currentLine + " " + word : word;
3231
- const testWidth = ctx.measureText(testLine).width;
3232
- if (testWidth > maxWidth && currentLine) {
3233
- wrappedLines.push(currentLine);
3234
- currentLine = word;
3235
- } else {
3236
- currentLine = testLine;
3237
- }
3238
- });
3239
- if (currentLine) {
3240
- wrappedLines.push(currentLine);
3241
- }
3242
- });
3243
- const lines = wrappedLines.length ? wrappedLines : [""];
3244
- const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3245
- const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3246
- const finalHeight = lineHeight * lines.length + padding * 2;
3247
- canvas.width = finalWidth;
3248
- canvas.height = finalHeight;
3249
- const ctx2 = canvas.getContext("2d");
3250
- ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3251
- ctx2.textAlign = textAlign;
3252
- if (background && background !== "transparent") {
3253
- ctx2.fillStyle = background;
3254
- ctx2.fillRect(0, 0, canvas.width, canvas.height);
2944
+ addOffset(deltaX, deltaY) {
2945
+ if (isNumber2(deltaX) && isNumber2(deltaY)) {
2946
+ this.#offsetX += deltaX;
2947
+ this.#offsetY += deltaY;
2948
+ this.#updatePosition();
3255
2949
  }
3256
- lines.forEach((line, i) => {
3257
- const y = padding + lineHeight * (i + 0.8);
3258
- let x = padding;
3259
- if (textAlign === "center") x = canvas.width / 2;
3260
- if (textAlign === "right" || textAlign === "end")
3261
- x = canvas.width - padding;
3262
- if (strokeWidth > 0) {
3263
- ctx2.lineWidth = strokeWidth;
3264
- ctx2.lineJoin = "round";
3265
- ctx2.miterLimit = 2;
3266
- ctx2.strokeStyle = strokeColor;
3267
- ctx2.strokeText(line, x, y);
3268
- }
3269
- ctx2.fillStyle = color;
3270
- ctx2.fillText(line, x, y);
3271
- });
3272
- const texture = new THREE.CanvasTexture(canvas);
3273
- texture.needsUpdate = true;
3274
- texture.minFilter = THREE.LinearFilter;
3275
- return texture;
3276
2950
  }
3277
- _updatePosition() {
3278
- const options = this.getOptions();
3279
- const layer = options.layer;
3280
- if (!layer) return;
3281
- const altitude = (options.altitude || 0) + this.#altitudeOffset;
3282
- const z = layer.altitudeToVector3(altitude, altitude).x;
3283
- const position = layer.coordinateToVector3(this._coordinate, z);
3284
- set(this.properties, "default.position", position);
3285
- this.getObject3d().position.copy(position);
2951
+ resetOffset() {
2952
+ this.#offsetX = 0;
2953
+ this.#offsetY = 0;
2954
+ this.#updatePosition();
3286
2955
  }
3287
- _animation() {
3288
- const layer = this.getLayer();
3289
- if (!this.isAdd || !layer) return;
3290
- if (this._visible === true) {
3291
- const zoom = layer.map.getZoom();
3292
- const object3d = this.getObject3d();
3293
- const { opacity } = this.getOptions();
3294
- let opacityValue;
3295
- if (typeof opacity === "number") {
3296
- opacityValue = opacity ?? 1;
3297
- } else if (Array.isArray(opacity.stops)) {
3298
- opacityValue = interpolateStops(opacity, zoom);
3299
- } else {
3300
- throw new Error(`Unknown opacity value ${opacity}`);
3301
- }
3302
- const visible = opacityValue > 0.5;
3303
- object3d.visible = visible;
2956
+ moveToPosition(targetX, targetY) {
2957
+ if (this.#originalPosition && this.#layer) {
2958
+ const currentCenter = this.#layer.vector3ToCoordinate(
2959
+ this.#originalPosition
2960
+ );
2961
+ this.#offsetX = targetX - currentCenter.x;
2962
+ this.#offsetY = targetY - currentCenter.y;
2963
+ this.#updatePosition();
3304
2964
  }
3305
2965
  }
3306
- setText(text) {
3307
- const options = this.getOptions();
3308
- options.text = text;
3309
- const newSprite = this._createSprite();
3310
- const group = this.getObject3d();
3311
- group.children.forEach((child) => group.remove(child));
3312
- group.add(newSprite);
3313
- this._updatePosition();
2966
+ updateText(newText, options = {}) {
2967
+ this.#text = newText;
2968
+ const materialOptions = {
2969
+ fillStyle: options.fillStyle || this.properties.fillStyle,
2970
+ fontSize: options.fontSize || this.properties.fontSize,
2971
+ textAlign: options.textAlign || this.properties.textAlign,
2972
+ textBaseline: options.textBaseline || this.properties.textBaseline,
2973
+ fontFamily: options.fontFamily || this.properties.fontFamily,
2974
+ strokeStyle: options.strokeStyle || this.properties.strokeStyle,
2975
+ lineWidth: options.lineWidth || this.properties.lineWidth
2976
+ };
2977
+ const newMaterial = getMaterial(newText, materialOptions);
2978
+ this.getObject3d().material = newMaterial;
2979
+ newMaterial.needsUpdate = true;
2980
+ }
2981
+ _animation() {
2982
+ const map = this.getMap();
2983
+ if (!map) return;
2984
+ const bearing = map.getBearing();
2985
+ this.bearing = bearing;
3314
2986
  }
2987
+ // Add bottomHeight to altitude as final altitude position
3315
2988
  setAltitude(altitude) {
3316
2989
  const bottomHeight = this.options.bottomHeight ?? 0;
3317
- return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
2990
+ return super.setAltitude(altitude + bottomHeight);
3318
2991
  }
3319
2992
  };
3320
2993
 
3321
- // src/IndoorMap/renderer/3d/Element3DRenderer.ts
2994
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
2995
+ var element3DRendererOptions = {
2996
+ unit: {
2997
+ default: { color: "#ffffff", height: 0.2 },
2998
+ byCategory: {
2999
+ walkway: { color: "#cccccc", height: 0.1 },
3000
+ terrace: { color: "#cccccc", height: 0.1 },
3001
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3002
+ nonpublic: { color: "#999999", height: 0.3 },
3003
+ escalator: { height: 0.2 },
3004
+ parking: { color: "#999999", height: 0.1 },
3005
+ room: { color: "#ffffff", height: 0.5, bottomHeight: 0.12 }
3006
+ }
3007
+ },
3008
+ kiosk: {
3009
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3010
+ },
3011
+ fixture: {
3012
+ default: { color: "#ffffff", height: 0.5 },
3013
+ byCategory: {
3014
+ water: { color: "#ACD7EC", height: 0.1 },
3015
+ vegetation: { color: "#91C499", height: 0.5 },
3016
+ wall: { color: "#787878", topColor: "#ffffff", height: 4.2, width: 1 }
3017
+ }
3018
+ }
3019
+ };
3020
+
3021
+ // src/IndoorMap/renderer/3d/utils/get3DRendererOption.ts
3322
3022
  var DEFAULT_POLYGON_OPTION = {
3323
3023
  color: "#FFFFFF",
3324
3024
  offset: 0,
3325
3025
  altitude: 0
3326
3026
  };
3327
- var HEIGHT_METER = 4;
3328
- var MULTIORDINAL_HEIGHT_METER = 9;
3329
- var getGeometryOption = (feature2, options) => {
3027
+ var get3DRendererOption = (featureType, category, options) => {
3330
3028
  try {
3331
- const option = options[feature2.feature_type] ?? element3DRendererOptions[feature2.feature_type];
3332
- const category = feature2.properties.category;
3029
+ const option = options[featureType] ?? element3DRendererOptions[featureType];
3333
3030
  return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION;
3334
3031
  } catch (err) {
3335
- console.log(err.message, { options, feature: feature2 });
3032
+ console.log(err.message, { options, featureType, category });
3336
3033
  }
3337
3034
  };
3035
+
3036
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3037
+ import lineSplit from "@turf/line-split";
3038
+ var HEIGHT_METER = 4;
3039
+ var MULTIORDINAL_HEIGHT_METER = 9;
3338
3040
  var Element3DRenderer = class extends EventTarget {
3339
3041
  options;
3340
3042
  map;
3043
+ gltfLayer;
3341
3044
  threeLayer;
3342
- dracoLoader;
3045
+ scene;
3343
3046
  lineMaterial;
3344
3047
  materialByColorMap;
3345
- markerRenderer;
3346
3048
  // Renderer is Ready
3347
3049
  isReady = false;
3348
- constructor(map, options, layer) {
3050
+ constructor(map, options) {
3349
3051
  super();
3350
3052
  this.options = options;
3351
3053
  this.map = map;
3352
- this.dracoLoader = new DRACOLoader();
3353
- this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
3354
- this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3355
- this.threeLayer = layer;
3054
+ const groupLayer = this.map.getLayer("group");
3055
+ this.threeLayer = groupLayer.getLayer("three");
3056
+ this.gltfLayer = groupLayer.getLayer("gltf");
3057
+ this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
3356
3058
  this.render();
3357
3059
  }
3358
3060
  animation() {
@@ -3367,7 +3069,7 @@ var Element3DRenderer = class extends EventTarget {
3367
3069
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3368
3070
  const existingMaterial = this.materialByColorMap.get(color);
3369
3071
  if (existingMaterial) return existingMaterial;
3370
- const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3072
+ const created = new THREE.MeshLambertMaterial({ color, transparent: true });
3371
3073
  created.toneMapped = false;
3372
3074
  this.materialByColorMap.set(color, created);
3373
3075
  return created;
@@ -3379,49 +3081,65 @@ var Element3DRenderer = class extends EventTarget {
3379
3081
  bottomHeight: bottomHeightOptions,
3380
3082
  color: colorOptions,
3381
3083
  ...options
3382
- } = getGeometryOption(feature2, this.options);
3084
+ } = get3DRendererOption(feature2.feature_type, feature2.properties.category, this.options);
3383
3085
  const _this = this;
3384
3086
  const createPolygon = (geometry, feature3) => {
3385
- const [outerRing, ...innerRings] = geometry.coordinates;
3386
- const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3387
- const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3388
- if (color === "transparent") return;
3389
- const material = this.getOrCreateMaterialByColor(color);
3390
- const altitude = feature3.properties.ordinal * HEIGHT_METER;
3391
- const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3392
- const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3393
- const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3394
- offsetFeature,
3395
- { asynchronous: true, ...options, height, bottomHeight, altitude },
3396
- material
3397
- );
3398
- extrudedPolygon.on("click", (e) => {
3399
- console.log(e.target.options.polygon.id);
3400
- });
3401
- const topLineStrings = [
3402
- new maptalks4.LineString(outerRing),
3403
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3404
- ];
3405
- const topLines = this.threeLayer.toLines(
3406
- topLineStrings,
3407
- { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3408
- this.lineMaterial
3409
- );
3410
- const bottomLineStrings = [
3411
- new maptalks4.LineString(outerRing),
3412
- ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3413
- ];
3414
- const bottomLines = this.threeLayer.toLines(
3415
- bottomLineStrings,
3416
- { altitude, bottomHeight, interactive: false },
3417
- this.lineMaterial
3418
- );
3419
- return [extrudedPolygon, topLines, bottomLines];
3087
+ try {
3088
+ const [outerRing, ...innerRings] = geometry.coordinates;
3089
+ const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3090
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3091
+ if (color === "transparent") return;
3092
+ const material = this.getOrCreateMaterialByColor(color);
3093
+ const altitude = 0;
3094
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3095
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3096
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3097
+ offsetFeature,
3098
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3099
+ material
3100
+ );
3101
+ const topLineStrings = [
3102
+ new maptalks4.LineString(outerRing),
3103
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3104
+ ];
3105
+ const topLines = this.threeLayer.toLines(
3106
+ topLineStrings,
3107
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3108
+ this.lineMaterial
3109
+ );
3110
+ const bottomLineStrings = [
3111
+ new maptalks4.LineString(outerRing),
3112
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3113
+ ];
3114
+ const bottomLines = this.threeLayer.toLines(
3115
+ bottomLineStrings,
3116
+ { altitude, bottomHeight, interactive: false },
3117
+ this.lineMaterial
3118
+ );
3119
+ return [extrudedPolygon, topLines, bottomLines];
3120
+ } catch (err) {
3121
+ return [];
3122
+ }
3123
+ };
3124
+ const createLineString = (geometry, feature3) => {
3125
+ try {
3126
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#000000";
3127
+ const material = this.getOrCreateMaterialByColor(color);
3128
+ const extrudedLine = this.threeLayer.toExtrudeLine(
3129
+ new maptalks4.LineString(geometry.coordinates),
3130
+ { height: heightOptions, ...options },
3131
+ material
3132
+ );
3133
+ return [extrudedLine];
3134
+ } catch (err) {
3135
+ return [];
3136
+ }
3420
3137
  };
3421
3138
  try {
3422
3139
  switch (feature2.geometry.type) {
3423
3140
  case "MultiPolygon": {
3424
3141
  const { coordinates } = feature2.geometry;
3142
+ if (!coordinates) return [];
3425
3143
  const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3426
3144
  const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3427
3145
  this.threeLayer.addMesh(meshes);
@@ -3430,70 +3148,126 @@ var Element3DRenderer = class extends EventTarget {
3430
3148
  return multiMeshes;
3431
3149
  }
3432
3150
  case "Polygon": {
3151
+ const { coordinates } = feature2.geometry;
3152
+ if (!coordinates) return [];
3433
3153
  const meshes = createPolygon(feature2.geometry, feature2);
3434
3154
  this.threeLayer.addMesh(meshes);
3435
3155
  return meshes;
3436
3156
  }
3157
+ case "LineString": {
3158
+ const { coordinates } = feature2.geometry;
3159
+ if (!coordinates) return [];
3160
+ const meshes = createLineString(feature2.geometry, feature2);
3161
+ this.threeLayer.addMesh(meshes);
3162
+ return meshes;
3163
+ }
3437
3164
  }
3438
3165
  } catch (err) {
3439
- console.log(`error createGeometry`, { feature: feature2, options });
3166
+ console.log(`error createGeometry`, err, { feature: feature2, options });
3440
3167
  }
3441
3168
  };
3169
+ createRoomWall(unit, openings = []) {
3170
+ const polygons = unit.geometry.type === "Polygon" ? [unit.geometry.coordinates] : unit.geometry.coordinates;
3171
+ return polygons.map((plg) => {
3172
+ return plg.map((ring) => {
3173
+ const roomWall = cleanCoords(polygonToLine(polygon([ring])));
3174
+ if (openings.length === 0) {
3175
+ const color = "#ababab";
3176
+ const material = this.getOrCreateMaterialByColor(color);
3177
+ const extrudedWall = this.threeLayer.toExtrudeLine(
3178
+ new maptalks4.LineString(roomWall.geometry.coordinates),
3179
+ { height: 4, width: 1 },
3180
+ material
3181
+ );
3182
+ return extrudedWall;
3183
+ }
3184
+ let openingPoints = [];
3185
+ openings.forEach((opening) => {
3186
+ const doorCoords = opening?.geometry?.coordinates;
3187
+ const p0 = point(doorCoords[0]);
3188
+ const p1 = point(doorCoords[doorCoords.length - 1]);
3189
+ const s0 = nearestPointOnLine(roomWall, p0, { units: "meters" });
3190
+ const s1 = nearestPointOnLine(roomWall, p1, { units: "meters" });
3191
+ const d0 = s0.properties.dist;
3192
+ const d1 = s1.properties.dist;
3193
+ if (d0 > 1 || d1 > 1) {
3194
+ } else {
3195
+ openingPoints = openingPoints.concat([s0.geometry.coordinates, s1.geometry.coordinates]);
3196
+ }
3197
+ });
3198
+ try {
3199
+ const split = lineSplit(roomWall, multiPoint(openingPoints));
3200
+ const wallsOnly = split.features.filter((seg) => {
3201
+ const mid = along(seg, length(seg, { units: "meters" }) / 2, { units: "meters" });
3202
+ for (const opening of openings) {
3203
+ const dist = pointToLineDistance(mid, opening, { units: "meters" });
3204
+ if (dist < 0.05) return false;
3205
+ }
3206
+ return true;
3207
+ });
3208
+ const wallMeshes = wallsOnly.map((feature2, i) => {
3209
+ const color = "#ababab";
3210
+ const material = this.getOrCreateMaterialByColor(color);
3211
+ const extrudedLine = this.threeLayer.toExtrudeLine(
3212
+ new maptalks4.LineString(feature2.geometry.coordinates),
3213
+ { height: 3, width: 0.4, id: unit.id },
3214
+ material
3215
+ );
3216
+ extrudedLine.getObject3d().userData = {
3217
+ unitId: unit.id,
3218
+ coords: feature2.geometry.coordinates
3219
+ };
3220
+ return extrudedLine;
3221
+ }).flat();
3222
+ this.threeLayer.addMesh(wallMeshes);
3223
+ return wallMeshes;
3224
+ } catch (e) {
3225
+ console.log(e.message, { unit, roomWall });
3226
+ return [];
3227
+ }
3228
+ }).flat();
3229
+ }).flat();
3230
+ }
3442
3231
  async createEscalator(f, coordinate, options) {
3232
+ const model = {
3233
+ url: "https://cdn.venue.in.th/static/glb/escalator.glb",
3234
+ size: 4.4
3235
+ };
3443
3236
  const { direction: dir, angle } = options;
3444
- const model = await this.loadModel3d({
3445
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
3446
- properties: {
3447
- rotation: {
3448
- x: 0.5 * Math.PI,
3449
- // Rotate the model up (new_escalator.glb)
3450
- y: 0,
3451
- z: 0
3452
- },
3453
- position: { x: 0, y: 0, z: 0 },
3454
- scale: 0.01
3237
+ const rotationZ = dir === "up" ? 180 + angle : angle;
3238
+ var escalatorMarker = new maptalks4.GLTFMarker(coordinate, {
3239
+ symbol: {
3240
+ url: model.url,
3241
+ rotationZ,
3242
+ translationX: dir === "up" ? 0 : model.size * Math.cos(Math.PI * rotationZ / 180),
3243
+ translationY: dir === "up" ? 0 : model.size * Math.sin(Math.PI * rotationZ / 180),
3244
+ translationZ: dir === "up" ? -0.05 * model.size : -0.5 * model.size
3455
3245
  }
3456
3246
  });
3457
- model.rotation.y += dir === "up" ? Math.PI + angle : angle;
3458
- const box = new THREE2.Box3().setFromObject(model);
3459
- const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
3460
- 1 * (box.min.x + box.max.x),
3461
- 1 * (box.min.y + box.max.y),
3462
- 0.6 * box.max.z
3463
- );
3464
- const pivot = new THREE2.Group();
3465
- pivot.add(model);
3466
- model.position.sub(pivotPoint);
3467
- model.updateMatrixWorld(true);
3468
- const altitude = f.properties.ordinal * HEIGHT_METER;
3469
- const baseObjectModel = this.threeLayer.toModel(pivot, {
3470
- coordinate,
3471
- altitude
3472
- });
3473
- this.threeLayer.addMesh(baseObjectModel);
3474
- return baseObjectModel;
3475
- }
3476
- async createTree(coordinate, ordinal) {
3477
- const model = await this.loadModel3d({
3478
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
3479
- properties: {
3480
- rotation: {
3481
- x: 0.5 * Math.PI,
3482
- // Rotate the model up (new_escalator.glb)
3483
- y: 0,
3484
- z: 0
3485
- },
3486
- position: { x: 0, y: 0, z: 0 },
3487
- scale: 0.01
3247
+ escalatorMarker.addTo(this.gltfLayer);
3248
+ return escalatorMarker;
3249
+ }
3250
+ // Note: Move to another renderer and keep this file on Geometry only?
3251
+ createGroundLabel(f, unit) {
3252
+ const text = f.properties.name;
3253
+ const bound = f.geometry.coordinates[0];
3254
+ const { height: unitHeight } = get3DRendererOption("unit", unit.properties.category, this.options);
3255
+ const options = { bottomHeight: unitHeight + 5e-3 };
3256
+ const groundLabel = new GroundLabel(bound, text, options, this.threeLayer);
3257
+ this.threeLayer.addMesh(groundLabel);
3258
+ return groundLabel;
3259
+ }
3260
+ async createModel3d(f) {
3261
+ const marker = new maptalks4.GLTFMarker(f.properties.center, {
3262
+ symbol: {
3263
+ url: f.properties.model
3488
3264
  }
3489
3265
  });
3490
- const altitude = ordinal * HEIGHT_METER;
3491
- const baseObjectModel = this.threeLayer.toModel(model, {
3492
- coordinate,
3493
- altitude
3494
- });
3495
- this.threeLayer.addMesh(baseObjectModel);
3496
- return baseObjectModel;
3266
+ marker.addTo(this.gltfLayer);
3267
+ return marker;
3268
+ }
3269
+ async createBuilding(coordinate, ordinal) {
3270
+ return Promise.resolve(null);
3497
3271
  }
3498
3272
  createElement(f) {
3499
3273
  switch (f.feature_type) {
@@ -3516,34 +3290,35 @@ var Element3DRenderer = class extends EventTarget {
3516
3290
  }
3517
3291
  });
3518
3292
  }
3519
- async loadModel3d(model3d) {
3520
- const loader = new GLTFLoader2();
3521
- loader.setDRACOLoader(this.dracoLoader);
3522
- const { url, properties: modelProperties } = model3d;
3523
- const gltf = await loader.loadAsync(url);
3524
- const model = gltf.scene;
3525
- model.rotation.x = modelProperties.rotation.x;
3526
- model.rotation.y = modelProperties.rotation.y;
3527
- model.position.x = modelProperties.position.x;
3528
- model.position.y = modelProperties.position.y;
3529
- model.position.z = modelProperties.position.z;
3530
- const scale2 = modelProperties.scale;
3531
- model.scale.set(scale2, scale2, scale2);
3532
- return model;
3533
- }
3534
- createMarker = (coordinates, ordinal, text) => {
3535
- const options = {
3536
- // scale: 0.05,
3537
- // altitude: ordinal * HEIGHT_METER,
3538
- text
3539
- // interactive: true,
3540
- };
3541
- const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
3542
- this.threeLayer.addMesh([marker]);
3543
- return marker;
3544
- };
3545
- removeMarker = () => {
3546
- };
3293
+ createHighlightController(element) {
3294
+ if (!(element instanceof BaseObject5)) {
3295
+ return null;
3296
+ }
3297
+ switch (element.type) {
3298
+ case "ExtrudePolygon":
3299
+ case "ExtrudeLine": {
3300
+ const mesh = element.getObject3d();
3301
+ const originalMaterial = mesh.material;
3302
+ const highlightMaterial = this.getOrCreateMaterialByColor("#ff0000");
3303
+ return {
3304
+ start: () => {
3305
+ mesh.material = highlightMaterial;
3306
+ },
3307
+ clear: () => {
3308
+ mesh.material = originalMaterial;
3309
+ }
3310
+ };
3311
+ }
3312
+ default: {
3313
+ return {
3314
+ start() {
3315
+ },
3316
+ clear() {
3317
+ }
3318
+ };
3319
+ }
3320
+ }
3321
+ }
3547
3322
  render() {
3548
3323
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3549
3324
  if (this.threeLayer._needsUpdate) {
@@ -3602,7 +3377,7 @@ var getGeometryProperties = (feature2) => ({
3602
3377
  category: feature2.properties.category,
3603
3378
  name: feature2.properties.name?.en
3604
3379
  });
3605
- var getGeometryOption2 = (feature2, options) => {
3380
+ var getGeometryOption = (feature2, options) => {
3606
3381
  try {
3607
3382
  const option = options[feature2.feature_type] ?? element2DRendererOptions[feature2.feature_type];
3608
3383
  const category = feature2.properties.category;
@@ -3629,7 +3404,7 @@ var Element2DRenderer = class extends EventTarget {
3629
3404
  }
3630
3405
  createGeometry = (imdfFeature) => {
3631
3406
  const feature2 = getGeometryProperties(imdfFeature);
3632
- const { symbol, ...options } = getGeometryOption2(imdfFeature, this.options);
3407
+ const { symbol, ...options } = getGeometryOption(imdfFeature, this.options);
3633
3408
  const altitude = feature2.properties.ordinal * 10;
3634
3409
  const geometry = maptalks5.Geometry.fromJSON({
3635
3410
  feature: feature2,
@@ -3640,135 +3415,283 @@ var Element2DRenderer = class extends EventTarget {
3640
3415
  properties: { altitude }
3641
3416
  }
3642
3417
  });
3643
- if (Array.isArray(geometry)) {
3644
- geometry.forEach((g) => g.addTo(this.elementLayer));
3645
- return new maptalks5.GeometryCollection(geometry);
3646
- } else {
3647
- geometry.addTo(this.elementLayer);
3648
- return geometry;
3649
- }
3650
- };
3651
- async createEscalator(f, coordinates) {
3652
- return Promise.resolve(null);
3653
- }
3654
- async createTree(f, coordinates) {
3655
- return Promise.resolve(null);
3656
- }
3657
- createElement = (imdfFeature) => {
3658
- switch (imdfFeature.feature_type) {
3659
- default:
3660
- return null;
3418
+ if (Array.isArray(geometry)) {
3419
+ geometry.forEach((g) => g.addTo(this.elementLayer));
3420
+ return new maptalks5.GeometryCollection(geometry);
3421
+ } else {
3422
+ geometry.addTo(this.elementLayer);
3423
+ return geometry;
3424
+ }
3425
+ };
3426
+ createRoomWall(unit, openings) {
3427
+ return null;
3428
+ }
3429
+ async createEscalator(f, coordinates) {
3430
+ return Promise.resolve(null);
3431
+ }
3432
+ createGroundLabel(f, unit) {
3433
+ const text = f.properties.name;
3434
+ const bound = f.geometry.coordinates[0];
3435
+ return null;
3436
+ }
3437
+ async createBuilding(coordinate, ordinal) {
3438
+ return Promise.resolve(null);
3439
+ }
3440
+ createElement = (imdfFeature) => {
3441
+ switch (imdfFeature.feature_type) {
3442
+ default:
3443
+ return null;
3444
+ }
3445
+ };
3446
+ showElements(elements, ordinalDiff = 0) {
3447
+ elements.forEach((element) => {
3448
+ element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER2);
3449
+ element.show();
3450
+ });
3451
+ }
3452
+ hideElements(elements, ordinalDiff = 0) {
3453
+ elements.forEach((element) => {
3454
+ element.hide();
3455
+ });
3456
+ }
3457
+ createHighlightController(element) {
3458
+ if (!(element instanceof maptalks5.Geometry)) return null;
3459
+ return {
3460
+ start() {
3461
+ },
3462
+ clear() {
3463
+ }
3464
+ };
3465
+ }
3466
+ };
3467
+
3468
+ // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
3469
+ import * as maptalks6 from "maptalks";
3470
+ var Marker2DRenderer = class extends EventTarget {
3471
+ isReady = false;
3472
+ map;
3473
+ markerLayer;
3474
+ constructor(map) {
3475
+ super();
3476
+ this.map = map;
3477
+ }
3478
+ createMarker = (coordinates, ordinal, content) => {
3479
+ const marker = new maptalks6.ui.UIMarker(coordinates, {
3480
+ content,
3481
+ collision: true,
3482
+ collisionFadeIn: true,
3483
+ altitude: 0
3484
+ });
3485
+ marker.addTo(this.map);
3486
+ return marker;
3487
+ };
3488
+ removeMarker = (marker) => {
3489
+ marker.remove();
3490
+ };
3491
+ showMarkers(elements, ordinalDiff = 0) {
3492
+ }
3493
+ hideMarkers(elements, ordinalDiff = 0) {
3494
+ }
3495
+ };
3496
+
3497
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3498
+ import * as maptalks7 from "maptalks-gl";
3499
+
3500
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3501
+ import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3502
+ import * as THREE2 from "three";
3503
+ import { BaseObject as BaseObject6 } from "maptalks.three";
3504
+ import { isNil, set } from "lodash";
3505
+
3506
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3507
+ var interpolateStops = ({ stops }, zoom) => {
3508
+ if (zoom <= stops[0][0]) return stops[0][1];
3509
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3510
+ for (let i = 0; i < stops.length - 1; i++) {
3511
+ const [z1, v1] = stops[i];
3512
+ const [z2, v2] = stops[i + 1];
3513
+ if (zoom >= z1 && zoom <= z2) {
3514
+ const t = (zoom - z1) / (z2 - z1);
3515
+ return v1 + t * (v2 - v1);
3516
+ }
3517
+ }
3518
+ };
3519
+
3520
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3521
+ var OPTIONS4 = {
3522
+ // Texture options
3523
+ text: "",
3524
+ textAlign: "center",
3525
+ color: "#ffffff",
3526
+ fontFamily: "sans-serif",
3527
+ fontSize: 28,
3528
+ fontWeight: 400,
3529
+ background: "transparent",
3530
+ lineHeight: 32,
3531
+ padding: 8,
3532
+ strokeColor: "#000000",
3533
+ strokeWidth: 3,
3534
+ strokeStyle: "round",
3535
+ // Sprite options
3536
+ /* Overall scale multiplier */
3537
+ scale: 1,
3538
+ altitude: 0,
3539
+ opacity: 1
3540
+ };
3541
+ var TextSpriteMarker = class extends BaseObject6 {
3542
+ #altitudeOffset = 0;
3543
+ constructor(coordinate, options, layer, properties = {}) {
3544
+ options = Util4.extend({}, OPTIONS4, options, { layer });
3545
+ super();
3546
+ this._coordinate = new Coordinate2(coordinate);
3547
+ this._initOptions(options);
3548
+ this._createGroup();
3549
+ this.properties = { ...properties };
3550
+ const sprite = this._createSprite();
3551
+ this.getObject3d().add(sprite);
3552
+ this._updatePosition();
3553
+ this.type = "TextSpriteMarker";
3554
+ }
3555
+ getOptions() {
3556
+ return super.getOptions();
3557
+ }
3558
+ _createSprite() {
3559
+ const options = this.getOptions();
3560
+ const texture = this._createTextTexture(options.text, options);
3561
+ const material = new THREE2.SpriteMaterial({
3562
+ map: texture,
3563
+ transparent: true,
3564
+ alphaTest: 0.1
3565
+ });
3566
+ const sprite = new THREE2.Sprite(material);
3567
+ const w = texture.image.width;
3568
+ const h = texture.image.height;
3569
+ const base = 1 / 16;
3570
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3571
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3572
+ this.#altitudeOffset = Math.max(
3573
+ h * base * options.scale * 0.5,
3574
+ 0.05
3575
+ // minimum lift in world units
3576
+ );
3577
+ return sprite;
3578
+ }
3579
+ _createTextTexture(text, options = {}) {
3580
+ const {
3581
+ padding,
3582
+ fontSize,
3583
+ fontFamily,
3584
+ fontWeight,
3585
+ lineHeight,
3586
+ background,
3587
+ color,
3588
+ textAlign,
3589
+ strokeColor,
3590
+ strokeWidth,
3591
+ maxWidth
3592
+ } = options || {};
3593
+ const canvas = document.createElement("canvas");
3594
+ const ctx = canvas.getContext("2d");
3595
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3596
+ const paragraphs = String(text).split("\n");
3597
+ const wrappedLines = [];
3598
+ paragraphs.forEach((paragraph) => {
3599
+ if (isNil(maxWidth) || isNaN(maxWidth)) {
3600
+ wrappedLines.push(paragraph);
3601
+ return;
3602
+ }
3603
+ const words = paragraph.split(/\s+/);
3604
+ let currentLine = "";
3605
+ words.forEach((word) => {
3606
+ const testLine = currentLine ? currentLine + " " + word : word;
3607
+ const testWidth = ctx.measureText(testLine).width;
3608
+ if (testWidth > maxWidth && currentLine) {
3609
+ wrappedLines.push(currentLine);
3610
+ currentLine = word;
3611
+ } else {
3612
+ currentLine = testLine;
3613
+ }
3614
+ });
3615
+ if (currentLine) {
3616
+ wrappedLines.push(currentLine);
3617
+ }
3618
+ });
3619
+ const lines = wrappedLines.length ? wrappedLines : [""];
3620
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3621
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3622
+ const finalHeight = lineHeight * lines.length + padding * 2;
3623
+ canvas.width = finalWidth;
3624
+ canvas.height = finalHeight;
3625
+ const ctx2 = canvas.getContext("2d");
3626
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3627
+ ctx2.textAlign = textAlign;
3628
+ if (background && background !== "transparent") {
3629
+ ctx2.fillStyle = background;
3630
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3661
3631
  }
3662
- };
3663
- showElements(elements, ordinalDiff = 0) {
3664
- elements.forEach((element) => {
3665
- element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER2);
3666
- element.show();
3667
- });
3668
- }
3669
- hideElements(elements, ordinalDiff = 0) {
3670
- elements.forEach((element) => {
3671
- element.hide();
3632
+ lines.forEach((line, i) => {
3633
+ const y = padding + lineHeight * (i + 0.8);
3634
+ let x = padding;
3635
+ if (textAlign === "center") x = canvas.width / 2;
3636
+ if (textAlign === "right" || textAlign === "end")
3637
+ x = canvas.width - padding;
3638
+ if (strokeWidth > 0) {
3639
+ ctx2.lineWidth = strokeWidth;
3640
+ ctx2.lineJoin = "round";
3641
+ ctx2.miterLimit = 2;
3642
+ ctx2.strokeStyle = strokeColor;
3643
+ ctx2.strokeText(line, x, y);
3644
+ }
3645
+ ctx2.fillStyle = color;
3646
+ ctx2.fillText(line, x, y);
3672
3647
  });
3648
+ const texture = new THREE2.CanvasTexture(canvas);
3649
+ texture.needsUpdate = true;
3650
+ texture.minFilter = THREE2.LinearFilter;
3651
+ return texture;
3673
3652
  }
3674
- };
3675
-
3676
- // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
3677
- import * as maptalks6 from "maptalks";
3678
- var Marker2DRenderer = class extends EventTarget {
3679
- isReady = false;
3680
- map;
3681
- markerLayer;
3682
- constructor(map) {
3683
- super();
3684
- }
3685
- createMarker = (coordinates, ordinal, content) => {
3686
- const marker = new maptalks6.ui.UIMarker(coordinates, {
3687
- content,
3688
- collision: true,
3689
- collisionFadeIn: true,
3690
- altitude: 0
3691
- });
3692
- marker.addTo(this.map);
3693
- return marker;
3694
- };
3695
- removeMarker = (marker) => {
3696
- marker.remove();
3697
- };
3698
- showMarkers(elements, ordinalDiff = 0) {
3653
+ _updatePosition() {
3654
+ const options = this.getOptions();
3655
+ const layer = options.layer;
3656
+ if (!layer) return;
3657
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3658
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3659
+ const position = layer.coordinateToVector3(this._coordinate, z);
3660
+ set(this.properties, "default.position", position);
3661
+ this.getObject3d().position.copy(position);
3699
3662
  }
3700
- hideMarkers(elements, ordinalDiff = 0) {
3663
+ _animation() {
3664
+ const layer = this.getLayer();
3665
+ if (!this.isAdd || !layer) return;
3666
+ if (this._visible === true) {
3667
+ const zoom = layer.map.getZoom();
3668
+ const object3d = this.getObject3d();
3669
+ const { opacity } = this.getOptions();
3670
+ let opacityValue;
3671
+ if (typeof opacity === "number") {
3672
+ opacityValue = opacity ?? 1;
3673
+ } else if (Array.isArray(opacity.stops)) {
3674
+ opacityValue = interpolateStops(opacity, zoom);
3675
+ } else {
3676
+ throw new Error(`Unknown opacity value ${opacity}`);
3677
+ }
3678
+ const visible = opacityValue > 0.5;
3679
+ object3d.visible = visible;
3680
+ }
3701
3681
  }
3702
- };
3703
-
3704
- // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3705
- import * as maptalks7 from "maptalks";
3706
-
3707
- // src/IndoorMap/renderer/utils/svg2material.ts
3708
- import { SpriteMaterial as SpriteMaterial5, TextureLoader as TextureLoader3 } from "three";
3709
- var svgToDataURL = (svgString, scaleFactor = 1) => {
3710
- const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
3711
- const url = URL.createObjectURL(svgBlob);
3712
- const img = new Image();
3713
- return new Promise((resolve, reject) => {
3714
- img.onload = function() {
3715
- const newWidth = img.width * scaleFactor;
3716
- const newHeight = img.height * scaleFactor;
3717
- const canvas = document.createElement("canvas");
3718
- canvas.width = newWidth;
3719
- canvas.height = newHeight;
3720
- const ctx = canvas.getContext("2d");
3721
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
3722
- const pngDataUrl = canvas.toDataURL("image/png");
3723
- resolve(pngDataUrl);
3724
- };
3725
- img.onerror = function(error) {
3726
- reject(error);
3727
- };
3728
- img.src = url;
3729
- });
3730
- };
3731
- var createSVGPathFromMarkerSymbol2 = (style) => {
3732
- const {
3733
- markerWidth = 24,
3734
- markerDx = 0,
3735
- markerDy = 0,
3736
- // markerFill,
3737
- markerPath,
3738
- fill = "#000000"
3739
- } = style;
3740
- const scale2 = markerWidth / 24;
3741
- const strokeWidth = 2;
3742
- const halfStrokeWidth = 0.5 * strokeWidth;
3743
- if (Array.isArray(markerPath)) {
3744
- return markerPath.map(
3745
- ({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
3746
- );
3682
+ setText(text) {
3683
+ const options = this.getOptions();
3684
+ options.text = text;
3685
+ const newSprite = this._createSprite();
3686
+ const group = this.getObject3d();
3687
+ group.children.forEach((child) => group.remove(child));
3688
+ group.add(newSprite);
3689
+ this._updatePosition();
3747
3690
  }
3748
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
3749
- };
3750
- var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
3751
- const material = new SpriteMaterial5();
3752
- try {
3753
- const [base, icon] = labelSymbol ?? [{}, {}];
3754
- const { markerWidth: baseWidth = 24 } = base;
3755
- const { markerWidth: iconWidth = 24 } = icon;
3756
- const viewBoxDimension = Math.max(baseWidth, iconWidth);
3757
- const baseSVG = createSVGPathFromMarkerSymbol2(base);
3758
- const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
3759
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
3760
- const textureLoader = new TextureLoader3();
3761
- const scaleFactor = 200 / 24;
3762
- svgToDataURL(svg, scaleFactor).then((png) => {
3763
- const texture = textureLoader.load(png, () => {
3764
- material.map = texture;
3765
- material.needsUpdate = true;
3766
- });
3767
- });
3768
- } catch (error) {
3769
- console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
3691
+ setAltitude(altitude) {
3692
+ const bottomHeight = this.options.bottomHeight ?? 0;
3693
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3770
3694
  }
3771
- return material;
3772
3695
  };
3773
3696
 
3774
3697
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
@@ -3818,67 +3741,547 @@ var Marker3DRenderer = class extends EventTarget {
3818
3741
  }
3819
3742
  });
3820
3743
  }
3821
- /** Marker */
3822
- getOrCreateIconMaterial(key) {
3823
- if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
3824
- const existingMaterial = this.materialByKey.get(key);
3825
- if (existingMaterial) return existingMaterial;
3826
- const baseSymbol = {
3827
- markerType: "path",
3828
- markerPath: [
3829
- {
3830
- path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3831
- fill: "#ff0000"
3832
- }
3833
- ],
3834
- markerPathWidth: 24,
3835
- markerPathHeight: 24
3836
- };
3837
- const markerSymbol = {
3838
- markerType: "path",
3839
- markerPath: [],
3840
- // TODO: Get Path by featureType.category
3841
- // markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
3842
- markerPathWidth: 24,
3843
- markerPathHeight: 24,
3844
- markerWidth: 24,
3845
- markerHeight: 24,
3846
- markerDy: 1.5,
3847
- markerDx: 1.5
3848
- };
3849
- const created = createSpriteMaterialByLabelSymbol2([
3850
- baseSymbol,
3851
- markerSymbol
3852
- ]);
3853
- this.materialByKey.set(key, created);
3854
- return created;
3744
+ /** Marker */
3745
+ // getOrCreateIconMaterial(key) {
3746
+ // if (!this.materialByKey) this.materialByKey = new Map()
3747
+ // const existingMaterial = this.materialByKey.get(key)
3748
+ // if (existingMaterial) return existingMaterial
3749
+ // // Create new
3750
+ // const baseSymbol: maptalks.Path = {
3751
+ // markerType: "path",
3752
+ // markerPath: [
3753
+ // {
3754
+ // path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3755
+ // fill: "#ff0000",
3756
+ // },
3757
+ // ],
3758
+ // markerPathWidth: 24,
3759
+ // markerPathHeight: 24
3760
+ // }
3761
+ // const markerSymbol: maptalks.PathMarkerSymbol = {
3762
+ // markerType: "path",
3763
+ // markerPath: [],
3764
+ // // TODO: Get Path by featureType.category
3765
+ // // 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" }],
3766
+ // markerPathWidth: 24,
3767
+ // markerPathHeight: 24,
3768
+ // markerWidth: 24,
3769
+ // markerHeight: 24,
3770
+ // markerDy: 1.5,
3771
+ // markerDx: 1.5,
3772
+ // }
3773
+ // const created = createSpriteMaterialByLabelSymbol([
3774
+ // baseSymbol,
3775
+ // markerSymbol,
3776
+ // ])
3777
+ // this.materialByKey.set(key, created)
3778
+ // return created
3779
+ // }
3780
+ };
3781
+
3782
+ // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
3783
+ var getLineCenter = (line) => {
3784
+ let x = 0, y = 0;
3785
+ for (const [lx, ly] of line) {
3786
+ x += lx;
3787
+ y += ly;
3788
+ }
3789
+ const len = line.length;
3790
+ return [x / len, y / len];
3791
+ };
3792
+ var angleBetweenLineStrings = (line1, line2) => {
3793
+ const [x1, y1] = getLineCenter(line1);
3794
+ const [x2, y2] = getLineCenter(line2);
3795
+ const dx = x2 - x1;
3796
+ const dy = y2 - y1;
3797
+ return Math.atan2(dy, dx);
3798
+ };
3799
+
3800
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/util.js
3801
+ var epsilon = 11102230246251565e-32;
3802
+ var splitter = 134217729;
3803
+ var resulterrbound = (3 + 8 * epsilon) * epsilon;
3804
+ function sum(elen, e, flen, f, h) {
3805
+ let Q, Qnew, hh, bvirt;
3806
+ let enow = e[0];
3807
+ let fnow = f[0];
3808
+ let eindex = 0;
3809
+ let findex = 0;
3810
+ if (fnow > enow === fnow > -enow) {
3811
+ Q = enow;
3812
+ enow = e[++eindex];
3813
+ } else {
3814
+ Q = fnow;
3815
+ fnow = f[++findex];
3816
+ }
3817
+ let hindex = 0;
3818
+ if (eindex < elen && findex < flen) {
3819
+ if (fnow > enow === fnow > -enow) {
3820
+ Qnew = enow + Q;
3821
+ hh = Q - (Qnew - enow);
3822
+ enow = e[++eindex];
3823
+ } else {
3824
+ Qnew = fnow + Q;
3825
+ hh = Q - (Qnew - fnow);
3826
+ fnow = f[++findex];
3827
+ }
3828
+ Q = Qnew;
3829
+ if (hh !== 0) {
3830
+ h[hindex++] = hh;
3831
+ }
3832
+ while (eindex < elen && findex < flen) {
3833
+ if (fnow > enow === fnow > -enow) {
3834
+ Qnew = Q + enow;
3835
+ bvirt = Qnew - Q;
3836
+ hh = Q - (Qnew - bvirt) + (enow - bvirt);
3837
+ enow = e[++eindex];
3838
+ } else {
3839
+ Qnew = Q + fnow;
3840
+ bvirt = Qnew - Q;
3841
+ hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3842
+ fnow = f[++findex];
3843
+ }
3844
+ Q = Qnew;
3845
+ if (hh !== 0) {
3846
+ h[hindex++] = hh;
3847
+ }
3848
+ }
3849
+ }
3850
+ while (eindex < elen) {
3851
+ Qnew = Q + enow;
3852
+ bvirt = Qnew - Q;
3853
+ hh = Q - (Qnew - bvirt) + (enow - bvirt);
3854
+ enow = e[++eindex];
3855
+ Q = Qnew;
3856
+ if (hh !== 0) {
3857
+ h[hindex++] = hh;
3858
+ }
3859
+ }
3860
+ while (findex < flen) {
3861
+ Qnew = Q + fnow;
3862
+ bvirt = Qnew - Q;
3863
+ hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3864
+ fnow = f[++findex];
3865
+ Q = Qnew;
3866
+ if (hh !== 0) {
3867
+ h[hindex++] = hh;
3868
+ }
3869
+ }
3870
+ if (Q !== 0 || hindex === 0) {
3871
+ h[hindex++] = Q;
3872
+ }
3873
+ return hindex;
3874
+ }
3875
+ function estimate(elen, e) {
3876
+ let Q = e[0];
3877
+ for (let i = 1; i < elen; i++) Q += e[i];
3878
+ return Q;
3879
+ }
3880
+ function vec(n) {
3881
+ return new Float64Array(n);
3882
+ }
3883
+
3884
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient2d.js
3885
+ var ccwerrboundA = (3 + 16 * epsilon) * epsilon;
3886
+ var ccwerrboundB = (2 + 12 * epsilon) * epsilon;
3887
+ var ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;
3888
+ var B = vec(4);
3889
+ var C1 = vec(8);
3890
+ var C2 = vec(12);
3891
+ var D = vec(16);
3892
+ var u = vec(4);
3893
+ function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {
3894
+ let acxtail, acytail, bcxtail, bcytail;
3895
+ let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u32;
3896
+ const acx = ax - cx;
3897
+ const bcx = bx - cx;
3898
+ const acy = ay - cy;
3899
+ const bcy = by - cy;
3900
+ s1 = acx * bcy;
3901
+ c = splitter * acx;
3902
+ ahi = c - (c - acx);
3903
+ alo = acx - ahi;
3904
+ c = splitter * bcy;
3905
+ bhi = c - (c - bcy);
3906
+ blo = bcy - bhi;
3907
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3908
+ t1 = acy * bcx;
3909
+ c = splitter * acy;
3910
+ ahi = c - (c - acy);
3911
+ alo = acy - ahi;
3912
+ c = splitter * bcx;
3913
+ bhi = c - (c - bcx);
3914
+ blo = bcx - bhi;
3915
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3916
+ _i = s0 - t0;
3917
+ bvirt = s0 - _i;
3918
+ B[0] = s0 - (_i + bvirt) + (bvirt - t0);
3919
+ _j = s1 + _i;
3920
+ bvirt = _j - s1;
3921
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
3922
+ _i = _0 - t1;
3923
+ bvirt = _0 - _i;
3924
+ B[1] = _0 - (_i + bvirt) + (bvirt - t1);
3925
+ u32 = _j + _i;
3926
+ bvirt = u32 - _j;
3927
+ B[2] = _j - (u32 - bvirt) + (_i - bvirt);
3928
+ B[3] = u32;
3929
+ let det = estimate(4, B);
3930
+ let errbound = ccwerrboundB * detsum;
3931
+ if (det >= errbound || -det >= errbound) {
3932
+ return det;
3933
+ }
3934
+ bvirt = ax - acx;
3935
+ acxtail = ax - (acx + bvirt) + (bvirt - cx);
3936
+ bvirt = bx - bcx;
3937
+ bcxtail = bx - (bcx + bvirt) + (bvirt - cx);
3938
+ bvirt = ay - acy;
3939
+ acytail = ay - (acy + bvirt) + (bvirt - cy);
3940
+ bvirt = by - bcy;
3941
+ bcytail = by - (bcy + bvirt) + (bvirt - cy);
3942
+ if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {
3943
+ return det;
3944
+ }
3945
+ errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);
3946
+ det += acx * bcytail + bcy * acxtail - (acy * bcxtail + bcx * acytail);
3947
+ if (det >= errbound || -det >= errbound) return det;
3948
+ s1 = acxtail * bcy;
3949
+ c = splitter * acxtail;
3950
+ ahi = c - (c - acxtail);
3951
+ alo = acxtail - ahi;
3952
+ c = splitter * bcy;
3953
+ bhi = c - (c - bcy);
3954
+ blo = bcy - bhi;
3955
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3956
+ t1 = acytail * bcx;
3957
+ c = splitter * acytail;
3958
+ ahi = c - (c - acytail);
3959
+ alo = acytail - ahi;
3960
+ c = splitter * bcx;
3961
+ bhi = c - (c - bcx);
3962
+ blo = bcx - bhi;
3963
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3964
+ _i = s0 - t0;
3965
+ bvirt = s0 - _i;
3966
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
3967
+ _j = s1 + _i;
3968
+ bvirt = _j - s1;
3969
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
3970
+ _i = _0 - t1;
3971
+ bvirt = _0 - _i;
3972
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
3973
+ u32 = _j + _i;
3974
+ bvirt = u32 - _j;
3975
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
3976
+ u[3] = u32;
3977
+ const C1len = sum(4, B, 4, u, C1);
3978
+ s1 = acx * bcytail;
3979
+ c = splitter * acx;
3980
+ ahi = c - (c - acx);
3981
+ alo = acx - ahi;
3982
+ c = splitter * bcytail;
3983
+ bhi = c - (c - bcytail);
3984
+ blo = bcytail - bhi;
3985
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3986
+ t1 = acy * bcxtail;
3987
+ c = splitter * acy;
3988
+ ahi = c - (c - acy);
3989
+ alo = acy - ahi;
3990
+ c = splitter * bcxtail;
3991
+ bhi = c - (c - bcxtail);
3992
+ blo = bcxtail - bhi;
3993
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3994
+ _i = s0 - t0;
3995
+ bvirt = s0 - _i;
3996
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
3997
+ _j = s1 + _i;
3998
+ bvirt = _j - s1;
3999
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
4000
+ _i = _0 - t1;
4001
+ bvirt = _0 - _i;
4002
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4003
+ u32 = _j + _i;
4004
+ bvirt = u32 - _j;
4005
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4006
+ u[3] = u32;
4007
+ const C2len = sum(C1len, C1, 4, u, C2);
4008
+ s1 = acxtail * bcytail;
4009
+ c = splitter * acxtail;
4010
+ ahi = c - (c - acxtail);
4011
+ alo = acxtail - ahi;
4012
+ c = splitter * bcytail;
4013
+ bhi = c - (c - bcytail);
4014
+ blo = bcytail - bhi;
4015
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
4016
+ t1 = acytail * bcxtail;
4017
+ c = splitter * acytail;
4018
+ ahi = c - (c - acytail);
4019
+ alo = acytail - ahi;
4020
+ c = splitter * bcxtail;
4021
+ bhi = c - (c - bcxtail);
4022
+ blo = bcxtail - bhi;
4023
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
4024
+ _i = s0 - t0;
4025
+ bvirt = s0 - _i;
4026
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
4027
+ _j = s1 + _i;
4028
+ bvirt = _j - s1;
4029
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
4030
+ _i = _0 - t1;
4031
+ bvirt = _0 - _i;
4032
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4033
+ u32 = _j + _i;
4034
+ bvirt = u32 - _j;
4035
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4036
+ u[3] = u32;
4037
+ const Dlen = sum(C2len, C2, 4, u, D);
4038
+ return D[Dlen - 1];
4039
+ }
4040
+ function orient2d(ax, ay, bx, by, cx, cy) {
4041
+ const detleft = (ay - cy) * (bx - cx);
4042
+ const detright = (ax - cx) * (by - cy);
4043
+ const det = detleft - detright;
4044
+ const detsum = Math.abs(detleft + detright);
4045
+ if (Math.abs(det) >= ccwerrboundA * detsum) return det;
4046
+ return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);
4047
+ }
4048
+
4049
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient3d.js
4050
+ var o3derrboundA = (7 + 56 * epsilon) * epsilon;
4051
+ var o3derrboundB = (3 + 28 * epsilon) * epsilon;
4052
+ var o3derrboundC = (26 + 288 * epsilon) * epsilon * epsilon;
4053
+ var bc = vec(4);
4054
+ var ca = vec(4);
4055
+ var ab = vec(4);
4056
+ var at_b = vec(4);
4057
+ var at_c = vec(4);
4058
+ var bt_c = vec(4);
4059
+ var bt_a = vec(4);
4060
+ var ct_a = vec(4);
4061
+ var ct_b = vec(4);
4062
+ var bct = vec(8);
4063
+ var cat = vec(8);
4064
+ var abt = vec(8);
4065
+ var u2 = vec(4);
4066
+ var _8 = vec(8);
4067
+ var _8b = vec(8);
4068
+ var _16 = vec(8);
4069
+ var _12 = vec(12);
4070
+ var fin = vec(192);
4071
+ var fin2 = vec(192);
4072
+
4073
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/incircle.js
4074
+ var iccerrboundA = (10 + 96 * epsilon) * epsilon;
4075
+ var iccerrboundB = (4 + 48 * epsilon) * epsilon;
4076
+ var iccerrboundC = (44 + 576 * epsilon) * epsilon * epsilon;
4077
+ var bc2 = vec(4);
4078
+ var ca2 = vec(4);
4079
+ var ab2 = vec(4);
4080
+ var aa = vec(4);
4081
+ var bb = vec(4);
4082
+ var cc = vec(4);
4083
+ var u3 = vec(4);
4084
+ var v = vec(4);
4085
+ var axtbc = vec(8);
4086
+ var aytbc = vec(8);
4087
+ var bxtca = vec(8);
4088
+ var bytca = vec(8);
4089
+ var cxtab = vec(8);
4090
+ var cytab = vec(8);
4091
+ var abt2 = vec(8);
4092
+ var bct2 = vec(8);
4093
+ var cat2 = vec(8);
4094
+ var abtt = vec(4);
4095
+ var bctt = vec(4);
4096
+ var catt = vec(4);
4097
+ var _82 = vec(8);
4098
+ var _162 = vec(16);
4099
+ var _16b = vec(16);
4100
+ var _16c = vec(16);
4101
+ var _32 = vec(32);
4102
+ var _32b = vec(32);
4103
+ var _48 = vec(48);
4104
+ var _64 = vec(64);
4105
+ var fin3 = vec(1152);
4106
+ var fin22 = vec(1152);
4107
+
4108
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/insphere.js
4109
+ var isperrboundA = (16 + 224 * epsilon) * epsilon;
4110
+ var isperrboundB = (5 + 72 * epsilon) * epsilon;
4111
+ var isperrboundC = (71 + 1408 * epsilon) * epsilon * epsilon;
4112
+ var ab3 = vec(4);
4113
+ var bc3 = vec(4);
4114
+ var cd = vec(4);
4115
+ var de = vec(4);
4116
+ var ea = vec(4);
4117
+ var ac = vec(4);
4118
+ var bd = vec(4);
4119
+ var ce = vec(4);
4120
+ var da = vec(4);
4121
+ var eb = vec(4);
4122
+ var abc = vec(24);
4123
+ var bcd = vec(24);
4124
+ var cde = vec(24);
4125
+ var dea = vec(24);
4126
+ var eab = vec(24);
4127
+ var abd = vec(24);
4128
+ var bce = vec(24);
4129
+ var cda = vec(24);
4130
+ var deb = vec(24);
4131
+ var eac = vec(24);
4132
+ var adet = vec(1152);
4133
+ var bdet = vec(1152);
4134
+ var cdet = vec(1152);
4135
+ var ddet = vec(1152);
4136
+ var edet = vec(1152);
4137
+ var abdet = vec(2304);
4138
+ var cddet = vec(2304);
4139
+ var cdedet = vec(3456);
4140
+ var deter = vec(5760);
4141
+ var _83 = vec(8);
4142
+ var _8b2 = vec(8);
4143
+ var _8c = vec(8);
4144
+ var _163 = vec(16);
4145
+ var _24 = vec(24);
4146
+ var _482 = vec(48);
4147
+ var _48b = vec(48);
4148
+ var _96 = vec(96);
4149
+ var _192 = vec(192);
4150
+ var _384x = vec(384);
4151
+ var _384y = vec(384);
4152
+ var _384z = vec(384);
4153
+ var _768 = vec(768);
4154
+ var xdet = vec(96);
4155
+ var ydet = vec(96);
4156
+ var zdet = vec(96);
4157
+ var fin4 = vec(1152);
4158
+
4159
+ // ../../node_modules/point-in-polygon-hao/dist/esm/index.js
4160
+ function pointInPolygon(p, polygon2) {
4161
+ var i;
4162
+ var ii;
4163
+ var k = 0;
4164
+ var f;
4165
+ var u1;
4166
+ var v1;
4167
+ var u22;
4168
+ var v2;
4169
+ var currentP;
4170
+ var nextP;
4171
+ var x = p[0];
4172
+ var y = p[1];
4173
+ var numContours = polygon2.length;
4174
+ for (i = 0; i < numContours; i++) {
4175
+ ii = 0;
4176
+ var contour = polygon2[i];
4177
+ var contourLen = contour.length - 1;
4178
+ currentP = contour[0];
4179
+ if (currentP[0] !== contour[contourLen][0] && currentP[1] !== contour[contourLen][1]) {
4180
+ throw new Error("First and last coordinates in a ring must be the same");
4181
+ }
4182
+ u1 = currentP[0] - x;
4183
+ v1 = currentP[1] - y;
4184
+ for (ii; ii < contourLen; ii++) {
4185
+ nextP = contour[ii + 1];
4186
+ u22 = nextP[0] - x;
4187
+ v2 = nextP[1] - y;
4188
+ if (v1 === 0 && v2 === 0) {
4189
+ if (u22 <= 0 && u1 >= 0 || u1 <= 0 && u22 >= 0) {
4190
+ return 0;
4191
+ }
4192
+ } else if (v2 >= 0 && v1 <= 0 || v2 <= 0 && v1 >= 0) {
4193
+ f = orient2d(u1, u22, v1, v2, 0, 0);
4194
+ if (f === 0) {
4195
+ return 0;
4196
+ }
4197
+ if (f > 0 && v2 > 0 && v1 <= 0 || f < 0 && v2 <= 0 && v1 > 0) {
4198
+ k++;
4199
+ }
4200
+ }
4201
+ currentP = nextP;
4202
+ v1 = v2;
4203
+ u1 = u22;
4204
+ }
4205
+ }
4206
+ if (k % 2 === 0) {
4207
+ return false;
4208
+ }
4209
+ return true;
4210
+ }
4211
+
4212
+ // ../../node_modules/@turf/invariant/dist/esm/index.js
4213
+ function getCoord(coord) {
4214
+ if (!coord) {
4215
+ throw new Error("coord is required");
4216
+ }
4217
+ if (!Array.isArray(coord)) {
4218
+ if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {
4219
+ return [...coord.geometry.coordinates];
4220
+ }
4221
+ if (coord.type === "Point") {
4222
+ return [...coord.coordinates];
4223
+ }
4224
+ }
4225
+ if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {
4226
+ return [...coord];
3855
4227
  }
3856
- };
4228
+ throw new Error("coord must be GeoJSON Point or an Array of numbers");
4229
+ }
4230
+ function getGeom(geojson) {
4231
+ if (geojson.type === "Feature") {
4232
+ return geojson.geometry;
4233
+ }
4234
+ return geojson;
4235
+ }
3857
4236
 
3858
- // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
3859
- var getLineCenter = (line) => {
3860
- let x = 0, y = 0;
3861
- for (const [lx, ly] of line) {
3862
- x += lx;
3863
- y += ly;
4237
+ // ../../node_modules/@turf/boolean-point-in-polygon/dist/esm/index.js
4238
+ function booleanPointInPolygon(point2, polygon2, options = {}) {
4239
+ if (!point2) {
4240
+ throw new Error("point is required");
4241
+ }
4242
+ if (!polygon2) {
4243
+ throw new Error("polygon is required");
4244
+ }
4245
+ const pt = getCoord(point2);
4246
+ const geom = getGeom(polygon2);
4247
+ const type = geom.type;
4248
+ const bbox2 = polygon2.bbox;
4249
+ let polys = geom.coordinates;
4250
+ if (bbox2 && inBBox(pt, bbox2) === false) {
4251
+ return false;
4252
+ }
4253
+ if (type === "Polygon") {
4254
+ polys = [polys];
4255
+ }
4256
+ let result = false;
4257
+ for (var i = 0; i < polys.length; ++i) {
4258
+ const polyResult = pointInPolygon(pt, polys[i]);
4259
+ if (polyResult === 0) return options.ignoreBoundary ? false : true;
4260
+ else if (polyResult) result = true;
3864
4261
  }
3865
- const len = line.length;
3866
- return [x / len, y / len];
3867
- };
3868
- var angleBetweenLineStrings = (line1, line2) => {
3869
- const [x1, y1] = getLineCenter(line1);
3870
- const [x2, y2] = getLineCenter(line2);
3871
- const dx = x2 - x1;
3872
- const dy = y2 - y1;
3873
- return Math.atan2(dy, dx);
4262
+ return result;
4263
+ }
4264
+ function inBBox(pt, bbox2) {
4265
+ return bbox2[0] <= pt[0] && bbox2[1] <= pt[1] && bbox2[2] >= pt[0] && bbox2[3] >= pt[1];
4266
+ }
4267
+
4268
+ // src/IndoorMap/renderer/utils/findUnitOnPoint.ts
4269
+ var findUnitOnPoint = (units, point2) => {
4270
+ return units.find((unit) => booleanPointInPolygon(point2, polygon(unit.geometry.coordinates)));
3874
4271
  };
3875
4272
 
3876
4273
  // src/IndoorMap/renderer/RendererManager.ts
4274
+ function delay(ms) {
4275
+ return new Promise((resolve) => setTimeout(resolve, ms));
4276
+ }
3877
4277
  var RendererManager = class extends EventTarget {
3878
4278
  map;
3879
4279
  options;
3880
4280
  // Client for fetching data
3881
4281
  #dataClient;
4282
+ #isClicked = false;
4283
+ #onClickElement = (e) => {
4284
+ };
3882
4285
  /** Elements: Responsible for converting feature info elements and add to map */
3883
4286
  elementRenderer;
3884
4287
  markerRenderer;
@@ -3887,6 +4290,7 @@ var RendererManager = class extends EventTarget {
3887
4290
  currentOrdinals;
3888
4291
  markersMap;
3889
4292
  markersByOrdinal;
4293
+ highlightControllers = [];
3890
4294
  constructor(map, dataClient, options) {
3891
4295
  super();
3892
4296
  this.map = map;
@@ -3896,48 +4300,87 @@ var RendererManager = class extends EventTarget {
3896
4300
  this.markersMap = /* @__PURE__ */ new Map();
3897
4301
  this.markersByOrdinal = /* @__PURE__ */ new Map();
3898
4302
  this.#dataClient = dataClient;
4303
+ const _this = this;
3899
4304
  if (options.type === "3D") {
3900
- const threeLayer = new ThreeLayer3("elements", {
3901
- forceRenderOnMoving: true,
3902
- forceRenderOnRotating: true
3903
- });
3904
- const _this = this;
4305
+ const groupLayer = this.map.getLayer("group");
4306
+ const threeLayer = groupLayer.getLayer("three");
3905
4307
  threeLayer.prepareToDraw = function(gl, scene, camera) {
4308
+ function findBadMeshes(scene2) {
4309
+ const bad = [];
4310
+ scene2.traverse((obj) => {
4311
+ if (!obj?.isMesh) return;
4312
+ const geom = obj.geometry;
4313
+ const pos = geom?.attributes?.position?.array;
4314
+ if (!pos || pos.length === 0) return;
4315
+ for (let i = 0; i < pos.length; i++) {
4316
+ const v2 = pos[i];
4317
+ if (!Number.isFinite(v2)) {
4318
+ bad.push({ mesh: obj, index: i, value: v2 });
4319
+ break;
4320
+ }
4321
+ }
4322
+ });
4323
+ if (bad.length) {
4324
+ console.group(`\u274C Found ${bad.length} meshes with invalid positions`);
4325
+ for (const b of bad) {
4326
+ console.log({
4327
+ name: b.mesh.name,
4328
+ userData: b.mesh.userData,
4329
+ uuid: b.mesh.uuid,
4330
+ badIndex: b.index,
4331
+ badValue: b.value
4332
+ });
4333
+ }
4334
+ console.groupEnd();
4335
+ } else {
4336
+ console.log("\u2705 No invalid meshes found");
4337
+ }
4338
+ return bad;
4339
+ }
3906
4340
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3907
4341
  scene.add(ambientLight);
3908
4342
  const dirColor = 16777215;
3909
4343
  const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3910
- dllight.position.set(0, -10, 10).normalize();
4344
+ dllight.position.set(0, -10, 20).normalize();
3911
4345
  scene.add(dllight);
3912
4346
  const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3913
4347
  scene.add(hemi);
3914
- _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
4348
+ _this.elementRenderer = new Element3DRenderer(map, options.elements);
3915
4349
  _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3916
4350
  if (typeof options.onRendererReady === "function") {
3917
4351
  options.onRendererReady();
3918
4352
  }
3919
4353
  _this.#createElements();
4354
+ setTimeout(() => {
4355
+ findBadMeshes(scene);
4356
+ }, 3e3);
3920
4357
  };
3921
- threeLayer.addTo(this.map);
3922
4358
  } else {
3923
4359
  this.elementRenderer = new Element2DRenderer(map, options.elements);
3924
4360
  this.markerRenderer = new Marker2DRenderer(map);
3925
4361
  this.#createElements();
3926
4362
  }
3927
4363
  }
4364
+ set onClickElement(func) {
4365
+ this.#onClickElement = func;
4366
+ }
4367
+ handleClickElement = (e) => {
4368
+ if (this.#isClicked) return;
4369
+ this.#isClicked = true;
4370
+ const onClickElement = this.#onClickElement;
4371
+ if (!isFunction(onClickElement)) return;
4372
+ this.#onClickElement(e);
4373
+ this.#isClicked = false;
4374
+ };
3928
4375
  getElementsByOrdinal = (ordinal) => {
3929
4376
  const exist = this.elementsByOrdinal.get(ordinal);
3930
4377
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3931
4378
  return this.elementsByOrdinal.get(ordinal);
3932
4379
  };
3933
- getMarkersByOrdinal = (ordinal) => {
3934
- const exist = this.markersByOrdinal.get(ordinal);
3935
- if (!exist) this.markersByOrdinal.set(ordinal, []);
3936
- return this.markersByOrdinal.get(ordinal);
3937
- };
3938
4380
  addElementsToManager = (id, elements, ordinal) => {
3939
4381
  this.elementsMap.set(id, elements);
3940
4382
  elements.forEach((el) => {
4383
+ el.on("click", (e) => this.handleClickElement(id));
3941
4384
  this.getElementsByOrdinal(ordinal).push(el);
3942
4385
  });
3943
4386
  const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
@@ -3947,22 +4390,14 @@ var RendererManager = class extends EventTarget {
3947
4390
  this.elementRenderer.hideElements(elements, ordinal);
3948
4391
  }
3949
4392
  };
3950
- addMarkersToManager = (id, markers, ordinal) => {
3951
- this.markersMap.set(id, markers);
3952
- markers.forEach((el) => {
3953
- this.getMarkersByOrdinal(ordinal).push(el);
3954
- });
3955
- const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
3956
- if (inOrdinal) {
3957
- this.markerRenderer.showMarkers(markers, ordinal);
3958
- } else {
3959
- this.markerRenderer.hideMarkers(markers, ordinal);
3960
- }
3961
- };
3962
4393
  async #createElements() {
4394
+ await delay(this.options.delayBeforeCreateElements ?? 0);
3963
4395
  const levels = await this.#dataClient.filterByType("level", {
3964
4396
  populate: true
3965
4397
  });
4398
+ const openings = await this.#dataClient.filterByType("opening", {
4399
+ populate: true
4400
+ });
3966
4401
  const relationships = await this.#dataClient.filterByType("relationship");
3967
4402
  const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
3968
4403
  fixtures.forEach((fixture) => {
@@ -3976,7 +4411,7 @@ var RendererManager = class extends EventTarget {
3976
4411
  populate: true
3977
4412
  });
3978
4413
  units.filter(
3979
- (u) => !["opentobelow", "escalator"].includes(u.properties.category)
4414
+ (u4) => !["opentobelow", "escalator", "room"].includes(u4.properties.category)
3980
4415
  ).forEach((unit) => {
3981
4416
  const element = this.elementRenderer.createGeometry(unit);
3982
4417
  if (element) {
@@ -3984,6 +4419,22 @@ var RendererManager = class extends EventTarget {
3984
4419
  this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
3985
4420
  }
3986
4421
  });
4422
+ units.filter((u4) => u4.properties.category === "room").forEach((unit) => {
4423
+ const openingRelationships = relationships.filter((r) => r.properties.origin?.id === unit.id || r.properties.destination?.id === unit.id);
4424
+ const roomOpenings = compact2(openingRelationships.map((rel) => {
4425
+ const openingId = rel?.properties.intermediary[0].id;
4426
+ return openings.find((o) => o.id === openingId);
4427
+ }));
4428
+ const innerElements = this.elementRenderer.createGeometry(unit);
4429
+ const wallElements = this.elementRenderer.createRoomWall(unit, roomOpenings);
4430
+ if (innerElements || wallElements) {
4431
+ const _innerElements = Array.isArray(innerElements) ? innerElements : [innerElements];
4432
+ const _wallElements = Array.isArray(wallElements) ? wallElements : [wallElements];
4433
+ const _elements = [..._innerElements, ..._wallElements];
4434
+ const ordinal = unit.properties.level.properties.ordinal;
4435
+ this.addElementsToManager(unit.id, _elements, ordinal);
4436
+ }
4437
+ });
3987
4438
  const kiosks = await this.#dataClient.filterByType("kiosk", {
3988
4439
  populate: true
3989
4440
  });
@@ -3994,7 +4445,7 @@ var RendererManager = class extends EventTarget {
3994
4445
  this.addElementsToManager(kiosk.id, _elements, kiosk.properties.level.properties.ordinal);
3995
4446
  }
3996
4447
  });
3997
- const escalators = units.filter((u) => u.properties.category === "escalator");
4448
+ const escalators = units.filter((u4) => u4.properties.category === "escalator");
3998
4449
  for (const escalator of escalators) {
3999
4450
  try {
4000
4451
  const escalatorRelationships = relationships.filter((r) => (r.properties?.intermediary || []).some((inter) => inter.id === escalator.id));
@@ -4006,13 +4457,15 @@ var RendererManager = class extends EventTarget {
4006
4457
  }
4007
4458
  const thisOrdinal = escalator.properties.ordinal;
4008
4459
  const relationship = escalatorRelationships[0];
4460
+ if (!relationship.properties.origin?.id) throw new Error(`relationship (id=${relationship.id}) - origin not exists`);
4461
+ if (!relationship.properties.destination?.id) throw new Error(`relationship (id=${relationship.id}) - destination not exists`);
4009
4462
  const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
4010
4463
  const bothOpenings = await Promise.all(
4011
4464
  bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
4012
4465
  );
4013
4466
  const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
4014
4467
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
4015
- const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4468
+ const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4016
4469
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
4017
4470
  const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
4018
4471
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
@@ -4021,7 +4474,23 @@ var RendererManager = class extends EventTarget {
4021
4474
  this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
4022
4475
  }
4023
4476
  } catch (err) {
4024
- console.log(`cannot create escalator`, err);
4477
+ console.warn(`cannot create escalator`, err.message);
4478
+ }
4479
+ }
4480
+ const groundLabels = await this.#dataClient.filterByType("label");
4481
+ for (const label of groundLabels) {
4482
+ const center2 = turfCenter2(polygon(label.geometry.coordinates)).geometry.coordinates;
4483
+ const unit = findUnitOnPoint(units, center2);
4484
+ const element = this.elementRenderer.createGroundLabel(label, unit);
4485
+ if (element) {
4486
+ const _elements = Array.isArray(element) ? element : [element];
4487
+ this.addElementsToManager(label.id, _elements, label.properties.ordinal);
4488
+ }
4489
+ }
4490
+ if (this.options.type === "3D") {
4491
+ const model3ds = await this.#dataClient.filterByType("model3d");
4492
+ for (const model3d of model3ds) {
4493
+ this.elementRenderer.createModel3d(model3d);
4025
4494
  }
4026
4495
  }
4027
4496
  this.changeLevelByOrdinal(this.currentOrdinals);
@@ -4038,7 +4507,7 @@ var RendererManager = class extends EventTarget {
4038
4507
  this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
4039
4508
  }
4040
4509
  } else {
4041
- const baseOrdinal = Array.isArray(targetOrdinal) ? _min(targetOrdinal) : targetOrdinal;
4510
+ const baseOrdinal = Array.isArray(targetOrdinal) ? min(targetOrdinal) : targetOrdinal;
4042
4511
  for (const [ordinal, elements] of this.elementsByOrdinal) {
4043
4512
  const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
4044
4513
  if (inOrdinal) {
@@ -4057,14 +4526,50 @@ var RendererManager = class extends EventTarget {
4057
4526
  }
4058
4527
  }
4059
4528
  }
4529
+ highlightElements = (elemIds, options) => {
4530
+ const { reset = true } = options ?? {};
4531
+ if (reset) {
4532
+ this.clearHighlightElements();
4533
+ }
4534
+ const elements = elemIds.map((id) => this.elementsMap.get(id)).flat();
4535
+ elements.forEach((element) => {
4536
+ const controller = this.elementRenderer.createHighlightController(element);
4537
+ if (controller && isFunction(controller.start)) {
4538
+ controller.start();
4539
+ this.highlightControllers.push(controller);
4540
+ }
4541
+ });
4542
+ };
4543
+ clearHighlightElements = () => {
4544
+ this.highlightControllers.forEach((controller) => {
4545
+ if (isFunction(controller?.clear)) controller.clear();
4546
+ });
4547
+ };
4060
4548
  /**
4061
4549
  * ========================================================================
4062
4550
  * Markers
4063
4551
  * ======================================================================== */
4552
+ _getMarkersByOrdinal = (ordinal) => {
4553
+ const exist = this.markersByOrdinal.get(ordinal);
4554
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
4555
+ return this.markersByOrdinal.get(ordinal);
4556
+ };
4557
+ _addMarkersToManager = (id, markers, ordinal) => {
4558
+ this.markersMap.set(id, markers);
4559
+ markers.forEach((el) => {
4560
+ this._getMarkersByOrdinal(ordinal).push(el);
4561
+ });
4562
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
4563
+ if (inOrdinal) {
4564
+ this.markerRenderer.showMarkers(markers, ordinal);
4565
+ } else {
4566
+ this.markerRenderer.hideMarkers(markers, ordinal);
4567
+ }
4568
+ };
4064
4569
  createMarker(coordinate, ordinal, text, options) {
4065
4570
  const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
4066
4571
  const markerId = `${this.markersMap.size + 1}`;
4067
- this.addMarkersToManager(markerId, [marker], ordinal);
4572
+ this._addMarkersToManager(markerId, [marker], ordinal);
4068
4573
  }
4069
4574
  clearMarkers() {
4070
4575
  for (const [markerId, marker] of this.markersMap) {
@@ -4079,9 +4584,25 @@ var INITIAL_ZOOM = 18.5;
4079
4584
  var CLICK_TOLERANCE = 20;
4080
4585
  var defaultOptions = {
4081
4586
  pixelRatio: 1,
4587
+ interactions: true,
4082
4588
  locale: DEFAULT_LOCALE
4083
4589
  };
4590
+ var parseMaptalksOptions = (options) => {
4591
+ return {
4592
+ centerCross: options.centerCross ?? false,
4593
+ ...options.interactions === false ? {
4594
+ draggable: false,
4595
+ dragPan: false,
4596
+ dragRotate: false,
4597
+ dragPitch: false,
4598
+ scrollWheelZoom: false,
4599
+ touchZoom: false,
4600
+ doubleClickZoom: false
4601
+ } : {}
4602
+ };
4603
+ };
4084
4604
  var IndoorMap = class extends EventTarget {
4605
+ options;
4085
4606
  //TODO: refac functions; let them do only 1 thing in a function
4086
4607
  /** Note: "#" means private variables */
4087
4608
  #styler = null;
@@ -4098,7 +4619,6 @@ var IndoorMap = class extends EventTarget {
4098
4619
  #billboardObjects = [];
4099
4620
  #spriteMarkerObjects = [];
4100
4621
  #mapDecorations = [];
4101
- #groundLabels = [];
4102
4622
  #groundObjects = [];
4103
4623
  #navigationGeometries = {};
4104
4624
  #venueObjects = [];
@@ -4133,18 +4653,23 @@ var IndoorMap = class extends EventTarget {
4133
4653
  };
4134
4654
  constructor(elementId, options) {
4135
4655
  super();
4656
+ const combinedOptions = _5.merge({}, defaultOptions, options);
4657
+ this.options = combinedOptions;
4136
4658
  const {
4137
4659
  onMapReady,
4138
4660
  onMapLoading,
4139
4661
  pixelRatio,
4140
4662
  locale
4141
- } = _6.merge({}, defaultOptions, options);
4663
+ } = combinedOptions;
4664
+ const maptalksOptions = parseMaptalksOptions(combinedOptions);
4142
4665
  this.map = new Map2(elementId, {
4143
4666
  attribution: false,
4667
+ // Temporart set, not really default view
4668
+ // Default view is set in camera manager
4144
4669
  center: INITIAL_CENTER,
4145
4670
  zoom: INITIAL_ZOOM,
4146
4671
  clickTimeThreshold: 600,
4147
- centerCross: options.centerCross ?? false,
4672
+ ...maptalksOptions,
4148
4673
  baseLayer: new TileLayer("base", {
4149
4674
  urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
4150
4675
  subdomains: ["a", "b", "c", "d"],
@@ -4156,8 +4681,16 @@ var IndoorMap = class extends EventTarget {
4156
4681
  }),
4157
4682
  layers: []
4158
4683
  });
4684
+ const groupLayer = new GroupGLLayer("group", [], {}).addTo(this.map);
4685
+ const threeLayer = new ThreeLayer5("three", {
4686
+ forceRenderOnMoving: true,
4687
+ forceRenderOnRotating: true
4688
+ });
4689
+ groupLayer.addLayer(threeLayer);
4690
+ const gltfLayer = new GLTFLayer("gltf");
4691
+ groupLayer.addLayer(gltfLayer);
4159
4692
  this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
4160
- this.camera = new CameraManager(this.map);
4693
+ this.camera = new CameraManager(this.map, options.camera);
4161
4694
  this.locale = locale;
4162
4695
  this.pixelRatio = pixelRatio;
4163
4696
  this.onMapReady = onMapReady;
@@ -4166,25 +4699,33 @@ var IndoorMap = class extends EventTarget {
4166
4699
  this.map.on("click", this.handleMapClick);
4167
4700
  this.dataClient = options.dataClient;
4168
4701
  }
4702
+ setOptions(options) {
4703
+ const combinedOptions = _5.merge({}, defaultOptions, options);
4704
+ this.options = combinedOptions;
4705
+ const maptalksOptions = parseMaptalksOptions(combinedOptions);
4706
+ this.map.setOptions(maptalksOptions);
4707
+ }
4169
4708
  set dataClient(value) {
4170
4709
  this.#dataClient = value;
4171
- this.#dataClient.filterByType("venue").then((venues) => {
4172
- const venueCenters = turfCenter3(featureCollection(venues));
4173
- const [x, y] = venueCenters.geometry.coordinates;
4174
- const center2 = new Coordinate4(x, y);
4175
- this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4176
- });
4177
- }
4178
- on(eventName, handler) {
4179
- this.map.on(eventName, handler);
4710
+ if (!this.options.camera?.defaultView?.center) {
4711
+ this.#dataClient.filterByType("venue").then((venues) => {
4712
+ const venueCenters = turfCenter3(featureCollection(venues));
4713
+ const [x, y] = venueCenters.geometry.coordinates;
4714
+ const center2 = new Coordinate4(x, y);
4715
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4716
+ });
4717
+ }
4180
4718
  }
4181
4719
  /**
4182
4720
  * Events
4183
4721
  */
4722
+ on(eventName, handler) {
4723
+ this.map.on(eventName, handler);
4724
+ }
4184
4725
  handleMapClick = ({ coordinate }) => {
4185
4726
  const { x, y } = coordinate;
4186
4727
  console.log(
4187
- `[Coordinates]: x: ${_6.round(x, 8)} y: ${_6.round(
4728
+ `[Coordinates]: x: ${_5.round(x, 8)} y: ${_5.round(
4188
4729
  y,
4189
4730
  8
4190
4731
  )}, [Bearing]: ${this.map.getBearing()}, [Pitch]: ${this.map.getPitch()}`
@@ -4236,48 +4777,17 @@ var IndoorMap = class extends EventTarget {
4236
4777
  this.map.off("moveend", this.#findAndSetVenueInView);
4237
4778
  }
4238
4779
  }
4239
- get ordinals() {
4240
- return this.#ordinals || [];
4241
- }
4242
- set ordinals(value) {
4243
- if (!Array.isArray(value)) throw new Error("ordinals must be Array");
4244
- this.#ordinals = value;
4245
- }
4246
4780
  set billboards(value) {
4247
4781
  this.#billboards = value;
4248
4782
  }
4249
- set mapConfig(value) {
4250
- this.#mapConfig = value;
4251
- }
4252
4783
  set mapDecorations(value) {
4253
4784
  this.#mapDecorations = value;
4254
4785
  }
4255
- set maxZoom(value) {
4256
- this.map.setMaxZoom(value);
4257
- const spatialReference = {
4258
- projection: "EPSG:3857",
4259
- resolutions: (function() {
4260
- const resolutions = [];
4261
- const d = 2 * 6378137 * Math.PI;
4262
- for (let i = 0; i < value; i++) {
4263
- resolutions[i] = d / (256 * Math.pow(2, i));
4264
- }
4265
- return resolutions;
4266
- })()
4267
- };
4268
- this.map.setSpatialReference(spatialReference);
4269
- }
4270
- set minZoom(value) {
4271
- this.map.setMinZoom(value);
4272
- }
4273
- set groundLabels(value) {
4274
- this.#groundLabels = value;
4275
- }
4276
4786
  set pixelRatio(value) {
4277
4787
  this.map.setDevicePixelRatio(value);
4278
4788
  }
4279
4789
  set onClickElement(func) {
4280
- this.#onClickElement = func;
4790
+ this.rendererManager.onClickElement = func;
4281
4791
  }
4282
4792
  set locale(value) {
4283
4793
  this.#locale = value || defaultOptions.locale;
@@ -4301,66 +4811,36 @@ var IndoorMap = class extends EventTarget {
4301
4811
  if (this.#isClicked) return;
4302
4812
  this.#isClicked = true;
4303
4813
  const onClickElement = this.#onClickElement;
4304
- if (!_6.isFunction(onClickElement)) return;
4814
+ if (!_5.isFunction(onClickElement)) return;
4305
4815
  this.#onClickElement(e);
4306
4816
  this.#isClicked = false;
4307
4817
  };
4308
- setCenter(center2, padding) {
4309
- this.map.setCenter(center2, padding);
4310
- }
4311
4818
  async #legacy_createElements() {
4312
4819
  const {
4313
4820
  // 2D
4314
- createVenue,
4315
4821
  createOpening,
4316
4822
  createSection,
4317
- createFixture,
4318
- createOccupant,
4319
4823
  createDecoration,
4320
4824
  // 3D
4321
- create3DFootprint,
4322
- create3DGroundLabel,
4323
4825
  create3DBillboard,
4324
- createVenue3DModel,
4325
- createExtrudedUnit,
4326
- create3DFixture,
4327
4826
  create3DAmenityMarker,
4328
- create3DOccupantAmenityMarker,
4329
- create3DOpeningMarker,
4330
- createOccupantGroundLabel,
4331
- // Light
4332
- createAmbientLight,
4333
- createDirectionalLight
4827
+ create3DOpeningMarker
4334
4828
  } = this.#styler;
4335
4829
  let elements = {};
4336
4830
  let object3ds = [];
4337
- const scene = this.threeLayer.getScene();
4338
- if (scene) {
4339
- const {
4340
- ambientLight: ambientLightConfig = {},
4341
- directionalLight: directionalLightConfig = {}
4342
- } = _6.get(this.#mapConfig, "light", {
4343
- ambientLight: {},
4344
- directionalLight: {}
4345
- });
4346
- const ambientLight = createAmbientLight(ambientLightConfig);
4347
- scene.add(ambientLight);
4348
- const light = createDirectionalLight(directionalLightConfig);
4349
- scene.add(light);
4350
- }
4351
4831
  for (const feature2 of this.#features) {
4352
4832
  try {
4353
4833
  const { feature_type: featureType, properties, id } = feature2;
4354
- const layerName = _6.get(
4834
+ const layerName = _5.get(
4355
4835
  LAYER_FEATURE_TYPE_OBJ,
4356
4836
  featureType,
4357
4837
  featureType
4358
4838
  );
4359
4839
  const layer = this.map.getLayer(layerName);
4360
4840
  let geometry;
4361
- const category = _6.get(feature2, "properties.category");
4362
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4363
- const textMarkerType = _6.get(
4841
+ const category = _5.get(feature2, "properties.category");
4842
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
4843
+ const textMarkerType = _5.get(
4364
4844
  this.#mapConfig,
4365
4845
  "text_marker_type",
4366
4846
  "ui-marker"
@@ -4370,16 +4850,6 @@ var IndoorMap = class extends EventTarget {
4370
4850
  feature2
4371
4851
  );
4372
4852
  switch (featureType) {
4373
- case "venue": {
4374
- geometry = createVenue(feature2).addTo(layer);
4375
- const models = await createVenue3DModel(feature2, this.threeLayer);
4376
- models.forEach((model) => {
4377
- model.on("click", this.handleClickElement);
4378
- object3ds.push(model);
4379
- this.#venueObjects.push(model);
4380
- });
4381
- break;
4382
- }
4383
4853
  case "amenity": {
4384
4854
  if (feature2.properties.is_featured) {
4385
4855
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4423,127 +4893,6 @@ var IndoorMap = class extends EventTarget {
4423
4893
  geometry = createSection(feature2)?.addTo(layer);
4424
4894
  break;
4425
4895
  }
4426
- case "occupant": {
4427
- switch (category) {
4428
- // Create only marker if it is amenity occupant
4429
- case "currencyexchange":
4430
- case "donationcenter":
4431
- case "postoffice":
4432
- const markerFeature = {
4433
- ...feature2,
4434
- geometry: feature2.properties?.anchor?.geometry
4435
- };
4436
- const marker3d = create3DOccupantAmenityMarker(
4437
- markerFeature,
4438
- this.threeLayer,
4439
- extrudeConfig
4440
- )?.on("click", this.handleClickElement);
4441
- object3ds.push(marker3d);
4442
- break;
4443
- default: {
4444
- const { kiosk, anchor } = feature2.properties;
4445
- const { unit } = anchor.properties;
4446
- let mainLocation = kiosk || unit || null;
4447
- const relatedLocations = [
4448
- ...feature2.properties.units,
4449
- ...feature2.properties.kiosks
4450
- ].filter((f) => f.properties.ordinal !== properties.ordinal);
4451
- const occupantLocations = [mainLocation, ...relatedLocations];
4452
- const renderType = feature2.properties.render_type;
4453
- occupantLocations.forEach((location, index) => {
4454
- const isMainLocation = index === 0;
4455
- if (renderType === "Label") {
4456
- const occupantGroundLabel = createOccupantGroundLabel(
4457
- feature2,
4458
- location,
4459
- { textMarkerType, extrudeConfig },
4460
- this.threeLayer
4461
- );
4462
- if (occupantGroundLabel instanceof GroundLabel) {
4463
- occupantGroundLabel.on("click", this.handleClickElement);
4464
- occupantGroundLabel.addTo(this.threeLayer);
4465
- object3ds.push(occupantGroundLabel);
4466
- this.#groundObjects.push(occupantGroundLabel);
4467
- }
4468
- } else {
4469
- const occupantMarker = createOccupant(feature2, location, {
4470
- textMarkerType,
4471
- extrudeConfig
4472
- });
4473
- if (occupantMarker instanceof ui3.UIMarker) {
4474
- occupantMarker.addTo(this.map);
4475
- } else {
4476
- occupantMarker?.on("click", this.handleClickElement);
4477
- occupantMarker?.addTo(layer);
4478
- }
4479
- if (isMainLocation) {
4480
- geometry = occupantMarker;
4481
- } else {
4482
- elements[`${feature2.id}_${index}`] = {
4483
- geometry: occupantMarker,
4484
- properties: location.properties,
4485
- featureType: "occupant",
4486
- feature: feature2
4487
- };
4488
- }
4489
- }
4490
- });
4491
- }
4492
- }
4493
- break;
4494
- }
4495
- case "fixture": {
4496
- const models = await create3DFixture(feature2, this.threeLayer);
4497
- models.forEach((model) => {
4498
- model.on("click", this.handleClickElement);
4499
- object3ds.push(model);
4500
- this.#glbObjects.push(model);
4501
- });
4502
- if (!featureExtrudeConfig) {
4503
- geometry = createFixture(feature2)?.addTo(layer);
4504
- } else {
4505
- const locatedLevel = feature2?.properties?.level;
4506
- const levelExtrudeConfig = getExtrudeConfigByFeature(
4507
- extrudeConfig,
4508
- locatedLevel
4509
- );
4510
- const levelHeight = _6.get(levelExtrudeConfig, "height", 0);
4511
- const option = { ...featureExtrudeConfig, altitude: levelHeight };
4512
- const extrudedFixture = createExtrudedUnit(
4513
- feature2,
4514
- this.threeLayer,
4515
- option
4516
- );
4517
- object3ds.push(extrudedFixture);
4518
- }
4519
- break;
4520
- }
4521
- case "footprint": {
4522
- const objects = await create3DFootprint(
4523
- feature2,
4524
- this.threeLayer,
4525
- featureExtrudeConfig
4526
- );
4527
- objects.forEach((object) => {
4528
- object.on("click", () => {
4529
- const {
4530
- geometry: { coordinates }
4531
- } = turfCenter3(feature2);
4532
- this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4533
- });
4534
- object3ds.push(object);
4535
- this.#objects.push(object);
4536
- });
4537
- if (feature2.properties.logo) {
4538
- const footprintMarker = create3DBillboard(
4539
- feature2,
4540
- this.threeLayer
4541
- );
4542
- object3ds.push(footprintMarker);
4543
- this.#billboardObjects.push(footprintMarker);
4544
- }
4545
- break;
4546
- }
4547
4896
  default:
4548
4897
  break;
4549
4898
  }
@@ -4553,16 +4902,6 @@ var IndoorMap = class extends EventTarget {
4553
4902
  console.warn(`Cannot create ${feature2.id}: ${err.message}`);
4554
4903
  }
4555
4904
  }
4556
- this.#groundLabels.forEach((label) => {
4557
- const text = label.properties.name;
4558
- try {
4559
- const groundLabel = create3DGroundLabel(label, this.threeLayer);
4560
- object3ds.push(groundLabel);
4561
- this.#groundObjects.push(groundLabel);
4562
- } catch (error) {
4563
- console.log("error creating ground label for ", text);
4564
- }
4565
- });
4566
4905
  this.#mapDecorations.forEach((decoration) => {
4567
4906
  const { id, geometry, properties } = decoration;
4568
4907
  const geometryType = decoration?.geometry?.type;
@@ -4612,27 +4951,6 @@ var IndoorMap = class extends EventTarget {
4612
4951
  changeLevelByOrdinal(ordinal) {
4613
4952
  this.rendererManager.changeLevelByOrdinal(ordinal);
4614
4953
  }
4615
- getFeatureExtent = (feature2, scaleFactor = 1) => {
4616
- const [minX, minY, maxX, maxY] = index_default(
4617
- scale(bboxPolygon(index_default(feature2)), scaleFactor)
4618
- );
4619
- return new Extent(minX, minY, maxX, maxY);
4620
- };
4621
- getExtentCenter = (extent) => {
4622
- return extent.getCenter();
4623
- };
4624
- getExtentZoom = (extent, options = {
4625
- isFraction: false,
4626
- padding: {
4627
- paddingLeft: 0,
4628
- paddingRight: 0,
4629
- paddingTop: 0,
4630
- paddingBottom: 0
4631
- }
4632
- }) => {
4633
- const { isFraction = false, padding } = options;
4634
- return this.map.getFitZoom(extent, isFraction, padding);
4635
- };
4636
4954
  findVenueInView = () => {
4637
4955
  const mapCenter = this.map.getCenter();
4638
4956
  const result = this.#venues.reduce((closest, venue) => {
@@ -4645,9 +4963,6 @@ var IndoorMap = class extends EventTarget {
4645
4963
  }, null);
4646
4964
  return result;
4647
4965
  };
4648
- flyTo = (center2, options) => {
4649
- this.camera.flyTo(center2, options);
4650
- };
4651
4966
  getLineStringBearing = (feature2) => {
4652
4967
  const { geometry } = feature2;
4653
4968
  const path = new LineString3(geometry.coordinates);
@@ -4668,186 +4983,6 @@ var IndoorMap = class extends EventTarget {
4668
4983
  clearAnimations() {
4669
4984
  this.#animationsToRun = [];
4670
4985
  }
4671
- /**
4672
- * Hilighting Elements
4673
- * ========================================= */
4674
- // TODO: To consider if we should use setter `set hilightElementIds` instead?
4675
- setHighlightElementIds(targetElementIds, options = {}) {
4676
- const highlight3DOptions = _6.merge(
4677
- {},
4678
- DEFAULT_HIGHLIGHT_OPTIONS,
4679
- _6.get(options, "highlight3DOptions", {})
4680
- );
4681
- const highlight2DOptions = _6.merge(
4682
- {},
4683
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4684
- _6.get(options, "highlight2DOptions", {})
4685
- );
4686
- this.setHighlightedObject(targetElementIds, highlight3DOptions);
4687
- return this.setHighlight2DElementIds(targetElementIds, highlight2DOptions);
4688
- }
4689
- setHighlight2DElementIds(targetElementIds, options = {}) {
4690
- const { defaultMarker, symbolSet } = _6.merge(
4691
- {},
4692
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
4693
- options
4694
- );
4695
- const {
4696
- createMarker,
4697
- createHighlightOccupantMarker,
4698
- getElementSymbol,
4699
- getHilighPolygonalSymbol,
4700
- getHighlightMarkerSymbol
4701
- } = this.#styler;
4702
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4703
- const elementToHilights = targetElementIds.map(
4704
- (elemId) => this.#elements[elemId] || this.#elements[`${LAST_USER_LOCATION_ELEMENT_ID_PREFIX}${elemId}`]
4705
- ).filter((elem) => elem);
4706
- elementToHilights.forEach((elem) => {
4707
- const { feature: feature2, geometry } = elem;
4708
- if (!geometry || !feature2) return;
4709
- const hilightLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4710
- if (!hilightLayer) return;
4711
- const defaultSymbol = getHilighPolygonalSymbol(geometry.type);
4712
- const definedSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4713
- const symbol = _6.isEmpty(definedSymbol) ? defaultSymbol : definedSymbol;
4714
- switch (geometry.type) {
4715
- case "MultiPolygon":
4716
- case "Polygon": {
4717
- geometry?.updateSymbol(symbol);
4718
- break;
4719
- }
4720
- default:
4721
- break;
4722
- }
4723
- switch (feature2.feature_type) {
4724
- case "amenity":
4725
- const highlightedAmenityMarker = definedSymbol || getHighlightMarkerSymbol();
4726
- geometry?.updateSymbol(highlightedAmenityMarker);
4727
- break;
4728
- case "occupant": {
4729
- switch (feature2.properties.category) {
4730
- case "currencyexchange":
4731
- case "donationcenter":
4732
- case "postoffice":
4733
- const highlightedAmenityMarker2 = definedSymbol || getHighlightMarkerSymbol();
4734
- geometry?.updateSymbol(highlightedAmenityMarker2);
4735
- break;
4736
- default:
4737
- if (feature2.properties.render_type === "Logo") {
4738
- this.hideGeometryByElementId(feature2.id);
4739
- }
4740
- createHighlightOccupantMarker(feature2, {
4741
- extrudeConfig,
4742
- symbol: definedSymbol
4743
- }).on("click", this.handleClickElement).addTo(hilightLayer);
4744
- break;
4745
- }
4746
- break;
4747
- }
4748
- case "opening":
4749
- break;
4750
- default:
4751
- if (defaultMarker) createMarker(feature2).addTo(hilightLayer);
4752
- break;
4753
- }
4754
- });
4755
- this.#highlightElementIds = targetElementIds;
4756
- if (elementToHilights.length === 0) return;
4757
- return featureCollection(
4758
- elementToHilights.map(({ feature: feature2 }) => {
4759
- const { geometry } = feature2;
4760
- if (feature2.feature_type === "occupant")
4761
- return feature(feature2?.properties?.anchor?.geometry);
4762
- return feature(geometry);
4763
- })
4764
- );
4765
- }
4766
- clearHighlightElements() {
4767
- this.#clearAllElementOnLayerByName(HIGHLIGHT_LAYER_NAME);
4768
- _6(this.#highlightElementIds).map((elemId) => this.#elements[elemId]?.geometry).compact().forEach((geometry) => {
4769
- if (geometry instanceof ui3.UIMarker) return;
4770
- if (geometry instanceof Marker2) {
4771
- this.showGeometryByElementId(geometry.properties.id);
4772
- return;
4773
- }
4774
- try {
4775
- const defaultSymbol = geometry.options.defaultSymbol;
4776
- geometry.updateSymbol(defaultSymbol);
4777
- } catch (err) {
4778
- console.log(
4779
- `error cannot return to defaultSymbol, check if "defaultSymbol" exists in element creation function`
4780
- );
4781
- }
4782
- });
4783
- this.#highlightElementIds = [];
4784
- }
4785
- setHighlightedObject(targetObjectIds, options = {}) {
4786
- const { symbolSet } = _6.merge({}, DEFAULT_HIGHLIGHT_OPTIONS, options);
4787
- const {
4788
- getElementSymbol,
4789
- getHilighPolygonalSymbol,
4790
- createHighlight2DAmenityMarkerFrom3DMarker
4791
- } = this.#styler;
4792
- const objects = this.threeLayer?.getBaseObjects();
4793
- const objectsToHighlight = objects.filter(
4794
- ({ properties }) => targetObjectIds.includes(properties?.id)
4795
- );
4796
- const defaultSymbol = getHilighPolygonalSymbol("Polygon");
4797
- const targetSymbol = symbolSet ? getElementSymbol(symbolSet) : null;
4798
- const { polygonFill: color } = _6.isEmpty(targetSymbol) ? defaultSymbol : targetSymbol;
4799
- const amenityHighlightMode = _6.get(
4800
- this.#mapConfig,
4801
- "amenity_highlight_mode",
4802
- ""
4803
- );
4804
- objectsToHighlight.forEach((obj) => {
4805
- if (obj.type === "ExtrudePolygon") {
4806
- const newController = createHighlighExtrudeObjectController(obj, {
4807
- color
4808
- });
4809
- newController.start();
4810
- this.#highlightObjectControllers.push(newController);
4811
- }
4812
- if (obj instanceof SpriteMarker) {
4813
- if (amenityHighlightMode === "2DMarker") {
4814
- const hilight2DLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
4815
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4816
- obj.hide();
4817
- const { properties: featureProperties } = obj;
4818
- createHighlight2DAmenityMarkerFrom3DMarker(
4819
- featureProperties,
4820
- extrudeConfig
4821
- ).on("click", this.handleClickElement).addTo(hilight2DLayer);
4822
- } else {
4823
- obj.highlight();
4824
- }
4825
- }
4826
- if (obj instanceof Billboard) {
4827
- const newController = createHighlighBillboardController(obj);
4828
- newController.start();
4829
- this.#highlightObjectControllers.push(newController);
4830
- }
4831
- });
4832
- this.#highlightObjectIds = targetObjectIds;
4833
- }
4834
- clearHighlightObject() {
4835
- this.#highlightObjectControllers.forEach((controller) => {
4836
- if (_6.isFunction(controller?.clear)) controller.clear();
4837
- });
4838
- this.#highlightObjectIds.forEach((objIds) => {
4839
- const objects = this.threeLayer?.getBaseObjects();
4840
- const objectToResetHighlight = objects.find(
4841
- ({ properties }) => objIds.includes(properties?.id)
4842
- );
4843
- if (objectToResetHighlight instanceof SpriteMarker) {
4844
- objectToResetHighlight.show();
4845
- objectToResetHighlight.removeHighlight();
4846
- }
4847
- });
4848
- this.#highlightObjectControllers = [];
4849
- this.#highlightObjectIds = [];
4850
- }
4851
4986
  /**
4852
4987
  * User Location
4853
4988
  ****************************/
@@ -4872,15 +5007,15 @@ var IndoorMap = class extends EventTarget {
4872
5007
  }
4873
5008
  }
4874
5009
  updateUserLocationSymbolByLocale(locale) {
4875
- const userLocationGeometry = _6.get(
5010
+ const userLocationGeometry = _5.get(
4876
5011
  this.#elements,
4877
5012
  `${USER_LOCATION_ELEMENT_ID}.geometry`
4878
5013
  );
4879
5014
  if (!userLocationGeometry) return;
4880
5015
  const currentSymbol = userLocationGeometry.getSymbol();
4881
5016
  const localeSymbolToUpdate = currentSymbol.map((symbol) => {
4882
- const localeSymbol = _6.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _6.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
4883
- if (!_6.isPlainObject(localeSymbol)) return symbol;
5017
+ const localeSymbol = _5.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _5.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
5018
+ if (!_5.isPlainObject(localeSymbol)) return symbol;
4884
5019
  return {
4885
5020
  ...symbol,
4886
5021
  ...localeSymbol
@@ -4954,14 +5089,14 @@ var IndoorMap = class extends EventTarget {
4954
5089
  * END of User Location
4955
5090
  ****************************/
4956
5091
  showGeometryByElementId = (elementId) => {
4957
- const geometry = _6.get(
5092
+ const geometry = _5.get(
4958
5093
  this.#elements,
4959
5094
  `${elementId}.geometry`
4960
5095
  );
4961
5096
  if (geometry) geometry.show();
4962
5097
  };
4963
5098
  hideGeometryByElementId = (elementId) => {
4964
- const geometry = _6.get(this.#elements, `${elementId}.geometry`);
5099
+ const geometry = _5.get(this.#elements, `${elementId}.geometry`);
4965
5100
  if (geometry) geometry.hide();
4966
5101
  };
4967
5102
  setSpriteMarkersOpacity = (opacity = 1) => {
@@ -5008,13 +5143,13 @@ var IndoorMap = class extends EventTarget {
5008
5143
  const line = lineStrings[i];
5009
5144
  const coords = line.geometry.coordinates;
5010
5145
  const prevLine = lineStrings[i - 1];
5011
- const firstCoord = _6.first(coords);
5146
+ const firstCoord = _5.first(coords);
5012
5147
  const isFirstLine = i === 0;
5013
5148
  if (isFirstLine) {
5014
5149
  accLine.push(...coords);
5015
5150
  continue;
5016
5151
  }
5017
- const prevLastCoord = _6.last(prevLine.geometry.coordinates);
5152
+ const prevLastCoord = _5.last(prevLine.geometry.coordinates);
5018
5153
  const isNearby = turfDistance(point(firstCoord), point(prevLastCoord)) < distance;
5019
5154
  if (!isNearby) {
5020
5155
  const remainingLines = lineStrings.slice(i);
@@ -5035,8 +5170,8 @@ var IndoorMap = class extends EventTarget {
5035
5170
  create3DStepPath
5036
5171
  } = this.#styler;
5037
5172
  const routeMarkerLayer = this.map.getLayer(HIGHLIGHT_LAYER_NAME);
5038
- const linesByOrdinal = _6(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5039
- const joinedLines = _6(linesByOrdinal).reduce((acc, lines, key) => {
5173
+ const linesByOrdinal = _5(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5174
+ const joinedLines = _5(linesByOrdinal).reduce((acc, lines, key) => {
5040
5175
  const joined = this.combineNearbyLineStrings(lines, {
5041
5176
  properties: { ordinal: +key }
5042
5177
  });
@@ -5064,14 +5199,14 @@ var IndoorMap = class extends EventTarget {
5064
5199
  stepElement = createOriginMarker(stepGeometry).addTo(routeMarkerLayer);
5065
5200
  break;
5066
5201
  case "destination-marker":
5067
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
5202
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
5068
5203
  if (destinationFeature.feature_type === "occupant") {
5069
- const stepId = _6.get(stepGeometry, "id");
5204
+ const stepId = _5.get(stepGeometry, "id");
5070
5205
  const normalizedDestinationFeature = {
5071
5206
  ...destinationFeature,
5072
5207
  id: stepId
5073
5208
  };
5074
- const logoUrl = _6.get(
5209
+ const logoUrl = _5.get(
5075
5210
  normalizedDestinationFeature,
5076
5211
  "properties.logo.url"
5077
5212
  );
@@ -5116,15 +5251,15 @@ var IndoorMap = class extends EventTarget {
5116
5251
  const routeMarkerLayer = this.map.getLayer(
5117
5252
  HIGHLIGHT_LAYER_NAME
5118
5253
  );
5119
- const originMarkerGeometry = _6.get(
5254
+ const originMarkerGeometry = _5.get(
5120
5255
  this.#elements,
5121
5256
  `${ORIGIN_MARKER_ID}.geometry`
5122
5257
  );
5123
- const destinationMarkerGeometry = _6.get(
5258
+ const destinationMarkerGeometry = _5.get(
5124
5259
  this.#elements,
5125
5260
  `${DESTINATION_MARKER_ID}.geometry`
5126
5261
  );
5127
- const geometriesToRemove = _6.compact([
5262
+ const geometriesToRemove = _5.compact([
5128
5263
  originMarkerGeometry,
5129
5264
  destinationMarkerGeometry
5130
5265
  ]);
@@ -5135,7 +5270,7 @@ var IndoorMap = class extends EventTarget {
5135
5270
  (obj) => !(obj instanceof NavigationPath)
5136
5271
  );
5137
5272
  const objects = this.#navigationGeometries || {};
5138
- _6.forEach(objects, (obj) => {
5273
+ _5.forEach(objects, (obj) => {
5139
5274
  if (!obj) return;
5140
5275
  this.#navigationGeometries[obj.properties.id] = null;
5141
5276
  obj.remove();
@@ -5163,33 +5298,6 @@ var IndoorMap = class extends EventTarget {
5163
5298
  /**
5164
5299
  * render (frame)
5165
5300
  */
5166
- getTargetViewCenter = (targetView, options = { offset: { top: 0, left: 0, right: 0, bottom: 0 } }) => {
5167
- const map = this.map;
5168
- const { offset } = options;
5169
- const { top = 0, left = 0, right = 0, bottom = 0 } = offset;
5170
- const originalState = {
5171
- bearing: map.getBearing(),
5172
- center: map.getCenter(),
5173
- pitch: map.getPitch(),
5174
- zoom: map.getZoom()
5175
- };
5176
- const finalView = {
5177
- bearing: _6.isNil(targetView.bearing) ? map.getBearing() : targetView.bearing,
5178
- center: _6.isNil(targetView.center) ? map.getCenter() : targetView.center,
5179
- pitch: _6.isNil(targetView.pitch) ? map.getPitch() : targetView.pitch,
5180
- zoom: _6.isNil(targetView.zoom) ? map.getZoom() : targetView.zoom
5181
- };
5182
- map.setView(finalView);
5183
- const projectedTargetCenter = map.coordinateToContainerPoint(finalView.center).add(right / 2 - left / 2, bottom / 2 - top / 2);
5184
- const adjustedTargetCenter = map.containerPointToCoordinate(
5185
- projectedTargetCenter
5186
- );
5187
- map.setView(originalState);
5188
- return adjustedTargetCenter;
5189
- };
5190
- setMaxExtent(extent) {
5191
- return this.map.setMaxExtent(extent);
5192
- }
5193
5301
  render() {
5194
5302
  const view = this.map.getView();
5195
5303
  const currBearing = view.bearing;
@@ -5198,7 +5306,8 @@ var IndoorMap = class extends EventTarget {
5198
5306
  this.threeLayer.redraw();
5199
5307
  }
5200
5308
  if (this.threeLayer) {
5201
- const objectOpacity = _6.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5309
+ const currentView = this.camera.getView();
5310
+ const objectOpacity = _5.clamp(38 - 2 * currentView.zoom, 0, 1);
5202
5311
  this.#objects.forEach((object) => {
5203
5312
  object.getObject3d().traverse((child) => {
5204
5313
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5208,8 +5317,8 @@ var IndoorMap = class extends EventTarget {
5208
5317
  });
5209
5318
  if (this.#billboardObjects) {
5210
5319
  this.#billboardObjects.forEach((object) => {
5211
- const objectScale = _6.clamp(
5212
- 20 - 1 * this.camera.getZoom(),
5320
+ const objectScale = _5.clamp(
5321
+ 20 - 1 * currentView.zoom,
5213
5322
  1,
5214
5323
  1.05
5215
5324
  );
@@ -5217,7 +5326,7 @@ var IndoorMap = class extends EventTarget {
5217
5326
  });
5218
5327
  }
5219
5328
  if (this.#isLayersFadingOnZoom) {
5220
- const layerOpacity = _6.clamp(1 - objectOpacity, 0, 1);
5329
+ const layerOpacity = _5.clamp(1 - objectOpacity, 0, 1);
5221
5330
  LAYERS.forEach((layerKey) => {
5222
5331
  const layer = this.map.getLayer(layerKey);
5223
5332
  if (layer) layer.setOpacity(layerOpacity);
@@ -5231,23 +5340,17 @@ var IndoorMap = class extends EventTarget {
5231
5340
  child.visible = this.showVenueObject && objectOpacity > 0.4;
5232
5341
  });
5233
5342
  });
5234
- this.#groundObjects.forEach((gLabel) => {
5235
- gLabel.bearing = currBearing;
5236
- });
5237
5343
  }
5238
5344
  this.#animationsToRun.forEach(({ callback }) => callback(this));
5239
- TWEEN2.update();
5345
+ TWEEN.update();
5240
5346
  requestAnimationFrame(this.render.bind(this));
5241
5347
  }
5242
5348
  };
5243
5349
  export {
5244
5350
  ALL_FEATURE_TYPES,
5245
- ALWAYS_VISIBLE_FEATURE_TYPES,
5246
5351
  BASE_LAYER_NAME,
5247
5352
  DEFAULT_BASE_URL,
5248
- DEFAULT_HIGHLIGHT_OPTIONS,
5249
5353
  DEFAULT_LOCALE,
5250
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
5251
5354
  DESTINATION_MARKER_ID,
5252
5355
  GEOJSON_FEATURE_TYPES,
5253
5356
  HIGHLIGHT_LAYER_NAME,
@@ -5261,8 +5364,10 @@ export {
5261
5364
  MARKER_LAYER_NAME,
5262
5365
  NONIMDF_FEATURE_TYPES,
5263
5366
  ORIGIN_MARKER_ID,
5367
+ occupant_helper_exports as OccupantHelpers,
5264
5368
  POI_MARKER_LAYER_NAME,
5265
5369
  QueryObserver2 as QueryObserver,
5370
+ TextSpriteMarker,
5266
5371
  USER_LOCATION_ELEMENT_ID,
5267
5372
  USER_LOCATION_LAYER_NAME,
5268
5373
  VENUE_EVENTS,
@@ -5288,6 +5393,16 @@ export {
5288
5393
  getRelatedLocationsByOccupant,
5289
5394
  getSuitablyValueBetweenBearings,
5290
5395
  isClickableFeature,
5396
+ isValidCoordinate,
5397
+ isValidLineString,
5398
+ isValidLineStringCoordinates,
5399
+ isValidMultiPolygon,
5400
+ isValidMultiPolygonCoordinates,
5401
+ isValidPoint,
5402
+ isValidPolygon,
5403
+ isValidPolygonCoordinates,
5404
+ matchFilter,
5405
+ matchFilters,
5291
5406
  safeFetchFeature,
5292
5407
  styledFeatureGenerator
5293
5408
  };