@mapvx/web-js 1.3.0-dev.2 → 1.4.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/config/draco.js +15 -0
- package/dist/cjs/config/draco.js.map +1 -0
- package/dist/cjs/domain/models/mapConfig.js.map +1 -1
- package/dist/cjs/domain/models/scene3D.js +3 -0
- package/dist/cjs/domain/models/scene3D.js.map +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/logger/logger.js +1 -1
- package/dist/cjs/logger/rollbar.js +1 -1
- package/dist/cjs/map/map.js +298 -245
- package/dist/cjs/map/map.js.map +1 -1
- package/dist/cjs/utils/3d.js +104 -3
- package/dist/cjs/utils/3d.js.map +1 -1
- package/dist/cjs/utils/loadGlb.js +63 -0
- package/dist/cjs/utils/loadGlb.js.map +1 -0
- package/dist/cjs/utils/three.js +55 -0
- package/dist/cjs/utils/three.js.map +1 -0
- package/dist/es/config/draco.d.ts +12 -0
- package/dist/es/config/draco.d.ts.map +1 -0
- package/dist/es/config/draco.js +12 -0
- package/dist/es/config/draco.js.map +1 -0
- package/dist/es/domain/models/mapConfig.d.ts +13 -0
- package/dist/es/domain/models/mapConfig.d.ts.map +1 -1
- package/dist/es/domain/models/mapConfig.js.map +1 -1
- package/dist/es/domain/models/scene3D.d.ts +308 -0
- package/dist/es/domain/models/scene3D.d.ts.map +1 -0
- package/dist/es/domain/models/scene3D.js +2 -0
- package/dist/es/domain/models/scene3D.js.map +1 -0
- package/dist/es/index.d.ts +1 -0
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/logger/logger.js +1 -1
- package/dist/es/logger/rollbar.js +1 -1
- package/dist/es/map/map.d.ts +30 -18
- package/dist/es/map/map.d.ts.map +1 -1
- package/dist/es/map/map.js +291 -238
- package/dist/es/map/map.js.map +1 -1
- package/dist/es/utils/3d.d.ts +39 -1
- package/dist/es/utils/3d.d.ts.map +1 -1
- package/dist/es/utils/3d.js +95 -2
- package/dist/es/utils/3d.js.map +1 -1
- package/dist/es/utils/loadGlb.d.ts +22 -0
- package/dist/es/utils/loadGlb.d.ts.map +1 -0
- package/dist/es/utils/loadGlb.js +57 -0
- package/dist/es/utils/loadGlb.js.map +1 -0
- package/dist/es/utils/three.d.ts +26 -0
- package/dist/es/utils/three.d.ts.map +1 -0
- package/dist/es/utils/three.js +26 -0
- package/dist/es/utils/three.js.map +1 -0
- package/dist/umd/index.js +23965 -21381
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -2
package/dist/cjs/map/map.js
CHANGED
|
@@ -27,9 +27,8 @@ exports.InternalMapVXMap = void 0;
|
|
|
27
27
|
const geo_layers_1 = require("@deck.gl/geo-layers");
|
|
28
28
|
const layers_1 = require("@deck.gl/layers");
|
|
29
29
|
const maplibre_gl_1 = __importStar(require("maplibre-gl"));
|
|
30
|
-
const THREE = __importStar(require("three"));
|
|
31
|
-
const GLTFLoader_js_1 = require("three/examples/jsm/loaders/GLTFLoader.js");
|
|
32
30
|
const semaphore_1 = require("../utils/semaphore");
|
|
31
|
+
const three_1 = require("../utils/three");
|
|
33
32
|
/** Shared GeoJSON source holding every circle drawn through the circle API. */
|
|
34
33
|
const CIRCLE_SOURCE_ID = "mapvx-circles";
|
|
35
34
|
/** Fill layer rendering the translucent interior of the circles. */
|
|
@@ -162,13 +161,15 @@ const icons_1 = require("../assets/icons");
|
|
|
162
161
|
const routeController_1 = require("../controllers/routeController");
|
|
163
162
|
const _rtl_1 = require("../domain/models/_rtl");
|
|
164
163
|
const animation_1 = require("../domain/models/animation");
|
|
165
|
-
const circle_1 = require("../domain/models/circle");
|
|
166
164
|
const loggeable_1 = require("../domain/models/loggeable");
|
|
167
165
|
const mapConfig_1 = require("../domain/models/mapConfig");
|
|
166
|
+
const circle_1 = require("../domain/models/circle");
|
|
168
167
|
const marker_1 = require("../domain/models/marker");
|
|
169
168
|
const route_1 = require("../domain/models/route");
|
|
170
169
|
const routeConfiguration_1 = require("../domain/models/routeConfiguration");
|
|
171
170
|
const repository_1 = require("../repository/repository");
|
|
171
|
+
const _3d_1 = require("../utils/3d");
|
|
172
|
+
const loadGlb_1 = require("../utils/loadGlb");
|
|
172
173
|
const route_utils_1 = require("../utils/route-utils");
|
|
173
174
|
const utils_1 = require("../utils/utils");
|
|
174
175
|
const mapInteractionOptions_1 = require("./mapInteractionOptions");
|
|
@@ -187,7 +188,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
187
188
|
* @returns A new instance of MapVXMap.
|
|
188
189
|
*/
|
|
189
190
|
constructor(mapConfig, container, token) {
|
|
190
|
-
var _a, _b, _c;
|
|
191
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
191
192
|
super();
|
|
192
193
|
this.potentialParentPlaces = [];
|
|
193
194
|
this.innerFloors = [];
|
|
@@ -202,18 +203,17 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
202
203
|
this.geoLocation = navigator.geolocation;
|
|
203
204
|
// 3d related variables
|
|
204
205
|
this.mode = "2D";
|
|
206
|
+
this.scene3DConfig = undefined;
|
|
205
207
|
this.deckOverlay = undefined;
|
|
206
|
-
this.
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
|
|
210
|
-
this.
|
|
211
|
-
/**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this.ESCALATOR_LIGHTS = 3;
|
|
216
|
-
this.SPRITE_URL = "https://lazarillo.app/internal/maps/vector-style/cenco-cl-pe-co-ar-3D/sprites_cencosud";
|
|
208
|
+
this.scene3DGlbScene = undefined;
|
|
209
|
+
/** Loaded GLB roots keyed by URL (deduplicated). */
|
|
210
|
+
this.scene3DGlbRootByUrl = new globalThis.Map();
|
|
211
|
+
/** Per-asset template root and bottom anchor for cloning. */
|
|
212
|
+
this.scene3DGlbTemplateById = new globalThis.Map();
|
|
213
|
+
/** Number of light objects in `scene3DGlbScene` (kept when clearing meshes). */
|
|
214
|
+
this.scene3DGlbLightCount = 0;
|
|
215
|
+
/** Container group holding all placed GLB pivots; rebuilt on each floor change. */
|
|
216
|
+
this.scene3DModelsGroup = undefined;
|
|
217
217
|
this.spriteIconMapping = {};
|
|
218
218
|
this.spriteAtlasImage = new Image();
|
|
219
219
|
if (_rtl_1.rtlLanguages.includes((_a = mapConfig.lang) !== null && _a !== void 0 ? _a : "")) {
|
|
@@ -227,15 +227,16 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
227
227
|
this.watchPositionID = undefined;
|
|
228
228
|
this.onFloorChange = mapConfig.onFloorChange;
|
|
229
229
|
this.onParentPlaceChange = mapConfig.onParentPlaceChange;
|
|
230
|
-
this.mode = (_c = mapConfig.mode) !== null && _c !== void 0 ? _c : "2D";
|
|
231
|
-
this.initialCenter = mapConfig.center;
|
|
232
230
|
this.tileCacheConfig = (() => {
|
|
233
231
|
const merged = Object.assign(Object.assign({}, mapConfig_1.DEFAULT_TILE_CACHE_CONFIG), mapConfig.tileCache);
|
|
234
232
|
merged.maxTiles = Math.min(merged.maxTiles, mapConfig_1.MAPLIBRE_MAX_TILE_CACHE_HARD_CAP);
|
|
235
233
|
return merged;
|
|
236
234
|
})();
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
this.mode = (_c = mapConfig.mode) !== null && _c !== void 0 ? _c : "2D";
|
|
236
|
+
this.scene3DConfig = mapConfig.scene3D;
|
|
237
|
+
this.initialCenter = mapConfig.center;
|
|
238
|
+
if (this.is3DSceneActive() && ((_f = (_e = (_d = this.scene3DConfig) === null || _d === void 0 ? void 0 : _d.customLayers) === null || _e === void 0 ? void 0 : _e.iconLayers) === null || _f === void 0 ? void 0 : _f.spriteUrl)) {
|
|
239
|
+
this.loadSpriteAtlas((_j = (_h = (_g = this.scene3DConfig) === null || _g === void 0 ? void 0 : _g.customLayers) === null || _h === void 0 ? void 0 : _h.iconLayers) === null || _j === void 0 ? void 0 : _j.spriteUrl).catch(console.error);
|
|
239
240
|
}
|
|
240
241
|
if (mapConfig.parentPlaceId != null) {
|
|
241
242
|
this.initialPlaceDetailSetUp(mapConfig.parentPlaceId, mapConfig.authToken);
|
|
@@ -363,35 +364,22 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
363
364
|
showZoom: mapConfig.showZoom !== undefined ? mapConfig.showZoom : true,
|
|
364
365
|
}), (_e = mapConfig.navigationPosition) !== null && _e !== void 0 ? _e : "top-right");
|
|
365
366
|
this.map.on("load", () => {
|
|
366
|
-
var _a;
|
|
367
|
-
if (this.
|
|
367
|
+
var _a, _b, _c;
|
|
368
|
+
if (this.is3DSceneActive()) {
|
|
368
369
|
this.deckOverlay = new mapbox_1.MapboxOverlay({ layers: [] });
|
|
369
370
|
this.map.addControl(this.deckOverlay);
|
|
370
|
-
this.hideIndoorSymbolLayers();
|
|
371
371
|
// Hide MapLibre icon layers — replaced by deck.gl IconLayer
|
|
372
|
-
this.
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
}
|
|
372
|
+
this.hideLayers((_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.hideLayers);
|
|
373
|
+
const models = (_b = this.scene3DConfig) === null || _b === void 0 ? void 0 : _b.models;
|
|
374
|
+
const glbModelsActive = models !== undefined && models.enabled !== false && models.assets.length > 0;
|
|
375
|
+
if (glbModelsActive) {
|
|
376
|
+
this.map.addLayer(this.createGlbCustomLayer());
|
|
378
377
|
}
|
|
379
|
-
// Add 3D escalator layer and hide 2D transportation line
|
|
380
|
-
this.map.addLayer(this.createEscalatorLayer());
|
|
381
|
-
this.map.setPaintProperty("indoor-transportation", "line-opacity", 0);
|
|
382
|
-
// Capture escalator positions when new tiles arrive (stops once cached)
|
|
383
|
-
this.map.on("sourcedata", (e) => {
|
|
384
|
-
if (e.sourceId === "indoorequal" &&
|
|
385
|
-
this.currentFloor &&
|
|
386
|
-
!this.escalatorCache[this.currentFloor]) {
|
|
387
|
-
this.placeEscalators();
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
378
|
}
|
|
391
379
|
this.whenStyleUpdates(style);
|
|
392
380
|
if (mapConfig.lang)
|
|
393
381
|
this.setLayersForLanguage(mapConfig.lang);
|
|
394
|
-
(
|
|
382
|
+
(_c = mapConfig.onMapReady) === null || _c === void 0 ? void 0 : _c.call(mapConfig);
|
|
395
383
|
this.onHover();
|
|
396
384
|
this.subscribeToFailedTiles();
|
|
397
385
|
});
|
|
@@ -401,6 +389,11 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
401
389
|
if (this.circles.length > 0)
|
|
402
390
|
this.ensureCircleLayers();
|
|
403
391
|
});
|
|
392
|
+
this.map.on("zoom", () => {
|
|
393
|
+
if (this.is3DSceneActive()) {
|
|
394
|
+
this.applyModelZoomOpacity();
|
|
395
|
+
}
|
|
396
|
+
});
|
|
404
397
|
this.map.on("zoomend", () => {
|
|
405
398
|
var _a;
|
|
406
399
|
(_a = mapConfig.onZoomEnd) === null || _a === void 0 ? void 0 : _a.call(mapConfig, this.getZoomLevel());
|
|
@@ -538,214 +531,253 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
538
531
|
// Tile cache clear may fail if cache doesn't exist
|
|
539
532
|
}
|
|
540
533
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
// Hide text-only layers (replaced by deck.gl)
|
|
550
|
-
if (hasText && !hasIcon) {
|
|
551
|
-
this.map.setLayoutProperty(layer.id, "visibility", "none");
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
534
|
+
/**
|
|
535
|
+
* Whether 3D scene features (deck.gl overlay, declarative GLB custom layer, etc.) are active.
|
|
536
|
+
* Requires {@link MapConfig.mode} `"3D"` and {@link Scene3DConfig.enabled} not `false`.
|
|
537
|
+
* When `scene3D` is omitted, 3D features remain available for backward compatibility.
|
|
538
|
+
*/
|
|
539
|
+
is3DSceneActive() {
|
|
540
|
+
var _a;
|
|
541
|
+
return this.mode === "3D" && ((_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.enabled) !== false;
|
|
555
542
|
}
|
|
556
|
-
|
|
543
|
+
// Start 3D related methods ------------------------------------------------------------
|
|
544
|
+
createGlbCustomLayer() {
|
|
545
|
+
var _a;
|
|
557
546
|
const refMercator = maplibre_gl_1.MercatorCoordinate.fromLngLat(this.initialCenter, 0);
|
|
558
547
|
const meterScale = refMercator.meterInMercatorCoordinateUnits();
|
|
559
|
-
const modelTransform = new THREE.Matrix4()
|
|
548
|
+
const modelTransform = new three_1.THREE.Matrix4()
|
|
560
549
|
.makeTranslation(refMercator.x, refMercator.y, refMercator.z)
|
|
561
|
-
.scale(new THREE.Vector3(meterScale, -meterScale, meterScale))
|
|
562
|
-
.multiply(new THREE.Matrix4().makeRotationX(Math.PI / 2));
|
|
563
|
-
this.
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
this.placeEscalators();
|
|
550
|
+
.scale(new three_1.THREE.Vector3(meterScale, -meterScale, meterScale))
|
|
551
|
+
.multiply(new three_1.THREE.Matrix4().makeRotationX(Math.PI / 2));
|
|
552
|
+
this.scene3DGlbScene = new three_1.THREE.Scene();
|
|
553
|
+
const models = (_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.models;
|
|
554
|
+
if (models && models.enabled !== false && models.assets.length > 0) {
|
|
555
|
+
const lights = (0, _3d_1.resolveModels3DLights)(models);
|
|
556
|
+
this.scene3DGlbLightCount = (0, loadGlb_1.addScene3DLights)(this.scene3DGlbScene, lights);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
this.scene3DGlbLightCount = 0;
|
|
560
|
+
}
|
|
561
|
+
void this.loadScene3DGlbTemplates()
|
|
562
|
+
.then(() => this.placeScene3DModels())
|
|
563
|
+
.catch((err) => {
|
|
564
|
+
console.error("Failed to initialize declarative GLB models", err);
|
|
577
565
|
});
|
|
578
566
|
let renderer = undefined;
|
|
579
567
|
let camera = undefined;
|
|
580
|
-
const tmpMatrix = new THREE.Matrix4();
|
|
568
|
+
const tmpMatrix = new three_1.THREE.Matrix4();
|
|
581
569
|
return {
|
|
582
|
-
id: "3d-
|
|
570
|
+
id: "3d-glb-models",
|
|
583
571
|
type: "custom",
|
|
584
572
|
renderingMode: "3d",
|
|
585
573
|
onAdd(_map, gl) {
|
|
586
|
-
camera = new THREE.Camera();
|
|
587
|
-
renderer = new THREE.WebGLRenderer({
|
|
574
|
+
camera = new three_1.THREE.Camera();
|
|
575
|
+
renderer = new three_1.THREE.WebGLRenderer({
|
|
588
576
|
canvas: _map.getCanvas(),
|
|
589
577
|
context: gl,
|
|
590
578
|
antialias: true,
|
|
591
579
|
});
|
|
592
580
|
renderer.autoClear = false;
|
|
581
|
+
// MapLibre owns canvas dimensions; only sync the GL viewport on resize.
|
|
582
|
+
renderer.setSize = function (width, height) {
|
|
583
|
+
this.setViewport(0, 0, width, height);
|
|
584
|
+
};
|
|
593
585
|
},
|
|
594
|
-
render: (
|
|
595
|
-
var _a
|
|
586
|
+
render: (_gl, args) => {
|
|
587
|
+
var _a;
|
|
596
588
|
if (!camera ||
|
|
597
589
|
!renderer ||
|
|
598
|
-
!this.
|
|
599
|
-
!this.
|
|
600
|
-
this.
|
|
590
|
+
!this.scene3DGlbScene ||
|
|
591
|
+
!this.scene3DModelsGroup ||
|
|
592
|
+
this.scene3DModelsGroup.children.length === 0) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const canvas = this.map.getCanvas();
|
|
596
|
+
const width = canvas.width;
|
|
597
|
+
const height = canvas.height;
|
|
598
|
+
// Skip while the framebuffer has no drawable area (e.g. devtools opening).
|
|
599
|
+
if (width === 0 || height === 0) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const mainMatrix = (_a = args.defaultProjectionData) === null || _a === void 0 ? void 0 : _a.mainMatrix;
|
|
603
|
+
if (!mainMatrix) {
|
|
601
604
|
return;
|
|
602
|
-
|
|
603
|
-
|
|
605
|
+
}
|
|
606
|
+
renderer.setSize(width, height);
|
|
607
|
+
tmpMatrix.fromArray(mainMatrix).multiply(modelTransform);
|
|
604
608
|
camera.projectionMatrix.copy(tmpMatrix);
|
|
605
609
|
renderer.resetState();
|
|
606
|
-
renderer.render(this.
|
|
610
|
+
renderer.render(this.scene3DGlbScene, camera);
|
|
607
611
|
},
|
|
608
612
|
};
|
|
609
613
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
!this.escalatorCenter)
|
|
615
|
-
return;
|
|
616
|
-
// Try to capture positions if not cached yet
|
|
617
|
-
this.captureEscalatorPositions();
|
|
618
|
-
const positions = this.escalatorCache[this.currentFloor];
|
|
619
|
-
if (!positions)
|
|
614
|
+
async loadScene3DGlbTemplates() {
|
|
615
|
+
var _a;
|
|
616
|
+
const models = (_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.models;
|
|
617
|
+
if (!models || models.enabled === false || models.assets.length === 0) {
|
|
620
618
|
return;
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
619
|
+
}
|
|
620
|
+
this.scene3DGlbRootByUrl.clear();
|
|
621
|
+
this.scene3DGlbTemplateById.clear();
|
|
622
|
+
for (const asset of models.assets) {
|
|
623
|
+
try {
|
|
624
|
+
let root = this.scene3DGlbRootByUrl.get(asset.url);
|
|
625
|
+
if (!root) {
|
|
626
|
+
root = await (0, loadGlb_1.loadGlbRoot)(asset.url);
|
|
627
|
+
this.scene3DGlbRootByUrl.set(asset.url, root);
|
|
628
|
+
}
|
|
629
|
+
const center = (0, loadGlb_1.computeGlbBottomAnchor)(root);
|
|
630
|
+
this.scene3DGlbTemplateById.set(asset.id, { root, center });
|
|
631
|
+
}
|
|
632
|
+
catch (err) {
|
|
633
|
+
console.error(`Failed to load GLB asset "${asset.id}" from ${asset.url}`, err);
|
|
626
634
|
}
|
|
627
635
|
}
|
|
636
|
+
}
|
|
637
|
+
placeScene3DModels() {
|
|
638
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
639
|
+
if (!this.scene3DGlbScene) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const models = (_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.models;
|
|
643
|
+
if (!models || models.enabled === false) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (this.scene3DModelsGroup) {
|
|
647
|
+
this.scene3DGlbScene.remove(this.scene3DModelsGroup);
|
|
648
|
+
this.scene3DModelsGroup = undefined;
|
|
649
|
+
}
|
|
650
|
+
if (this.scene3DGlbTemplateById.size === 0) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
628
653
|
// Guard against an invalid initial center before it reaches fromLngLat.
|
|
629
654
|
if (!this.initialCenter ||
|
|
630
655
|
!Number.isFinite(this.initialCenter.lng) ||
|
|
631
|
-
!Number.isFinite(this.initialCenter.lat))
|
|
656
|
+
!Number.isFinite(this.initialCenter.lat)) {
|
|
632
657
|
return;
|
|
658
|
+
}
|
|
633
659
|
const refMercator = maplibre_gl_1.MercatorCoordinate.fromLngLat(this.initialCenter, 0);
|
|
634
660
|
const meterScale = refMercator.meterInMercatorCoordinateUnits();
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
661
|
+
const floorKey = (_b = this.currentFloor) !== null && _b !== void 0 ? _b : "";
|
|
662
|
+
const modelsGroup = new three_1.THREE.Group();
|
|
663
|
+
modelsGroup.position.set((_d = (_c = models.globalOffset) === null || _c === void 0 ? void 0 : _c.x) !== null && _d !== void 0 ? _d : 0, (_f = (_e = models.globalOffset) === null || _e === void 0 ? void 0 : _e.y) !== null && _f !== void 0 ? _f : 0, (_h = (_g = models.globalOffset) === null || _g === void 0 ? void 0 : _g.z) !== null && _h !== void 0 ? _h : 0);
|
|
664
|
+
for (const placement of models.placements) {
|
|
665
|
+
if (!(0, _3d_1.isPlacementVisibleOnFloor)(placement, floorKey)) {
|
|
638
666
|
continue;
|
|
639
|
-
|
|
667
|
+
}
|
|
668
|
+
const template = this.scene3DGlbTemplateById.get(placement.assetId);
|
|
669
|
+
if (!template) {
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
const asset = models.assets.find((a) => a.id === placement.assetId);
|
|
673
|
+
if (!asset) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
// Placement positions come from external consumer config: skip any
|
|
677
|
+
// non-finite coordinate so a malformed config can never crash
|
|
678
|
+
// fromLngLat and break the whole floor render.
|
|
679
|
+
if (!placement.position ||
|
|
680
|
+
!Number.isFinite(placement.position.lng) ||
|
|
681
|
+
!Number.isFinite(placement.position.lat)) {
|
|
682
|
+
this.logWarning(new Error(`Invalid scene3D placement position (assetId=${placement.assetId}, floorKey=${floorKey})`));
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
const target = maplibre_gl_1.default.MercatorCoordinate.fromLngLat([placement.position.lng, placement.position.lat], (_j = placement.position.altitude) !== null && _j !== void 0 ? _j : 0);
|
|
640
686
|
const sx = (target.x - refMercator.x) / meterScale;
|
|
641
687
|
const sz = (target.y - refMercator.y) / meterScale;
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
const
|
|
647
|
-
|
|
688
|
+
const ax = (_l = (_k = asset.defaultModelOffset) === null || _k === void 0 ? void 0 : _k.x) !== null && _l !== void 0 ? _l : 0;
|
|
689
|
+
const ay = (_o = (_m = asset.defaultModelOffset) === null || _m === void 0 ? void 0 : _m.y) !== null && _o !== void 0 ? _o : 0;
|
|
690
|
+
const az = (_q = (_p = asset.defaultModelOffset) === null || _p === void 0 ? void 0 : _p.z) !== null && _q !== void 0 ? _q : 0;
|
|
691
|
+
const px = (_s = (_r = placement.offset) === null || _r === void 0 ? void 0 : _r.x) !== null && _s !== void 0 ? _s : 0;
|
|
692
|
+
const py = (_u = (_t = placement.offset) === null || _t === void 0 ? void 0 : _t.y) !== null && _u !== void 0 ? _u : 0;
|
|
693
|
+
const pz = (_w = (_v = placement.offset) === null || _v === void 0 ? void 0 : _v.z) !== null && _w !== void 0 ? _w : 0;
|
|
694
|
+
const pivot = new three_1.THREE.Group();
|
|
695
|
+
pivot.position.set(sx + ax + px, ay + py, sz + az + pz);
|
|
696
|
+
const mergedRot = (0, _3d_1.mergeRotation3D)(asset.defaultRotation, placement.rotation);
|
|
697
|
+
pivot.rotation.set(three_1.THREE.MathUtils.degToRad(mergedRot.pitch), three_1.THREE.MathUtils.degToRad(-mergedRot.yaw), three_1.THREE.MathUtils.degToRad(mergedRot.roll), "YXZ");
|
|
698
|
+
const [sx3, sy3, sz3] = (0, _3d_1.mergeGlbScale)(asset.defaultScale, placement.scale);
|
|
699
|
+
pivot.scale.set(sx3, sy3, sz3);
|
|
700
|
+
const model = template.root.clone(true);
|
|
701
|
+
// `clone(true)` shares materials between instances; clone them per placement so each
|
|
702
|
+
// placement's zoom-based opacity is independent and does not bleed into sibling models.
|
|
703
|
+
model.traverse((obj) => {
|
|
704
|
+
const mesh = obj;
|
|
705
|
+
if (!mesh.isMesh) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
mesh.material = Array.isArray(mesh.material)
|
|
709
|
+
? mesh.material.map((m) => m.clone())
|
|
710
|
+
: mesh.material.clone();
|
|
711
|
+
});
|
|
712
|
+
model.position.set(-template.center.x, -template.center.y, -template.center.z);
|
|
713
|
+
// Stash the resolved zoom-transparency config so it can be re-applied on every zoom change.
|
|
714
|
+
pivot.userData.zoomTransparency = (0, _3d_1.resolveZoomTransparency)(models, asset, placement);
|
|
648
715
|
pivot.add(model);
|
|
649
|
-
|
|
716
|
+
modelsGroup.add(pivot);
|
|
650
717
|
}
|
|
718
|
+
this.scene3DModelsGroup = modelsGroup;
|
|
719
|
+
this.scene3DGlbScene.add(modelsGroup);
|
|
720
|
+
this.applyModelZoomOpacity();
|
|
651
721
|
this.map.triggerRepaint();
|
|
652
722
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
.filter((f) => { var _a; return ((_a = f.properties) === null || _a === void 0 ? void 0 : _a.floor_key) === this.currentFloor; });
|
|
662
|
-
if (!features.length)
|
|
723
|
+
/**
|
|
724
|
+
* Applies zoom-based transparency to placed GLB models, using each placement's resolved
|
|
725
|
+
* {@link ZoomTransparencyConfig} stored in `pivot.userData.zoomTransparency`. Hard threshold:
|
|
726
|
+
* fully opaque below the configured zoom, configured opacity at/above it. Only triggers a
|
|
727
|
+
* repaint when at least one material actually changed.
|
|
728
|
+
*/
|
|
729
|
+
applyModelZoomOpacity() {
|
|
730
|
+
if (!this.scene3DModelsGroup) {
|
|
663
731
|
return;
|
|
664
|
-
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
// feature (a MultiLineString is just one escalator line split across
|
|
675
|
-
// tiles, not several escalators).
|
|
676
|
-
let lineParts;
|
|
677
|
-
if (geom.type === "LineString") {
|
|
678
|
-
lineParts = [geom.coordinates];
|
|
679
|
-
}
|
|
680
|
-
else if (geom.type === "MultiLineString") {
|
|
681
|
-
lineParts = geom.coordinates;
|
|
682
|
-
}
|
|
683
|
-
else {
|
|
684
|
-
continue;
|
|
685
|
-
}
|
|
686
|
-
const coords = lineParts.flat();
|
|
687
|
-
if (coords.length < 2)
|
|
688
|
-
continue;
|
|
689
|
-
const start = coords[0];
|
|
690
|
-
const end = coords[coords.length - 1];
|
|
691
|
-
const midLng = (start[0] + end[0]) / 2;
|
|
692
|
-
const midLat = (start[1] + end[1]) / 2;
|
|
693
|
-
const bearing = Math.atan2(end[0] - start[0], end[1] - start[1]);
|
|
694
|
-
// Skip any non-finite result so a bad feature can never poison the
|
|
695
|
-
// cache (and later crash MercatorCoordinate.fromLngLat).
|
|
696
|
-
if (!Number.isFinite(midLng) || !Number.isFinite(midLat) || !Number.isFinite(bearing))
|
|
697
|
-
continue;
|
|
698
|
-
allMids.push({ lng: midLng, lat: midLat, bearing });
|
|
699
|
-
}
|
|
700
|
-
// Merge points within ~15m of each other into one
|
|
701
|
-
const MERGE_DEG = 0.00015; // ~15m
|
|
702
|
-
const positions = [];
|
|
703
|
-
const used = new Set();
|
|
704
|
-
for (let i = 0; i < allMids.length; i++) {
|
|
705
|
-
if (used.has(i))
|
|
706
|
-
continue;
|
|
707
|
-
used.add(i);
|
|
708
|
-
const group = [allMids[i]];
|
|
709
|
-
for (let j = i + 1; j < allMids.length; j++) {
|
|
710
|
-
if (used.has(j))
|
|
711
|
-
continue;
|
|
712
|
-
const dLng = allMids[i].lng - allMids[j].lng;
|
|
713
|
-
const dLat = allMids[i].lat - allMids[j].lat;
|
|
714
|
-
if (Math.abs(dLng) < MERGE_DEG && Math.abs(dLat) < MERGE_DEG) {
|
|
715
|
-
used.add(j);
|
|
716
|
-
group.push(allMids[j]);
|
|
732
|
+
}
|
|
733
|
+
const zoom = this.getZoomLevel();
|
|
734
|
+
let changed = false;
|
|
735
|
+
for (const pivot of this.scene3DModelsGroup.children) {
|
|
736
|
+
const cfg = pivot.userData.zoomTransparency;
|
|
737
|
+
const opacity = (0, _3d_1.opacityForZoom)(cfg, zoom);
|
|
738
|
+
pivot.traverse((obj) => {
|
|
739
|
+
const mesh = obj;
|
|
740
|
+
if (!mesh.isMesh) {
|
|
741
|
+
return;
|
|
717
742
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
743
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
744
|
+
for (const material of materials) {
|
|
745
|
+
if (material.opacity !== opacity) {
|
|
746
|
+
material.transparent = opacity < 1;
|
|
747
|
+
material.opacity = opacity;
|
|
748
|
+
// Disable depth writes while transparent to avoid draw-order artifacts.
|
|
749
|
+
material.depthWrite = opacity >= 1;
|
|
750
|
+
changed = true;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
});
|
|
723
754
|
}
|
|
724
|
-
if (
|
|
725
|
-
this.
|
|
755
|
+
if (changed) {
|
|
756
|
+
this.map.triggerRepaint();
|
|
726
757
|
}
|
|
727
758
|
}
|
|
728
|
-
async loadSpriteAtlas() {
|
|
759
|
+
async loadSpriteAtlas(spriteUrl) {
|
|
729
760
|
const [json, img] = await Promise.all([
|
|
730
|
-
fetch(`${
|
|
761
|
+
fetch(`${spriteUrl}.json`).then((r) => r.json()),
|
|
731
762
|
new Promise((resolve, reject) => {
|
|
732
763
|
const image = new Image();
|
|
733
764
|
image.crossOrigin = "anonymous";
|
|
734
765
|
image.onload = () => resolve(image);
|
|
735
766
|
image.onerror = reject;
|
|
736
|
-
image.src = `${
|
|
767
|
+
image.src = `${spriteUrl}.png`;
|
|
737
768
|
}),
|
|
738
769
|
]);
|
|
739
770
|
this.spriteIconMapping = json;
|
|
740
771
|
this.spriteAtlasImage = img;
|
|
741
772
|
}
|
|
742
|
-
|
|
773
|
+
makeElevatedLinesLayer(floorKey, layerConfig) {
|
|
774
|
+
var _a;
|
|
743
775
|
return new geo_layers_1.MVTLayer({
|
|
744
776
|
id: "indoor-lines-elevated",
|
|
745
|
-
data:
|
|
746
|
-
binary: false,
|
|
777
|
+
data: layerConfig.dataUrl,
|
|
778
|
+
binary: (_a = layerConfig.binaryData) !== null && _a !== void 0 ? _a : false,
|
|
747
779
|
renderSubLayers: (props) => {
|
|
748
|
-
var _a;
|
|
780
|
+
var _a, _b, _c, _d, _e;
|
|
749
781
|
const roomData = (props.data || []);
|
|
750
782
|
const roomFeatures = roomData.filter((f) => {
|
|
751
783
|
var _a, _b, _c;
|
|
@@ -757,7 +789,9 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
757
789
|
return null;
|
|
758
790
|
const paths = [];
|
|
759
791
|
for (const f of roomFeatures) {
|
|
760
|
-
const z = ((_a = f.properties) === null || _a === void 0 ? void 0 : _a.height)
|
|
792
|
+
const z = ((_a = f.properties) === null || _a === void 0 ? void 0 : _a.height)
|
|
793
|
+
? Number(f.properties.height)
|
|
794
|
+
: ((_b = layerConfig.defaultHeight) !== null && _b !== void 0 ? _b : 5);
|
|
761
795
|
const geom = f.geometry;
|
|
762
796
|
const polygons = geom.type === "Polygon"
|
|
763
797
|
? [geom.coordinates]
|
|
@@ -770,21 +804,23 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
770
804
|
}
|
|
771
805
|
}
|
|
772
806
|
}
|
|
773
|
-
return new layers_1.PathLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-paths`, data: paths, getPath: (d) => d.path, getColor:
|
|
807
|
+
return new layers_1.PathLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-paths`, data: paths, getPath: (d) => d.path, getColor: (0, _3d_1.hexToRgb)((_c = layerConfig.lineColor) !== null && _c !== void 0 ? _c : "#cbcbcb"), getWidth: (_d = layerConfig.lineWidth) !== null && _d !== void 0 ? _d : 1.5, widthUnits: (_e = layerConfig.widthUnits) !== null && _e !== void 0 ? _e : "pixels", pickable: false }));
|
|
774
808
|
},
|
|
775
809
|
updateTriggers: {
|
|
776
810
|
renderSubLayers: [floorKey],
|
|
777
811
|
},
|
|
778
812
|
});
|
|
779
813
|
}
|
|
780
|
-
makeLabelLayer(floorKey, useSdf = true) {
|
|
814
|
+
makeLabelLayer(floorKey, layerConfig, useSdf = true) {
|
|
815
|
+
var _a, _b, _c;
|
|
781
816
|
return new geo_layers_1.MVTLayer({
|
|
782
817
|
id: "indoor-labels",
|
|
783
|
-
data:
|
|
784
|
-
binary: false,
|
|
785
|
-
minZoom: 19.5,
|
|
786
|
-
maxZoom: 24,
|
|
818
|
+
data: layerConfig.dataUrl,
|
|
819
|
+
binary: (_a = layerConfig.binaryData) !== null && _a !== void 0 ? _a : false,
|
|
820
|
+
minZoom: (_b = layerConfig.minZoom) !== null && _b !== void 0 ? _b : 19.5,
|
|
821
|
+
maxZoom: (_c = layerConfig.maxZoom) !== null && _c !== void 0 ? _c : 24,
|
|
787
822
|
renderSubLayers: (props) => {
|
|
823
|
+
var _a, _b, _c, _d, _e;
|
|
788
824
|
// Use area_name and poi Point features — unique per tile, no duplicates
|
|
789
825
|
// If logo-{name} image exists in sprite, icon has priority over text label
|
|
790
826
|
const labelData = (props.data || []);
|
|
@@ -806,32 +842,34 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
806
842
|
if (!labelFeatures.length)
|
|
807
843
|
return null;
|
|
808
844
|
const textData = labelFeatures.map((f) => {
|
|
809
|
-
var _a, _b, _c;
|
|
845
|
+
var _a, _b, _c, _d;
|
|
810
846
|
return ({
|
|
811
847
|
position: [
|
|
812
848
|
...f.geometry.coordinates.slice(0, 2),
|
|
813
|
-
((_a = f.properties) === null || _a === void 0 ? void 0 : _a.height) ? Number(f.properties.height) : 5,
|
|
849
|
+
((_a = f.properties) === null || _a === void 0 ? void 0 : _a.height) ? Number(f.properties.height) : ((_b = layerConfig.defaultHeight) !== null && _b !== void 0 ? _b : 5),
|
|
814
850
|
],
|
|
815
|
-
text: ((
|
|
851
|
+
text: ((_c = f.properties) === null || _c === void 0 ? void 0 : _c["name:latin"]) || ((_d = f.properties) === null || _d === void 0 ? void 0 : _d.name) || "",
|
|
816
852
|
});
|
|
817
853
|
});
|
|
818
|
-
return new layers_1.TextLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-labels`, data: textData, getPosition: (d) => d.position, getText: (d) => d.text, getSize: 16, getColor:
|
|
854
|
+
return new layers_1.TextLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-labels`, data: textData, getPosition: (d) => d.position, getText: (d) => d.text, getSize: (_a = layerConfig.size) !== null && _a !== void 0 ? _a : 16, getColor: (0, _3d_1.hexToRgb)((_b = layerConfig.color) !== null && _b !== void 0 ? _b : "#91969b"), outlineColor: useSdf ? [255, 255, 255, 255] : [0, 0, 0, 0], outlineWidth: useSdf ? 4 : 0, fontSettings: { sdf: useSdf }, fontFamily: (_c = layerConfig.fontFamily) !== null && _c !== void 0 ? _c : "Open Sans, sans-serif", fontWeight: (_d = layerConfig.fontWeight) !== null && _d !== void 0 ? _d : 600, billboard: true, pickable: false, characterSet: "auto", wordBreak: "break-word", maxWidth: (_e = layerConfig.maxWidth) !== null && _e !== void 0 ? _e : 150 }));
|
|
819
855
|
},
|
|
820
856
|
updateTriggers: {
|
|
821
857
|
renderSubLayers: [floorKey],
|
|
822
858
|
},
|
|
823
859
|
});
|
|
824
860
|
}
|
|
825
|
-
makePoiIconLayer(floorKey) {
|
|
861
|
+
makePoiIconLayer(floorKey, layerConfig) {
|
|
862
|
+
var _a, _b, _c;
|
|
826
863
|
if (!this.spriteIconMapping || !this.spriteAtlasImage)
|
|
827
864
|
return null;
|
|
828
865
|
return new geo_layers_1.MVTLayer({
|
|
829
866
|
id: "indoor-poi-icons",
|
|
830
|
-
data:
|
|
831
|
-
binary: false,
|
|
832
|
-
minZoom: 17,
|
|
833
|
-
maxZoom: 24,
|
|
867
|
+
data: layerConfig.dataUrl,
|
|
868
|
+
binary: (_a = layerConfig.binaryData) !== null && _a !== void 0 ? _a : false,
|
|
869
|
+
minZoom: (_b = layerConfig.minZoom) !== null && _b !== void 0 ? _b : 17,
|
|
870
|
+
maxZoom: (_c = layerConfig.maxZoom) !== null && _c !== void 0 ? _c : 24,
|
|
834
871
|
renderSubLayers: (props) => {
|
|
872
|
+
var _a, _b, _c, _d;
|
|
835
873
|
const poiData = (props.data || []);
|
|
836
874
|
const poiFeatures = poiData.filter((f) => {
|
|
837
875
|
var _a, _b, _c;
|
|
@@ -845,7 +883,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
845
883
|
if (!poiFeatures.length)
|
|
846
884
|
return null;
|
|
847
885
|
const iconData = poiFeatures.map((f) => {
|
|
848
|
-
var _a, _b, _c;
|
|
886
|
+
var _a, _b, _c, _d;
|
|
849
887
|
const tags = ((_a = f.properties) === null || _a === void 0 ? void 0 : _a.tags) || "";
|
|
850
888
|
let icon;
|
|
851
889
|
if (tags.includes("wheelchair"))
|
|
@@ -857,28 +895,30 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
857
895
|
return {
|
|
858
896
|
position: [
|
|
859
897
|
...f.geometry.coordinates.slice(0, 2),
|
|
860
|
-
((_c = f.properties) === null || _c === void 0 ? void 0 : _c.height) ? Number(f.properties.height) : 5,
|
|
898
|
+
((_c = f.properties) === null || _c === void 0 ? void 0 : _c.height) ? Number(f.properties.height) : ((_d = layerConfig.defaultHeight) !== null && _d !== void 0 ? _d : 5),
|
|
861
899
|
],
|
|
862
900
|
icon,
|
|
863
901
|
};
|
|
864
902
|
});
|
|
865
|
-
return new layers_1.IconLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-poi-icons`, data: iconData, iconAtlas: this.spriteAtlasImage, iconMapping: this.spriteIconMapping, getIcon: (d) => d.icon, getPosition: (d) => d.position, getSize: 2, sizeUnits: "meters", sizeScale: 1, billboard: true, pickable: false }));
|
|
903
|
+
return new layers_1.IconLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-poi-icons`, data: iconData, iconAtlas: this.spriteAtlasImage, iconMapping: this.spriteIconMapping, getIcon: (d) => d.icon, getPosition: (d) => d.position, getSize: (_a = layerConfig.size) !== null && _a !== void 0 ? _a : 2, sizeUnits: (_b = layerConfig.sizeUnits) !== null && _b !== void 0 ? _b : "meters", sizeScale: (_c = layerConfig.sizeScale) !== null && _c !== void 0 ? _c : 1, billboard: (_d = layerConfig.billboard) !== null && _d !== void 0 ? _d : true, pickable: false }));
|
|
866
904
|
},
|
|
867
905
|
updateTriggers: {
|
|
868
906
|
renderSubLayers: [floorKey],
|
|
869
907
|
},
|
|
870
908
|
});
|
|
871
909
|
}
|
|
872
|
-
makeStoreLogoLayer(floorKey) {
|
|
910
|
+
makeStoreLogoLayer(floorKey, layerConfig) {
|
|
911
|
+
var _a, _b, _c;
|
|
873
912
|
if (!this.spriteIconMapping || !this.spriteAtlasImage)
|
|
874
913
|
return null;
|
|
875
914
|
return new geo_layers_1.MVTLayer({
|
|
876
915
|
id: "indoor-store-logos",
|
|
877
|
-
data:
|
|
878
|
-
binary: false,
|
|
879
|
-
minZoom: 13,
|
|
880
|
-
maxZoom: 24,
|
|
916
|
+
data: layerConfig.dataUrl,
|
|
917
|
+
binary: (_a = layerConfig.binaryData) !== null && _a !== void 0 ? _a : false,
|
|
918
|
+
minZoom: (_b = layerConfig.minZoom) !== null && _b !== void 0 ? _b : 13,
|
|
919
|
+
maxZoom: (_c = layerConfig.maxZoom) !== null && _c !== void 0 ? _c : 24,
|
|
881
920
|
renderSubLayers: (props) => {
|
|
921
|
+
var _a, _b, _c;
|
|
882
922
|
const propsData = (props.data || []);
|
|
883
923
|
const logoFeatures = propsData.filter((f) => {
|
|
884
924
|
var _a, _b, _c;
|
|
@@ -894,30 +934,22 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
894
934
|
if (!logoFeatures.length)
|
|
895
935
|
return null;
|
|
896
936
|
const logoData = logoFeatures.map((f) => {
|
|
897
|
-
var _a, _b, _c;
|
|
937
|
+
var _a, _b, _c, _d;
|
|
898
938
|
const name = (_a = f.properties) === null || _a === void 0 ? void 0 : _a.name;
|
|
899
939
|
const icon = "logo-" + name;
|
|
900
940
|
const rotation = ((_b = f.properties) === null || _b === void 0 ? void 0 : _b.rotation_icon) ? Number(f.properties.rotation_icon) : 0;
|
|
901
941
|
return {
|
|
902
942
|
position: [
|
|
903
943
|
...f.geometry.coordinates.slice(0, 2),
|
|
904
|
-
((_c = f.properties) === null || _c === void 0 ? void 0 : _c.height) ? Number(f.properties.height) : 5,
|
|
944
|
+
((_c = f.properties) === null || _c === void 0 ? void 0 : _c.height) ? Number(f.properties.height) : ((_d = layerConfig.defaultHeight) !== null && _d !== void 0 ? _d : 5),
|
|
905
945
|
],
|
|
906
946
|
icon,
|
|
907
947
|
rotation,
|
|
908
948
|
};
|
|
909
949
|
});
|
|
910
950
|
return new layers_1.IconLayer(Object.assign(Object.assign({}, props), { id: `${props.id}-store-logos`, data: logoData, iconAtlas: this.spriteAtlasImage, iconMapping: this.spriteIconMapping, getIcon: (d) => d.icon, getPosition: (d) => d.position, getAngle: (d) => -d.rotation, getSize: (d) => {
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
"logo-Ripley": 2,
|
|
914
|
-
"logo-Falabella": 2,
|
|
915
|
-
"logo-CasaIdeas": 2,
|
|
916
|
-
"logo-Sky Costanera": 0.6,
|
|
917
|
-
"logo-Easy": 1.4,
|
|
918
|
-
"logo-Jumbo": 2,
|
|
919
|
-
"logo-Decathlon": 1.4,
|
|
920
|
-
};
|
|
951
|
+
var _a;
|
|
952
|
+
const LOGO_SCALE = (_a = layerConfig.logoScale) !== null && _a !== void 0 ? _a : {};
|
|
921
953
|
const m = this.spriteIconMapping[d.icon];
|
|
922
954
|
if (!m)
|
|
923
955
|
return 10;
|
|
@@ -926,7 +958,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
926
958
|
const h = m.height / pr;
|
|
927
959
|
const base = 10 * (h / Math.max(w, h));
|
|
928
960
|
return base * (LOGO_SCALE[d.icon] || 1);
|
|
929
|
-
}, sizeUnits: "meters", sizeScale: 1, billboard: false, pickable: false }));
|
|
961
|
+
}, sizeUnits: (_a = layerConfig.sizeUnits) !== null && _a !== void 0 ? _a : "meters", sizeScale: (_b = layerConfig.sizeScale) !== null && _b !== void 0 ? _b : 1, billboard: (_c = layerConfig.billboard) !== null && _c !== void 0 ? _c : false, pickable: false }));
|
|
930
962
|
},
|
|
931
963
|
updateTriggers: {
|
|
932
964
|
renderSubLayers: [floorKey],
|
|
@@ -934,20 +966,40 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
934
966
|
});
|
|
935
967
|
}
|
|
936
968
|
updateDeckOverlay() {
|
|
969
|
+
var _a;
|
|
937
970
|
if (!this.deckOverlay || !this.currentFloor)
|
|
938
971
|
return;
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
];
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
972
|
+
if (!((_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.customLayers))
|
|
973
|
+
return;
|
|
974
|
+
const { customLayers } = this.scene3DConfig;
|
|
975
|
+
const layers = [];
|
|
976
|
+
if (customLayers.elevatedLinesLayer) {
|
|
977
|
+
layers.push(this.makeElevatedLinesLayer(this.currentFloor, customLayers.elevatedLinesLayer));
|
|
978
|
+
}
|
|
979
|
+
if (customLayers.labelsLayer) {
|
|
980
|
+
layers.push(this.makeLabelLayer(this.currentFloor, customLayers.labelsLayer, false));
|
|
981
|
+
}
|
|
982
|
+
if (customLayers.iconLayers) {
|
|
983
|
+
const { storeLogosLayer, poiIconsLayer } = customLayers.iconLayers;
|
|
984
|
+
if (storeLogosLayer) {
|
|
985
|
+
layers.push(this.makeStoreLogoLayer(this.currentFloor, storeLogosLayer));
|
|
986
|
+
}
|
|
987
|
+
if (poiIconsLayer) {
|
|
988
|
+
layers.push(this.makePoiIconLayer(this.currentFloor, poiIconsLayer));
|
|
989
|
+
}
|
|
990
|
+
}
|
|
949
991
|
this.deckOverlay.setProps({ layers });
|
|
950
992
|
}
|
|
993
|
+
hideLayers(layersIds) {
|
|
994
|
+
if (!layersIds)
|
|
995
|
+
return;
|
|
996
|
+
for (const layerId of layersIds) {
|
|
997
|
+
const layer = this.map.getLayer(layerId);
|
|
998
|
+
if (!layer)
|
|
999
|
+
continue;
|
|
1000
|
+
this.map.setLayoutProperty(layer.id, "visibility", "none");
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
951
1003
|
// End 3D related methods ------------------------------------------------------------
|
|
952
1004
|
getCurrentFloor() {
|
|
953
1005
|
var _a;
|
|
@@ -968,9 +1020,9 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
968
1020
|
if (place) {
|
|
969
1021
|
this.subPlacesLoad(place.mapvxId);
|
|
970
1022
|
}
|
|
971
|
-
if (this.
|
|
1023
|
+
if (this.is3DSceneActive()) {
|
|
972
1024
|
this.updateDeckOverlay();
|
|
973
|
-
this.
|
|
1025
|
+
this.placeScene3DModels();
|
|
974
1026
|
}
|
|
975
1027
|
if (updateStyle) {
|
|
976
1028
|
this.repository
|
|
@@ -1000,9 +1052,9 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1000
1052
|
this.innerFloors = (_a = place === null || place === void 0 ? void 0 : place.innerFloors.sort((a, b) => a.index - b.index)) !== null && _a !== void 0 ? _a : [];
|
|
1001
1053
|
this.currentFloor =
|
|
1002
1054
|
(_e = (_c = floorId !== null && floorId !== void 0 ? floorId : (_b = this.innerFloors.find((floor) => floor.defaultFloor)) === null || _b === void 0 ? void 0 : _b.key) !== null && _c !== void 0 ? _c : (_d = this.innerFloors[0]) === null || _d === void 0 ? void 0 : _d.key) !== null && _e !== void 0 ? _e : "";
|
|
1003
|
-
if (this.
|
|
1055
|
+
if (this.is3DSceneActive()) {
|
|
1004
1056
|
this.updateDeckOverlay();
|
|
1005
|
-
this.
|
|
1057
|
+
this.placeScene3DModels();
|
|
1006
1058
|
}
|
|
1007
1059
|
}
|
|
1008
1060
|
updateParentPlaceAndFloor(parentPlaceId, floorId, options) {
|
|
@@ -1056,7 +1108,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1056
1108
|
this.routeController.addSourcesAndLayers();
|
|
1057
1109
|
this.refreshCircles();
|
|
1058
1110
|
this.filterByFloorKey(this.currentFloor);
|
|
1059
|
-
if (this.
|
|
1111
|
+
if (this.is3DSceneActive()) {
|
|
1060
1112
|
this.updateDeckOverlay();
|
|
1061
1113
|
}
|
|
1062
1114
|
}
|
|
@@ -1488,9 +1540,10 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1488
1540
|
this.logEvent("invalidFloorKey", { floorKey: floorKeyString });
|
|
1489
1541
|
}
|
|
1490
1542
|
// Critical base-map updates run first and must never be blocked by an
|
|
1491
|
-
// optional 3D decoration failing. A throw in
|
|
1492
|
-
// this method before updateFiltersTo, leaving the base polygons
|
|
1493
|
-
// (showing the wrong floor) while the caller's empty catch hid
|
|
1543
|
+
// optional 3D decoration failing. A throw in placeScene3DModels used to
|
|
1544
|
+
// abort this method before updateFiltersTo, leaving the base polygons
|
|
1545
|
+
// unfiltered (showing the wrong floor) while the caller's empty catch hid
|
|
1546
|
+
// the error.
|
|
1494
1547
|
this.updateFiltersTo(floorKeyString);
|
|
1495
1548
|
this.updateMarkersTo(floorKeyString);
|
|
1496
1549
|
this.refreshCircles();
|
|
@@ -1498,10 +1551,10 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1498
1551
|
this.routeController.updateRouteMarkerVisibility(floorKeyString);
|
|
1499
1552
|
// 3D decorations are best-effort: isolate so any failure here can never
|
|
1500
1553
|
// break base-map rendering.
|
|
1501
|
-
if (this.
|
|
1554
|
+
if (this.is3DSceneActive()) {
|
|
1502
1555
|
try {
|
|
1503
1556
|
this.updateDeckOverlay();
|
|
1504
|
-
this.
|
|
1557
|
+
this.placeScene3DModels();
|
|
1505
1558
|
}
|
|
1506
1559
|
catch (error) {
|
|
1507
1560
|
this.logError(error, "filterByFloorKey: 3D layer update failed");
|