venue-js 1.2.0 → 1.3.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,
@@ -198,6 +322,7 @@ import {
198
322
  } from "@tanstack/query-core";
199
323
 
200
324
  // src/data/populator/index.ts
325
+ import { compact as compact2 } from "lodash-es";
201
326
  import { booleanWithin } from "@turf/boolean-within";
202
327
  var createPopulator = ({
203
328
  internalFindById,
@@ -344,13 +469,13 @@ var createPopulator = ({
344
469
  ...occupant.properties,
345
470
  anchor: anchor ? await populateAnchor(anchor) : null,
346
471
  local_categories: await Promise.all(
347
- localCategories.map(populateTaxonomy)
472
+ compact2(localCategories).map(populateTaxonomy)
348
473
  ),
349
474
  venue,
350
475
  promotions,
351
476
  privileges,
352
- kiosk,
353
- unit,
477
+ kiosk: kiosk ? await populateKiosk(kiosk) : null,
478
+ unit: unit ? await populateUnit(unit) : null,
354
479
  kiosks: await Promise.all(kiosks.map(populateKiosk)),
355
480
  units: await Promise.all(units.map(populateUnit))
356
481
  }
@@ -442,26 +567,6 @@ var createPopulator = ({
442
567
  };
443
568
  };
444
569
 
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
570
  // src/data/getDataClient.ts
466
571
  var getDataClient = (options) => {
467
572
  const observers = /* @__PURE__ */ new Map();
@@ -590,16 +695,16 @@ var getDataClient = (options) => {
590
695
 
591
696
  // src/IndoorMap/IndoorMap.ts
592
697
  import {
593
- ui as ui3,
594
698
  Map as Map2,
595
699
  TileLayer,
596
- Extent,
597
700
  LineString as LineString3,
598
- Marker as Marker2,
599
- Coordinate as Coordinate4
701
+ Coordinate as Coordinate4,
702
+ GroupGLLayer,
703
+ GLTFLayer
600
704
  } from "maptalks-gl";
601
- import TWEEN2 from "@tweenjs/tween.js";
602
- import _6 from "lodash";
705
+ import "@maptalks/transcoders.draco";
706
+ import TWEEN from "@tweenjs/tween.js";
707
+ import _5 from "lodash";
603
708
 
604
709
  // ../../node_modules/@turf/helpers/dist/esm/index.js
605
710
  var earthRadius = 63710088e-1;
@@ -651,6 +756,28 @@ function point(coordinates, properties, options = {}) {
651
756
  };
652
757
  return feature(geom, properties, options);
653
758
  }
759
+ function polygon(coordinates, properties, options = {}) {
760
+ for (const ring of coordinates) {
761
+ if (ring.length < 4) {
762
+ throw new Error(
763
+ "Each LinearRing of a Polygon must have 4 or more Positions."
764
+ );
765
+ }
766
+ if (ring[ring.length - 1].length !== ring[0].length) {
767
+ throw new Error("First and last Position are not equivalent.");
768
+ }
769
+ for (let j = 0; j < ring[ring.length - 1].length; j++) {
770
+ if (ring[ring.length - 1][j] !== ring[0][j]) {
771
+ throw new Error("First and last Position are not equivalent.");
772
+ }
773
+ }
774
+ }
775
+ const geom = {
776
+ type: "Polygon",
777
+ coordinates
778
+ };
779
+ return feature(geom, properties, options);
780
+ }
654
781
  function lineString(coordinates, properties, options = {}) {
655
782
  if (coordinates.length < 2) {
656
783
  throw new Error("coordinates must be an array of two or more positions");
@@ -672,6 +799,13 @@ function featureCollection(features, options = {}) {
672
799
  fc.features = features;
673
800
  return fc;
674
801
  }
802
+ function multiPoint(coordinates, properties, options = {}) {
803
+ const geom = {
804
+ type: "MultiPoint",
805
+ coordinates
806
+ };
807
+ return feature(geom, properties, options);
808
+ }
675
809
  function isNumber(num) {
676
810
  return !isNaN(num) && num !== null && !Array.isArray(num);
677
811
  }
@@ -679,133 +813,8 @@ function isNumber(num) {
679
813
  // src/IndoorMap/IndoorMap.ts
680
814
  import turfDistance from "@turf/distance";
681
815
  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
816
  import { PerspectiveCamera } from "three";
817
+ import { ThreeLayer as ThreeLayer5 } from "maptalks.three";
809
818
 
810
819
  // src/IndoorMap/constants.ts
811
820
  var defaultLayerOption = { enableAltitude: true };
@@ -823,7 +832,6 @@ var GEOLOCATION = "geolocation";
823
832
  var ORIGIN_MARKER = "origin-marker";
824
833
  var DESTINATION_MARKER = "destination-marker";
825
834
  var DECORATION = "decoration";
826
- var ALWAYS_VISIBLE_FEATURE_TYPES = [VENUE, FOOTPRINT];
827
835
  var BASE_LAYER_NAME = "base";
828
836
  var POI_MARKER_LAYER_NAME = "poi";
829
837
  var MARKER_LAYER_NAME = "marker";
@@ -835,13 +843,6 @@ var USER_LOCATION_ELEMENT_ID = "user_location";
835
843
  var LAST_USER_LOCATION_ELEMENT_ID_PREFIX = "last_user_location-";
836
844
  var LOCALE_SYMBOL_KEY = "locale_symbol";
837
845
  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
846
  var LAYERS = [
846
847
  BASE_LAYER_NAME,
847
848
  POI_MARKER_LAYER_NAME,
@@ -905,11 +906,8 @@ import turfBuffer from "@turf/buffer";
905
906
  import {
906
907
  TextureLoader as TextureLoader2,
907
908
  SpriteMaterial as SpriteMaterial3,
908
- MeshLambertMaterial,
909
- AmbientLight,
910
- DirectionalLight
909
+ MeshLambertMaterial
911
910
  } from "three";
912
- import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
913
911
 
914
912
  // src/IndoorMap/object3d/Billboard.js
915
913
  import * as maptalks from "maptalks";
@@ -949,7 +947,7 @@ var Billboard = class extends BaseObject {
949
947
  this._initOptions(options);
950
948
  const {
951
949
  altitude = OPTIONS.altitude,
952
- scale: scale2 = OPTIONS.scale,
950
+ scale: scale3 = OPTIONS.scale,
953
951
  alphaTest = OPTIONS.alphaTest,
954
952
  legColor = OPTIONS.legColor,
955
953
  showLeg = OPTIONS.showLeg
@@ -983,8 +981,8 @@ var Billboard = class extends BaseObject {
983
981
  const sprite = new Sprite(material);
984
982
  sprite.material.sizeAttenuation = false;
985
983
  sprite.scale.set(
986
- scale2 * naturalWidth / divider,
987
- scale2 * naturalHeight / divider,
984
+ scale3 * naturalWidth / divider,
985
+ scale3 * naturalHeight / divider,
988
986
  1
989
987
  );
990
988
  this.getObject3d().add(sprite);
@@ -993,7 +991,7 @@ var Billboard = class extends BaseObject {
993
991
  const position = layer.coordinateToVector3(coordinate, z);
994
992
  _.set(this.properties, "default.position", position);
995
993
  _.set(this.properties, "default.altitude", altitude);
996
- _.set(this.properties, "default.scale", scale2);
994
+ _.set(this.properties, "default.scale", scale3);
997
995
  this.getObject3d().position.copy(position);
998
996
  }
999
997
  setLineHeight(altitude) {
@@ -1006,319 +1004,25 @@ var Billboard = class extends BaseObject {
1006
1004
  }
1007
1005
  };
1008
1006
 
1009
- // src/IndoorMap/object3d/GroundLabel.ts
1010
- import * as maptalks2 from "maptalks";
1007
+ // src/IndoorMap/object3d/SpriteMarker.ts
1011
1008
  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"
1009
+ import { Sprite as Sprite2, SpriteMaterial as SpriteMaterial2 } from "three";
1010
+ import _2 from "lodash";
1011
+ var DEFAULT_SCALE = 0.05;
1012
+ var DEFAULT_ALTITUDE = 0;
1013
+ var DEFAULT_ALPHATEST = 0.3;
1014
+ var DEFAULT_OPTIONS = {
1015
+ scale: DEFAULT_SCALE,
1016
+ altitude: DEFAULT_ALTITUDE,
1017
+ alphaTest: DEFAULT_ALPHATEST,
1018
+ highlight: {
1019
+ options: {
1020
+ scale: DEFAULT_SCALE * 1.25
1021
+ },
1022
+ material: null
1023
+ }
1035
1024
  };
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 {
1025
+ var SpriteMarker = class extends BaseObject2 {
1322
1026
  #default = null;
1323
1027
  #highlight = null;
1324
1028
  constructor(coordinate, options, material, layer, properties) {
@@ -1327,18 +1031,18 @@ var SpriteMarker = class extends BaseObject3 {
1327
1031
  this._createGroup();
1328
1032
  const {
1329
1033
  altitude = DEFAULT_OPTIONS.altitude,
1330
- scale: scale2 = DEFAULT_OPTIONS.scale,
1034
+ scale: scale3 = DEFAULT_OPTIONS.scale,
1331
1035
  highlight = DEFAULT_OPTIONS.highlight,
1332
1036
  alphaTest = DEFAULT_OPTIONS.alphaTest
1333
1037
  } = options;
1334
1038
  this.properties = { ...properties };
1335
1039
  const modifiedAltitude = altitude + 2;
1336
- this.#default = { options: { scale: scale2, altitude: modifiedAltitude }, material };
1040
+ this.#default = { options: { scale: scale3, altitude: modifiedAltitude }, material };
1337
1041
  this.#highlight = _2.merge({}, DEFAULT_OPTIONS.highlight, highlight);
1338
1042
  if (material && material instanceof SpriteMaterial2)
1339
1043
  material.alphaTest = alphaTest;
1340
1044
  const sprite = new Sprite2(material);
1341
- sprite.scale.set(scale2, scale2, scale2);
1045
+ sprite.scale.set(scale3, scale3, scale3);
1342
1046
  const obj3d = this.getObject3d();
1343
1047
  obj3d.add(sprite);
1344
1048
  const z = layer.altitudeToVector3(modifiedAltitude, modifiedAltitude).x;
@@ -1383,10 +1087,10 @@ var SpriteMarker = class extends BaseObject3 {
1383
1087
  };
1384
1088
 
1385
1089
  // src/IndoorMap/object3d/NavigationPath.ts
1386
- import * as maptalks3 from "maptalks";
1387
- import { BaseObject as BaseObject4 } from "maptalks.three";
1090
+ import * as maptalks2 from "maptalks";
1091
+ import { BaseObject as BaseObject3 } from "maptalks.three";
1388
1092
  import { MeshBasicMaterial, ShaderMaterial, Color } from "three";
1389
- var OPTIONS3 = {
1093
+ var OPTIONS2 = {
1390
1094
  altitude: 0
1391
1095
  };
1392
1096
  var DEFAULT_LINE_OPTION = {
@@ -1398,14 +1102,14 @@ var DEFAULT_LINE_EFFECT_OPTION = {
1398
1102
  opacity: 1
1399
1103
  };
1400
1104
  var ENABLE_ANIMATED_PATH = true;
1401
- var NavigationPath = class extends BaseObject4 {
1105
+ var NavigationPath = class extends BaseObject3 {
1402
1106
  constructor(feature2, layer, properties, options, lineOptions = DEFAULT_LINE_OPTION, outlineOption = DEFAULT_LINE_EFFECT_OPTION) {
1403
- options = maptalks3.Util.extend({}, OPTIONS3, options, {
1107
+ options = maptalks2.Util.extend({}, OPTIONS2, options, {
1404
1108
  layer
1405
1109
  });
1406
1110
  super();
1407
1111
  this._initOptions(options);
1408
- const { altitude = OPTIONS3.altitude } = options;
1112
+ const { altitude = OPTIONS2.altitude } = options;
1409
1113
  this.properties = { ...properties };
1410
1114
  this._createGroup();
1411
1115
  const { color: lineColor, opacity: lineOpacity } = lineOptions || DEFAULT_LINE_OPTION;
@@ -1445,7 +1149,7 @@ var NavigationPath = class extends BaseObject4 {
1445
1149
  }
1446
1150
  `
1447
1151
  });
1448
- const pathGeometry = maptalks3.GeoJSON.toGeometry(feature2);
1152
+ const pathGeometry = maptalks2.GeoJSON.toGeometry(feature2);
1449
1153
  const line = layer.toPath(
1450
1154
  pathGeometry,
1451
1155
  {
@@ -1503,8 +1207,8 @@ var createPolygonFromLineString = (geometry) => {
1503
1207
  const right = turfLineOffset(line, -0.3, { units: "meters" });
1504
1208
  const leftCoords = left.geometry.coordinates;
1505
1209
  const rightCoords = right.geometry.coordinates.reverse();
1506
- const polygon = [...leftCoords, ...rightCoords, leftCoords[0]];
1507
- return [polygon];
1210
+ const polygon2 = [...leftCoords, ...rightCoords, leftCoords[0]];
1211
+ return [polygon2];
1508
1212
  };
1509
1213
 
1510
1214
  // src/IndoorMap/utils/svg.ts
@@ -1538,8 +1242,8 @@ var createSVGPathFromMarkerSymbol = (style) => {
1538
1242
  markerFill,
1539
1243
  markerPath
1540
1244
  } = style;
1541
- const scale2 = markerWidth / 24;
1542
- return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${markerFill}"/>`;
1245
+ const scale3 = markerWidth / 24;
1246
+ return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale3})" fill="${markerFill}"/>`;
1543
1247
  };
1544
1248
 
1545
1249
  // src/IndoorMap/utils/createElements.js
@@ -1680,8 +1384,8 @@ var createObstructionalFixture = (feature2, style = {}, options = {}) => {
1680
1384
  if (allowOverride) _4.merge(symbolStyle, properties.style);
1681
1385
  if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
1682
1386
  if (geometry.type === "LineString") {
1683
- const polygon = createPolygonFromLineString(geometry);
1684
- return new GeometryType["Polygon"](polygon, {
1387
+ const polygon2 = createPolygonFromLineString(geometry);
1388
+ return new GeometryType["Polygon"](polygon2, {
1685
1389
  properties: {
1686
1390
  altitude: getAltitude(properties)
1687
1391
  },
@@ -1797,48 +1501,6 @@ var createPedestrianOpening = (feature2, style, options = {}) => {
1797
1501
  console.log(`error creating pedestrian opening:`, feature2);
1798
1502
  }
1799
1503
  };
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
1504
  var createExtrudePolygon = (geometry, threeLayer, material, height, properties = {}, options) => {
1843
1505
  const { offset = 0, altitude = 0 } = options;
1844
1506
  const offsetGeometry = turfBuffer(geometry, offset, { units: "meters" });
@@ -2512,104 +2174,12 @@ var styledFeatureGenerator = (mapTheme) => {
2512
2174
  return null;
2513
2175
  }
2514
2176
  },
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
2177
  create3DBillboard: (billboard, threeLayer) => {
2608
2178
  const { id, feature_type, properties } = billboard;
2609
2179
  const {
2610
2180
  logo,
2611
2181
  altitude,
2612
- scale: scale2,
2182
+ scale: scale3,
2613
2183
  alphaTest,
2614
2184
  legColor,
2615
2185
  showLeg,
@@ -2623,7 +2193,7 @@ var styledFeatureGenerator = (mapTheme) => {
2623
2193
  };
2624
2194
  const options = {
2625
2195
  altitude,
2626
- scale: scale2,
2196
+ scale: scale3,
2627
2197
  alphaTest,
2628
2198
  legColor,
2629
2199
  showLeg,
@@ -2746,44 +2316,6 @@ var styledFeatureGenerator = (mapTheme) => {
2746
2316
  markerProperties
2747
2317
  );
2748
2318
  },
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
2319
  createExtrudedUnit: (unit, threeLayer, options) => {
2788
2320
  const extrudeHeight = _4.get(options, "height");
2789
2321
  if (!extrudeHeight) return;
@@ -2800,10 +2332,10 @@ var styledFeatureGenerator = (mapTheme) => {
2800
2332
  transparent: true
2801
2333
  });
2802
2334
  if (unit.geometry.type === "LineString") {
2803
- const polygon = createPolygonFromLineString(unit.geometry);
2335
+ const polygon2 = createPolygonFromLineString(unit.geometry);
2804
2336
  const geometry = {
2805
2337
  type: "Polygon",
2806
- coordinates: polygon
2338
+ coordinates: polygon2
2807
2339
  };
2808
2340
  return createExtrudePolygon(
2809
2341
  geometry,
@@ -2823,24 +2355,6 @@ var styledFeatureGenerator = (mapTheme) => {
2823
2355
  options3d
2824
2356
  );
2825
2357
  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
2358
  }
2845
2359
  };
2846
2360
  };
@@ -2923,9 +2437,9 @@ var getRelatedLocationsByAmenity = (feature2) => {
2923
2437
  var getRelatedLocationIdsByFeature = (feature2) => {
2924
2438
  switch (feature2?.feature_type) {
2925
2439
  case "amenity":
2926
- return getRelatedLocationsByAmenity(feature2).map((v) => v?.id);
2440
+ return getRelatedLocationsByAmenity(feature2).map((v2) => v2?.id);
2927
2441
  case "occupant":
2928
- return getRelatedLocationsByOccupant(feature2).map((v) => v?.id);
2442
+ return getRelatedLocationsByOccupant(feature2).map((v2) => v2?.id);
2929
2443
  default:
2930
2444
  return [];
2931
2445
  }
@@ -2970,48 +2484,134 @@ var getSuitablyValueBetweenBearings = (newBearing, currentBearing) => {
2970
2484
  return newBearing;
2971
2485
  };
2972
2486
 
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);
2487
+ // src/IndoorMap/camera/CameraManager.ts
2488
+ import { Extent } from "maptalks";
2489
+
2490
+ // ../../node_modules/@turf/meta/dist/esm/index.js
2491
+ function coordEach(geojson, callback, excludeWrapCoord) {
2492
+ if (geojson === null) return;
2493
+ 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;
2494
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2495
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2496
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2497
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2498
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2499
+ var multiFeatureIndex = 0;
2500
+ var geometryIndex = 0;
2501
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2502
+ if (geometry === null) continue;
2503
+ coords = geometry.coordinates;
2504
+ var geomType = geometry.type;
2505
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2506
+ switch (geomType) {
2507
+ case null:
2508
+ break;
2509
+ case "Point":
2510
+ if (callback(
2511
+ coords,
2512
+ coordIndex,
2513
+ featureIndex,
2514
+ multiFeatureIndex,
2515
+ geometryIndex
2516
+ ) === false)
2517
+ return false;
2518
+ coordIndex++;
2519
+ multiFeatureIndex++;
2520
+ break;
2521
+ case "LineString":
2522
+ case "MultiPoint":
2523
+ for (j = 0; j < coords.length; j++) {
2524
+ if (callback(
2525
+ coords[j],
2526
+ coordIndex,
2527
+ featureIndex,
2528
+ multiFeatureIndex,
2529
+ geometryIndex
2530
+ ) === false)
2531
+ return false;
2532
+ coordIndex++;
2533
+ if (geomType === "MultiPoint") multiFeatureIndex++;
2534
+ }
2535
+ if (geomType === "LineString") multiFeatureIndex++;
2536
+ break;
2537
+ case "Polygon":
2538
+ case "MultiLineString":
2539
+ for (j = 0; j < coords.length; j++) {
2540
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2541
+ if (callback(
2542
+ coords[j][k],
2543
+ coordIndex,
2544
+ featureIndex,
2545
+ multiFeatureIndex,
2546
+ geometryIndex
2547
+ ) === false)
2548
+ return false;
2549
+ coordIndex++;
2550
+ }
2551
+ if (geomType === "MultiLineString") multiFeatureIndex++;
2552
+ if (geomType === "Polygon") geometryIndex++;
2553
+ }
2554
+ if (geomType === "Polygon") multiFeatureIndex++;
2555
+ break;
2556
+ case "MultiPolygon":
2557
+ for (j = 0; j < coords.length; j++) {
2558
+ geometryIndex = 0;
2559
+ for (k = 0; k < coords[j].length; k++) {
2560
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2561
+ if (callback(
2562
+ coords[j][k][l],
2563
+ coordIndex,
2564
+ featureIndex,
2565
+ multiFeatureIndex,
2566
+ geometryIndex
2567
+ ) === false)
2568
+ return false;
2569
+ coordIndex++;
2570
+ }
2571
+ geometryIndex++;
2572
+ }
2573
+ multiFeatureIndex++;
2574
+ }
2575
+ break;
2576
+ case "GeometryCollection":
2577
+ for (j = 0; j < geometry.geometries.length; j++)
2578
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2579
+ return false;
2580
+ break;
2581
+ default:
2582
+ throw new Error("Unknown Geometry Type");
2583
+ }
2584
+ }
2585
+ }
2586
+ }
2587
+
2588
+ // ../../node_modules/@turf/bbox/dist/esm/index.js
2589
+ function bbox(geojson, options = {}) {
2590
+ if (geojson.bbox != null && true !== options.recompute) {
2591
+ return geojson.bbox;
2592
+ }
2593
+ const result = [Infinity, Infinity, -Infinity, -Infinity];
2594
+ coordEach(geojson, (coord) => {
2595
+ if (result[0] > coord[0]) {
2596
+ result[0] = coord[0];
2597
+ }
2598
+ if (result[1] > coord[1]) {
2599
+ result[1] = coord[1];
2600
+ }
2601
+ if (result[2] < coord[0]) {
2602
+ result[2] = coord[0];
2603
+ }
2604
+ if (result[3] < coord[1]) {
2605
+ result[3] = coord[1];
2606
+ }
2987
2607
  });
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
- };
2608
+ return result;
2609
+ }
2610
+ var index_default = bbox;
3011
2611
 
3012
2612
  // src/IndoorMap/camera/CameraManager.ts
3013
- var ZOOM_OUT_LEVEL = 21;
3014
- var ZOOM_IN_LEVEL = 24;
2613
+ import scale from "@turf/transform-scale";
2614
+ import bboxPolygon from "@turf/bbox-polygon";
3015
2615
  var CameraManager = class {
3016
2616
  map;
3017
2617
  constructor(map, options) {
@@ -3020,339 +2620,442 @@ var CameraManager = class {
3020
2620
  this.setView(options?.defaultView);
3021
2621
  }
3022
2622
  }
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
2623
  /** Public methods */
3040
2624
  getView = () => {
3041
2625
  return this.map.getView();
3042
2626
  };
3043
- getZoom = () => {
3044
- return this.map.getView().zoom;
3045
- };
3046
2627
  setView = (value) => {
3047
- this.map.setView(value);
2628
+ if (this.map && Object.keys(value).length !== 0) {
2629
+ this.map.setView(value);
2630
+ }
3048
2631
  };
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
- );
2632
+ animateTo = (view, options = {}, step) => {
2633
+ this.map.animateTo(view, options, step);
3067
2634
  };
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 }
2635
+ setMaxExtent(extent) {
2636
+ return this.map.setMaxExtent(extent);
2637
+ }
2638
+ getFeatureExtent = (feature2, scaleFactor = 1) => {
2639
+ const [minX, minY, maxX, maxY] = index_default(
2640
+ scale(bboxPolygon(index_default(feature2)), scaleFactor)
3082
2641
  );
2642
+ return new Extent(minX, minY, maxX, maxY);
2643
+ };
2644
+ getExtentZoom = (extent, options = {
2645
+ isFraction: false,
2646
+ padding: {
2647
+ paddingLeft: 0,
2648
+ paddingRight: 0,
2649
+ paddingTop: 0,
2650
+ paddingBottom: 0
2651
+ }
2652
+ }) => {
2653
+ const { isFraction = false, padding } = options;
2654
+ return this.map.getFitZoom(extent, isFraction, padding);
3083
2655
  };
2656
+ set maxZoom(value) {
2657
+ this.map.setMaxZoom(value);
2658
+ const spatialReference = {
2659
+ projection: "EPSG:3857",
2660
+ resolutions: (function() {
2661
+ const resolutions = [];
2662
+ const d = 2 * 6378137 * Math.PI;
2663
+ for (let i = 0; i < value; i++) {
2664
+ resolutions[i] = d / (256 * Math.pow(2, i));
2665
+ }
2666
+ return resolutions;
2667
+ })()
2668
+ };
2669
+ this.map.setSpatialReference(spatialReference);
2670
+ }
2671
+ set minZoom(value) {
2672
+ this.map.setMinZoom(value);
2673
+ }
3084
2674
  };
3085
2675
 
3086
2676
  // src/IndoorMap/renderer/RendererManager.ts
3087
- import _min from "lodash/min";
2677
+ import { min, compact as compact3, isFunction } from "lodash-es";
3088
2678
  import { center as turfCenter2 } from "@turf/center";
3089
- import { ThreeLayer as ThreeLayer3 } from "maptalks.three";
3090
2679
  import * as THREE3 from "three";
3091
2680
 
3092
2681
  // 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";
2682
+ import * as maptalks4 from "maptalks-gl";
2683
+ import * as THREE from "three";
2684
+ import { BaseObject as BaseObject5 } from "maptalks.three";
3097
2685
  import turfBuffer2 from "@turf/buffer";
2686
+ import { cleanCoords } from "@turf/clean-coords";
2687
+ import { polygonToLine } from "@turf/polygon-to-line";
2688
+ import { nearestPointOnLine } from "@turf/nearest-point-on-line";
2689
+ import { length } from "@turf/length";
2690
+ import { along } from "@turf/along";
2691
+ import { pointToLineDistance } from "@turf/point-to-line-distance";
3098
2692
 
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 }
2693
+ // src/IndoorMap/renderer/3d/objects/GroundLabel.ts
2694
+ import * as maptalks3 from "maptalks-gl";
2695
+ import { BaseObject as BaseObject4 } from "maptalks.three";
2696
+ import {
2697
+ Texture,
2698
+ MeshPhongMaterial,
2699
+ PlaneGeometry
2700
+ } from "three";
2701
+ import { largestRect } from "d3plus-shape";
2702
+ import { max, merge, isNumber as isNumber2, isArray, range } from "lodash-es";
2703
+ var OPTIONS3 = {
2704
+ // Allowing click through and prevent interaction
2705
+ interactive: false,
2706
+ altitude: 0
2707
+ };
2708
+ var defaultFlatLabelOptions = {
2709
+ fontSize: 14,
2710
+ fontFamily: "Manrope",
2711
+ fontWeight: 600,
2712
+ margin: 0,
2713
+ scaleMin: 0.5,
2714
+ lineHeight: 1.05,
2715
+ scaleStep: 0.05,
2716
+ textAlign: "center",
2717
+ textBaseline: "middle",
2718
+ fillStyle: "#000"
2719
+ };
2720
+ var defaultRectAngleToCalc = range(-90, 92, 2);
2721
+ var getMaterial = (text, flatLabelOptions) => {
2722
+ const options = merge({}, defaultFlatLabelOptions, flatLabelOptions);
2723
+ const {
2724
+ fontSize: initialFontSize,
2725
+ fontFamily,
2726
+ fontWeight,
2727
+ margin,
2728
+ scaleMin,
2729
+ scaleStep,
2730
+ fillStyle,
2731
+ lineHeight,
2732
+ textAlign,
2733
+ strokeStyle,
2734
+ lineWidth,
2735
+ textBaseline
2736
+ } = options;
2737
+ const pixelMultiplier = 4;
2738
+ const SIZE = 100 * pixelMultiplier;
2739
+ const fontSize = initialFontSize * (pixelMultiplier * 1.25);
2740
+ const canvas = document.createElement("canvas");
2741
+ canvas.width = canvas.height = SIZE;
2742
+ const ctx = canvas.getContext("2d");
2743
+ ctx.font = `${fontWeight} ${fontSize}px "${fontFamily}", Arial`;
2744
+ ctx.textAlign = textAlign;
2745
+ ctx.textBaseline = textBaseline;
2746
+ ctx.fillStyle = fillStyle;
2747
+ ctx.strokeStyle = strokeStyle;
2748
+ ctx.lineWidth = lineWidth;
2749
+ const wrapText = (ctx2, text2, maxWidth) => {
2750
+ const words = text2.trim().split(/\s+/);
2751
+ if (words.length <= 1) return [text2];
2752
+ const lines = [];
2753
+ const MAX_LINES = 3;
2754
+ let currentLine = words[0];
2755
+ for (let i = 1; i < words.length; i++) {
2756
+ const lineToMeasure = currentLine + " " + words[i];
2757
+ if (ctx2.measureText(lineToMeasure).width > maxWidth) {
2758
+ lines.push(currentLine);
2759
+ currentLine = words[i];
2760
+ } else {
2761
+ currentLine = lineToMeasure;
2762
+ }
3110
2763
  }
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 }
2764
+ lines.push(currentLine);
2765
+ return lines.slice(0, MAX_LINES);
2766
+ };
2767
+ const hasManualBreaks = text.includes("\n");
2768
+ let texts;
2769
+ if (hasManualBreaks) {
2770
+ texts = text.split(/\n/g);
2771
+ } else {
2772
+ const maxWidth = SIZE - 2 * margin;
2773
+ texts = wrapText(ctx, text, maxWidth);
2774
+ }
2775
+ let textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
2776
+ let scale3 = 1;
2777
+ while (scale3 > 0 && textWidth + 2 * margin > SIZE) {
2778
+ scale3 -= scaleStep;
2779
+ ctx.font = `${fontWeight} ${scale3 * fontSize}px "${fontFamily}", Arial`;
2780
+ textWidth = max(texts.map((text2) => ctx.measureText(text2).width));
2781
+ }
2782
+ const center2 = { x: 0.5 * SIZE, y: 0.5 * SIZE };
2783
+ if (scale3 > scaleMin) {
2784
+ const totalHeight = texts.length * (fontSize * scale3 * lineHeight);
2785
+ const startY = center2.y - totalHeight / 2 + fontSize * scale3 * lineHeight * 0.5;
2786
+ texts.forEach((text2, index) => {
2787
+ const yOffset = startY + index * (fontSize * scale3 * lineHeight);
2788
+ if (strokeStyle && lineWidth) {
2789
+ ctx.strokeText(text2, center2.x, yOffset);
2790
+ }
2791
+ ctx.fillText(text2, center2.x, yOffset);
2792
+ });
2793
+ }
2794
+ const texture = new Texture(canvas);
2795
+ texture.needsUpdate = true;
2796
+ const material = new MeshPhongMaterial({
2797
+ map: texture,
2798
+ transparent: true,
2799
+ // @ref: https://threejs.org/docs/#api/en/materials/Material.alphaTest
2800
+ alphaTest: 0.3
2801
+ });
2802
+ return material;
2803
+ };
2804
+ var GroundLabel = class extends BaseObject4 {
2805
+ #angle = 0;
2806
+ #bearing = 0;
2807
+ #text = "";
2808
+ #offsetX = 0;
2809
+ #offsetY = 0;
2810
+ #originalPosition = null;
2811
+ #layer = null;
2812
+ constructor(bound, text, options, layer) {
2813
+ options = maptalks3.Util.extend({}, OPTIONS3, options, {
2814
+ layer,
2815
+ coordinate: bound
2816
+ });
2817
+ const {
2818
+ altitude = 0,
2819
+ bottomHeight = 0,
2820
+ fontSize,
2821
+ fillStyle,
2822
+ textAlign,
2823
+ fontFamily,
2824
+ textBaseline,
2825
+ strokeStyle,
2826
+ lineWidth,
2827
+ angle = defaultRectAngleToCalc,
2828
+ maxFontScale,
2829
+ offsetX = 0,
2830
+ offsetY = 0,
2831
+ ...properties
2832
+ } = options;
2833
+ super();
2834
+ this._initOptions(options);
2835
+ this.properties = properties;
2836
+ this.#offsetX = offsetX;
2837
+ this.#offsetY = offsetY;
2838
+ this.#layer = layer;
2839
+ const material = getMaterial(text, {
2840
+ fillStyle,
2841
+ fontSize,
2842
+ textAlign,
2843
+ textBaseline,
2844
+ fontFamily,
2845
+ strokeStyle,
2846
+ lineWidth
2847
+ });
2848
+ const rectAngles = isArray(angle) ? angle : [angle];
2849
+ material.needsUpdate = true;
2850
+ const rect = largestRect(bound, {
2851
+ cache: true,
2852
+ /**
2853
+ * Black magic here:
2854
+ * For some reason if we allow angle -90 or 90, some polygon will use that angle even if it's wrong angle to use.
2855
+ * So we remove -90 and 90 from choices, and use -85 & 85 instead.
2856
+ */
2857
+ angle: rectAngles
2858
+ });
2859
+ const { cx, cy, width, angle: calculatedAngle } = rect;
2860
+ this.#text = text;
2861
+ this.#angle = calculatedAngle;
2862
+ const geometry = new PlaneGeometry(1, 1);
2863
+ this._createMesh(geometry, material);
2864
+ const z = layer.altitudeToVector3(altitude + bottomHeight, altitude + bottomHeight).x;
2865
+ const basePosition = layer.coordinateToVector3([cx, cy], z);
2866
+ this.#originalPosition = basePosition.clone();
2867
+ const finalPosition = this.#calculateFinalPosition(basePosition);
2868
+ const scale3 = width / 6456122659e-13;
2869
+ const finalScale = maxFontScale && scale3 > maxFontScale ? maxFontScale : scale3;
2870
+ this.getObject3d().scale.set(finalScale, finalScale, finalScale);
2871
+ this.getObject3d().position.copy(finalPosition);
2872
+ this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
2873
+ }
2874
+ #calculateFinalPosition(basePosition) {
2875
+ if (this.#offsetX === 0 && this.#offsetY === 0) {
2876
+ return basePosition;
2877
+ }
2878
+ const offsetCoordinate = [this.#offsetX, this.#offsetY];
2879
+ const z = this.#layer.altitudeToVector3(0, 0).x;
2880
+ const offsetVector = this.#layer.coordinateToVector3(offsetCoordinate, z);
2881
+ const zeroVector = this.#layer.coordinateToVector3([0, 0], z);
2882
+ const worldOffsetX = offsetVector.x - zeroVector.x;
2883
+ const worldOffsetY = offsetVector.y - zeroVector.y;
2884
+ return {
2885
+ x: basePosition.x + worldOffsetX,
2886
+ y: basePosition.y + worldOffsetY,
2887
+ z: basePosition.z
2888
+ };
2889
+ }
2890
+ #updatePosition() {
2891
+ if (this.#originalPosition && this.#layer) {
2892
+ const finalPosition = this.#calculateFinalPosition(this.#originalPosition);
2893
+ this.getObject3d().position.copy(finalPosition);
3120
2894
  }
3121
2895
  }
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);
2896
+ set bearing(value) {
2897
+ this.#bearing = value;
2898
+ const degree = this.#angle + this.#bearing;
2899
+ const angle = degree > 90 || degree < -90 ? this.#angle + 180 : this.#angle;
2900
+ this.getObject3d().rotation.z = Math.PI / 180 * angle;
2901
+ }
2902
+ get angle() {
2903
+ return this.#angle;
2904
+ }
2905
+ get currentAngle() {
2906
+ return this.#angle;
2907
+ }
2908
+ get text() {
2909
+ return this.#text;
2910
+ }
2911
+ get offsetX() {
2912
+ return this.#offsetX;
2913
+ }
2914
+ get offsetY() {
2915
+ return this.#offsetY;
2916
+ }
2917
+ get offset() {
2918
+ return { x: this.#offsetX, y: this.#offsetY };
2919
+ }
2920
+ set offsetX(value) {
2921
+ if (isNumber2(value)) {
2922
+ this.#offsetX = value;
2923
+ this.#updatePosition();
3140
2924
  }
3141
2925
  }
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";
2926
+ set offsetY(value) {
2927
+ if (isNumber2(value)) {
2928
+ this.#offsetY = value;
2929
+ this.#updatePosition();
2930
+ }
3178
2931
  }
3179
- getOptions() {
3180
- return super.getOptions();
2932
+ set angle(newAngle) {
2933
+ if (isNumber2(newAngle)) {
2934
+ this.#angle = newAngle;
2935
+ this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
2936
+ }
3181
2937
  }
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;
2938
+ setOffset(offsetX, offsetY) {
2939
+ if (isNumber2(offsetX) && isNumber2(offsetY)) {
2940
+ this.#offsetX = offsetX;
2941
+ this.#offsetY = offsetY;
2942
+ this.#updatePosition();
2943
+ }
3202
2944
  }
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);
2945
+ addOffset(deltaX, deltaY) {
2946
+ if (isNumber2(deltaX) && isNumber2(deltaY)) {
2947
+ this.#offsetX += deltaX;
2948
+ this.#offsetY += deltaY;
2949
+ this.#updatePosition();
3255
2950
  }
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
2951
  }
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);
2952
+ resetOffset() {
2953
+ this.#offsetX = 0;
2954
+ this.#offsetY = 0;
2955
+ this.#updatePosition();
3286
2956
  }
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;
2957
+ moveToPosition(targetX, targetY) {
2958
+ if (this.#originalPosition && this.#layer) {
2959
+ const currentCenter = this.#layer.vector3ToCoordinate(
2960
+ this.#originalPosition
2961
+ );
2962
+ this.#offsetX = targetX - currentCenter.x;
2963
+ this.#offsetY = targetY - currentCenter.y;
2964
+ this.#updatePosition();
3304
2965
  }
3305
2966
  }
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();
2967
+ updateText(newText, options = {}) {
2968
+ this.#text = newText;
2969
+ const materialOptions = {
2970
+ fillStyle: options.fillStyle || this.properties.fillStyle,
2971
+ fontSize: options.fontSize || this.properties.fontSize,
2972
+ textAlign: options.textAlign || this.properties.textAlign,
2973
+ textBaseline: options.textBaseline || this.properties.textBaseline,
2974
+ fontFamily: options.fontFamily || this.properties.fontFamily,
2975
+ strokeStyle: options.strokeStyle || this.properties.strokeStyle,
2976
+ lineWidth: options.lineWidth || this.properties.lineWidth
2977
+ };
2978
+ const newMaterial = getMaterial(newText, materialOptions);
2979
+ this.getObject3d().material = newMaterial;
2980
+ newMaterial.needsUpdate = true;
2981
+ }
2982
+ _animation() {
2983
+ const map = this.getMap();
2984
+ if (!map) return;
2985
+ const bearing = map.getBearing();
2986
+ this.bearing = bearing;
3314
2987
  }
2988
+ // Add bottomHeight to altitude as final altitude position
3315
2989
  setAltitude(altitude) {
3316
2990
  const bottomHeight = this.options.bottomHeight ?? 0;
3317
- return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
2991
+ return super.setAltitude(altitude + bottomHeight);
3318
2992
  }
3319
2993
  };
3320
2994
 
3321
- // src/IndoorMap/renderer/3d/Element3DRenderer.ts
2995
+ // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
2996
+ var element3DRendererOptions = {
2997
+ unit: {
2998
+ default: { color: "#ffffff", height: 0.2 },
2999
+ byCategory: {
3000
+ walkway: { color: "#cccccc", height: 0.1 },
3001
+ terrace: { color: "#cccccc", height: 0.1 },
3002
+ unenclosedarea: { color: "#cccccc", height: 0.2 },
3003
+ nonpublic: { color: "#999999", height: 0.3 },
3004
+ escalator: { height: 0.2 },
3005
+ parking: { color: "#999999", height: 0.1 },
3006
+ room: { color: "#ffffff", height: 0.5, bottomHeight: 0.12 }
3007
+ }
3008
+ },
3009
+ kiosk: {
3010
+ default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
3011
+ },
3012
+ fixture: {
3013
+ default: { color: "#ffffff", height: 0.5 },
3014
+ byCategory: {
3015
+ water: { color: "#ACD7EC", height: 0.1 },
3016
+ vegetation: { color: "#91C499", height: 0.5 },
3017
+ wall: { color: "#787878", topColor: "#ffffff", height: 4.2, width: 1 }
3018
+ }
3019
+ }
3020
+ };
3021
+
3022
+ // src/IndoorMap/renderer/3d/utils/get3DRendererOption.ts
3322
3023
  var DEFAULT_POLYGON_OPTION = {
3323
3024
  color: "#FFFFFF",
3324
3025
  offset: 0,
3325
3026
  altitude: 0
3326
3027
  };
3327
- var HEIGHT_METER = 4;
3328
- var MULTIORDINAL_HEIGHT_METER = 9;
3329
- var getGeometryOption = (feature2, options) => {
3028
+ var get3DRendererOption = (featureType, category, options) => {
3330
3029
  try {
3331
- const option = options[feature2.feature_type] ?? element3DRendererOptions[feature2.feature_type];
3332
- const category = feature2.properties.category;
3030
+ const option = options[featureType] ?? element3DRendererOptions[featureType];
3333
3031
  return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION;
3334
3032
  } catch (err) {
3335
- console.log(err.message, { options, feature: feature2 });
3033
+ console.log(err.message, { options, featureType, category });
3336
3034
  }
3337
3035
  };
3036
+
3037
+ // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3038
+ import lineSplit from "@turf/line-split";
3039
+ var HEIGHT_METER = 4;
3040
+ var MULTIORDINAL_HEIGHT_METER = 9;
3338
3041
  var Element3DRenderer = class extends EventTarget {
3339
3042
  options;
3340
3043
  map;
3044
+ gltfLayer;
3341
3045
  threeLayer;
3342
- dracoLoader;
3046
+ scene;
3343
3047
  lineMaterial;
3344
3048
  materialByColorMap;
3345
- markerRenderer;
3346
3049
  // Renderer is Ready
3347
3050
  isReady = false;
3348
- constructor(map, options, layer) {
3051
+ constructor(map, options) {
3349
3052
  super();
3350
3053
  this.options = options;
3351
3054
  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;
3055
+ const groupLayer = this.map.getLayer("group");
3056
+ this.threeLayer = groupLayer.getLayer("three");
3057
+ this.gltfLayer = groupLayer.getLayer("gltf");
3058
+ this.lineMaterial = new THREE.LineBasicMaterial({ color: "#000" });
3356
3059
  this.render();
3357
3060
  }
3358
3061
  animation() {
@@ -3367,7 +3070,7 @@ var Element3DRenderer = class extends EventTarget {
3367
3070
  if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
3368
3071
  const existingMaterial = this.materialByColorMap.get(color);
3369
3072
  if (existingMaterial) return existingMaterial;
3370
- const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
3073
+ const created = new THREE.MeshLambertMaterial({ color, transparent: true });
3371
3074
  created.toneMapped = false;
3372
3075
  this.materialByColorMap.set(color, created);
3373
3076
  return created;
@@ -3379,49 +3082,65 @@ var Element3DRenderer = class extends EventTarget {
3379
3082
  bottomHeight: bottomHeightOptions,
3380
3083
  color: colorOptions,
3381
3084
  ...options
3382
- } = getGeometryOption(feature2, this.options);
3085
+ } = get3DRendererOption(feature2.feature_type, feature2.properties.category, this.options);
3383
3086
  const _this = this;
3384
3087
  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];
3088
+ try {
3089
+ const [outerRing, ...innerRings] = geometry.coordinates;
3090
+ const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3091
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
3092
+ if (color === "transparent") return;
3093
+ const material = this.getOrCreateMaterialByColor(color);
3094
+ const altitude = 0;
3095
+ const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
3096
+ const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
3097
+ const extrudedPolygon = this.threeLayer.toExtrudePolygon(
3098
+ offsetFeature,
3099
+ { asynchronous: true, ...options, height, bottomHeight, altitude },
3100
+ material
3101
+ );
3102
+ const topLineStrings = [
3103
+ new maptalks4.LineString(outerRing),
3104
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3105
+ ];
3106
+ const topLines = this.threeLayer.toLines(
3107
+ topLineStrings,
3108
+ { altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
3109
+ this.lineMaterial
3110
+ );
3111
+ const bottomLineStrings = [
3112
+ new maptalks4.LineString(outerRing),
3113
+ ...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
3114
+ ];
3115
+ const bottomLines = this.threeLayer.toLines(
3116
+ bottomLineStrings,
3117
+ { altitude, bottomHeight, interactive: false },
3118
+ this.lineMaterial
3119
+ );
3120
+ return [extrudedPolygon, topLines, bottomLines];
3121
+ } catch (err) {
3122
+ return [];
3123
+ }
3124
+ };
3125
+ const createLineString = (geometry, feature3) => {
3126
+ try {
3127
+ const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#000000";
3128
+ const material = this.getOrCreateMaterialByColor(color);
3129
+ const extrudedLine = this.threeLayer.toExtrudeLine(
3130
+ new maptalks4.LineString(geometry.coordinates),
3131
+ { height: heightOptions, ...options },
3132
+ material
3133
+ );
3134
+ return [extrudedLine];
3135
+ } catch (err) {
3136
+ return [];
3137
+ }
3420
3138
  };
3421
3139
  try {
3422
3140
  switch (feature2.geometry.type) {
3423
3141
  case "MultiPolygon": {
3424
3142
  const { coordinates } = feature2.geometry;
3143
+ if (!coordinates) return [];
3425
3144
  const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3426
3145
  const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3427
3146
  this.threeLayer.addMesh(meshes);
@@ -3430,70 +3149,126 @@ var Element3DRenderer = class extends EventTarget {
3430
3149
  return multiMeshes;
3431
3150
  }
3432
3151
  case "Polygon": {
3152
+ const { coordinates } = feature2.geometry;
3153
+ if (!coordinates) return [];
3433
3154
  const meshes = createPolygon(feature2.geometry, feature2);
3434
3155
  this.threeLayer.addMesh(meshes);
3435
3156
  return meshes;
3436
3157
  }
3158
+ case "LineString": {
3159
+ const { coordinates } = feature2.geometry;
3160
+ if (!coordinates) return [];
3161
+ const meshes = createLineString(feature2.geometry, feature2);
3162
+ this.threeLayer.addMesh(meshes);
3163
+ return meshes;
3164
+ }
3437
3165
  }
3438
3166
  } catch (err) {
3439
- console.log(`error createGeometry`, { feature: feature2, options });
3167
+ console.log(`error createGeometry`, err, { feature: feature2, options });
3440
3168
  }
3441
3169
  };
3170
+ createRoomWall(unit, openings = []) {
3171
+ const polygons = unit.geometry.type === "Polygon" ? [unit.geometry.coordinates] : unit.geometry.coordinates;
3172
+ return polygons.map((plg) => {
3173
+ return plg.map((ring) => {
3174
+ const roomWall = cleanCoords(polygonToLine(polygon([ring])));
3175
+ if (openings.length === 0) {
3176
+ const color = "#ababab";
3177
+ const material = this.getOrCreateMaterialByColor(color);
3178
+ const extrudedWall = this.threeLayer.toExtrudeLine(
3179
+ new maptalks4.LineString(roomWall.geometry.coordinates),
3180
+ { height: 4, width: 1 },
3181
+ material
3182
+ );
3183
+ return extrudedWall;
3184
+ }
3185
+ let openingPoints = [];
3186
+ openings.forEach((opening) => {
3187
+ const doorCoords = opening?.geometry?.coordinates;
3188
+ const p0 = point(doorCoords[0]);
3189
+ const p1 = point(doorCoords[doorCoords.length - 1]);
3190
+ const s0 = nearestPointOnLine(roomWall, p0, { units: "meters" });
3191
+ const s1 = nearestPointOnLine(roomWall, p1, { units: "meters" });
3192
+ const d0 = s0.properties.dist;
3193
+ const d1 = s1.properties.dist;
3194
+ if (d0 > 1 || d1 > 1) {
3195
+ } else {
3196
+ openingPoints = openingPoints.concat([s0.geometry.coordinates, s1.geometry.coordinates]);
3197
+ }
3198
+ });
3199
+ try {
3200
+ const split = lineSplit(roomWall, multiPoint(openingPoints));
3201
+ const wallsOnly = split.features.filter((seg) => {
3202
+ const mid = along(seg, length(seg, { units: "meters" }) / 2, { units: "meters" });
3203
+ for (const opening of openings) {
3204
+ const dist = pointToLineDistance(mid, opening, { units: "meters" });
3205
+ if (dist < 0.05) return false;
3206
+ }
3207
+ return true;
3208
+ });
3209
+ const wallMeshes = wallsOnly.map((feature2, i) => {
3210
+ const color = "#ababab";
3211
+ const material = this.getOrCreateMaterialByColor(color);
3212
+ const extrudedLine = this.threeLayer.toExtrudeLine(
3213
+ new maptalks4.LineString(feature2.geometry.coordinates),
3214
+ { height: 3, width: 0.4, id: unit.id },
3215
+ material
3216
+ );
3217
+ extrudedLine.getObject3d().userData = {
3218
+ unitId: unit.id,
3219
+ coords: feature2.geometry.coordinates
3220
+ };
3221
+ return extrudedLine;
3222
+ }).flat();
3223
+ this.threeLayer.addMesh(wallMeshes);
3224
+ return wallMeshes;
3225
+ } catch (e) {
3226
+ console.log(e.message, { unit, roomWall });
3227
+ return [];
3228
+ }
3229
+ }).flat();
3230
+ }).flat();
3231
+ }
3442
3232
  async createEscalator(f, coordinate, options) {
3233
+ const model = {
3234
+ url: "https://cdn.venue.in.th/static/glb/escalator.glb",
3235
+ size: 4.4
3236
+ };
3443
3237
  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
3238
+ const rotationZ = dir === "up" ? 180 + angle : angle;
3239
+ var escalatorMarker = new maptalks4.GLTFMarker(coordinate, {
3240
+ symbol: {
3241
+ url: model.url,
3242
+ rotationZ,
3243
+ translationX: dir === "up" ? 0 : model.size * Math.cos(Math.PI * rotationZ / 180),
3244
+ translationY: dir === "up" ? 0 : model.size * Math.sin(Math.PI * rotationZ / 180),
3245
+ translationZ: dir === "up" ? -0.05 * model.size : -0.5 * model.size
3455
3246
  }
3456
3247
  });
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
3248
+ escalatorMarker.addTo(this.gltfLayer);
3249
+ return escalatorMarker;
3250
+ }
3251
+ // Note: Move to another renderer and keep this file on Geometry only?
3252
+ createGroundLabel(f, unit) {
3253
+ const text = f.properties.name;
3254
+ const bound = f.geometry.coordinates[0];
3255
+ const { height: unitHeight } = get3DRendererOption("unit", unit.properties.category, this.options);
3256
+ const options = { bottomHeight: unitHeight + 5e-3 };
3257
+ const groundLabel = new GroundLabel(bound, text, options, this.threeLayer);
3258
+ this.threeLayer.addMesh(groundLabel);
3259
+ return groundLabel;
3260
+ }
3261
+ async createModel3d(f) {
3262
+ const marker = new maptalks4.GLTFMarker(f.properties.center, {
3263
+ symbol: {
3264
+ url: f.properties.model
3488
3265
  }
3489
3266
  });
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;
3267
+ marker.addTo(this.gltfLayer);
3268
+ return marker;
3269
+ }
3270
+ async createBuilding(coordinate, ordinal) {
3271
+ return Promise.resolve(null);
3497
3272
  }
3498
3273
  createElement(f) {
3499
3274
  switch (f.feature_type) {
@@ -3516,34 +3291,35 @@ var Element3DRenderer = class extends EventTarget {
3516
3291
  }
3517
3292
  });
3518
3293
  }
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
- };
3294
+ createHighlightController(element) {
3295
+ if (!(element instanceof BaseObject5)) {
3296
+ return null;
3297
+ }
3298
+ switch (element.type) {
3299
+ case "ExtrudePolygon":
3300
+ case "ExtrudeLine": {
3301
+ const mesh = element.getObject3d();
3302
+ const originalMaterial = mesh.material;
3303
+ const highlightMaterial = this.getOrCreateMaterialByColor("#ff0000");
3304
+ return {
3305
+ start: () => {
3306
+ mesh.material = highlightMaterial;
3307
+ },
3308
+ clear: () => {
3309
+ mesh.material = originalMaterial;
3310
+ }
3311
+ };
3312
+ }
3313
+ default: {
3314
+ return {
3315
+ start() {
3316
+ },
3317
+ clear() {
3318
+ }
3319
+ };
3320
+ }
3321
+ }
3322
+ }
3547
3323
  render() {
3548
3324
  this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
3549
3325
  if (this.threeLayer._needsUpdate) {
@@ -3602,7 +3378,7 @@ var getGeometryProperties = (feature2) => ({
3602
3378
  category: feature2.properties.category,
3603
3379
  name: feature2.properties.name?.en
3604
3380
  });
3605
- var getGeometryOption2 = (feature2, options) => {
3381
+ var getGeometryOption = (feature2, options) => {
3606
3382
  try {
3607
3383
  const option = options[feature2.feature_type] ?? element2DRendererOptions[feature2.feature_type];
3608
3384
  const category = feature2.properties.category;
@@ -3629,7 +3405,7 @@ var Element2DRenderer = class extends EventTarget {
3629
3405
  }
3630
3406
  createGeometry = (imdfFeature) => {
3631
3407
  const feature2 = getGeometryProperties(imdfFeature);
3632
- const { symbol, ...options } = getGeometryOption2(imdfFeature, this.options);
3408
+ const { symbol, ...options } = getGeometryOption(imdfFeature, this.options);
3633
3409
  const altitude = feature2.properties.ordinal * 10;
3634
3410
  const geometry = maptalks5.Geometry.fromJSON({
3635
3411
  feature: feature2,
@@ -3640,135 +3416,283 @@ var Element2DRenderer = class extends EventTarget {
3640
3416
  properties: { altitude }
3641
3417
  }
3642
3418
  });
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;
3419
+ if (Array.isArray(geometry)) {
3420
+ geometry.forEach((g) => g.addTo(this.elementLayer));
3421
+ return new maptalks5.GeometryCollection(geometry);
3422
+ } else {
3423
+ geometry.addTo(this.elementLayer);
3424
+ return geometry;
3425
+ }
3426
+ };
3427
+ createRoomWall(unit, openings) {
3428
+ return null;
3429
+ }
3430
+ async createEscalator(f, coordinates) {
3431
+ return Promise.resolve(null);
3432
+ }
3433
+ createGroundLabel(f, unit) {
3434
+ const text = f.properties.name;
3435
+ const bound = f.geometry.coordinates[0];
3436
+ return null;
3437
+ }
3438
+ async createBuilding(coordinate, ordinal) {
3439
+ return Promise.resolve(null);
3440
+ }
3441
+ createElement = (imdfFeature) => {
3442
+ switch (imdfFeature.feature_type) {
3443
+ default:
3444
+ return null;
3445
+ }
3446
+ };
3447
+ showElements(elements, ordinalDiff = 0) {
3448
+ elements.forEach((element) => {
3449
+ element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER2);
3450
+ element.show();
3451
+ });
3452
+ }
3453
+ hideElements(elements, ordinalDiff = 0) {
3454
+ elements.forEach((element) => {
3455
+ element.hide();
3456
+ });
3457
+ }
3458
+ createHighlightController(element) {
3459
+ if (!(element instanceof maptalks5.Geometry)) return null;
3460
+ return {
3461
+ start() {
3462
+ },
3463
+ clear() {
3464
+ }
3465
+ };
3466
+ }
3467
+ };
3468
+
3469
+ // src/IndoorMap/renderer/2d/Marker2DRenderer.ts
3470
+ import * as maptalks6 from "maptalks";
3471
+ var Marker2DRenderer = class extends EventTarget {
3472
+ isReady = false;
3473
+ map;
3474
+ markerLayer;
3475
+ constructor(map) {
3476
+ super();
3477
+ this.map = map;
3478
+ }
3479
+ createMarker = (coordinates, ordinal, content) => {
3480
+ const marker = new maptalks6.ui.UIMarker(coordinates, {
3481
+ content,
3482
+ collision: true,
3483
+ collisionFadeIn: true,
3484
+ altitude: 0
3485
+ });
3486
+ marker.addTo(this.map);
3487
+ return marker;
3488
+ };
3489
+ removeMarker = (marker) => {
3490
+ marker.remove();
3491
+ };
3492
+ showMarkers(elements, ordinalDiff = 0) {
3493
+ }
3494
+ hideMarkers(elements, ordinalDiff = 0) {
3495
+ }
3496
+ };
3497
+
3498
+ // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
3499
+ import * as maptalks7 from "maptalks-gl";
3500
+
3501
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3502
+ import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
3503
+ import * as THREE2 from "three";
3504
+ import { BaseObject as BaseObject6 } from "maptalks.three";
3505
+ import { isNil, set } from "lodash";
3506
+
3507
+ // src/IndoorMap/renderer/utils/interpolateStops.ts
3508
+ var interpolateStops = ({ stops }, zoom) => {
3509
+ if (zoom <= stops[0][0]) return stops[0][1];
3510
+ if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
3511
+ for (let i = 0; i < stops.length - 1; i++) {
3512
+ const [z1, v1] = stops[i];
3513
+ const [z2, v2] = stops[i + 1];
3514
+ if (zoom >= z1 && zoom <= z2) {
3515
+ const t = (zoom - z1) / (z2 - z1);
3516
+ return v1 + t * (v2 - v1);
3517
+ }
3518
+ }
3519
+ };
3520
+
3521
+ // src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
3522
+ var OPTIONS4 = {
3523
+ // Texture options
3524
+ text: "",
3525
+ textAlign: "center",
3526
+ color: "#ffffff",
3527
+ fontFamily: "sans-serif",
3528
+ fontSize: 28,
3529
+ fontWeight: 400,
3530
+ background: "transparent",
3531
+ lineHeight: 32,
3532
+ padding: 8,
3533
+ strokeColor: "#000000",
3534
+ strokeWidth: 3,
3535
+ strokeStyle: "round",
3536
+ // Sprite options
3537
+ /* Overall scale multiplier */
3538
+ scale: 1,
3539
+ altitude: 0,
3540
+ opacity: 1
3541
+ };
3542
+ var TextSpriteMarker = class extends BaseObject6 {
3543
+ #altitudeOffset = 0;
3544
+ constructor(coordinate, options, layer, properties = {}) {
3545
+ options = Util4.extend({}, OPTIONS4, options, { layer });
3546
+ super();
3547
+ this._coordinate = new Coordinate2(coordinate);
3548
+ this._initOptions(options);
3549
+ this._createGroup();
3550
+ this.properties = { ...properties };
3551
+ const sprite = this._createSprite();
3552
+ this.getObject3d().add(sprite);
3553
+ this._updatePosition();
3554
+ this.type = "TextSpriteMarker";
3555
+ }
3556
+ getOptions() {
3557
+ return super.getOptions();
3558
+ }
3559
+ _createSprite() {
3560
+ const options = this.getOptions();
3561
+ const texture = this._createTextTexture(options.text, options);
3562
+ const material = new THREE2.SpriteMaterial({
3563
+ map: texture,
3564
+ transparent: true,
3565
+ alphaTest: 0.1
3566
+ });
3567
+ const sprite = new THREE2.Sprite(material);
3568
+ const w = texture.image.width;
3569
+ const h = texture.image.height;
3570
+ const base = 1 / 16;
3571
+ const normalizedScale = options.scale / this.getMap().getGLRes();
3572
+ sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
3573
+ this.#altitudeOffset = Math.max(
3574
+ h * base * options.scale * 0.5,
3575
+ 0.05
3576
+ // minimum lift in world units
3577
+ );
3578
+ return sprite;
3579
+ }
3580
+ _createTextTexture(text, options = {}) {
3581
+ const {
3582
+ padding,
3583
+ fontSize,
3584
+ fontFamily,
3585
+ fontWeight,
3586
+ lineHeight,
3587
+ background,
3588
+ color,
3589
+ textAlign,
3590
+ strokeColor,
3591
+ strokeWidth,
3592
+ maxWidth
3593
+ } = options || {};
3594
+ const canvas = document.createElement("canvas");
3595
+ const ctx = canvas.getContext("2d");
3596
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3597
+ const paragraphs = String(text).split("\n");
3598
+ const wrappedLines = [];
3599
+ paragraphs.forEach((paragraph) => {
3600
+ if (isNil(maxWidth) || isNaN(maxWidth)) {
3601
+ wrappedLines.push(paragraph);
3602
+ return;
3603
+ }
3604
+ const words = paragraph.split(/\s+/);
3605
+ let currentLine = "";
3606
+ words.forEach((word) => {
3607
+ const testLine = currentLine ? currentLine + " " + word : word;
3608
+ const testWidth = ctx.measureText(testLine).width;
3609
+ if (testWidth > maxWidth && currentLine) {
3610
+ wrappedLines.push(currentLine);
3611
+ currentLine = word;
3612
+ } else {
3613
+ currentLine = testLine;
3614
+ }
3615
+ });
3616
+ if (currentLine) {
3617
+ wrappedLines.push(currentLine);
3618
+ }
3619
+ });
3620
+ const lines = wrappedLines.length ? wrappedLines : [""];
3621
+ const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
3622
+ const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
3623
+ const finalHeight = lineHeight * lines.length + padding * 2;
3624
+ canvas.width = finalWidth;
3625
+ canvas.height = finalHeight;
3626
+ const ctx2 = canvas.getContext("2d");
3627
+ ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
3628
+ ctx2.textAlign = textAlign;
3629
+ if (background && background !== "transparent") {
3630
+ ctx2.fillStyle = background;
3631
+ ctx2.fillRect(0, 0, canvas.width, canvas.height);
3661
3632
  }
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();
3633
+ lines.forEach((line, i) => {
3634
+ const y = padding + lineHeight * (i + 0.8);
3635
+ let x = padding;
3636
+ if (textAlign === "center") x = canvas.width / 2;
3637
+ if (textAlign === "right" || textAlign === "end")
3638
+ x = canvas.width - padding;
3639
+ if (strokeWidth > 0) {
3640
+ ctx2.lineWidth = strokeWidth;
3641
+ ctx2.lineJoin = "round";
3642
+ ctx2.miterLimit = 2;
3643
+ ctx2.strokeStyle = strokeColor;
3644
+ ctx2.strokeText(line, x, y);
3645
+ }
3646
+ ctx2.fillStyle = color;
3647
+ ctx2.fillText(line, x, y);
3672
3648
  });
3649
+ const texture = new THREE2.CanvasTexture(canvas);
3650
+ texture.needsUpdate = true;
3651
+ texture.minFilter = THREE2.LinearFilter;
3652
+ return texture;
3673
3653
  }
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) {
3654
+ _updatePosition() {
3655
+ const options = this.getOptions();
3656
+ const layer = options.layer;
3657
+ if (!layer) return;
3658
+ const altitude = (options.altitude || 0) + this.#altitudeOffset;
3659
+ const z = layer.altitudeToVector3(altitude, altitude).x;
3660
+ const position = layer.coordinateToVector3(this._coordinate, z);
3661
+ set(this.properties, "default.position", position);
3662
+ this.getObject3d().position.copy(position);
3699
3663
  }
3700
- hideMarkers(elements, ordinalDiff = 0) {
3664
+ _animation() {
3665
+ const layer = this.getLayer();
3666
+ if (!this.isAdd || !layer) return;
3667
+ if (this._visible === true) {
3668
+ const zoom = layer.map.getZoom();
3669
+ const object3d = this.getObject3d();
3670
+ const { opacity } = this.getOptions();
3671
+ let opacityValue;
3672
+ if (typeof opacity === "number") {
3673
+ opacityValue = opacity ?? 1;
3674
+ } else if (Array.isArray(opacity.stops)) {
3675
+ opacityValue = interpolateStops(opacity, zoom);
3676
+ } else {
3677
+ throw new Error(`Unknown opacity value ${opacity}`);
3678
+ }
3679
+ const visible = opacityValue > 0.5;
3680
+ object3d.visible = visible;
3681
+ }
3701
3682
  }
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
- );
3683
+ setText(text) {
3684
+ const options = this.getOptions();
3685
+ options.text = text;
3686
+ const newSprite = this._createSprite();
3687
+ const group = this.getObject3d();
3688
+ group.children.forEach((child) => group.remove(child));
3689
+ group.add(newSprite);
3690
+ this._updatePosition();
3747
3691
  }
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);
3692
+ setAltitude(altitude) {
3693
+ const bottomHeight = this.options.bottomHeight ?? 0;
3694
+ return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
3770
3695
  }
3771
- return material;
3772
3696
  };
3773
3697
 
3774
3698
  // src/IndoorMap/renderer/3d/Marker3DRenderer.ts
@@ -3818,67 +3742,547 @@ var Marker3DRenderer = class extends EventTarget {
3818
3742
  }
3819
3743
  });
3820
3744
  }
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;
3745
+ /** Marker */
3746
+ // getOrCreateIconMaterial(key) {
3747
+ // if (!this.materialByKey) this.materialByKey = new Map()
3748
+ // const existingMaterial = this.materialByKey.get(key)
3749
+ // if (existingMaterial) return existingMaterial
3750
+ // // Create new
3751
+ // const baseSymbol: maptalks.Path = {
3752
+ // markerType: "path",
3753
+ // markerPath: [
3754
+ // {
3755
+ // path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
3756
+ // fill: "#ff0000",
3757
+ // },
3758
+ // ],
3759
+ // markerPathWidth: 24,
3760
+ // markerPathHeight: 24
3761
+ // }
3762
+ // const markerSymbol: maptalks.PathMarkerSymbol = {
3763
+ // markerType: "path",
3764
+ // markerPath: [],
3765
+ // // TODO: Get Path by featureType.category
3766
+ // // 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" }],
3767
+ // markerPathWidth: 24,
3768
+ // markerPathHeight: 24,
3769
+ // markerWidth: 24,
3770
+ // markerHeight: 24,
3771
+ // markerDy: 1.5,
3772
+ // markerDx: 1.5,
3773
+ // }
3774
+ // const created = createSpriteMaterialByLabelSymbol([
3775
+ // baseSymbol,
3776
+ // markerSymbol,
3777
+ // ])
3778
+ // this.materialByKey.set(key, created)
3779
+ // return created
3780
+ // }
3781
+ };
3782
+
3783
+ // src/IndoorMap/renderer/utils/angleBetweenLineString.ts
3784
+ var getLineCenter = (line) => {
3785
+ let x = 0, y = 0;
3786
+ for (const [lx, ly] of line) {
3787
+ x += lx;
3788
+ y += ly;
3789
+ }
3790
+ const len = line.length;
3791
+ return [x / len, y / len];
3792
+ };
3793
+ var angleBetweenLineStrings = (line1, line2) => {
3794
+ const [x1, y1] = getLineCenter(line1);
3795
+ const [x2, y2] = getLineCenter(line2);
3796
+ const dx = x2 - x1;
3797
+ const dy = y2 - y1;
3798
+ return Math.atan2(dy, dx);
3799
+ };
3800
+
3801
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/util.js
3802
+ var epsilon = 11102230246251565e-32;
3803
+ var splitter = 134217729;
3804
+ var resulterrbound = (3 + 8 * epsilon) * epsilon;
3805
+ function sum(elen, e, flen, f, h) {
3806
+ let Q, Qnew, hh, bvirt;
3807
+ let enow = e[0];
3808
+ let fnow = f[0];
3809
+ let eindex = 0;
3810
+ let findex = 0;
3811
+ if (fnow > enow === fnow > -enow) {
3812
+ Q = enow;
3813
+ enow = e[++eindex];
3814
+ } else {
3815
+ Q = fnow;
3816
+ fnow = f[++findex];
3817
+ }
3818
+ let hindex = 0;
3819
+ if (eindex < elen && findex < flen) {
3820
+ if (fnow > enow === fnow > -enow) {
3821
+ Qnew = enow + Q;
3822
+ hh = Q - (Qnew - enow);
3823
+ enow = e[++eindex];
3824
+ } else {
3825
+ Qnew = fnow + Q;
3826
+ hh = Q - (Qnew - fnow);
3827
+ fnow = f[++findex];
3828
+ }
3829
+ Q = Qnew;
3830
+ if (hh !== 0) {
3831
+ h[hindex++] = hh;
3832
+ }
3833
+ while (eindex < elen && findex < flen) {
3834
+ if (fnow > enow === fnow > -enow) {
3835
+ Qnew = Q + enow;
3836
+ bvirt = Qnew - Q;
3837
+ hh = Q - (Qnew - bvirt) + (enow - bvirt);
3838
+ enow = e[++eindex];
3839
+ } else {
3840
+ Qnew = Q + fnow;
3841
+ bvirt = Qnew - Q;
3842
+ hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3843
+ fnow = f[++findex];
3844
+ }
3845
+ Q = Qnew;
3846
+ if (hh !== 0) {
3847
+ h[hindex++] = hh;
3848
+ }
3849
+ }
3850
+ }
3851
+ while (eindex < elen) {
3852
+ Qnew = Q + enow;
3853
+ bvirt = Qnew - Q;
3854
+ hh = Q - (Qnew - bvirt) + (enow - bvirt);
3855
+ enow = e[++eindex];
3856
+ Q = Qnew;
3857
+ if (hh !== 0) {
3858
+ h[hindex++] = hh;
3859
+ }
3860
+ }
3861
+ while (findex < flen) {
3862
+ Qnew = Q + fnow;
3863
+ bvirt = Qnew - Q;
3864
+ hh = Q - (Qnew - bvirt) + (fnow - bvirt);
3865
+ fnow = f[++findex];
3866
+ Q = Qnew;
3867
+ if (hh !== 0) {
3868
+ h[hindex++] = hh;
3869
+ }
3870
+ }
3871
+ if (Q !== 0 || hindex === 0) {
3872
+ h[hindex++] = Q;
3873
+ }
3874
+ return hindex;
3875
+ }
3876
+ function estimate(elen, e) {
3877
+ let Q = e[0];
3878
+ for (let i = 1; i < elen; i++) Q += e[i];
3879
+ return Q;
3880
+ }
3881
+ function vec(n) {
3882
+ return new Float64Array(n);
3883
+ }
3884
+
3885
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient2d.js
3886
+ var ccwerrboundA = (3 + 16 * epsilon) * epsilon;
3887
+ var ccwerrboundB = (2 + 12 * epsilon) * epsilon;
3888
+ var ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;
3889
+ var B = vec(4);
3890
+ var C1 = vec(8);
3891
+ var C2 = vec(12);
3892
+ var D = vec(16);
3893
+ var u = vec(4);
3894
+ function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {
3895
+ let acxtail, acytail, bcxtail, bcytail;
3896
+ let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u32;
3897
+ const acx = ax - cx;
3898
+ const bcx = bx - cx;
3899
+ const acy = ay - cy;
3900
+ const bcy = by - cy;
3901
+ s1 = acx * bcy;
3902
+ c = splitter * acx;
3903
+ ahi = c - (c - acx);
3904
+ alo = acx - ahi;
3905
+ c = splitter * bcy;
3906
+ bhi = c - (c - bcy);
3907
+ blo = bcy - bhi;
3908
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3909
+ t1 = acy * bcx;
3910
+ c = splitter * acy;
3911
+ ahi = c - (c - acy);
3912
+ alo = acy - ahi;
3913
+ c = splitter * bcx;
3914
+ bhi = c - (c - bcx);
3915
+ blo = bcx - bhi;
3916
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3917
+ _i = s0 - t0;
3918
+ bvirt = s0 - _i;
3919
+ B[0] = s0 - (_i + bvirt) + (bvirt - t0);
3920
+ _j = s1 + _i;
3921
+ bvirt = _j - s1;
3922
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
3923
+ _i = _0 - t1;
3924
+ bvirt = _0 - _i;
3925
+ B[1] = _0 - (_i + bvirt) + (bvirt - t1);
3926
+ u32 = _j + _i;
3927
+ bvirt = u32 - _j;
3928
+ B[2] = _j - (u32 - bvirt) + (_i - bvirt);
3929
+ B[3] = u32;
3930
+ let det = estimate(4, B);
3931
+ let errbound = ccwerrboundB * detsum;
3932
+ if (det >= errbound || -det >= errbound) {
3933
+ return det;
3934
+ }
3935
+ bvirt = ax - acx;
3936
+ acxtail = ax - (acx + bvirt) + (bvirt - cx);
3937
+ bvirt = bx - bcx;
3938
+ bcxtail = bx - (bcx + bvirt) + (bvirt - cx);
3939
+ bvirt = ay - acy;
3940
+ acytail = ay - (acy + bvirt) + (bvirt - cy);
3941
+ bvirt = by - bcy;
3942
+ bcytail = by - (bcy + bvirt) + (bvirt - cy);
3943
+ if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {
3944
+ return det;
3945
+ }
3946
+ errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);
3947
+ det += acx * bcytail + bcy * acxtail - (acy * bcxtail + bcx * acytail);
3948
+ if (det >= errbound || -det >= errbound) return det;
3949
+ s1 = acxtail * bcy;
3950
+ c = splitter * acxtail;
3951
+ ahi = c - (c - acxtail);
3952
+ alo = acxtail - ahi;
3953
+ c = splitter * bcy;
3954
+ bhi = c - (c - bcy);
3955
+ blo = bcy - bhi;
3956
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3957
+ t1 = acytail * bcx;
3958
+ c = splitter * acytail;
3959
+ ahi = c - (c - acytail);
3960
+ alo = acytail - ahi;
3961
+ c = splitter * bcx;
3962
+ bhi = c - (c - bcx);
3963
+ blo = bcx - bhi;
3964
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3965
+ _i = s0 - t0;
3966
+ bvirt = s0 - _i;
3967
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
3968
+ _j = s1 + _i;
3969
+ bvirt = _j - s1;
3970
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
3971
+ _i = _0 - t1;
3972
+ bvirt = _0 - _i;
3973
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
3974
+ u32 = _j + _i;
3975
+ bvirt = u32 - _j;
3976
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
3977
+ u[3] = u32;
3978
+ const C1len = sum(4, B, 4, u, C1);
3979
+ s1 = acx * bcytail;
3980
+ c = splitter * acx;
3981
+ ahi = c - (c - acx);
3982
+ alo = acx - ahi;
3983
+ c = splitter * bcytail;
3984
+ bhi = c - (c - bcytail);
3985
+ blo = bcytail - bhi;
3986
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
3987
+ t1 = acy * bcxtail;
3988
+ c = splitter * acy;
3989
+ ahi = c - (c - acy);
3990
+ alo = acy - ahi;
3991
+ c = splitter * bcxtail;
3992
+ bhi = c - (c - bcxtail);
3993
+ blo = bcxtail - bhi;
3994
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
3995
+ _i = s0 - t0;
3996
+ bvirt = s0 - _i;
3997
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
3998
+ _j = s1 + _i;
3999
+ bvirt = _j - s1;
4000
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
4001
+ _i = _0 - t1;
4002
+ bvirt = _0 - _i;
4003
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4004
+ u32 = _j + _i;
4005
+ bvirt = u32 - _j;
4006
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4007
+ u[3] = u32;
4008
+ const C2len = sum(C1len, C1, 4, u, C2);
4009
+ s1 = acxtail * bcytail;
4010
+ c = splitter * acxtail;
4011
+ ahi = c - (c - acxtail);
4012
+ alo = acxtail - ahi;
4013
+ c = splitter * bcytail;
4014
+ bhi = c - (c - bcytail);
4015
+ blo = bcytail - bhi;
4016
+ s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
4017
+ t1 = acytail * bcxtail;
4018
+ c = splitter * acytail;
4019
+ ahi = c - (c - acytail);
4020
+ alo = acytail - ahi;
4021
+ c = splitter * bcxtail;
4022
+ bhi = c - (c - bcxtail);
4023
+ blo = bcxtail - bhi;
4024
+ t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
4025
+ _i = s0 - t0;
4026
+ bvirt = s0 - _i;
4027
+ u[0] = s0 - (_i + bvirt) + (bvirt - t0);
4028
+ _j = s1 + _i;
4029
+ bvirt = _j - s1;
4030
+ _0 = s1 - (_j - bvirt) + (_i - bvirt);
4031
+ _i = _0 - t1;
4032
+ bvirt = _0 - _i;
4033
+ u[1] = _0 - (_i + bvirt) + (bvirt - t1);
4034
+ u32 = _j + _i;
4035
+ bvirt = u32 - _j;
4036
+ u[2] = _j - (u32 - bvirt) + (_i - bvirt);
4037
+ u[3] = u32;
4038
+ const Dlen = sum(C2len, C2, 4, u, D);
4039
+ return D[Dlen - 1];
4040
+ }
4041
+ function orient2d(ax, ay, bx, by, cx, cy) {
4042
+ const detleft = (ay - cy) * (bx - cx);
4043
+ const detright = (ax - cx) * (by - cy);
4044
+ const det = detleft - detright;
4045
+ const detsum = Math.abs(detleft + detright);
4046
+ if (Math.abs(det) >= ccwerrboundA * detsum) return det;
4047
+ return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);
4048
+ }
4049
+
4050
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/orient3d.js
4051
+ var o3derrboundA = (7 + 56 * epsilon) * epsilon;
4052
+ var o3derrboundB = (3 + 28 * epsilon) * epsilon;
4053
+ var o3derrboundC = (26 + 288 * epsilon) * epsilon * epsilon;
4054
+ var bc = vec(4);
4055
+ var ca = vec(4);
4056
+ var ab = vec(4);
4057
+ var at_b = vec(4);
4058
+ var at_c = vec(4);
4059
+ var bt_c = vec(4);
4060
+ var bt_a = vec(4);
4061
+ var ct_a = vec(4);
4062
+ var ct_b = vec(4);
4063
+ var bct = vec(8);
4064
+ var cat = vec(8);
4065
+ var abt = vec(8);
4066
+ var u2 = vec(4);
4067
+ var _8 = vec(8);
4068
+ var _8b = vec(8);
4069
+ var _16 = vec(8);
4070
+ var _12 = vec(12);
4071
+ var fin = vec(192);
4072
+ var fin2 = vec(192);
4073
+
4074
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/incircle.js
4075
+ var iccerrboundA = (10 + 96 * epsilon) * epsilon;
4076
+ var iccerrboundB = (4 + 48 * epsilon) * epsilon;
4077
+ var iccerrboundC = (44 + 576 * epsilon) * epsilon * epsilon;
4078
+ var bc2 = vec(4);
4079
+ var ca2 = vec(4);
4080
+ var ab2 = vec(4);
4081
+ var aa = vec(4);
4082
+ var bb = vec(4);
4083
+ var cc = vec(4);
4084
+ var u3 = vec(4);
4085
+ var v = vec(4);
4086
+ var axtbc = vec(8);
4087
+ var aytbc = vec(8);
4088
+ var bxtca = vec(8);
4089
+ var bytca = vec(8);
4090
+ var cxtab = vec(8);
4091
+ var cytab = vec(8);
4092
+ var abt2 = vec(8);
4093
+ var bct2 = vec(8);
4094
+ var cat2 = vec(8);
4095
+ var abtt = vec(4);
4096
+ var bctt = vec(4);
4097
+ var catt = vec(4);
4098
+ var _82 = vec(8);
4099
+ var _162 = vec(16);
4100
+ var _16b = vec(16);
4101
+ var _16c = vec(16);
4102
+ var _32 = vec(32);
4103
+ var _32b = vec(32);
4104
+ var _48 = vec(48);
4105
+ var _64 = vec(64);
4106
+ var fin3 = vec(1152);
4107
+ var fin22 = vec(1152);
4108
+
4109
+ // ../../node_modules/point-in-polygon-hao/node_modules/robust-predicates/esm/insphere.js
4110
+ var isperrboundA = (16 + 224 * epsilon) * epsilon;
4111
+ var isperrboundB = (5 + 72 * epsilon) * epsilon;
4112
+ var isperrboundC = (71 + 1408 * epsilon) * epsilon * epsilon;
4113
+ var ab3 = vec(4);
4114
+ var bc3 = vec(4);
4115
+ var cd = vec(4);
4116
+ var de = vec(4);
4117
+ var ea = vec(4);
4118
+ var ac = vec(4);
4119
+ var bd = vec(4);
4120
+ var ce = vec(4);
4121
+ var da = vec(4);
4122
+ var eb = vec(4);
4123
+ var abc = vec(24);
4124
+ var bcd = vec(24);
4125
+ var cde = vec(24);
4126
+ var dea = vec(24);
4127
+ var eab = vec(24);
4128
+ var abd = vec(24);
4129
+ var bce = vec(24);
4130
+ var cda = vec(24);
4131
+ var deb = vec(24);
4132
+ var eac = vec(24);
4133
+ var adet = vec(1152);
4134
+ var bdet = vec(1152);
4135
+ var cdet = vec(1152);
4136
+ var ddet = vec(1152);
4137
+ var edet = vec(1152);
4138
+ var abdet = vec(2304);
4139
+ var cddet = vec(2304);
4140
+ var cdedet = vec(3456);
4141
+ var deter = vec(5760);
4142
+ var _83 = vec(8);
4143
+ var _8b2 = vec(8);
4144
+ var _8c = vec(8);
4145
+ var _163 = vec(16);
4146
+ var _24 = vec(24);
4147
+ var _482 = vec(48);
4148
+ var _48b = vec(48);
4149
+ var _96 = vec(96);
4150
+ var _192 = vec(192);
4151
+ var _384x = vec(384);
4152
+ var _384y = vec(384);
4153
+ var _384z = vec(384);
4154
+ var _768 = vec(768);
4155
+ var xdet = vec(96);
4156
+ var ydet = vec(96);
4157
+ var zdet = vec(96);
4158
+ var fin4 = vec(1152);
4159
+
4160
+ // ../../node_modules/point-in-polygon-hao/dist/esm/index.js
4161
+ function pointInPolygon(p, polygon2) {
4162
+ var i;
4163
+ var ii;
4164
+ var k = 0;
4165
+ var f;
4166
+ var u1;
4167
+ var v1;
4168
+ var u22;
4169
+ var v2;
4170
+ var currentP;
4171
+ var nextP;
4172
+ var x = p[0];
4173
+ var y = p[1];
4174
+ var numContours = polygon2.length;
4175
+ for (i = 0; i < numContours; i++) {
4176
+ ii = 0;
4177
+ var contour = polygon2[i];
4178
+ var contourLen = contour.length - 1;
4179
+ currentP = contour[0];
4180
+ if (currentP[0] !== contour[contourLen][0] && currentP[1] !== contour[contourLen][1]) {
4181
+ throw new Error("First and last coordinates in a ring must be the same");
4182
+ }
4183
+ u1 = currentP[0] - x;
4184
+ v1 = currentP[1] - y;
4185
+ for (ii; ii < contourLen; ii++) {
4186
+ nextP = contour[ii + 1];
4187
+ u22 = nextP[0] - x;
4188
+ v2 = nextP[1] - y;
4189
+ if (v1 === 0 && v2 === 0) {
4190
+ if (u22 <= 0 && u1 >= 0 || u1 <= 0 && u22 >= 0) {
4191
+ return 0;
4192
+ }
4193
+ } else if (v2 >= 0 && v1 <= 0 || v2 <= 0 && v1 >= 0) {
4194
+ f = orient2d(u1, u22, v1, v2, 0, 0);
4195
+ if (f === 0) {
4196
+ return 0;
4197
+ }
4198
+ if (f > 0 && v2 > 0 && v1 <= 0 || f < 0 && v2 <= 0 && v1 > 0) {
4199
+ k++;
4200
+ }
4201
+ }
4202
+ currentP = nextP;
4203
+ v1 = v2;
4204
+ u1 = u22;
4205
+ }
4206
+ }
4207
+ if (k % 2 === 0) {
4208
+ return false;
4209
+ }
4210
+ return true;
4211
+ }
4212
+
4213
+ // ../../node_modules/@turf/invariant/dist/esm/index.js
4214
+ function getCoord(coord) {
4215
+ if (!coord) {
4216
+ throw new Error("coord is required");
4217
+ }
4218
+ if (!Array.isArray(coord)) {
4219
+ if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {
4220
+ return [...coord.geometry.coordinates];
4221
+ }
4222
+ if (coord.type === "Point") {
4223
+ return [...coord.coordinates];
4224
+ }
4225
+ }
4226
+ if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {
4227
+ return [...coord];
3855
4228
  }
3856
- };
4229
+ throw new Error("coord must be GeoJSON Point or an Array of numbers");
4230
+ }
4231
+ function getGeom(geojson) {
4232
+ if (geojson.type === "Feature") {
4233
+ return geojson.geometry;
4234
+ }
4235
+ return geojson;
4236
+ }
3857
4237
 
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;
4238
+ // ../../node_modules/@turf/boolean-point-in-polygon/dist/esm/index.js
4239
+ function booleanPointInPolygon(point2, polygon2, options = {}) {
4240
+ if (!point2) {
4241
+ throw new Error("point is required");
4242
+ }
4243
+ if (!polygon2) {
4244
+ throw new Error("polygon is required");
4245
+ }
4246
+ const pt = getCoord(point2);
4247
+ const geom = getGeom(polygon2);
4248
+ const type = geom.type;
4249
+ const bbox2 = polygon2.bbox;
4250
+ let polys = geom.coordinates;
4251
+ if (bbox2 && inBBox(pt, bbox2) === false) {
4252
+ return false;
4253
+ }
4254
+ if (type === "Polygon") {
4255
+ polys = [polys];
4256
+ }
4257
+ let result = false;
4258
+ for (var i = 0; i < polys.length; ++i) {
4259
+ const polyResult = pointInPolygon(pt, polys[i]);
4260
+ if (polyResult === 0) return options.ignoreBoundary ? false : true;
4261
+ else if (polyResult) result = true;
3864
4262
  }
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);
4263
+ return result;
4264
+ }
4265
+ function inBBox(pt, bbox2) {
4266
+ return bbox2[0] <= pt[0] && bbox2[1] <= pt[1] && bbox2[2] >= pt[0] && bbox2[3] >= pt[1];
4267
+ }
4268
+
4269
+ // src/IndoorMap/renderer/utils/findUnitOnPoint.ts
4270
+ var findUnitOnPoint = (units, point2) => {
4271
+ return units.find((unit) => booleanPointInPolygon(point2, polygon(unit.geometry.coordinates)));
3874
4272
  };
3875
4273
 
3876
4274
  // src/IndoorMap/renderer/RendererManager.ts
4275
+ function delay(ms) {
4276
+ return new Promise((resolve) => setTimeout(resolve, ms));
4277
+ }
3877
4278
  var RendererManager = class extends EventTarget {
3878
4279
  map;
3879
4280
  options;
3880
4281
  // Client for fetching data
3881
4282
  #dataClient;
4283
+ #isClicked = false;
4284
+ #onClickElement = (e) => {
4285
+ };
3882
4286
  /** Elements: Responsible for converting feature info elements and add to map */
3883
4287
  elementRenderer;
3884
4288
  markerRenderer;
@@ -3887,6 +4291,7 @@ var RendererManager = class extends EventTarget {
3887
4291
  currentOrdinals;
3888
4292
  markersMap;
3889
4293
  markersByOrdinal;
4294
+ highlightControllers = [];
3890
4295
  constructor(map, dataClient, options) {
3891
4296
  super();
3892
4297
  this.map = map;
@@ -3896,48 +4301,87 @@ var RendererManager = class extends EventTarget {
3896
4301
  this.markersMap = /* @__PURE__ */ new Map();
3897
4302
  this.markersByOrdinal = /* @__PURE__ */ new Map();
3898
4303
  this.#dataClient = dataClient;
4304
+ const _this = this;
3899
4305
  if (options.type === "3D") {
3900
- const threeLayer = new ThreeLayer3("elements", {
3901
- forceRenderOnMoving: true,
3902
- forceRenderOnRotating: true
3903
- });
3904
- const _this = this;
4306
+ const groupLayer = this.map.getLayer("group");
4307
+ const threeLayer = groupLayer.getLayer("three");
3905
4308
  threeLayer.prepareToDraw = function(gl, scene, camera) {
4309
+ function findBadMeshes(scene2) {
4310
+ const bad = [];
4311
+ scene2.traverse((obj) => {
4312
+ if (!obj?.isMesh) return;
4313
+ const geom = obj.geometry;
4314
+ const pos = geom?.attributes?.position?.array;
4315
+ if (!pos || pos.length === 0) return;
4316
+ for (let i = 0; i < pos.length; i++) {
4317
+ const v2 = pos[i];
4318
+ if (!Number.isFinite(v2)) {
4319
+ bad.push({ mesh: obj, index: i, value: v2 });
4320
+ break;
4321
+ }
4322
+ }
4323
+ });
4324
+ if (bad.length) {
4325
+ console.group(`\u274C Found ${bad.length} meshes with invalid positions`);
4326
+ for (const b of bad) {
4327
+ console.log({
4328
+ name: b.mesh.name,
4329
+ userData: b.mesh.userData,
4330
+ uuid: b.mesh.uuid,
4331
+ badIndex: b.index,
4332
+ badValue: b.value
4333
+ });
4334
+ }
4335
+ console.groupEnd();
4336
+ } else {
4337
+ console.log("\u2705 No invalid meshes found");
4338
+ }
4339
+ return bad;
4340
+ }
3906
4341
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
3907
4342
  scene.add(ambientLight);
3908
4343
  const dirColor = 16777215;
3909
4344
  const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
3910
- dllight.position.set(0, -10, 10).normalize();
4345
+ dllight.position.set(0, -10, 20).normalize();
3911
4346
  scene.add(dllight);
3912
4347
  const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
3913
4348
  scene.add(hemi);
3914
- _this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
4349
+ _this.elementRenderer = new Element3DRenderer(map, options.elements);
3915
4350
  _this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
3916
4351
  if (typeof options.onRendererReady === "function") {
3917
4352
  options.onRendererReady();
3918
4353
  }
3919
4354
  _this.#createElements();
4355
+ setTimeout(() => {
4356
+ findBadMeshes(scene);
4357
+ }, 3e3);
3920
4358
  };
3921
- threeLayer.addTo(this.map);
3922
4359
  } else {
3923
4360
  this.elementRenderer = new Element2DRenderer(map, options.elements);
3924
4361
  this.markerRenderer = new Marker2DRenderer(map);
3925
4362
  this.#createElements();
3926
4363
  }
3927
4364
  }
4365
+ set onClickElement(func) {
4366
+ this.#onClickElement = func;
4367
+ }
4368
+ handleClickElement = (e) => {
4369
+ if (this.#isClicked) return;
4370
+ this.#isClicked = true;
4371
+ const onClickElement = this.#onClickElement;
4372
+ if (!isFunction(onClickElement)) return;
4373
+ this.#onClickElement(e);
4374
+ this.#isClicked = false;
4375
+ };
3928
4376
  getElementsByOrdinal = (ordinal) => {
3929
4377
  const exist = this.elementsByOrdinal.get(ordinal);
3930
4378
  if (!exist) this.elementsByOrdinal.set(ordinal, []);
3931
4379
  return this.elementsByOrdinal.get(ordinal);
3932
4380
  };
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
4381
  addElementsToManager = (id, elements, ordinal) => {
3939
4382
  this.elementsMap.set(id, elements);
3940
4383
  elements.forEach((el) => {
4384
+ el.on("click", (e) => this.handleClickElement(id));
3941
4385
  this.getElementsByOrdinal(ordinal).push(el);
3942
4386
  });
3943
4387
  const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
@@ -3947,22 +4391,14 @@ var RendererManager = class extends EventTarget {
3947
4391
  this.elementRenderer.hideElements(elements, ordinal);
3948
4392
  }
3949
4393
  };
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
4394
  async #createElements() {
4395
+ await delay(this.options.delayBeforeCreateElements ?? 0);
3963
4396
  const levels = await this.#dataClient.filterByType("level", {
3964
4397
  populate: true
3965
4398
  });
4399
+ const openings = await this.#dataClient.filterByType("opening", {
4400
+ populate: true
4401
+ });
3966
4402
  const relationships = await this.#dataClient.filterByType("relationship");
3967
4403
  const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
3968
4404
  fixtures.forEach((fixture) => {
@@ -3976,7 +4412,7 @@ var RendererManager = class extends EventTarget {
3976
4412
  populate: true
3977
4413
  });
3978
4414
  units.filter(
3979
- (u) => !["opentobelow", "escalator"].includes(u.properties.category)
4415
+ (u4) => !["opentobelow", "escalator", "room"].includes(u4.properties.category)
3980
4416
  ).forEach((unit) => {
3981
4417
  const element = this.elementRenderer.createGeometry(unit);
3982
4418
  if (element) {
@@ -3984,6 +4420,22 @@ var RendererManager = class extends EventTarget {
3984
4420
  this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
3985
4421
  }
3986
4422
  });
4423
+ units.filter((u4) => u4.properties.category === "room").forEach((unit) => {
4424
+ const openingRelationships = relationships.filter((r) => r.properties.origin?.id === unit.id || r.properties.destination?.id === unit.id);
4425
+ const roomOpenings = compact3(openingRelationships.map((rel) => {
4426
+ const openingId = rel?.properties.intermediary[0].id;
4427
+ return openings.find((o) => o.id === openingId);
4428
+ }));
4429
+ const innerElements = this.elementRenderer.createGeometry(unit);
4430
+ const wallElements = this.elementRenderer.createRoomWall(unit, roomOpenings);
4431
+ if (innerElements || wallElements) {
4432
+ const _innerElements = Array.isArray(innerElements) ? innerElements : [innerElements];
4433
+ const _wallElements = Array.isArray(wallElements) ? wallElements : [wallElements];
4434
+ const _elements = [..._innerElements, ..._wallElements];
4435
+ const ordinal = unit.properties.level.properties.ordinal;
4436
+ this.addElementsToManager(unit.id, _elements, ordinal);
4437
+ }
4438
+ });
3987
4439
  const kiosks = await this.#dataClient.filterByType("kiosk", {
3988
4440
  populate: true
3989
4441
  });
@@ -3994,7 +4446,7 @@ var RendererManager = class extends EventTarget {
3994
4446
  this.addElementsToManager(kiosk.id, _elements, kiosk.properties.level.properties.ordinal);
3995
4447
  }
3996
4448
  });
3997
- const escalators = units.filter((u) => u.properties.category === "escalator");
4449
+ const escalators = units.filter((u4) => u4.properties.category === "escalator");
3998
4450
  for (const escalator of escalators) {
3999
4451
  try {
4000
4452
  const escalatorRelationships = relationships.filter((r) => (r.properties?.intermediary || []).some((inter) => inter.id === escalator.id));
@@ -4006,13 +4458,15 @@ var RendererManager = class extends EventTarget {
4006
4458
  }
4007
4459
  const thisOrdinal = escalator.properties.ordinal;
4008
4460
  const relationship = escalatorRelationships[0];
4461
+ if (!relationship.properties.origin?.id) throw new Error(`relationship (id=${relationship.id}) - origin not exists`);
4462
+ if (!relationship.properties.destination?.id) throw new Error(`relationship (id=${relationship.id}) - destination not exists`);
4009
4463
  const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
4010
4464
  const bothOpenings = await Promise.all(
4011
4465
  bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
4012
4466
  );
4013
4467
  const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
4014
4468
  const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
4015
- const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4469
+ const angle = 180 * (1 / Math.PI) * angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
4016
4470
  const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
4017
4471
  const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
4018
4472
  const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
@@ -4021,7 +4475,23 @@ var RendererManager = class extends EventTarget {
4021
4475
  this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
4022
4476
  }
4023
4477
  } catch (err) {
4024
- console.log(`cannot create escalator`, err);
4478
+ console.warn(`cannot create escalator`, err.message);
4479
+ }
4480
+ }
4481
+ const groundLabels = await this.#dataClient.filterByType("label");
4482
+ for (const label of groundLabels) {
4483
+ const center2 = turfCenter2(polygon(label.geometry.coordinates)).geometry.coordinates;
4484
+ const unit = findUnitOnPoint(units, center2);
4485
+ const element = this.elementRenderer.createGroundLabel(label, unit);
4486
+ if (element) {
4487
+ const _elements = Array.isArray(element) ? element : [element];
4488
+ this.addElementsToManager(label.id, _elements, label.properties.ordinal);
4489
+ }
4490
+ }
4491
+ if (this.options.type === "3D") {
4492
+ const model3ds = await this.#dataClient.filterByType("model3d");
4493
+ for (const model3d of model3ds) {
4494
+ this.elementRenderer.createModel3d(model3d);
4025
4495
  }
4026
4496
  }
4027
4497
  this.changeLevelByOrdinal(this.currentOrdinals);
@@ -4038,7 +4508,7 @@ var RendererManager = class extends EventTarget {
4038
4508
  this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
4039
4509
  }
4040
4510
  } else {
4041
- const baseOrdinal = Array.isArray(targetOrdinal) ? _min(targetOrdinal) : targetOrdinal;
4511
+ const baseOrdinal = Array.isArray(targetOrdinal) ? min(targetOrdinal) : targetOrdinal;
4042
4512
  for (const [ordinal, elements] of this.elementsByOrdinal) {
4043
4513
  const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
4044
4514
  if (inOrdinal) {
@@ -4057,14 +4527,50 @@ var RendererManager = class extends EventTarget {
4057
4527
  }
4058
4528
  }
4059
4529
  }
4530
+ highlightElements = (elemIds, options) => {
4531
+ const { reset = true } = options ?? {};
4532
+ if (reset) {
4533
+ this.clearHighlightElements();
4534
+ }
4535
+ const elements = elemIds.map((id) => this.elementsMap.get(id)).flat();
4536
+ elements.forEach((element) => {
4537
+ const controller = this.elementRenderer.createHighlightController(element);
4538
+ if (controller && isFunction(controller.start)) {
4539
+ controller.start();
4540
+ this.highlightControllers.push(controller);
4541
+ }
4542
+ });
4543
+ };
4544
+ clearHighlightElements = () => {
4545
+ this.highlightControllers.forEach((controller) => {
4546
+ if (isFunction(controller?.clear)) controller.clear();
4547
+ });
4548
+ };
4060
4549
  /**
4061
4550
  * ========================================================================
4062
4551
  * Markers
4063
4552
  * ======================================================================== */
4553
+ _getMarkersByOrdinal = (ordinal) => {
4554
+ const exist = this.markersByOrdinal.get(ordinal);
4555
+ if (!exist) this.markersByOrdinal.set(ordinal, []);
4556
+ return this.markersByOrdinal.get(ordinal);
4557
+ };
4558
+ _addMarkersToManager = (id, markers, ordinal) => {
4559
+ this.markersMap.set(id, markers);
4560
+ markers.forEach((el) => {
4561
+ this._getMarkersByOrdinal(ordinal).push(el);
4562
+ });
4563
+ const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
4564
+ if (inOrdinal) {
4565
+ this.markerRenderer.showMarkers(markers, ordinal);
4566
+ } else {
4567
+ this.markerRenderer.hideMarkers(markers, ordinal);
4568
+ }
4569
+ };
4064
4570
  createMarker(coordinate, ordinal, text, options) {
4065
4571
  const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
4066
4572
  const markerId = `${this.markersMap.size + 1}`;
4067
- this.addMarkersToManager(markerId, [marker], ordinal);
4573
+ this._addMarkersToManager(markerId, [marker], ordinal);
4068
4574
  }
4069
4575
  clearMarkers() {
4070
4576
  for (const [markerId, marker] of this.markersMap) {
@@ -4079,9 +4585,25 @@ var INITIAL_ZOOM = 18.5;
4079
4585
  var CLICK_TOLERANCE = 20;
4080
4586
  var defaultOptions = {
4081
4587
  pixelRatio: 1,
4588
+ interactions: true,
4082
4589
  locale: DEFAULT_LOCALE
4083
4590
  };
4591
+ var parseMaptalksOptions = (options) => {
4592
+ return {
4593
+ centerCross: options.centerCross ?? false,
4594
+ ...options.interactions === false ? {
4595
+ draggable: false,
4596
+ dragPan: false,
4597
+ dragRotate: false,
4598
+ dragPitch: false,
4599
+ scrollWheelZoom: false,
4600
+ touchZoom: false,
4601
+ doubleClickZoom: false
4602
+ } : {}
4603
+ };
4604
+ };
4084
4605
  var IndoorMap = class extends EventTarget {
4606
+ options;
4085
4607
  //TODO: refac functions; let them do only 1 thing in a function
4086
4608
  /** Note: "#" means private variables */
4087
4609
  #styler = null;
@@ -4098,7 +4620,6 @@ var IndoorMap = class extends EventTarget {
4098
4620
  #billboardObjects = [];
4099
4621
  #spriteMarkerObjects = [];
4100
4622
  #mapDecorations = [];
4101
- #groundLabels = [];
4102
4623
  #groundObjects = [];
4103
4624
  #navigationGeometries = {};
4104
4625
  #venueObjects = [];
@@ -4133,18 +4654,23 @@ var IndoorMap = class extends EventTarget {
4133
4654
  };
4134
4655
  constructor(elementId, options) {
4135
4656
  super();
4657
+ const combinedOptions = _5.merge({}, defaultOptions, options);
4658
+ this.options = combinedOptions;
4136
4659
  const {
4137
4660
  onMapReady,
4138
4661
  onMapLoading,
4139
4662
  pixelRatio,
4140
4663
  locale
4141
- } = _6.merge({}, defaultOptions, options);
4664
+ } = combinedOptions;
4665
+ const maptalksOptions = parseMaptalksOptions(combinedOptions);
4142
4666
  this.map = new Map2(elementId, {
4143
4667
  attribution: false,
4668
+ // Temporart set, not really default view
4669
+ // Default view is set in camera manager
4144
4670
  center: INITIAL_CENTER,
4145
4671
  zoom: INITIAL_ZOOM,
4146
4672
  clickTimeThreshold: 600,
4147
- centerCross: options.centerCross ?? false,
4673
+ ...maptalksOptions,
4148
4674
  baseLayer: new TileLayer("base", {
4149
4675
  urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
4150
4676
  subdomains: ["a", "b", "c", "d"],
@@ -4156,8 +4682,16 @@ var IndoorMap = class extends EventTarget {
4156
4682
  }),
4157
4683
  layers: []
4158
4684
  });
4685
+ const groupLayer = new GroupGLLayer("group", [], {}).addTo(this.map);
4686
+ const threeLayer = new ThreeLayer5("three", {
4687
+ forceRenderOnMoving: true,
4688
+ forceRenderOnRotating: true
4689
+ });
4690
+ groupLayer.addLayer(threeLayer);
4691
+ const gltfLayer = new GLTFLayer("gltf");
4692
+ groupLayer.addLayer(gltfLayer);
4159
4693
  this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
4160
- this.camera = new CameraManager(this.map);
4694
+ this.camera = new CameraManager(this.map, options.camera);
4161
4695
  this.locale = locale;
4162
4696
  this.pixelRatio = pixelRatio;
4163
4697
  this.onMapReady = onMapReady;
@@ -4166,25 +4700,33 @@ var IndoorMap = class extends EventTarget {
4166
4700
  this.map.on("click", this.handleMapClick);
4167
4701
  this.dataClient = options.dataClient;
4168
4702
  }
4703
+ setOptions(options) {
4704
+ const combinedOptions = _5.merge({}, defaultOptions, options);
4705
+ this.options = combinedOptions;
4706
+ const maptalksOptions = parseMaptalksOptions(combinedOptions);
4707
+ this.map.setOptions(maptalksOptions);
4708
+ }
4169
4709
  set dataClient(value) {
4170
4710
  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);
4711
+ if (!this.options.camera?.defaultView?.center) {
4712
+ this.#dataClient.filterByType("venue").then((venues) => {
4713
+ const venueCenters = turfCenter3(featureCollection(venues));
4714
+ const [x, y] = venueCenters.geometry.coordinates;
4715
+ const center2 = new Coordinate4(x, y);
4716
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
4717
+ });
4718
+ }
4180
4719
  }
4181
4720
  /**
4182
4721
  * Events
4183
4722
  */
4723
+ on(eventName, handler) {
4724
+ this.map.on(eventName, handler);
4725
+ }
4184
4726
  handleMapClick = ({ coordinate }) => {
4185
4727
  const { x, y } = coordinate;
4186
4728
  console.log(
4187
- `[Coordinates]: x: ${_6.round(x, 8)} y: ${_6.round(
4729
+ `[Coordinates]: x: ${_5.round(x, 8)} y: ${_5.round(
4188
4730
  y,
4189
4731
  8
4190
4732
  )}, [Bearing]: ${this.map.getBearing()}, [Pitch]: ${this.map.getPitch()}`
@@ -4236,48 +4778,17 @@ var IndoorMap = class extends EventTarget {
4236
4778
  this.map.off("moveend", this.#findAndSetVenueInView);
4237
4779
  }
4238
4780
  }
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
4781
  set billboards(value) {
4247
4782
  this.#billboards = value;
4248
4783
  }
4249
- set mapConfig(value) {
4250
- this.#mapConfig = value;
4251
- }
4252
4784
  set mapDecorations(value) {
4253
4785
  this.#mapDecorations = value;
4254
4786
  }
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
4787
  set pixelRatio(value) {
4277
4788
  this.map.setDevicePixelRatio(value);
4278
4789
  }
4279
4790
  set onClickElement(func) {
4280
- this.#onClickElement = func;
4791
+ this.rendererManager.onClickElement = func;
4281
4792
  }
4282
4793
  set locale(value) {
4283
4794
  this.#locale = value || defaultOptions.locale;
@@ -4301,66 +4812,36 @@ var IndoorMap = class extends EventTarget {
4301
4812
  if (this.#isClicked) return;
4302
4813
  this.#isClicked = true;
4303
4814
  const onClickElement = this.#onClickElement;
4304
- if (!_6.isFunction(onClickElement)) return;
4815
+ if (!_5.isFunction(onClickElement)) return;
4305
4816
  this.#onClickElement(e);
4306
4817
  this.#isClicked = false;
4307
4818
  };
4308
- setCenter(center2, padding) {
4309
- this.map.setCenter(center2, padding);
4310
- }
4311
4819
  async #legacy_createElements() {
4312
4820
  const {
4313
4821
  // 2D
4314
- createVenue,
4315
4822
  createOpening,
4316
4823
  createSection,
4317
- createFixture,
4318
- createOccupant,
4319
4824
  createDecoration,
4320
4825
  // 3D
4321
- create3DFootprint,
4322
- create3DGroundLabel,
4323
4826
  create3DBillboard,
4324
- createVenue3DModel,
4325
- createExtrudedUnit,
4326
- create3DFixture,
4327
4827
  create3DAmenityMarker,
4328
- create3DOccupantAmenityMarker,
4329
- create3DOpeningMarker,
4330
- createOccupantGroundLabel,
4331
- // Light
4332
- createAmbientLight,
4333
- createDirectionalLight
4828
+ create3DOpeningMarker
4334
4829
  } = this.#styler;
4335
4830
  let elements = {};
4336
4831
  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
4832
  for (const feature2 of this.#features) {
4352
4833
  try {
4353
4834
  const { feature_type: featureType, properties, id } = feature2;
4354
- const layerName = _6.get(
4835
+ const layerName = _5.get(
4355
4836
  LAYER_FEATURE_TYPE_OBJ,
4356
4837
  featureType,
4357
4838
  featureType
4358
4839
  );
4359
4840
  const layer = this.map.getLayer(layerName);
4360
4841
  let geometry;
4361
- const category = _6.get(feature2, "properties.category");
4362
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
4363
- const textMarkerType = _6.get(
4842
+ const category = _5.get(feature2, "properties.category");
4843
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
4844
+ const textMarkerType = _5.get(
4364
4845
  this.#mapConfig,
4365
4846
  "text_marker_type",
4366
4847
  "ui-marker"
@@ -4370,16 +4851,6 @@ var IndoorMap = class extends EventTarget {
4370
4851
  feature2
4371
4852
  );
4372
4853
  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
4854
  case "amenity": {
4384
4855
  if (feature2.properties.is_featured) {
4385
4856
  const billboardObj = create3DBillboard(feature2, this.threeLayer);
@@ -4423,127 +4894,6 @@ var IndoorMap = class extends EventTarget {
4423
4894
  geometry = createSection(feature2)?.addTo(layer);
4424
4895
  break;
4425
4896
  }
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
4897
  default:
4548
4898
  break;
4549
4899
  }
@@ -4553,16 +4903,6 @@ var IndoorMap = class extends EventTarget {
4553
4903
  console.warn(`Cannot create ${feature2.id}: ${err.message}`);
4554
4904
  }
4555
4905
  }
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
4906
  this.#mapDecorations.forEach((decoration) => {
4567
4907
  const { id, geometry, properties } = decoration;
4568
4908
  const geometryType = decoration?.geometry?.type;
@@ -4612,27 +4952,6 @@ var IndoorMap = class extends EventTarget {
4612
4952
  changeLevelByOrdinal(ordinal) {
4613
4953
  this.rendererManager.changeLevelByOrdinal(ordinal);
4614
4954
  }
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
4955
  findVenueInView = () => {
4637
4956
  const mapCenter = this.map.getCenter();
4638
4957
  const result = this.#venues.reduce((closest, venue) => {
@@ -4645,9 +4964,6 @@ var IndoorMap = class extends EventTarget {
4645
4964
  }, null);
4646
4965
  return result;
4647
4966
  };
4648
- flyTo = (center2, options) => {
4649
- this.camera.flyTo(center2, options);
4650
- };
4651
4967
  getLineStringBearing = (feature2) => {
4652
4968
  const { geometry } = feature2;
4653
4969
  const path = new LineString3(geometry.coordinates);
@@ -4668,186 +4984,6 @@ var IndoorMap = class extends EventTarget {
4668
4984
  clearAnimations() {
4669
4985
  this.#animationsToRun = [];
4670
4986
  }
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
4987
  /**
4852
4988
  * User Location
4853
4989
  ****************************/
@@ -4872,15 +5008,15 @@ var IndoorMap = class extends EventTarget {
4872
5008
  }
4873
5009
  }
4874
5010
  updateUserLocationSymbolByLocale(locale) {
4875
- const userLocationGeometry = _6.get(
5011
+ const userLocationGeometry = _5.get(
4876
5012
  this.#elements,
4877
5013
  `${USER_LOCATION_ELEMENT_ID}.geometry`
4878
5014
  );
4879
5015
  if (!userLocationGeometry) return;
4880
5016
  const currentSymbol = userLocationGeometry.getSymbol();
4881
5017
  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;
5018
+ const localeSymbol = _5.get(symbol, `${LOCALE_SYMBOL_KEY}.${locale}`) || _5.get(symbol, `${LOCALE_SYMBOL_KEY}.default`);
5019
+ if (!_5.isPlainObject(localeSymbol)) return symbol;
4884
5020
  return {
4885
5021
  ...symbol,
4886
5022
  ...localeSymbol
@@ -4954,14 +5090,14 @@ var IndoorMap = class extends EventTarget {
4954
5090
  * END of User Location
4955
5091
  ****************************/
4956
5092
  showGeometryByElementId = (elementId) => {
4957
- const geometry = _6.get(
5093
+ const geometry = _5.get(
4958
5094
  this.#elements,
4959
5095
  `${elementId}.geometry`
4960
5096
  );
4961
5097
  if (geometry) geometry.show();
4962
5098
  };
4963
5099
  hideGeometryByElementId = (elementId) => {
4964
- const geometry = _6.get(this.#elements, `${elementId}.geometry`);
5100
+ const geometry = _5.get(this.#elements, `${elementId}.geometry`);
4965
5101
  if (geometry) geometry.hide();
4966
5102
  };
4967
5103
  setSpriteMarkersOpacity = (opacity = 1) => {
@@ -5008,13 +5144,13 @@ var IndoorMap = class extends EventTarget {
5008
5144
  const line = lineStrings[i];
5009
5145
  const coords = line.geometry.coordinates;
5010
5146
  const prevLine = lineStrings[i - 1];
5011
- const firstCoord = _6.first(coords);
5147
+ const firstCoord = _5.first(coords);
5012
5148
  const isFirstLine = i === 0;
5013
5149
  if (isFirstLine) {
5014
5150
  accLine.push(...coords);
5015
5151
  continue;
5016
5152
  }
5017
- const prevLastCoord = _6.last(prevLine.geometry.coordinates);
5153
+ const prevLastCoord = _5.last(prevLine.geometry.coordinates);
5018
5154
  const isNearby = turfDistance(point(firstCoord), point(prevLastCoord)) < distance;
5019
5155
  if (!isNearby) {
5020
5156
  const remainingLines = lineStrings.slice(i);
@@ -5035,8 +5171,8 @@ var IndoorMap = class extends EventTarget {
5035
5171
  create3DStepPath
5036
5172
  } = this.#styler;
5037
5173
  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) => {
5174
+ const linesByOrdinal = _5(stepGeometries).filter(({ geometry }) => geometry.type === "LineString").groupBy("properties.ordinal").value();
5175
+ const joinedLines = _5(linesByOrdinal).reduce((acc, lines, key) => {
5040
5176
  const joined = this.combineNearbyLineStrings(lines, {
5041
5177
  properties: { ordinal: +key }
5042
5178
  });
@@ -5064,14 +5200,14 @@ var IndoorMap = class extends EventTarget {
5064
5200
  stepElement = createOriginMarker(stepGeometry).addTo(routeMarkerLayer);
5065
5201
  break;
5066
5202
  case "destination-marker":
5067
- const extrudeConfig = _6.get(this.#mapConfig, "extrude");
5203
+ const extrudeConfig = _5.get(this.#mapConfig, "extrude");
5068
5204
  if (destinationFeature.feature_type === "occupant") {
5069
- const stepId = _6.get(stepGeometry, "id");
5205
+ const stepId = _5.get(stepGeometry, "id");
5070
5206
  const normalizedDestinationFeature = {
5071
5207
  ...destinationFeature,
5072
5208
  id: stepId
5073
5209
  };
5074
- const logoUrl = _6.get(
5210
+ const logoUrl = _5.get(
5075
5211
  normalizedDestinationFeature,
5076
5212
  "properties.logo.url"
5077
5213
  );
@@ -5116,15 +5252,15 @@ var IndoorMap = class extends EventTarget {
5116
5252
  const routeMarkerLayer = this.map.getLayer(
5117
5253
  HIGHLIGHT_LAYER_NAME
5118
5254
  );
5119
- const originMarkerGeometry = _6.get(
5255
+ const originMarkerGeometry = _5.get(
5120
5256
  this.#elements,
5121
5257
  `${ORIGIN_MARKER_ID}.geometry`
5122
5258
  );
5123
- const destinationMarkerGeometry = _6.get(
5259
+ const destinationMarkerGeometry = _5.get(
5124
5260
  this.#elements,
5125
5261
  `${DESTINATION_MARKER_ID}.geometry`
5126
5262
  );
5127
- const geometriesToRemove = _6.compact([
5263
+ const geometriesToRemove = _5.compact([
5128
5264
  originMarkerGeometry,
5129
5265
  destinationMarkerGeometry
5130
5266
  ]);
@@ -5135,7 +5271,7 @@ var IndoorMap = class extends EventTarget {
5135
5271
  (obj) => !(obj instanceof NavigationPath)
5136
5272
  );
5137
5273
  const objects = this.#navigationGeometries || {};
5138
- _6.forEach(objects, (obj) => {
5274
+ _5.forEach(objects, (obj) => {
5139
5275
  if (!obj) return;
5140
5276
  this.#navigationGeometries[obj.properties.id] = null;
5141
5277
  obj.remove();
@@ -5163,33 +5299,6 @@ var IndoorMap = class extends EventTarget {
5163
5299
  /**
5164
5300
  * render (frame)
5165
5301
  */
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
5302
  render() {
5194
5303
  const view = this.map.getView();
5195
5304
  const currBearing = view.bearing;
@@ -5198,7 +5307,8 @@ var IndoorMap = class extends EventTarget {
5198
5307
  this.threeLayer.redraw();
5199
5308
  }
5200
5309
  if (this.threeLayer) {
5201
- const objectOpacity = _6.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5310
+ const currentView = this.camera.getView();
5311
+ const objectOpacity = _5.clamp(38 - 2 * currentView.zoom, 0, 1);
5202
5312
  this.#objects.forEach((object) => {
5203
5313
  object.getObject3d().traverse((child) => {
5204
5314
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5208,8 +5318,8 @@ var IndoorMap = class extends EventTarget {
5208
5318
  });
5209
5319
  if (this.#billboardObjects) {
5210
5320
  this.#billboardObjects.forEach((object) => {
5211
- const objectScale = _6.clamp(
5212
- 20 - 1 * this.camera.getZoom(),
5321
+ const objectScale = _5.clamp(
5322
+ 20 - 1 * currentView.zoom,
5213
5323
  1,
5214
5324
  1.05
5215
5325
  );
@@ -5217,7 +5327,7 @@ var IndoorMap = class extends EventTarget {
5217
5327
  });
5218
5328
  }
5219
5329
  if (this.#isLayersFadingOnZoom) {
5220
- const layerOpacity = _6.clamp(1 - objectOpacity, 0, 1);
5330
+ const layerOpacity = _5.clamp(1 - objectOpacity, 0, 1);
5221
5331
  LAYERS.forEach((layerKey) => {
5222
5332
  const layer = this.map.getLayer(layerKey);
5223
5333
  if (layer) layer.setOpacity(layerOpacity);
@@ -5231,23 +5341,17 @@ var IndoorMap = class extends EventTarget {
5231
5341
  child.visible = this.showVenueObject && objectOpacity > 0.4;
5232
5342
  });
5233
5343
  });
5234
- this.#groundObjects.forEach((gLabel) => {
5235
- gLabel.bearing = currBearing;
5236
- });
5237
5344
  }
5238
5345
  this.#animationsToRun.forEach(({ callback }) => callback(this));
5239
- TWEEN2.update();
5346
+ TWEEN.update();
5240
5347
  requestAnimationFrame(this.render.bind(this));
5241
5348
  }
5242
5349
  };
5243
5350
  export {
5244
5351
  ALL_FEATURE_TYPES,
5245
- ALWAYS_VISIBLE_FEATURE_TYPES,
5246
5352
  BASE_LAYER_NAME,
5247
5353
  DEFAULT_BASE_URL,
5248
- DEFAULT_HIGHLIGHT_OPTIONS,
5249
5354
  DEFAULT_LOCALE,
5250
- DEFAULT_SET_HIGHLIGHT_2DELEMENT_IDS_OPTIONS,
5251
5355
  DESTINATION_MARKER_ID,
5252
5356
  GEOJSON_FEATURE_TYPES,
5253
5357
  HIGHLIGHT_LAYER_NAME,
@@ -5261,8 +5365,10 @@ export {
5261
5365
  MARKER_LAYER_NAME,
5262
5366
  NONIMDF_FEATURE_TYPES,
5263
5367
  ORIGIN_MARKER_ID,
5368
+ occupant_helper_exports as OccupantHelpers,
5264
5369
  POI_MARKER_LAYER_NAME,
5265
5370
  QueryObserver2 as QueryObserver,
5371
+ TextSpriteMarker,
5266
5372
  USER_LOCATION_ELEMENT_ID,
5267
5373
  USER_LOCATION_LAYER_NAME,
5268
5374
  VENUE_EVENTS,
@@ -5288,6 +5394,16 @@ export {
5288
5394
  getRelatedLocationsByOccupant,
5289
5395
  getSuitablyValueBetweenBearings,
5290
5396
  isClickableFeature,
5397
+ isValidCoordinate,
5398
+ isValidLineString,
5399
+ isValidLineStringCoordinates,
5400
+ isValidMultiPolygon,
5401
+ isValidMultiPolygonCoordinates,
5402
+ isValidPoint,
5403
+ isValidPolygon,
5404
+ isValidPolygonCoordinates,
5405
+ matchFilter,
5406
+ matchFilters,
5291
5407
  safeFetchFeature,
5292
5408
  styledFeatureGenerator
5293
5409
  };