@mappedin/dynamic-focus 6.0.1-beta.61 → 6.0.1-beta.62
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/lib/esm/chunk-YG54MHZY.js +1 -0
- package/lib/esm/index.d.ts +20383 -35961
- package/lib/esm/index.js +1 -7
- package/lib/esm/react/index.d.ts +20367 -35971
- package/lib/esm/react/index.js +1 -77
- package/lib/rn/index-rn.js +5 -258
- package/lib/rn/logger.d.ts +2 -2
- package/package.json +8 -6
- package/lib/dynamic-focus.iife.js.map +0 -7
- package/lib/esm/chunk-RSECYADN.js +0 -1175
- package/lib/esm/chunk-RSECYADN.js.map +0 -7
- package/lib/esm/index.js.map +0 -7
- package/lib/esm/react/index.js.map +0 -7
- package/lib/rn/index-rn.js.map +0 -7
|
@@ -1,1175 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
|
-
// <define:process>
|
|
5
|
-
var define_process_default = { env: { npm_package_version: "6.0.1-beta.61" } };
|
|
6
|
-
|
|
7
|
-
// src/dynamic-focus.ts
|
|
8
|
-
import { Floor as Floor3, getMultiFloorState as getMultiFloorState2 } from "@mappedin/mappedin-js";
|
|
9
|
-
|
|
10
|
-
// ../packages/common/array-utils.ts
|
|
11
|
-
function arraysEqual(arr1, arr2) {
|
|
12
|
-
if (arr1 == null || arr2 == null) {
|
|
13
|
-
return arr1 === arr2;
|
|
14
|
-
}
|
|
15
|
-
if (arr1.length !== arr2.length) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
for (let i = 0; i < arr1.length; i++) {
|
|
19
|
-
if (arr1[i] !== arr2[i]) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
__name(arraysEqual, "arraysEqual");
|
|
26
|
-
|
|
27
|
-
// ../packages/common/pubsub.ts
|
|
28
|
-
var PubSub = class {
|
|
29
|
-
static {
|
|
30
|
-
__name(this, "PubSub");
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* @private
|
|
34
|
-
* @internal
|
|
35
|
-
*/
|
|
36
|
-
_subscribers = {};
|
|
37
|
-
/**
|
|
38
|
-
* @private
|
|
39
|
-
* @internal
|
|
40
|
-
*/
|
|
41
|
-
_destroyed = false;
|
|
42
|
-
/**
|
|
43
|
-
* @private
|
|
44
|
-
* @internal
|
|
45
|
-
*/
|
|
46
|
-
publish(eventName, data) {
|
|
47
|
-
if (!this._subscribers || !this._subscribers[eventName] || this._destroyed) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this._subscribers[eventName].forEach(function(fn) {
|
|
51
|
-
if (typeof fn !== "function") {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
fn(data);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Subscribe a function to an event.
|
|
59
|
-
*
|
|
60
|
-
* @param eventName An event name which, when fired, will call the provided
|
|
61
|
-
* function.
|
|
62
|
-
* @param fn A callback that gets called when the corresponding event is fired. The
|
|
63
|
-
* callback will get passed an argument with a type that's one of event payloads.
|
|
64
|
-
* @example
|
|
65
|
-
* // Subscribe to the 'click' event
|
|
66
|
-
* const handler = (event) => {
|
|
67
|
-
* const { coordinate } = event;
|
|
68
|
-
* const { latitude, longitude } = coordinate;
|
|
69
|
-
* console.log(`Map was clicked at ${latitude}, ${longitude}`);
|
|
70
|
-
* };
|
|
71
|
-
* map.on('click', handler);
|
|
72
|
-
*/
|
|
73
|
-
on(eventName, fn) {
|
|
74
|
-
if (!this._subscribers || this._destroyed) {
|
|
75
|
-
this._subscribers = {};
|
|
76
|
-
}
|
|
77
|
-
this._subscribers[eventName] = this._subscribers[eventName] || [];
|
|
78
|
-
this._subscribers[eventName].push(fn);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Unsubscribe a function previously subscribed with {@link on}
|
|
82
|
-
*
|
|
83
|
-
* @param eventName An event name to which the provided function was previously
|
|
84
|
-
* subscribed.
|
|
85
|
-
* @param fn A function that was previously passed to {@link on}. The function must
|
|
86
|
-
* have the same reference as the function that was subscribed.
|
|
87
|
-
* @example
|
|
88
|
-
* // Unsubscribe from the 'click' event
|
|
89
|
-
* const handler = (event) => {
|
|
90
|
-
* console.log('Map was clicked', event);
|
|
91
|
-
* };
|
|
92
|
-
* map.off('click', handler);
|
|
93
|
-
*/
|
|
94
|
-
off(eventName, fn) {
|
|
95
|
-
if (!this._subscribers || this._subscribers[eventName] == null || this._destroyed) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const itemIdx = this._subscribers[eventName].indexOf(fn);
|
|
99
|
-
if (itemIdx !== -1) {
|
|
100
|
-
this._subscribers[eventName].splice(itemIdx, 1);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* @private
|
|
105
|
-
* @internal
|
|
106
|
-
*/
|
|
107
|
-
destroy() {
|
|
108
|
-
this._destroyed = true;
|
|
109
|
-
this._subscribers = {};
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// src/building.ts
|
|
114
|
-
import { Facade, Floor, FloorStack } from "@mappedin/mappedin-js";
|
|
115
|
-
var Building = class {
|
|
116
|
-
static {
|
|
117
|
-
__name(this, "Building");
|
|
118
|
-
}
|
|
119
|
-
__type = "building";
|
|
120
|
-
#floorStack;
|
|
121
|
-
#floorsById = /* @__PURE__ */ new Map();
|
|
122
|
-
#floorsByElevation = /* @__PURE__ */ new Map();
|
|
123
|
-
#floorsByElevationSorted = [];
|
|
124
|
-
#mapView;
|
|
125
|
-
#animationInProgress;
|
|
126
|
-
defaultFloor;
|
|
127
|
-
activeFloor;
|
|
128
|
-
excluded = false;
|
|
129
|
-
floorsAltitudesMap = /* @__PURE__ */ new Map();
|
|
130
|
-
aboveGroundFloors = [];
|
|
131
|
-
constructor(floorStack, mapView) {
|
|
132
|
-
this.#floorStack = floorStack;
|
|
133
|
-
this.#floorsById = new Map(floorStack.floors.map((floor) => [floor.id, floor]));
|
|
134
|
-
this.#floorsByElevation = new Map(floorStack.floors.map((floor) => [floor.elevation, floor]));
|
|
135
|
-
this.#floorsByElevationSorted = Array.from(this.#floorsByElevation.values()).sort(
|
|
136
|
-
(a, b) => a.elevation - b.elevation
|
|
137
|
-
);
|
|
138
|
-
this.defaultFloor = floorStack.defaultFloor;
|
|
139
|
-
this.activeFloor = this.defaultFloor;
|
|
140
|
-
this.#mapView = mapView;
|
|
141
|
-
this.aboveGroundFloors = this.#floorsByElevationSorted.filter((floor) => floor.elevation >= 0);
|
|
142
|
-
const sortedSpaces = floorStack.facade?.spaces.map((space) => this.#mapView.getState(space)).sort((a, b) => a.altitude - b.altitude);
|
|
143
|
-
if (sortedSpaces && sortedSpaces.length === this.aboveGroundFloors.length) {
|
|
144
|
-
for (const idx in this.aboveGroundFloors) {
|
|
145
|
-
const floor = this.aboveGroundFloors[idx];
|
|
146
|
-
const space = sortedSpaces[idx];
|
|
147
|
-
this.floorsAltitudesMap.set(floor.elevation, {
|
|
148
|
-
altitude: space.altitude,
|
|
149
|
-
effectiveHeight: space.height
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
get id() {
|
|
155
|
-
return this.#floorStack.id;
|
|
156
|
-
}
|
|
157
|
-
get name() {
|
|
158
|
-
return this.#floorStack.name;
|
|
159
|
-
}
|
|
160
|
-
get floors() {
|
|
161
|
-
return this.#floorStack.floors;
|
|
162
|
-
}
|
|
163
|
-
get floorStack() {
|
|
164
|
-
return this.#floorStack;
|
|
165
|
-
}
|
|
166
|
-
get facade() {
|
|
167
|
-
return this.#floorStack.facade;
|
|
168
|
-
}
|
|
169
|
-
get isCurrentFloorStack() {
|
|
170
|
-
return this.id === this.#mapView.currentFloorStack.id;
|
|
171
|
-
}
|
|
172
|
-
get isIndoor() {
|
|
173
|
-
const state = this.#mapView.getState(this.facade);
|
|
174
|
-
return this.isCurrentFloorStack || state?.visible === false && state?.opacity === 0;
|
|
175
|
-
}
|
|
176
|
-
get canSetFloor() {
|
|
177
|
-
return this.isIndoor || !this.excluded;
|
|
178
|
-
}
|
|
179
|
-
#maxElevation;
|
|
180
|
-
get maxElevation() {
|
|
181
|
-
if (this.#maxElevation == null) {
|
|
182
|
-
this.#maxElevation = Math.max(...this.#floorsByElevation.keys());
|
|
183
|
-
}
|
|
184
|
-
return this.#maxElevation;
|
|
185
|
-
}
|
|
186
|
-
#minElevation;
|
|
187
|
-
get minElevation() {
|
|
188
|
-
if (this.#minElevation == null) {
|
|
189
|
-
this.#minElevation = Math.min(...this.#floorsByElevation.keys());
|
|
190
|
-
}
|
|
191
|
-
return this.#minElevation;
|
|
192
|
-
}
|
|
193
|
-
has(f) {
|
|
194
|
-
if (Floor.is(f)) {
|
|
195
|
-
return this.#floorsById.has(f.id);
|
|
196
|
-
}
|
|
197
|
-
if (FloorStack.is(f)) {
|
|
198
|
-
return f.id === this.#floorStack.id;
|
|
199
|
-
}
|
|
200
|
-
if (Facade.is(f)) {
|
|
201
|
-
return f.id === this.facade.id;
|
|
202
|
-
}
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
getFloorByElevation(elevation) {
|
|
206
|
-
return this.#floorsByElevation.get(elevation);
|
|
207
|
-
}
|
|
208
|
-
getNearestFloorByElevation(targetElevation) {
|
|
209
|
-
const exactMatch = this.getFloorByElevation(targetElevation);
|
|
210
|
-
if (exactMatch) {
|
|
211
|
-
return exactMatch;
|
|
212
|
-
}
|
|
213
|
-
if (targetElevation >= 0) {
|
|
214
|
-
if (targetElevation > this.maxElevation) {
|
|
215
|
-
return this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];
|
|
216
|
-
}
|
|
217
|
-
for (let i = this.#floorsByElevationSorted.length - 1; i >= 0; i--) {
|
|
218
|
-
const floor = this.#floorsByElevationSorted[i];
|
|
219
|
-
if (floor.elevation <= targetElevation) {
|
|
220
|
-
return floor;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
} else {
|
|
224
|
-
if (targetElevation < this.minElevation) {
|
|
225
|
-
return this.#floorsByElevationSorted[0];
|
|
226
|
-
}
|
|
227
|
-
for (const floor of this.#floorsByElevationSorted) {
|
|
228
|
-
if (floor.elevation >= targetElevation) {
|
|
229
|
-
return floor;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return void 0;
|
|
234
|
-
}
|
|
235
|
-
getHighestFloor() {
|
|
236
|
-
return this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];
|
|
237
|
-
}
|
|
238
|
-
cancelAnimation() {
|
|
239
|
-
if (this.#animationInProgress) {
|
|
240
|
-
this.#animationInProgress.animation.cancel();
|
|
241
|
-
this.#animationInProgress = void 0;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
async animateFacade(newState, options = { duration: 150 }) {
|
|
245
|
-
const currentState = this.#animationInProgress?.state || this.#mapView.getState(this.facade);
|
|
246
|
-
if (!currentState || !newState || currentState?.opacity === newState.opacity && currentState?.visible === newState.visible) {
|
|
247
|
-
return { result: "completed" };
|
|
248
|
-
}
|
|
249
|
-
this.cancelAnimation();
|
|
250
|
-
const { opacity, visible } = newState;
|
|
251
|
-
this.#mapView.updateState(this.facade, {
|
|
252
|
-
visible: true
|
|
253
|
-
});
|
|
254
|
-
if (opacity !== void 0) {
|
|
255
|
-
this.#animationInProgress = {
|
|
256
|
-
animation: this.#mapView.animateState(
|
|
257
|
-
this.facade,
|
|
258
|
-
{
|
|
259
|
-
opacity
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
duration: options.duration
|
|
263
|
-
}
|
|
264
|
-
),
|
|
265
|
-
state: newState
|
|
266
|
-
};
|
|
267
|
-
const result = await this.#animationInProgress.animation;
|
|
268
|
-
this.#animationInProgress = void 0;
|
|
269
|
-
if (result.result === "cancelled") {
|
|
270
|
-
return result;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
if (visible === false) {
|
|
274
|
-
this.#mapView.updateState(this.facade, {
|
|
275
|
-
visible
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
return { result: "completed" };
|
|
279
|
-
}
|
|
280
|
-
destroy() {
|
|
281
|
-
this.cancelAnimation();
|
|
282
|
-
this.#floorStack.floors.forEach((floor) => {
|
|
283
|
-
this.#mapView.updateState(floor, {
|
|
284
|
-
visible: floor.id === this.#mapView.currentFloor.id
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
if (!this.has(this.#mapView.currentFloor)) {
|
|
288
|
-
this.#mapView.updateState(this.facade, {
|
|
289
|
-
visible: true,
|
|
290
|
-
opacity: 1
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
// src/dynamic-focus-scene.ts
|
|
297
|
-
function getZoomState(zoomLevel, indoorThreshold, outdoorThreshold) {
|
|
298
|
-
if (zoomLevel >= indoorThreshold) {
|
|
299
|
-
return "in-range";
|
|
300
|
-
}
|
|
301
|
-
if (zoomLevel <= outdoorThreshold) {
|
|
302
|
-
return "out-of-range";
|
|
303
|
-
}
|
|
304
|
-
return "transition";
|
|
305
|
-
}
|
|
306
|
-
__name(getZoomState, "getZoomState");
|
|
307
|
-
function getFloorToShow(target, mode, elevation) {
|
|
308
|
-
if (target.__type === "outdoors" && "floor" in target) {
|
|
309
|
-
return target.floor;
|
|
310
|
-
}
|
|
311
|
-
const building = target;
|
|
312
|
-
if (building.excluded) {
|
|
313
|
-
return building.activeFloor;
|
|
314
|
-
}
|
|
315
|
-
switch (mode) {
|
|
316
|
-
case "lock-elevation":
|
|
317
|
-
return building.getFloorByElevation(elevation);
|
|
318
|
-
case "nearest-elevation":
|
|
319
|
-
return building.getNearestFloorByElevation(elevation);
|
|
320
|
-
default:
|
|
321
|
-
break;
|
|
322
|
-
}
|
|
323
|
-
return building.isIndoor ? building.activeFloor : building.defaultFloor;
|
|
324
|
-
}
|
|
325
|
-
__name(getFloorToShow, "getFloorToShow");
|
|
326
|
-
function getFacadeState(facade, inFocus) {
|
|
327
|
-
return {
|
|
328
|
-
facade,
|
|
329
|
-
state: {
|
|
330
|
-
type: "facade",
|
|
331
|
-
visible: !inFocus,
|
|
332
|
-
opacity: inFocus ? 0 : 1
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
__name(getFacadeState, "getFacadeState");
|
|
337
|
-
function getSingleBuildingState(floorStack, currentFloor, inFocus) {
|
|
338
|
-
return {
|
|
339
|
-
outdoorOpacity: 1,
|
|
340
|
-
floorStates: floorStack.floors.map((f) => {
|
|
341
|
-
const visible = f.id === currentFloor.id && inFocus;
|
|
342
|
-
return {
|
|
343
|
-
floor: f,
|
|
344
|
-
state: {
|
|
345
|
-
type: "floor",
|
|
346
|
-
visible,
|
|
347
|
-
geometry: {
|
|
348
|
-
visible
|
|
349
|
-
},
|
|
350
|
-
labels: {
|
|
351
|
-
enabled: visible
|
|
352
|
-
},
|
|
353
|
-
markers: {
|
|
354
|
-
enabled: visible
|
|
355
|
-
},
|
|
356
|
-
footprint: {
|
|
357
|
-
visible: false
|
|
358
|
-
},
|
|
359
|
-
occlusion: {
|
|
360
|
-
enabled: false
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
})
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
__name(getSingleBuildingState, "getSingleBuildingState");
|
|
368
|
-
function getOutdoorOpacity(floorStackStates, mode) {
|
|
369
|
-
if (!mode.includes("lock-elevation")) {
|
|
370
|
-
return 1;
|
|
371
|
-
}
|
|
372
|
-
for (const state of floorStackStates) {
|
|
373
|
-
if (state.outdoorOpacity >= 0 && state.outdoorOpacity <= 1) {
|
|
374
|
-
return state.outdoorOpacity;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return 1;
|
|
378
|
-
}
|
|
379
|
-
__name(getOutdoorOpacity, "getOutdoorOpacity");
|
|
380
|
-
function getSetFloorTargetFromZoomState(buildings, outdoors, zoomState) {
|
|
381
|
-
switch (zoomState) {
|
|
382
|
-
case "in-range":
|
|
383
|
-
return buildings[0]?.canSetFloor ? buildings[0] : void 0;
|
|
384
|
-
case "out-of-range":
|
|
385
|
-
return outdoors;
|
|
386
|
-
case "transition":
|
|
387
|
-
default:
|
|
388
|
-
return void 0;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
__name(getSetFloorTargetFromZoomState, "getSetFloorTargetFromZoomState");
|
|
392
|
-
function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode, elevation, floorIdsInNavigation, floorStackIdsInNavigation, multiFloorView, getMultiFloorState3, dynamicBuildingInteriors) {
|
|
393
|
-
const buildingStates = /* @__PURE__ */ new Map();
|
|
394
|
-
for (const building of buildings) {
|
|
395
|
-
const inCameraView = inViewSet.has(building.id);
|
|
396
|
-
const showIndoor = shouldShowIndoor(
|
|
397
|
-
building,
|
|
398
|
-
currentFloor,
|
|
399
|
-
zoomState === "in-range",
|
|
400
|
-
inCameraView,
|
|
401
|
-
mode,
|
|
402
|
-
elevation,
|
|
403
|
-
floorStackIdsInNavigation.includes(building.id),
|
|
404
|
-
dynamicBuildingInteriors
|
|
405
|
-
);
|
|
406
|
-
const floorToShow = currentFloor.floorStack.id === building.id ? building.activeFloor : getFloorToShow(building, mode, elevation);
|
|
407
|
-
const floorStackState = multiFloorView.enabled ? getMultiFloorState3(
|
|
408
|
-
building.floors,
|
|
409
|
-
floorToShow || building.activeFloor,
|
|
410
|
-
multiFloorView?.floorGap,
|
|
411
|
-
floorIdsInNavigation,
|
|
412
|
-
building.floorsAltitudesMap
|
|
413
|
-
) : getSingleBuildingState(building.floorStack, floorToShow || building.activeFloor, showIndoor);
|
|
414
|
-
const facadeState = getFacadeState(building.facade, showIndoor);
|
|
415
|
-
buildingStates.set(building.id, {
|
|
416
|
-
building,
|
|
417
|
-
showIndoor,
|
|
418
|
-
floorStackState,
|
|
419
|
-
facadeState,
|
|
420
|
-
inFocus: inCameraView,
|
|
421
|
-
floorToShow
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
return buildingStates;
|
|
425
|
-
}
|
|
426
|
-
__name(getBuildingStates, "getBuildingStates");
|
|
427
|
-
function getBuildingAnimationType(building, showIndoor) {
|
|
428
|
-
if (building.excluded) {
|
|
429
|
-
return "none";
|
|
430
|
-
}
|
|
431
|
-
if (showIndoor) {
|
|
432
|
-
return "indoor";
|
|
433
|
-
}
|
|
434
|
-
return "outdoor";
|
|
435
|
-
}
|
|
436
|
-
__name(getBuildingAnimationType, "getBuildingAnimationType");
|
|
437
|
-
function shouldShowIndoor(building, currentFloor, inRange, inFocus, mode, elevation, inNavigation, dynamicBuildingInteriors) {
|
|
438
|
-
if (building.id === currentFloor.floorStack.id) {
|
|
439
|
-
return true;
|
|
440
|
-
}
|
|
441
|
-
if (building.excluded) {
|
|
442
|
-
return false;
|
|
443
|
-
}
|
|
444
|
-
if (inNavigation === true) {
|
|
445
|
-
return true;
|
|
446
|
-
}
|
|
447
|
-
if (!dynamicBuildingInteriors) {
|
|
448
|
-
return currentFloor.floorStack.type !== "Outdoor";
|
|
449
|
-
}
|
|
450
|
-
if (!inRange) {
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
if (!inFocus) {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
switch (mode) {
|
|
457
|
-
case "lock-elevation":
|
|
458
|
-
return building.getFloorByElevation(elevation) != null;
|
|
459
|
-
default:
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
return true;
|
|
463
|
-
}
|
|
464
|
-
__name(shouldShowIndoor, "shouldShowIndoor");
|
|
465
|
-
function shouldDeferSetFloor(trackedCameraElevation, currentCameraElevation, userInteracting) {
|
|
466
|
-
return trackedCameraElevation !== currentCameraElevation && !userInteracting;
|
|
467
|
-
}
|
|
468
|
-
__name(shouldDeferSetFloor, "shouldDeferSetFloor");
|
|
469
|
-
|
|
470
|
-
// src/types.ts
|
|
471
|
-
var DYNAMIC_FOCUS_MODES = ["default-floor", "lock-elevation", "nearest-elevation"];
|
|
472
|
-
|
|
473
|
-
// src/validation.ts
|
|
474
|
-
import { Floor as Floor2, FloorStack as FloorStack2 } from "@mappedin/mappedin-js";
|
|
475
|
-
|
|
476
|
-
// ../packages/common/Mappedin.Logger.ts
|
|
477
|
-
var MI_ERROR_LABEL = "[MappedinJS]";
|
|
478
|
-
function createLogger(name = "", { prefix = MI_ERROR_LABEL } = {}) {
|
|
479
|
-
const label = `${prefix}${name ? `-${name}` : ""}`;
|
|
480
|
-
const rnDebug = /* @__PURE__ */ __name((type, args) => {
|
|
481
|
-
if (typeof window !== "undefined" && window.rnDebug) {
|
|
482
|
-
const processed = args.map((arg) => {
|
|
483
|
-
if (arg instanceof Error && arg.stack) {
|
|
484
|
-
return `${arg.message}
|
|
485
|
-
${arg.stack}`;
|
|
486
|
-
}
|
|
487
|
-
return arg;
|
|
488
|
-
});
|
|
489
|
-
window.rnDebug(`${name} ${type}: ${processed.join(" ")}`);
|
|
490
|
-
}
|
|
491
|
-
}, "rnDebug");
|
|
492
|
-
return {
|
|
493
|
-
logState: define_process_default.env.NODE_ENV === "test" ? 3 /* SILENT */ : 0 /* LOG */,
|
|
494
|
-
log(...args) {
|
|
495
|
-
if (this.logState <= 0 /* LOG */) {
|
|
496
|
-
console.log(label, ...args);
|
|
497
|
-
rnDebug("log", args);
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
|
-
warn(...args) {
|
|
501
|
-
if (this.logState <= 1 /* WARN */) {
|
|
502
|
-
console.warn(label, ...args);
|
|
503
|
-
rnDebug("warn", args);
|
|
504
|
-
}
|
|
505
|
-
},
|
|
506
|
-
error(...args) {
|
|
507
|
-
if (this.logState <= 2 /* ERROR */) {
|
|
508
|
-
console.error(label, ...args);
|
|
509
|
-
rnDebug("error", args);
|
|
510
|
-
}
|
|
511
|
-
},
|
|
512
|
-
// It's a bit tricky to prepend [MappedinJs] to assert and time because of how the output is structured in the console, so it is left out for simplicity
|
|
513
|
-
assert(...args) {
|
|
514
|
-
console.assert(...args);
|
|
515
|
-
},
|
|
516
|
-
time(label2) {
|
|
517
|
-
console.time(label2);
|
|
518
|
-
},
|
|
519
|
-
timeEnd(label2) {
|
|
520
|
-
console.timeEnd(label2);
|
|
521
|
-
},
|
|
522
|
-
setLevel(level) {
|
|
523
|
-
if (0 /* LOG */ <= level && level <= 3 /* SILENT */) {
|
|
524
|
-
this.logState = level;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
__name(createLogger, "createLogger");
|
|
530
|
-
var Logger = createLogger();
|
|
531
|
-
var Mappedin_Logger_default = Logger;
|
|
532
|
-
|
|
533
|
-
// ../packages/common/math-utils.ts
|
|
534
|
-
function clampWithWarning(x, lower, upper, warning) {
|
|
535
|
-
if (x < lower || x > upper) {
|
|
536
|
-
Mappedin_Logger_default.warn(warning);
|
|
537
|
-
}
|
|
538
|
-
return Math.min(upper, Math.max(lower, x));
|
|
539
|
-
}
|
|
540
|
-
__name(clampWithWarning, "clampWithWarning");
|
|
541
|
-
|
|
542
|
-
// src/validation.ts
|
|
543
|
-
function validateFloorForStack(floor, floorStack) {
|
|
544
|
-
if (!Floor2.is(floor) || floor?.floorStack == null || !FloorStack2.is(floorStack)) {
|
|
545
|
-
return false;
|
|
546
|
-
}
|
|
547
|
-
if (floor.floorStack.id !== floorStack.id) {
|
|
548
|
-
Mappedin_Logger_default.warn(`Floor (${floor.id}) does not belong to floor stack (${floorStack.id}).`);
|
|
549
|
-
return false;
|
|
550
|
-
}
|
|
551
|
-
return true;
|
|
552
|
-
}
|
|
553
|
-
__name(validateFloorForStack, "validateFloorForStack");
|
|
554
|
-
function validateZoomThreshold(value, min, max, name) {
|
|
555
|
-
return clampWithWarning(value, min, max, `${name} must be between ${min} and ${max}.`);
|
|
556
|
-
}
|
|
557
|
-
__name(validateZoomThreshold, "validateZoomThreshold");
|
|
558
|
-
|
|
559
|
-
// src/logger.ts
|
|
560
|
-
var Logger2 = createLogger("", { prefix: "[DynamicFocus]" });
|
|
561
|
-
|
|
562
|
-
// src/outdoors.ts
|
|
563
|
-
var Outdoors = class {
|
|
564
|
-
static {
|
|
565
|
-
__name(this, "Outdoors");
|
|
566
|
-
}
|
|
567
|
-
__type = "outdoors";
|
|
568
|
-
#floorStack;
|
|
569
|
-
#mapView;
|
|
570
|
-
constructor(floorStack, mapView) {
|
|
571
|
-
this.#floorStack = floorStack;
|
|
572
|
-
this.#mapView = mapView;
|
|
573
|
-
}
|
|
574
|
-
get id() {
|
|
575
|
-
return this.#floorStack.id;
|
|
576
|
-
}
|
|
577
|
-
get floorStack() {
|
|
578
|
-
return this.#floorStack;
|
|
579
|
-
}
|
|
580
|
-
get floor() {
|
|
581
|
-
return this.#floorStack.defaultFloor;
|
|
582
|
-
}
|
|
583
|
-
matchesFloorStack(floorStack) {
|
|
584
|
-
return floorStack === this.#floorStack || floorStack === this.#floorStack.id;
|
|
585
|
-
}
|
|
586
|
-
#setVisible(visible) {
|
|
587
|
-
for (const floor of this.#floorStack.floors) {
|
|
588
|
-
this.#mapView.updateState(floor, {
|
|
589
|
-
visible
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
show() {
|
|
594
|
-
this.#setVisible(true);
|
|
595
|
-
}
|
|
596
|
-
hide() {
|
|
597
|
-
this.#setVisible(false);
|
|
598
|
-
}
|
|
599
|
-
destroy() {
|
|
600
|
-
if (!this.matchesFloorStack(this.#mapView.currentFloorStack)) {
|
|
601
|
-
this.hide();
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
function getOutdoorFloorStack(floorStacks, buildingsSet) {
|
|
606
|
-
const outdoorFloorStack = floorStacks.find((floorStack) => floorStack.type?.toLowerCase() === "outdoor");
|
|
607
|
-
if (outdoorFloorStack) {
|
|
608
|
-
return outdoorFloorStack;
|
|
609
|
-
}
|
|
610
|
-
const likelyOutdoorFloorStack = floorStacks.find(
|
|
611
|
-
(floorStack) => floorStack.facade == null && !buildingsSet.has(floorStack.id)
|
|
612
|
-
);
|
|
613
|
-
if (likelyOutdoorFloorStack) {
|
|
614
|
-
return likelyOutdoorFloorStack;
|
|
615
|
-
}
|
|
616
|
-
Logger2.warn("No good candidate for the outdoor floor stack was found. Using the first floor stack.");
|
|
617
|
-
return floorStacks[0];
|
|
618
|
-
}
|
|
619
|
-
__name(getOutdoorFloorStack, "getOutdoorFloorStack");
|
|
620
|
-
|
|
621
|
-
// src/constants.ts
|
|
622
|
-
import { getMultiFloorState } from "@mappedin/mappedin-js";
|
|
623
|
-
var DEFAULT_STATE = {
|
|
624
|
-
indoorZoomThreshold: 18,
|
|
625
|
-
outdoorZoomThreshold: 17,
|
|
626
|
-
setFloorOnFocus: true,
|
|
627
|
-
autoFocus: false,
|
|
628
|
-
indoorAnimationOptions: {
|
|
629
|
-
duration: 150
|
|
630
|
-
},
|
|
631
|
-
outdoorAnimationOptions: {
|
|
632
|
-
duration: 150
|
|
633
|
-
},
|
|
634
|
-
autoAdjustFacadeHeights: false,
|
|
635
|
-
mode: "default-floor",
|
|
636
|
-
preloadFloors: true,
|
|
637
|
-
customMultiFloorVisibilityState: getMultiFloorState,
|
|
638
|
-
dynamicBuildingInteriors: true
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
// src/dynamic-focus.ts
|
|
642
|
-
var DynamicFocus = class {
|
|
643
|
-
static {
|
|
644
|
-
__name(this, "DynamicFocus");
|
|
645
|
-
}
|
|
646
|
-
#pubsub;
|
|
647
|
-
#mapView;
|
|
648
|
-
#mapData;
|
|
649
|
-
#state = DEFAULT_STATE;
|
|
650
|
-
/**
|
|
651
|
-
* The buildings that are currently in view, sorted by the order they are in the facades-in-view-change event.
|
|
652
|
-
* While these will be within the camera view, these may not be in focus or showIndoor depending on the mode.
|
|
653
|
-
*/
|
|
654
|
-
#sortedBuildingsInView = [];
|
|
655
|
-
/**
|
|
656
|
-
* The buildings that are currently in view, as a set of building ids.
|
|
657
|
-
*/
|
|
658
|
-
#buildingIdsInViewSet = /* @__PURE__ */ new Set();
|
|
659
|
-
#buildings = /* @__PURE__ */ new Map();
|
|
660
|
-
#outdoors;
|
|
661
|
-
#userInteracting = false;
|
|
662
|
-
#pendingFacadeUpdate = false;
|
|
663
|
-
#floorElevation = 0;
|
|
664
|
-
#cameraElevation = 0;
|
|
665
|
-
/**
|
|
666
|
-
* Tracks the current zoom state based on camera zoom level:
|
|
667
|
-
* - 'in-range': Camera is zoomed in enough to show indoor details (>= indoorZoomThreshold)
|
|
668
|
-
* - 'out-of-range': Camera is zoomed out to show outdoor context (<= outdoorZoomThreshold)
|
|
669
|
-
* - 'transition': Camera is between the two thresholds (no floor changes occur)
|
|
670
|
-
*/
|
|
671
|
-
#zoomState = "transition";
|
|
672
|
-
#viewState = "outdoor";
|
|
673
|
-
/**
|
|
674
|
-
* The facades that are actually focused and shown (filtered by showIndoor logic)
|
|
675
|
-
*/
|
|
676
|
-
#facadesInFocus = [];
|
|
677
|
-
#enabled = false;
|
|
678
|
-
/**
|
|
679
|
-
* @internal
|
|
680
|
-
* Used to await the current scene update before starting a new one, or when the scene is updated asynchronously by an event.
|
|
681
|
-
*/
|
|
682
|
-
sceneUpdateQueue = Promise.resolve();
|
|
683
|
-
/**
|
|
684
|
-
* Creates a new instance of the Dynamic Focus controller.
|
|
685
|
-
*
|
|
686
|
-
* @param mapView - The {@link MapView} to attach Dynamic Focus to.
|
|
687
|
-
* @param options - Options for configuring Dynamic Focus.
|
|
688
|
-
*
|
|
689
|
-
* @example
|
|
690
|
-
* ```ts
|
|
691
|
-
* const mapView = show3dMap(...);
|
|
692
|
-
* const df = new DynamicFocus(mapView);
|
|
693
|
-
* df.enable({ autoFocus: true });
|
|
694
|
-
*
|
|
695
|
-
* // pause the listener
|
|
696
|
-
* df.updateState({ autoFocus: false });
|
|
697
|
-
*
|
|
698
|
-
* // manually trigger a focus
|
|
699
|
-
* df.focus();
|
|
700
|
-
* ```
|
|
701
|
-
*/
|
|
702
|
-
constructor(mapView) {
|
|
703
|
-
this.#pubsub = new PubSub();
|
|
704
|
-
this.#mapView = mapView;
|
|
705
|
-
Logger2.setLevel(Mappedin_Logger_default.logState);
|
|
706
|
-
this.#mapData = this.#mapView.getMapData();
|
|
707
|
-
this.#floorElevation = this.#mapView.currentFloor.elevation;
|
|
708
|
-
this.#cameraElevation = this.#mapView.Camera.elevation;
|
|
709
|
-
for (const facade of this.#mapData.getByType("facade")) {
|
|
710
|
-
this.#buildings.set(facade.floorStack.id, new Building(facade.floorStack, this.#mapView));
|
|
711
|
-
}
|
|
712
|
-
this.#outdoors = new Outdoors(
|
|
713
|
-
getOutdoorFloorStack(this.#mapData.getByType("floor-stack"), this.#buildings),
|
|
714
|
-
this.#mapView
|
|
715
|
-
);
|
|
716
|
-
this.#mapView.on("floor-change-start", this.#handleFloorChangeStart);
|
|
717
|
-
this.#mapView.on("camera-change", this.#handleCameraChange);
|
|
718
|
-
this.#mapView.on("facades-in-view-change", this.#handleFacadesInViewChange);
|
|
719
|
-
this.#mapView.on("user-interaction-start", this.#handleUserInteractionStart);
|
|
720
|
-
this.#mapView.on("user-interaction-end", this.#handleUserInteractionEnd);
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Enables Dynamic Focus with the given options.
|
|
724
|
-
* @param options - The options to enable Dynamic Focus with.
|
|
725
|
-
*/
|
|
726
|
-
enable(options) {
|
|
727
|
-
if (this.#enabled) {
|
|
728
|
-
Logger2.warn("enable() called on an already enabled Dynamic Focus instance.");
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
this.#enabled = true;
|
|
732
|
-
this.#mapView.manualFloorVisibility = true;
|
|
733
|
-
this.#outdoors.show();
|
|
734
|
-
this.updateState({ ...this.#state, ...options });
|
|
735
|
-
this.#handleCameraChange({
|
|
736
|
-
zoomLevel: this.#mapView.Camera.zoomLevel,
|
|
737
|
-
center: this.#mapView.Camera.center,
|
|
738
|
-
bearing: this.#mapView.Camera.bearing,
|
|
739
|
-
pitch: this.#mapView.Camera.pitch
|
|
740
|
-
});
|
|
741
|
-
this.#mapView.Camera.updateFacadesInView();
|
|
742
|
-
}
|
|
743
|
-
/**
|
|
744
|
-
* Disables Dynamic Focus and returns the MapView to it's previous state.
|
|
745
|
-
*/
|
|
746
|
-
disable() {
|
|
747
|
-
if (!this.#enabled) {
|
|
748
|
-
Logger2.warn("disable() called on an already disabled Dynamic Focus instance.");
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
this.#enabled = false;
|
|
752
|
-
this.#mapView.manualFloorVisibility = false;
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
* Returns true if Dynamic Focus is enabled.
|
|
756
|
-
*/
|
|
757
|
-
get isEnabled() {
|
|
758
|
-
return this.#enabled;
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Returns true if the current view state is indoor.
|
|
762
|
-
*/
|
|
763
|
-
get isIndoor() {
|
|
764
|
-
return this.#viewState === "indoor";
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Returns true if the current view state is outdoor.
|
|
768
|
-
*/
|
|
769
|
-
get isOutdoor() {
|
|
770
|
-
return this.#viewState === "outdoor";
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Sets the view state to indoor, regardless of the current zoom level.
|
|
774
|
-
*/
|
|
775
|
-
setIndoor() {
|
|
776
|
-
this.#viewState = "indoor";
|
|
777
|
-
this.#zoomState = "in-range";
|
|
778
|
-
this.#handleViewStateChange();
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Sets the view state to outdoor, regardless of the current zoom level.
|
|
782
|
-
*/
|
|
783
|
-
setOutdoor() {
|
|
784
|
-
this.#viewState = "outdoor";
|
|
785
|
-
this.#zoomState = "out-of-range";
|
|
786
|
-
this.#handleViewStateChange();
|
|
787
|
-
}
|
|
788
|
-
#handleViewStateChange() {
|
|
789
|
-
if (this.#state.autoFocus) {
|
|
790
|
-
if (this.#userInteracting) {
|
|
791
|
-
this.focus();
|
|
792
|
-
} else {
|
|
793
|
-
this.#pendingFacadeUpdate = true;
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
this.#pubsub.publish("state-change");
|
|
797
|
-
}
|
|
798
|
-
#preloadFloors(mode) {
|
|
799
|
-
this.#mapView.preloadFloors(
|
|
800
|
-
this.#mapData.getByType("facade").map((facade) => getFloorToShow(this.#buildings.get(facade.floorStack.id), mode, this.#floorElevation)).filter((f) => f != null && Floor3.is(f))
|
|
801
|
-
);
|
|
802
|
-
}
|
|
803
|
-
/**
|
|
804
|
-
* Returns the facades that are currently in focus.
|
|
805
|
-
*/
|
|
806
|
-
get focusedFacades() {
|
|
807
|
-
return [...this.#facadesInFocus];
|
|
808
|
-
}
|
|
809
|
-
/**
|
|
810
|
-
* Subscribe to a Dynamic Focus event.
|
|
811
|
-
*/
|
|
812
|
-
on = /* @__PURE__ */ __name((eventName, fn) => {
|
|
813
|
-
this.#pubsub.on(eventName, fn);
|
|
814
|
-
}, "on");
|
|
815
|
-
/**
|
|
816
|
-
* Unsubscribe from a Dynamic Focus event.
|
|
817
|
-
*/
|
|
818
|
-
off = /* @__PURE__ */ __name((eventName, fn) => {
|
|
819
|
-
this.#pubsub.off(eventName, fn);
|
|
820
|
-
}, "off");
|
|
821
|
-
/**
|
|
822
|
-
* Returns the current state of the Dynamic Focus controller.
|
|
823
|
-
*/
|
|
824
|
-
getState() {
|
|
825
|
-
return { ...this.#state };
|
|
826
|
-
}
|
|
827
|
-
/**
|
|
828
|
-
* Updates the state of the Dynamic Focus controller.
|
|
829
|
-
* @param state - The state to update.
|
|
830
|
-
*/
|
|
831
|
-
updateState(state) {
|
|
832
|
-
let shouldReapplyBuildingStates = false;
|
|
833
|
-
if (state.indoorZoomThreshold != null) {
|
|
834
|
-
state.indoorZoomThreshold = validateZoomThreshold(
|
|
835
|
-
state.indoorZoomThreshold,
|
|
836
|
-
state?.outdoorZoomThreshold ?? this.#state.outdoorZoomThreshold,
|
|
837
|
-
this.#mapView.Camera.maxZoomLevel,
|
|
838
|
-
"indoorZoomThreshold"
|
|
839
|
-
);
|
|
840
|
-
shouldReapplyBuildingStates = true;
|
|
841
|
-
}
|
|
842
|
-
if (state.outdoorZoomThreshold != null) {
|
|
843
|
-
state.outdoorZoomThreshold = validateZoomThreshold(
|
|
844
|
-
state.outdoorZoomThreshold,
|
|
845
|
-
this.#mapView.Camera.minZoomLevel,
|
|
846
|
-
state?.indoorZoomThreshold ?? this.#state.indoorZoomThreshold,
|
|
847
|
-
"outdoorZoomThreshold"
|
|
848
|
-
);
|
|
849
|
-
shouldReapplyBuildingStates = true;
|
|
850
|
-
}
|
|
851
|
-
if (state.mode != null) {
|
|
852
|
-
state.mode = DYNAMIC_FOCUS_MODES.includes(state.mode) ? state.mode : "default-floor";
|
|
853
|
-
}
|
|
854
|
-
if (state.autoAdjustFacadeHeights != null) {
|
|
855
|
-
this.#state.autoAdjustFacadeHeights = state.autoAdjustFacadeHeights;
|
|
856
|
-
}
|
|
857
|
-
if (state.dynamicBuildingInteriors != null && state.dynamicBuildingInteriors !== this.#state.dynamicBuildingInteriors) {
|
|
858
|
-
shouldReapplyBuildingStates = true;
|
|
859
|
-
}
|
|
860
|
-
this.#state = Object.assign(
|
|
861
|
-
{},
|
|
862
|
-
this.#state,
|
|
863
|
-
Object.fromEntries(Object.entries(state).filter(([, value]) => value != null))
|
|
864
|
-
);
|
|
865
|
-
if (state.mode != null && state.preloadFloors) {
|
|
866
|
-
this.#preloadFloors(state.mode);
|
|
867
|
-
}
|
|
868
|
-
if (shouldReapplyBuildingStates) {
|
|
869
|
-
this.#applyBuildingStates();
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* Destroys the Dynamic Focus instance and unsubscribes all MapView event listeners.
|
|
874
|
-
*/
|
|
875
|
-
destroy() {
|
|
876
|
-
this.disable();
|
|
877
|
-
this.#mapView.off("facades-in-view-change", this.#handleFacadesInViewChange);
|
|
878
|
-
this.#mapView.off("floor-change-start", this.#handleFloorChangeStart);
|
|
879
|
-
this.#mapView.off("camera-change", this.#handleCameraChange);
|
|
880
|
-
this.#mapView.off("user-interaction-start", this.#handleUserInteractionStart);
|
|
881
|
-
this.#mapView.off("user-interaction-end", this.#handleUserInteractionEnd);
|
|
882
|
-
this.#buildings.forEach((building) => building.destroy());
|
|
883
|
-
this.#outdoors.destroy();
|
|
884
|
-
this.#pubsub.destroy();
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Perform a manual visual update of the focused facades, and optionally set the floor.
|
|
888
|
-
* @param setFloor - Whether to set the floor. This will default to the current state of setFloorOnFocus.
|
|
889
|
-
*/
|
|
890
|
-
async focus(setFloor = this.#state.setFloorOnFocus) {
|
|
891
|
-
if (setFloor) {
|
|
892
|
-
if (shouldDeferSetFloor(this.#cameraElevation, this.#mapView.Camera.elevation, this.#userInteracting)) {
|
|
893
|
-
this.#cameraElevation = this.#mapView.Camera.elevation;
|
|
894
|
-
this.#pendingFacadeUpdate = true;
|
|
895
|
-
} else {
|
|
896
|
-
const target = getSetFloorTargetFromZoomState(this.#sortedBuildingsInView, this.#outdoors, this.#zoomState);
|
|
897
|
-
const floor = target ? getFloorToShow(target, this.#state.mode, this.#floorElevation) : void 0;
|
|
898
|
-
if (floor && floor.id !== this.#mapView.currentFloor.id) {
|
|
899
|
-
this.#mapView.setFloor(floor, { context: "dynamic-focus" });
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
await this.#applyBuildingStates();
|
|
904
|
-
this.#pubsub.publish("focus", { facades: this.focusedFacades });
|
|
905
|
-
}
|
|
906
|
-
/**
|
|
907
|
-
* Preloads the initial floors for each building to improve performance when rendering the building for the first time. See {@link DynamicFocusState.preloadFloors}.
|
|
908
|
-
*/
|
|
909
|
-
preloadFloors() {
|
|
910
|
-
this.#preloadFloors(this.#state.mode);
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Sets the default floor for a floor stack. This is the floor that will be shown when focusing on a facade if there is no currently active floor in the stack.
|
|
914
|
-
* See {@link resetDefaultFloorForStack} to reset the default floor.
|
|
915
|
-
* @param floorStack - The floor stack to set the default floor for.
|
|
916
|
-
* @param floor - The floor to set as the default floor.
|
|
917
|
-
*/
|
|
918
|
-
setDefaultFloorForStack(floorStack, floor) {
|
|
919
|
-
if (!validateFloorForStack(floor, floorStack)) {
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
const building = this.#buildings.get(floorStack.id);
|
|
923
|
-
if (building) {
|
|
924
|
-
building.defaultFloor = floor;
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Resets the default floor for a floor stack to it's initial value.
|
|
929
|
-
* @param floorStack - The floor stack to reset the default floor for.
|
|
930
|
-
*/
|
|
931
|
-
resetDefaultFloorForStack(floorStack) {
|
|
932
|
-
const building = this.#buildings.get(floorStack.id);
|
|
933
|
-
if (building) {
|
|
934
|
-
building.defaultFloor = floorStack.defaultFloor;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
/**
|
|
938
|
-
* Returns the current default floor for a floor stack.
|
|
939
|
-
* @param floorStack - The floor stack to get the default floor for.
|
|
940
|
-
* @returns The current default floor for the floor stack.
|
|
941
|
-
*/
|
|
942
|
-
getDefaultFloorForStack(floorStack) {
|
|
943
|
-
return this.#buildings.get(floorStack.id)?.defaultFloor || floorStack.defaultFloor || floorStack.floors[0];
|
|
944
|
-
}
|
|
945
|
-
/**
|
|
946
|
-
* Sets the current floor for a floor stack. If the floor stack is currently focused, this floor will become visible.
|
|
947
|
-
* @param floorStack - The floor stack to set the current floor for.
|
|
948
|
-
*/
|
|
949
|
-
setCurrentFloorForStack(floorStack, floor) {
|
|
950
|
-
if (!validateFloorForStack(floor, floorStack)) {
|
|
951
|
-
return;
|
|
952
|
-
}
|
|
953
|
-
const building = this.#buildings.get(floorStack.id);
|
|
954
|
-
if (building) {
|
|
955
|
-
building.activeFloor = floor;
|
|
956
|
-
this.#applyBuildingStates();
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
/**
|
|
960
|
-
* Excludes a floor stack from visibility changes.
|
|
961
|
-
* @param excluded - The floor stack or stacks to exclude.
|
|
962
|
-
*/
|
|
963
|
-
exclude(excluded) {
|
|
964
|
-
const excludedFloorStacks = Array.isArray(excluded) ? excluded : [excluded];
|
|
965
|
-
for (const floorStack of excludedFloorStacks) {
|
|
966
|
-
const building = this.#buildings.get(floorStack.id);
|
|
967
|
-
if (building) {
|
|
968
|
-
building.excluded = true;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
/**
|
|
973
|
-
* Includes a floor stack in visibility changes.
|
|
974
|
-
* @param included - The floor stack or stacks to include.
|
|
975
|
-
*/
|
|
976
|
-
include(included) {
|
|
977
|
-
const includedFloorStacks = Array.isArray(included) ? included : [included];
|
|
978
|
-
for (const floorStack of includedFloorStacks) {
|
|
979
|
-
const building = this.#buildings.get(floorStack.id);
|
|
980
|
-
if (building) {
|
|
981
|
-
building.excluded = false;
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* Returns the current floor for a floor stack.
|
|
987
|
-
* @param floorStack - The floor stack to get the current floor for.
|
|
988
|
-
* @returns The current floor for the floor stack.
|
|
989
|
-
*/
|
|
990
|
-
getCurrentFloorForStack(floorStack) {
|
|
991
|
-
return this.#buildings.get(floorStack.id)?.activeFloor || this.getDefaultFloorForStack(floorStack);
|
|
992
|
-
}
|
|
993
|
-
/**
|
|
994
|
-
* Handles management of focused facades but doesn't trigger view updates unless enabled.
|
|
995
|
-
* @see {@link focus} to manually trigger a view update.
|
|
996
|
-
*/
|
|
997
|
-
#handleFacadesInViewChange = /* @__PURE__ */ __name((event) => {
|
|
998
|
-
if (!this.isEnabled) {
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
const { facades } = event;
|
|
1002
|
-
if (arraysEqual(facades, this.focusedFacades) && this.#viewState === "transition" && !this.#pendingFacadeUpdate) {
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
this.#pendingFacadeUpdate = false;
|
|
1006
|
-
this.#sortedBuildingsInView = [];
|
|
1007
|
-
this.#buildingIdsInViewSet.clear();
|
|
1008
|
-
if (facades.length > 0) {
|
|
1009
|
-
for (const facade of facades) {
|
|
1010
|
-
const building = this.#buildings.get(facade.floorStack.id);
|
|
1011
|
-
if (building) {
|
|
1012
|
-
this.#buildingIdsInViewSet.add(building.id);
|
|
1013
|
-
this.#sortedBuildingsInView.push(building);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
if (this.#state.autoFocus) {
|
|
1018
|
-
this.focus();
|
|
1019
|
-
}
|
|
1020
|
-
}, "#handleFacadesInViewChange");
|
|
1021
|
-
/**
|
|
1022
|
-
* Handles floor and facade visibility when the floor changes.
|
|
1023
|
-
*/
|
|
1024
|
-
#handleFloorChangeStart = /* @__PURE__ */ __name(async (event) => {
|
|
1025
|
-
if (!this.isEnabled) {
|
|
1026
|
-
return;
|
|
1027
|
-
}
|
|
1028
|
-
const { floor: newFloor } = event;
|
|
1029
|
-
const building = this.#buildings.get(newFloor.floorStack.id);
|
|
1030
|
-
if (building) {
|
|
1031
|
-
building.activeFloor = newFloor;
|
|
1032
|
-
}
|
|
1033
|
-
if (building?.excluded === false && !this.#outdoors.matchesFloorStack(newFloor.floorStack)) {
|
|
1034
|
-
this.#floorElevation = newFloor.elevation;
|
|
1035
|
-
}
|
|
1036
|
-
if (this.#mapView.manualFloorVisibility === true) {
|
|
1037
|
-
if (event.reason !== "dynamic-focus") {
|
|
1038
|
-
await this.#applyBuildingStates(newFloor);
|
|
1039
|
-
this.#pubsub.publish("focus", { facades: this.focusedFacades });
|
|
1040
|
-
}
|
|
1041
|
-
const altitude = building?.floorsAltitudesMap.get(newFloor.elevation)?.altitude ?? 0;
|
|
1042
|
-
if (this.#mapView.options.multiFloorView != null && this.#mapView.options.multiFloorView?.enabled && this.#mapView.options.multiFloorView?.updateCameraElevationOnFloorChange && this.#mapView.Camera.elevation !== altitude) {
|
|
1043
|
-
this.#mapView.Camera.animateElevation(altitude, {
|
|
1044
|
-
duration: 750,
|
|
1045
|
-
easing: "ease-in-out"
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
}, "#handleFloorChangeStart");
|
|
1050
|
-
#handleUserInteractionStart = /* @__PURE__ */ __name(() => {
|
|
1051
|
-
this.#userInteracting = true;
|
|
1052
|
-
}, "#handleUserInteractionStart");
|
|
1053
|
-
#handleUserInteractionEnd = /* @__PURE__ */ __name(() => {
|
|
1054
|
-
this.#userInteracting = false;
|
|
1055
|
-
}, "#handleUserInteractionEnd");
|
|
1056
|
-
/**
|
|
1057
|
-
* Handles camera moving in and out of zoom range and fires a focus event if the camera is in range.
|
|
1058
|
-
*/
|
|
1059
|
-
#handleCameraChange = /* @__PURE__ */ __name((event) => {
|
|
1060
|
-
if (!this.isEnabled) {
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
const { zoomLevel } = event;
|
|
1064
|
-
const newZoomState = getZoomState(zoomLevel, this.#state.indoorZoomThreshold, this.#state.outdoorZoomThreshold);
|
|
1065
|
-
if (this.#zoomState !== newZoomState) {
|
|
1066
|
-
this.#zoomState = newZoomState;
|
|
1067
|
-
if (newZoomState === "in-range") {
|
|
1068
|
-
this.setIndoor();
|
|
1069
|
-
} else if (newZoomState === "out-of-range") {
|
|
1070
|
-
this.setOutdoor();
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
}, "#handleCameraChange");
|
|
1074
|
-
#updateFloorVisibility(floorStates, shouldShow, inFocus) {
|
|
1075
|
-
floorStates.forEach((floorState) => {
|
|
1076
|
-
if (floorState.floor) {
|
|
1077
|
-
if (shouldShow) {
|
|
1078
|
-
const state = inFocus !== void 0 ? {
|
|
1079
|
-
...floorState.state,
|
|
1080
|
-
labels: {
|
|
1081
|
-
...floorState.state.labels,
|
|
1082
|
-
enabled: floorState.state.labels.enabled && inFocus
|
|
1083
|
-
},
|
|
1084
|
-
markers: {
|
|
1085
|
-
...floorState.state.markers,
|
|
1086
|
-
enabled: floorState.state.markers.enabled && inFocus
|
|
1087
|
-
},
|
|
1088
|
-
occlusion: {
|
|
1089
|
-
...floorState.state.occlusion,
|
|
1090
|
-
// We don't want this floor to occlude if it's not in focus
|
|
1091
|
-
// Allows us to show a label above this floor while it's not active
|
|
1092
|
-
enabled: floorState.state.occlusion.enabled && inFocus
|
|
1093
|
-
}
|
|
1094
|
-
} : floorState.state;
|
|
1095
|
-
this.#mapView.updateState(floorState.floor, state);
|
|
1096
|
-
} else {
|
|
1097
|
-
this.#mapView.updateState(floorState.floor, { visible: false });
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
}
|
|
1102
|
-
async #animateIndoorSequence(building, floorStackState, facadeState, inFocus) {
|
|
1103
|
-
this.#updateFloorVisibility(floorStackState.floorStates, true, inFocus);
|
|
1104
|
-
return building.animateFacade(facadeState.state, this.#state.indoorAnimationOptions);
|
|
1105
|
-
}
|
|
1106
|
-
async #animateOutdoorSequence(building, floorStackState, facadeState, floorStackIdsInNavigation) {
|
|
1107
|
-
const result = await building.animateFacade(facadeState.state, this.#state.outdoorAnimationOptions);
|
|
1108
|
-
if (result.result === "completed") {
|
|
1109
|
-
this.#updateFloorVisibility(
|
|
1110
|
-
floorStackState.floorStates,
|
|
1111
|
-
shouldShowIndoor(
|
|
1112
|
-
building,
|
|
1113
|
-
this.#mapView.currentFloor,
|
|
1114
|
-
this.#zoomState === "in-range",
|
|
1115
|
-
this.#buildingIdsInViewSet.has(building.id),
|
|
1116
|
-
this.#state.mode,
|
|
1117
|
-
this.#floorElevation,
|
|
1118
|
-
floorStackIdsInNavigation.includes(building.floorStack.id),
|
|
1119
|
-
this.#state.dynamicBuildingInteriors
|
|
1120
|
-
)
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
return result;
|
|
1124
|
-
}
|
|
1125
|
-
#applyBuildingStates = /* @__PURE__ */ __name(async (newFloor) => {
|
|
1126
|
-
if (this.#mapView.manualFloorVisibility !== true || !this.isEnabled) {
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
const currentFloor = newFloor || this.#mapView.currentFloor;
|
|
1130
|
-
const multiFloorView = this.#mapView.options.multiFloorView;
|
|
1131
|
-
const floorIdsInNavigation = this.#mapView.Navigation?.floors?.map((f) => f.id) || [];
|
|
1132
|
-
const floorStackIdsInNavigation = this.#mapView.Navigation?.floorStacks.map((fs) => fs.id) || [];
|
|
1133
|
-
const updatePromise = new Promise(async (resolve) => {
|
|
1134
|
-
await this.sceneUpdateQueue;
|
|
1135
|
-
const buildingStates = getBuildingStates(
|
|
1136
|
-
Array.from(this.#buildings.values()),
|
|
1137
|
-
this.#buildingIdsInViewSet,
|
|
1138
|
-
currentFloor,
|
|
1139
|
-
this.#zoomState,
|
|
1140
|
-
this.#state.mode,
|
|
1141
|
-
this.#floorElevation,
|
|
1142
|
-
floorIdsInNavigation,
|
|
1143
|
-
floorStackIdsInNavigation,
|
|
1144
|
-
multiFloorView,
|
|
1145
|
-
this.#state.customMultiFloorVisibilityState ?? getMultiFloorState2,
|
|
1146
|
-
this.#state.dynamicBuildingInteriors
|
|
1147
|
-
);
|
|
1148
|
-
const floorStackStates = [];
|
|
1149
|
-
await Promise.all(
|
|
1150
|
-
Array.from(buildingStates.values()).map(async (buildingState) => {
|
|
1151
|
-
const { building, showIndoor, floorStackState, facadeState, inFocus } = buildingState;
|
|
1152
|
-
floorStackStates.push(floorStackState);
|
|
1153
|
-
const animation = getBuildingAnimationType(building, showIndoor);
|
|
1154
|
-
if (animation === "indoor") {
|
|
1155
|
-
return this.#animateIndoorSequence(building, floorStackState, facadeState, inFocus);
|
|
1156
|
-
} else if (animation === "outdoor") {
|
|
1157
|
-
return this.#animateOutdoorSequence(building, floorStackState, facadeState, floorStackIdsInNavigation);
|
|
1158
|
-
}
|
|
1159
|
-
})
|
|
1160
|
-
);
|
|
1161
|
-
this.#mapView.Outdoor.setOpacity(getOutdoorOpacity(floorStackStates, this.#state.mode));
|
|
1162
|
-
this.#facadesInFocus = this.#sortedBuildingsInView.filter((building) => buildingStates.get(building.id)?.showIndoor === true).map((building) => building.facade);
|
|
1163
|
-
this.#pubsub.publish("focus", { facades: this.#facadesInFocus });
|
|
1164
|
-
resolve();
|
|
1165
|
-
});
|
|
1166
|
-
this.sceneUpdateQueue = updatePromise;
|
|
1167
|
-
return updatePromise;
|
|
1168
|
-
}, "#applyBuildingStates");
|
|
1169
|
-
};
|
|
1170
|
-
|
|
1171
|
-
export {
|
|
1172
|
-
__name,
|
|
1173
|
-
DynamicFocus
|
|
1174
|
-
};
|
|
1175
|
-
//# sourceMappingURL=chunk-RSECYADN.js.map
|