venue-js 1.0.0 → 1.1.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +94 -44
- package/dist/index.d.ts +94 -44
- package/dist/index.js +876 -798
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +822 -746
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -6
package/dist/index.mjs
CHANGED
|
@@ -144,7 +144,6 @@ var createPopulator = ({
|
|
|
144
144
|
const populateDetail = (detail) => Promise.resolve(detail);
|
|
145
145
|
const populateFootprint = (footprint) => Promise.resolve(footprint);
|
|
146
146
|
const populateGeofence = (geofence) => Promise.resolve(geofence);
|
|
147
|
-
const populateOpening = (opening) => Promise.resolve(opening);
|
|
148
147
|
const populateRelationship = (relationship) => Promise.resolve(relationship);
|
|
149
148
|
const populatePrivilege = (privilege) => Promise.resolve(privilege);
|
|
150
149
|
const populateEvent = (event) => Promise.resolve(event);
|
|
@@ -220,8 +219,11 @@ var createPopulator = ({
|
|
|
220
219
|
const unit = units.find(
|
|
221
220
|
(unit2) => unit2.properties.category === "walkway" && unit2.properties.level_id === kiosk.properties.level_id && booleanWithin(kiosk, unit2)
|
|
222
221
|
);
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
let section = null;
|
|
223
|
+
if (anchor) {
|
|
224
|
+
const sections = await internalFilterByType("section");
|
|
225
|
+
section = sections.find((section2) => booleanWithin(anchor, section2));
|
|
226
|
+
}
|
|
225
227
|
return {
|
|
226
228
|
...kiosk,
|
|
227
229
|
properties: {
|
|
@@ -290,6 +292,18 @@ var createPopulator = ({
|
|
|
290
292
|
}
|
|
291
293
|
};
|
|
292
294
|
};
|
|
295
|
+
const populateOpening = async (opening) => {
|
|
296
|
+
const venue = await internalFindById(opening.properties.venue_id);
|
|
297
|
+
const level = await internalFindById(opening.properties.level_id);
|
|
298
|
+
return {
|
|
299
|
+
...opening,
|
|
300
|
+
properties: {
|
|
301
|
+
venue,
|
|
302
|
+
level: await populateLevel(level),
|
|
303
|
+
ordinal: level.properties.ordinal
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
};
|
|
293
307
|
const populateSection = async (section) => {
|
|
294
308
|
const venue = await internalFindById(section.properties.venue_id);
|
|
295
309
|
const level = await internalFindById(section.properties.level_id);
|
|
@@ -307,17 +321,21 @@ var createPopulator = ({
|
|
|
307
321
|
const venue = await internalFindById(unit.properties.venue_id);
|
|
308
322
|
const level = await internalFindById(unit.properties.level_id);
|
|
309
323
|
const sections = await internalFilterByType("section");
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
324
|
+
try {
|
|
325
|
+
const section = unit.geometry.type !== "MultiPolygon" ? sections.find((section2) => booleanWithin(unit, section2)) : null;
|
|
326
|
+
return {
|
|
327
|
+
...unit,
|
|
328
|
+
properties: {
|
|
329
|
+
...unit.properties,
|
|
330
|
+
venue,
|
|
331
|
+
ordinal: level.properties.ordinal,
|
|
332
|
+
level: await populateLevel(level),
|
|
333
|
+
section: section ? await populateSection(section) : null
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
} catch (err) {
|
|
337
|
+
console.log(`error finding section `, { unit, sections });
|
|
338
|
+
}
|
|
321
339
|
};
|
|
322
340
|
const populateVenue = (venue) => {
|
|
323
341
|
return Promise.resolve(venue);
|
|
@@ -360,6 +378,26 @@ var createPopulator = ({
|
|
|
360
378
|
};
|
|
361
379
|
};
|
|
362
380
|
|
|
381
|
+
// src/data/utils/match-filters.ts
|
|
382
|
+
function isInFilter(filter) {
|
|
383
|
+
return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
|
|
384
|
+
}
|
|
385
|
+
var someIntersect = (a, b) => a.some((v) => b.includes(v));
|
|
386
|
+
function matchFilter(value, filter) {
|
|
387
|
+
if (Array.isArray(value)) {
|
|
388
|
+
if (isInFilter(filter)) return someIntersect(value, filter.$in);
|
|
389
|
+
return value.includes(filter);
|
|
390
|
+
} else {
|
|
391
|
+
if (isInFilter(filter)) return filter.$in.includes(value);
|
|
392
|
+
return value === filter;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function matchFilters(item, filters) {
|
|
396
|
+
return Object.entries(filters).every(([key, filter]) => {
|
|
397
|
+
return matchFilter(item.properties[key], filter);
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
363
401
|
// src/data/getDataClient.ts
|
|
364
402
|
var getDataClient = (options) => {
|
|
365
403
|
const observers = /* @__PURE__ */ new Map();
|
|
@@ -435,7 +473,12 @@ var getDataClient = (options) => {
|
|
|
435
473
|
queryKey: [featureType, "list", params],
|
|
436
474
|
queryFn: async () => {
|
|
437
475
|
const features = await internalFilterByType(featureType);
|
|
438
|
-
|
|
476
|
+
const filters = params.filters ?? {};
|
|
477
|
+
let result = features;
|
|
478
|
+
if (params.filters) {
|
|
479
|
+
result = features.filter((f) => matchFilters(f, filters));
|
|
480
|
+
}
|
|
481
|
+
return params.populate === true ? await Promise.all(result.map((f) => populator[featureType](f))) : result;
|
|
439
482
|
},
|
|
440
483
|
...options2 ?? {}
|
|
441
484
|
});
|
|
@@ -482,13 +525,11 @@ import {
|
|
|
482
525
|
ui as ui3,
|
|
483
526
|
Map as Map2,
|
|
484
527
|
TileLayer,
|
|
485
|
-
VectorLayer as VectorLayer2,
|
|
486
528
|
Extent,
|
|
487
529
|
LineString as LineString3,
|
|
488
|
-
animation,
|
|
489
530
|
Marker as Marker2,
|
|
490
|
-
Coordinate as
|
|
491
|
-
} from "maptalks";
|
|
531
|
+
Coordinate as Coordinate4
|
|
532
|
+
} from "maptalks-gl";
|
|
492
533
|
import TWEEN2 from "@tweenjs/tween.js";
|
|
493
534
|
import _6 from "lodash";
|
|
494
535
|
|
|
@@ -569,7 +610,7 @@ function isNumber(num) {
|
|
|
569
610
|
|
|
570
611
|
// src/IndoorMap/IndoorMap.ts
|
|
571
612
|
import turfDistance from "@turf/distance";
|
|
572
|
-
import
|
|
613
|
+
import turfCenter3 from "@turf/center";
|
|
573
614
|
|
|
574
615
|
// ../../node_modules/@turf/meta/dist/esm/index.js
|
|
575
616
|
function coordEach(geojson, callback, excludeWrapCoord) {
|
|
@@ -691,13 +732,12 @@ function bbox(geojson, options = {}) {
|
|
|
691
732
|
});
|
|
692
733
|
return result;
|
|
693
734
|
}
|
|
694
|
-
var
|
|
735
|
+
var index_default = bbox;
|
|
695
736
|
|
|
696
737
|
// src/IndoorMap/IndoorMap.ts
|
|
697
738
|
import scale from "@turf/transform-scale";
|
|
698
739
|
import bboxPolygon from "@turf/bbox-polygon";
|
|
699
740
|
import { PerspectiveCamera } from "three";
|
|
700
|
-
import { ThreeLayer as ThreeLayer4 } from "maptalks.three";
|
|
701
741
|
|
|
702
742
|
// src/IndoorMap/constants.ts
|
|
703
743
|
var defaultLayerOption = { enableAltitude: true };
|
|
@@ -1442,10 +1482,8 @@ var GeometryType = {
|
|
|
1442
1482
|
var ORDINAL_HEIGHT = 0;
|
|
1443
1483
|
var VENUE_Z_INDEX = 0;
|
|
1444
1484
|
var LEVEL_Z_INDEX = 2;
|
|
1445
|
-
var UNIT_Z_INDEX = 3;
|
|
1446
1485
|
var FIXTURE_Z_INDEX = 4;
|
|
1447
1486
|
var DECORATION_Z_INDEX = 4;
|
|
1448
|
-
var KIOSK_Z_INDEX = 5;
|
|
1449
1487
|
var OPENING_Z_INDEX = 3;
|
|
1450
1488
|
var SECTION_Z_INDEX = 6;
|
|
1451
1489
|
var USER_LOCATION_Z_INDEX = 99;
|
|
@@ -1533,77 +1571,6 @@ var SPRITE_HIGHLIGHT_MARKER_FEATURE = SPRITE_MARKER_FEATURE.map(
|
|
|
1533
1571
|
);
|
|
1534
1572
|
var OCCUPANT_TEXT_MARKER_CLASSNAME = "mtk-occupant-text-marker";
|
|
1535
1573
|
var getAltitude = (properties) => Math.max(0, properties.ordinal * ORDINAL_HEIGHT || 0);
|
|
1536
|
-
var createRoomUnit = (feature2, style, options) => {
|
|
1537
|
-
const { geometry, id, properties } = feature2;
|
|
1538
|
-
const { allowOverride, inheritFillColorToLine } = options;
|
|
1539
|
-
const symbolStyle = { ...style };
|
|
1540
|
-
if (allowOverride) _4.merge(symbolStyle, properties.style);
|
|
1541
|
-
if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
|
|
1542
|
-
return new GeometryType[geometry.type](geometry.coordinates, {
|
|
1543
|
-
properties: {
|
|
1544
|
-
id,
|
|
1545
|
-
feature_type: "unit",
|
|
1546
|
-
category: properties.category,
|
|
1547
|
-
altitude: getAltitude(properties)
|
|
1548
|
-
},
|
|
1549
|
-
symbol: symbolStyle,
|
|
1550
|
-
defaultSymbol: symbolStyle
|
|
1551
|
-
});
|
|
1552
|
-
};
|
|
1553
|
-
var createAmenityUnit = (feature2, style, options = {}) => {
|
|
1554
|
-
const { geometry, id, properties } = feature2;
|
|
1555
|
-
const { allowOverride, inheritFillColorToLine } = options;
|
|
1556
|
-
const symbolStyle = { ...style };
|
|
1557
|
-
if (allowOverride) _4.merge(symbolStyle, properties.style);
|
|
1558
|
-
if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
|
|
1559
|
-
const area = new GeometryType[geometry.type](geometry.coordinates, {
|
|
1560
|
-
properties: {
|
|
1561
|
-
id,
|
|
1562
|
-
feature_type: "unit",
|
|
1563
|
-
category: properties.category,
|
|
1564
|
-
altitude: getAltitude(properties)
|
|
1565
|
-
},
|
|
1566
|
-
symbol: symbolStyle,
|
|
1567
|
-
defaultSymbol: symbolStyle
|
|
1568
|
-
});
|
|
1569
|
-
return area;
|
|
1570
|
-
};
|
|
1571
|
-
var createNonpublicUnit = (feature2, style, options = {}) => {
|
|
1572
|
-
const { geometry, id, properties } = feature2;
|
|
1573
|
-
const { allowOverride, inheritFillColorToLine } = options;
|
|
1574
|
-
const symbolStyle = { ...style };
|
|
1575
|
-
if (allowOverride) _4.merge(symbolStyle, properties.style);
|
|
1576
|
-
if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
|
|
1577
|
-
return new GeometryType[geometry.type](geometry.coordinates, {
|
|
1578
|
-
properties: {
|
|
1579
|
-
id,
|
|
1580
|
-
feature_type: "unit",
|
|
1581
|
-
category: properties.category,
|
|
1582
|
-
altitude: getAltitude(properties)
|
|
1583
|
-
},
|
|
1584
|
-
symbol: {
|
|
1585
|
-
...style
|
|
1586
|
-
}
|
|
1587
|
-
});
|
|
1588
|
-
};
|
|
1589
|
-
var createWalkwayUnit = (feature2, style, options) => {
|
|
1590
|
-
const { geometry, id, properties } = feature2;
|
|
1591
|
-
const { allowOverride, inheritFillColorToLine } = options;
|
|
1592
|
-
const symbolStyle = { ...style };
|
|
1593
|
-
if (allowOverride) _4.merge(symbolStyle, properties.style);
|
|
1594
|
-
if (inheritFillColorToLine) symbolStyle.lineColor = symbolStyle.polygonFill;
|
|
1595
|
-
return new GeometryType[geometry.type](geometry.coordinates, {
|
|
1596
|
-
properties: {
|
|
1597
|
-
id,
|
|
1598
|
-
feature_type: "unit",
|
|
1599
|
-
category: properties.category,
|
|
1600
|
-
altitude: getAltitude(properties)
|
|
1601
|
-
},
|
|
1602
|
-
symbol: {
|
|
1603
|
-
...symbolStyle
|
|
1604
|
-
}
|
|
1605
|
-
});
|
|
1606
|
-
};
|
|
1607
1574
|
var createWaterFixture = (feature2, style, options = {}) => {
|
|
1608
1575
|
const { geometry, properties } = feature2;
|
|
1609
1576
|
const { allowOverride, inheritFillColorToLine, zIndex } = options;
|
|
@@ -2155,62 +2122,6 @@ var styledFeatureGenerator = (mapTheme) => {
|
|
|
2155
2122
|
zIndex: LEVEL_Z_INDEX
|
|
2156
2123
|
});
|
|
2157
2124
|
},
|
|
2158
|
-
createUnit: (feature2) => {
|
|
2159
|
-
const {
|
|
2160
|
-
feature_type,
|
|
2161
|
-
properties: { category }
|
|
2162
|
-
} = feature2;
|
|
2163
|
-
const elementStyle = getElementSymbol(`${feature_type}.${category}`);
|
|
2164
|
-
const options = getElementOptions(`${feature_type}.${category}`);
|
|
2165
|
-
const zIndex = UNIT_Z_INDEX;
|
|
2166
|
-
switch (feature2.properties.category) {
|
|
2167
|
-
case "room":
|
|
2168
|
-
case "terrace":
|
|
2169
|
-
case "unenclosedarea":
|
|
2170
|
-
case "vegetation":
|
|
2171
|
-
case "unspecified":
|
|
2172
|
-
case "recreation":
|
|
2173
|
-
return createRoomUnit(feature2, elementStyle, options).setZIndex(
|
|
2174
|
-
zIndex
|
|
2175
|
-
);
|
|
2176
|
-
case "firstaid":
|
|
2177
|
-
case "restroom":
|
|
2178
|
-
case "restroom.female":
|
|
2179
|
-
case "restroom.male":
|
|
2180
|
-
case "escalator":
|
|
2181
|
-
case "elevator":
|
|
2182
|
-
case "stairs":
|
|
2183
|
-
case "stairs.emergencyexit":
|
|
2184
|
-
case "parking":
|
|
2185
|
-
case "smokingarea":
|
|
2186
|
-
case "mothersroom":
|
|
2187
|
-
case "privatelounge":
|
|
2188
|
-
case "shuttle":
|
|
2189
|
-
case "fieldofplay":
|
|
2190
|
-
return createAmenityUnit(feature2, elementStyle, options).setZIndex(
|
|
2191
|
-
zIndex
|
|
2192
|
-
);
|
|
2193
|
-
case "nonpublic":
|
|
2194
|
-
case "structure":
|
|
2195
|
-
case "brick":
|
|
2196
|
-
case "concrete":
|
|
2197
|
-
case "drywall":
|
|
2198
|
-
case "glass":
|
|
2199
|
-
case "wood":
|
|
2200
|
-
case "column":
|
|
2201
|
-
case "opentobelow":
|
|
2202
|
-
return createNonpublicUnit(feature2, elementStyle, options).setZIndex(
|
|
2203
|
-
zIndex
|
|
2204
|
-
);
|
|
2205
|
-
case "walkway":
|
|
2206
|
-
case "footbridge":
|
|
2207
|
-
return createWalkwayUnit(feature2, elementStyle, options).setZIndex(
|
|
2208
|
-
zIndex - 1
|
|
2209
|
-
);
|
|
2210
|
-
default:
|
|
2211
|
-
break;
|
|
2212
|
-
}
|
|
2213
|
-
},
|
|
2214
2125
|
createMarker: (feature2) => {
|
|
2215
2126
|
try {
|
|
2216
2127
|
const { geometry, properties } = feature2;
|
|
@@ -2395,32 +2306,6 @@ var styledFeatureGenerator = (mapTheme) => {
|
|
|
2395
2306
|
symbol
|
|
2396
2307
|
});
|
|
2397
2308
|
},
|
|
2398
|
-
createKiosk: (feature2) => {
|
|
2399
|
-
const { geometry, feature_type, properties, id } = feature2;
|
|
2400
|
-
const {
|
|
2401
|
-
properties: { category }
|
|
2402
|
-
} = feature2;
|
|
2403
|
-
const elementStyle = getElementSymbol(`${feature_type}.${category}`);
|
|
2404
|
-
const options = getElementOptions(
|
|
2405
|
-
`${feature_type}.${category}.geometry.options`
|
|
2406
|
-
);
|
|
2407
|
-
const { allowOverride, inheritFillColorToLine } = options;
|
|
2408
|
-
const symbolStyle = { ...elementStyle };
|
|
2409
|
-
if (allowOverride) _4.merge(symbolStyle, properties.style);
|
|
2410
|
-
if (inheritFillColorToLine)
|
|
2411
|
-
symbolStyle.lineColor = symbolStyle.polygonFill;
|
|
2412
|
-
return new GeometryType[geometry.type](geometry.coordinates, {
|
|
2413
|
-
properties: {
|
|
2414
|
-
id,
|
|
2415
|
-
feature_type,
|
|
2416
|
-
category: "kiosk",
|
|
2417
|
-
altitude: getAltitude(properties)
|
|
2418
|
-
},
|
|
2419
|
-
symbol: symbolStyle,
|
|
2420
|
-
defaultSymbol: symbolStyle,
|
|
2421
|
-
zIndex: KIOSK_Z_INDEX
|
|
2422
|
-
});
|
|
2423
|
-
},
|
|
2424
2309
|
createSection: (feature2) => {
|
|
2425
2310
|
const { properties, feature_type } = feature2;
|
|
2426
2311
|
const { category } = properties;
|
|
@@ -2793,43 +2678,6 @@ var styledFeatureGenerator = (mapTheme) => {
|
|
|
2793
2678
|
markerProperties
|
|
2794
2679
|
);
|
|
2795
2680
|
},
|
|
2796
|
-
create3DUnit: async (unit, threeLayer) => {
|
|
2797
|
-
const { id, feature_type, properties } = unit;
|
|
2798
|
-
const { category, ordinal, model3d } = properties;
|
|
2799
|
-
const modelProperty = {
|
|
2800
|
-
id,
|
|
2801
|
-
feature_type,
|
|
2802
|
-
category,
|
|
2803
|
-
ordinal
|
|
2804
|
-
};
|
|
2805
|
-
const center2 = turfCenter(unit);
|
|
2806
|
-
const coordinate = _4.get(center2, "geometry.coordinates");
|
|
2807
|
-
const models = await create3DModels(
|
|
2808
|
-
model3d,
|
|
2809
|
-
coordinate,
|
|
2810
|
-
modelProperty,
|
|
2811
|
-
threeLayer
|
|
2812
|
-
);
|
|
2813
|
-
return models;
|
|
2814
|
-
},
|
|
2815
|
-
create3DKiosk: async (kiosk, threeLayer) => {
|
|
2816
|
-
const { id, feature_type, properties } = kiosk;
|
|
2817
|
-
const { ordinal, model3d } = properties;
|
|
2818
|
-
const modelProperty = {
|
|
2819
|
-
id,
|
|
2820
|
-
feature_type,
|
|
2821
|
-
ordinal
|
|
2822
|
-
};
|
|
2823
|
-
const center2 = turfCenter(kiosk);
|
|
2824
|
-
const coordinate = _4.get(center2, "geometry.coordinates");
|
|
2825
|
-
const models = await create3DModels(
|
|
2826
|
-
model3d,
|
|
2827
|
-
coordinate,
|
|
2828
|
-
modelProperty,
|
|
2829
|
-
threeLayer
|
|
2830
|
-
);
|
|
2831
|
-
return models;
|
|
2832
|
-
},
|
|
2833
2681
|
createVenue3DModel: async (venue, threeLayer) => {
|
|
2834
2682
|
const { id, feature_type, properties } = venue;
|
|
2835
2683
|
const { category, model3d } = properties;
|
|
@@ -2908,52 +2756,6 @@ var styledFeatureGenerator = (mapTheme) => {
|
|
|
2908
2756
|
);
|
|
2909
2757
|
return object;
|
|
2910
2758
|
},
|
|
2911
|
-
createExtrudedKiosk: (kiosk, threeLayer, options) => {
|
|
2912
|
-
const extrudeHeight = _4.get(options, "height");
|
|
2913
|
-
if (!extrudeHeight) return;
|
|
2914
|
-
const kioskProperty = getFeatureProperties(kiosk);
|
|
2915
|
-
const options3d = {
|
|
2916
|
-
offset: -0.1,
|
|
2917
|
-
altitude: _4.get(options, "altitude", 0)
|
|
2918
|
-
};
|
|
2919
|
-
const color = kioskProperty.defaultColor;
|
|
2920
|
-
if (color === "transparent") return;
|
|
2921
|
-
const material = new MeshLambertMaterial({
|
|
2922
|
-
color,
|
|
2923
|
-
transparent: true
|
|
2924
|
-
});
|
|
2925
|
-
const object = createExtrudePolygon(
|
|
2926
|
-
kiosk.geometry,
|
|
2927
|
-
threeLayer,
|
|
2928
|
-
material,
|
|
2929
|
-
extrudeHeight,
|
|
2930
|
-
kioskProperty,
|
|
2931
|
-
options3d
|
|
2932
|
-
);
|
|
2933
|
-
return object;
|
|
2934
|
-
},
|
|
2935
|
-
createExtrudedLevel: (level, threeLayer, options) => {
|
|
2936
|
-
const extrudeHeight = _4.get(options, "height", 0);
|
|
2937
|
-
if (!extrudeHeight) return;
|
|
2938
|
-
const levelProperty = getFeatureProperties(level);
|
|
2939
|
-
const options3d = { offset: 0 };
|
|
2940
|
-
const color = levelProperty?.defaultColor || "#808080";
|
|
2941
|
-
if (color === "transparent" || _4.isEmpty(level?.geometry?.coordinates))
|
|
2942
|
-
return;
|
|
2943
|
-
const material = new MeshLambertMaterial({
|
|
2944
|
-
color,
|
|
2945
|
-
transparent: true
|
|
2946
|
-
});
|
|
2947
|
-
const object = createExtrudePolygon(
|
|
2948
|
-
level.geometry,
|
|
2949
|
-
threeLayer,
|
|
2950
|
-
material,
|
|
2951
|
-
extrudeHeight,
|
|
2952
|
-
levelProperty,
|
|
2953
|
-
options3d
|
|
2954
|
-
);
|
|
2955
|
-
return object;
|
|
2956
|
-
},
|
|
2957
2759
|
createAmbientLight: (config) => {
|
|
2958
2760
|
const { color: colorString = "0xffffff", intensity = 1 } = config;
|
|
2959
2761
|
const color = parseInt(colorString, 16);
|
|
@@ -3213,175 +3015,252 @@ var CameraManager = class {
|
|
|
3213
3015
|
};
|
|
3214
3016
|
};
|
|
3215
3017
|
|
|
3216
|
-
// src/IndoorMap/renderer/
|
|
3217
|
-
import
|
|
3218
|
-
import
|
|
3018
|
+
// src/IndoorMap/renderer/RendererManager.ts
|
|
3019
|
+
import _min from "lodash/min";
|
|
3020
|
+
import { center as turfCenter2 } from "@turf/center";
|
|
3219
3021
|
import { ThreeLayer as ThreeLayer3 } from "maptalks.three";
|
|
3220
|
-
import
|
|
3221
|
-
import { MeshLambertMaterial as MeshLambertMaterial3 } from "three";
|
|
3022
|
+
import * as THREE3 from "three";
|
|
3222
3023
|
|
|
3223
|
-
// src/IndoorMap/
|
|
3024
|
+
// src/IndoorMap/renderer/3d/Element3DRenderer.ts
|
|
3224
3025
|
import * as maptalks4 from "maptalks";
|
|
3225
|
-
import
|
|
3026
|
+
import * as THREE2 from "three";
|
|
3027
|
+
import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader";
|
|
3028
|
+
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
|
3029
|
+
import turfBuffer2 from "@turf/buffer";
|
|
3030
|
+
|
|
3031
|
+
// src/IndoorMap/renderer/3d/element3DRendererOptions.ts
|
|
3032
|
+
var element3DRendererOptions = {
|
|
3033
|
+
unit: {
|
|
3034
|
+
default: { color: "#ffffff", height: 4 },
|
|
3035
|
+
byCategory: {
|
|
3036
|
+
walkway: { color: "#cccccc", height: 0.1 },
|
|
3037
|
+
terrace: { color: "#cccccc", height: 0.1 },
|
|
3038
|
+
unenclosedarea: { color: "#cccccc", height: 0.2 },
|
|
3039
|
+
nonpublic: { color: "#999999", height: 0.3 },
|
|
3040
|
+
escalator: { height: 0.2 },
|
|
3041
|
+
room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
|
|
3042
|
+
}
|
|
3043
|
+
},
|
|
3044
|
+
kiosk: {
|
|
3045
|
+
default: { color: "#666666", height: 0.6, bottomHeight: 0.12 }
|
|
3046
|
+
},
|
|
3047
|
+
fixture: {
|
|
3048
|
+
default: { color: "#ffffff", height: 0.5 },
|
|
3049
|
+
byCategory: {
|
|
3050
|
+
water: { color: "#ACD7EC", height: 0.1 },
|
|
3051
|
+
vegetation: { color: "#91C499", height: 0.5 }
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
};
|
|
3055
|
+
|
|
3056
|
+
// src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
|
|
3057
|
+
import { Coordinate as Coordinate2, Util as Util4 } from "maptalks";
|
|
3226
3058
|
import * as THREE from "three";
|
|
3227
|
-
import {
|
|
3228
|
-
import {
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3059
|
+
import { BaseObject as BaseObject5 } from "maptalks.three";
|
|
3060
|
+
import { isNil, set } from "lodash";
|
|
3061
|
+
|
|
3062
|
+
// src/IndoorMap/renderer/utils/interpolateStops.ts
|
|
3063
|
+
var interpolateStops = ({ stops }, zoom) => {
|
|
3064
|
+
if (zoom <= stops[0][0]) return stops[0][1];
|
|
3065
|
+
if (zoom >= stops[stops.length - 1][0]) return stops[stops.length - 1][1];
|
|
3066
|
+
for (let i = 0; i < stops.length - 1; i++) {
|
|
3067
|
+
const [z1, v1] = stops[i];
|
|
3068
|
+
const [z2, v2] = stops[i + 1];
|
|
3069
|
+
if (zoom >= z1 && zoom <= z2) {
|
|
3070
|
+
const t = (zoom - z1) / (z2 - z1);
|
|
3071
|
+
return v1 + t * (v2 - v1);
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
};
|
|
3075
|
+
|
|
3076
|
+
// src/IndoorMap/renderer/3d/objects/TextSpriteMarker.ts
|
|
3077
|
+
var OPTIONS4 = {
|
|
3078
|
+
// Texture options
|
|
3079
|
+
text: "",
|
|
3080
|
+
textAlign: "center",
|
|
3081
|
+
color: "#ffffff",
|
|
3082
|
+
fontFamily: "sans-serif",
|
|
3083
|
+
fontSize: 28,
|
|
3084
|
+
fontWeight: 400,
|
|
3085
|
+
background: "rgba(0, 0, 0, 0.2)",
|
|
3086
|
+
lineHeight: 32,
|
|
3087
|
+
padding: 8,
|
|
3088
|
+
strokeColor: "#000000",
|
|
3089
|
+
strokeWidth: 6,
|
|
3090
|
+
strokeStyle: "round",
|
|
3091
|
+
// Sprite options
|
|
3092
|
+
/* Overall scale multiplier */
|
|
3093
|
+
scale: 1,
|
|
3094
|
+
altitude: 0,
|
|
3095
|
+
opacity: 1
|
|
3096
|
+
};
|
|
3097
|
+
var TextSpriteMarker = class extends BaseObject5 {
|
|
3098
|
+
#altitudeOffset = 0;
|
|
3099
|
+
constructor(coordinate, options, layer, properties = {}) {
|
|
3100
|
+
options = Util4.extend({}, OPTIONS4, options, { layer });
|
|
3233
3101
|
super();
|
|
3234
|
-
this.
|
|
3235
|
-
this.
|
|
3102
|
+
this._coordinate = new Coordinate2(coordinate);
|
|
3103
|
+
this._initOptions(options);
|
|
3236
3104
|
this._createGroup();
|
|
3237
|
-
|
|
3238
|
-
const
|
|
3239
|
-
this.
|
|
3240
|
-
|
|
3241
|
-
|
|
3105
|
+
this.properties = { ...properties };
|
|
3106
|
+
const sprite = this._createSprite();
|
|
3107
|
+
this.getObject3d().add(sprite);
|
|
3108
|
+
this._updatePosition();
|
|
3109
|
+
this.type = "TextSpriteMarker";
|
|
3110
|
+
}
|
|
3111
|
+
getOptions() {
|
|
3112
|
+
return super.getOptions();
|
|
3113
|
+
}
|
|
3114
|
+
_createSprite() {
|
|
3115
|
+
const options = this.getOptions();
|
|
3116
|
+
const texture = this._createTextTexture(options.text, options);
|
|
3117
|
+
const material = new THREE.SpriteMaterial({
|
|
3118
|
+
map: texture,
|
|
3119
|
+
transparent: true,
|
|
3120
|
+
alphaTest: 0.1
|
|
3242
3121
|
});
|
|
3243
|
-
|
|
3122
|
+
const sprite = new THREE.Sprite(material);
|
|
3123
|
+
const w = texture.image.width;
|
|
3124
|
+
const h = texture.image.height;
|
|
3125
|
+
const base = 1 / 16;
|
|
3126
|
+
const normalizedScale = options.scale / this.getMap().getGLRes();
|
|
3127
|
+
sprite.scale.set(w * base * normalizedScale, h * base * normalizedScale, 1);
|
|
3128
|
+
this.#altitudeOffset = Math.max(
|
|
3129
|
+
h * base * options.scale * 0.5,
|
|
3130
|
+
0.05
|
|
3131
|
+
// minimum lift in world units
|
|
3132
|
+
);
|
|
3133
|
+
return sprite;
|
|
3244
3134
|
}
|
|
3245
|
-
|
|
3246
|
-
const
|
|
3247
|
-
|
|
3248
|
-
|
|
3135
|
+
_createTextTexture(text, options = {}) {
|
|
3136
|
+
const {
|
|
3137
|
+
padding,
|
|
3138
|
+
fontSize,
|
|
3139
|
+
fontFamily,
|
|
3140
|
+
fontWeight,
|
|
3141
|
+
lineHeight,
|
|
3142
|
+
background,
|
|
3143
|
+
color,
|
|
3144
|
+
textAlign,
|
|
3145
|
+
strokeColor,
|
|
3146
|
+
strokeWidth,
|
|
3147
|
+
maxWidth
|
|
3148
|
+
} = options || {};
|
|
3149
|
+
const canvas = document.createElement("canvas");
|
|
3150
|
+
const ctx = canvas.getContext("2d");
|
|
3151
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
3152
|
+
const paragraphs = String(text).split("\n");
|
|
3153
|
+
const wrappedLines = [];
|
|
3154
|
+
paragraphs.forEach((paragraph) => {
|
|
3155
|
+
if (isNil(maxWidth) || isNaN(maxWidth)) {
|
|
3156
|
+
wrappedLines.push(paragraph);
|
|
3157
|
+
return;
|
|
3158
|
+
}
|
|
3159
|
+
const words = paragraph.split(/\s+/);
|
|
3160
|
+
let currentLine = "";
|
|
3161
|
+
words.forEach((word) => {
|
|
3162
|
+
const testLine = currentLine ? currentLine + " " + word : word;
|
|
3163
|
+
const testWidth = ctx.measureText(testLine).width;
|
|
3164
|
+
if (testWidth > maxWidth && currentLine) {
|
|
3165
|
+
wrappedLines.push(currentLine);
|
|
3166
|
+
currentLine = word;
|
|
3167
|
+
} else {
|
|
3168
|
+
currentLine = testLine;
|
|
3169
|
+
}
|
|
3170
|
+
});
|
|
3171
|
+
if (currentLine) {
|
|
3172
|
+
wrappedLines.push(currentLine);
|
|
3173
|
+
}
|
|
3249
3174
|
});
|
|
3250
|
-
const
|
|
3251
|
-
const
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
const
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
)
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
);
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
v1.z,
|
|
3279
|
-
v2.x,
|
|
3280
|
-
v2.y,
|
|
3281
|
-
v2.z,
|
|
3282
|
-
v0.x,
|
|
3283
|
-
v0.y,
|
|
3284
|
-
v0.z,
|
|
3285
|
-
v2.x,
|
|
3286
|
-
v2.y,
|
|
3287
|
-
v2.z,
|
|
3288
|
-
v3.x,
|
|
3289
|
-
v3.y,
|
|
3290
|
-
v3.z
|
|
3291
|
-
]);
|
|
3292
|
-
geom.setAttribute("position", new THREE.BufferAttribute(positions, 3));
|
|
3293
|
-
const uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1]);
|
|
3294
|
-
geom.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
|
|
3295
|
-
geom.computeVertexNormals();
|
|
3296
|
-
const mat = new THREE.MeshLambertMaterial({
|
|
3297
|
-
color: 11184810,
|
|
3298
|
-
// top
|
|
3299
|
-
emissive: 0,
|
|
3300
|
-
side: THREE.DoubleSide
|
|
3301
|
-
// visible from both sides (escalators are thin)
|
|
3175
|
+
const lines = wrappedLines.length ? wrappedLines : [""];
|
|
3176
|
+
const widest = Math.max(...lines.map((l) => ctx.measureText(l).width), 0);
|
|
3177
|
+
const finalWidth = (maxWidth ? Math.min(widest, maxWidth) : widest) + padding * 2;
|
|
3178
|
+
const finalHeight = lineHeight * lines.length + padding * 2;
|
|
3179
|
+
canvas.width = finalWidth;
|
|
3180
|
+
canvas.height = finalHeight;
|
|
3181
|
+
const ctx2 = canvas.getContext("2d");
|
|
3182
|
+
ctx2.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
3183
|
+
ctx2.textAlign = textAlign;
|
|
3184
|
+
if (background && background !== "transparent") {
|
|
3185
|
+
ctx2.fillStyle = background;
|
|
3186
|
+
ctx2.fillRect(0, 0, canvas.width, canvas.height);
|
|
3187
|
+
}
|
|
3188
|
+
lines.forEach((line, i) => {
|
|
3189
|
+
const y = padding + lineHeight * (i + 0.8);
|
|
3190
|
+
let x = padding;
|
|
3191
|
+
if (textAlign === "center") x = canvas.width / 2;
|
|
3192
|
+
if (textAlign === "right" || textAlign === "end")
|
|
3193
|
+
x = canvas.width - padding;
|
|
3194
|
+
if (strokeWidth > 0) {
|
|
3195
|
+
ctx2.lineWidth = strokeWidth;
|
|
3196
|
+
ctx2.lineJoin = "round";
|
|
3197
|
+
ctx2.miterLimit = 2;
|
|
3198
|
+
ctx2.strokeStyle = strokeColor;
|
|
3199
|
+
ctx2.strokeText(line, x, y);
|
|
3200
|
+
}
|
|
3201
|
+
ctx2.fillStyle = color;
|
|
3202
|
+
ctx2.fillText(line, x, y);
|
|
3302
3203
|
});
|
|
3303
|
-
|
|
3304
|
-
|
|
3204
|
+
const texture = new THREE.CanvasTexture(canvas);
|
|
3205
|
+
texture.needsUpdate = true;
|
|
3206
|
+
texture.minFilter = THREE.LinearFilter;
|
|
3207
|
+
return texture;
|
|
3208
|
+
}
|
|
3209
|
+
_updatePosition() {
|
|
3210
|
+
const options = this.getOptions();
|
|
3211
|
+
const layer = options.layer;
|
|
3212
|
+
if (!layer) return;
|
|
3213
|
+
const altitude = (options.altitude || 0) + this.#altitudeOffset;
|
|
3214
|
+
const z = layer.altitudeToVector3(altitude, altitude).x;
|
|
3215
|
+
const position = layer.coordinateToVector3(this._coordinate, z);
|
|
3216
|
+
set(this.properties, "default.position", position);
|
|
3217
|
+
this.getObject3d().position.copy(position);
|
|
3218
|
+
}
|
|
3219
|
+
_animation() {
|
|
3220
|
+
const layer = this.getLayer();
|
|
3221
|
+
if (!this.isAdd || !layer) return;
|
|
3222
|
+
if (this._visible === true) {
|
|
3223
|
+
const zoom = layer.map.getZoom();
|
|
3224
|
+
const object3d = this.getObject3d();
|
|
3225
|
+
const { opacity } = this.getOptions();
|
|
3226
|
+
let opacityValue;
|
|
3227
|
+
if (typeof opacity === "number") {
|
|
3228
|
+
opacityValue = opacity ?? 1;
|
|
3229
|
+
} else if (Array.isArray(opacity.stops)) {
|
|
3230
|
+
opacityValue = interpolateStops(opacity, zoom);
|
|
3231
|
+
} else {
|
|
3232
|
+
throw new Error(`Unknown opacity value ${opacity}`);
|
|
3233
|
+
}
|
|
3234
|
+
const visible = opacityValue > 0.5;
|
|
3235
|
+
object3d.visible = visible;
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
setText(text) {
|
|
3239
|
+
const options = this.getOptions();
|
|
3240
|
+
options.text = text;
|
|
3241
|
+
const newSprite = this._createSprite();
|
|
3242
|
+
const group = this.getObject3d();
|
|
3243
|
+
group.children.forEach((child) => group.remove(child));
|
|
3244
|
+
group.add(newSprite);
|
|
3245
|
+
this._updatePosition();
|
|
3246
|
+
}
|
|
3247
|
+
setAltitude(altitude) {
|
|
3248
|
+
const bottomHeight = this.options.bottomHeight ?? 0;
|
|
3249
|
+
return super.setAltitude(altitude + bottomHeight + this.#altitudeOffset);
|
|
3305
3250
|
}
|
|
3306
3251
|
};
|
|
3307
3252
|
|
|
3308
|
-
// src/IndoorMap/renderer/Element3DRenderer
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
const img = new Image();
|
|
3314
|
-
return new Promise((resolve, reject) => {
|
|
3315
|
-
img.onload = function() {
|
|
3316
|
-
const newWidth = img.width * scaleFactor;
|
|
3317
|
-
const newHeight = img.height * scaleFactor;
|
|
3318
|
-
const canvas = document.createElement("canvas");
|
|
3319
|
-
canvas.width = newWidth;
|
|
3320
|
-
canvas.height = newHeight;
|
|
3321
|
-
const ctx = canvas.getContext("2d");
|
|
3322
|
-
ctx.drawImage(img, 0, 0, newWidth, newHeight);
|
|
3323
|
-
const pngDataUrl = canvas.toDataURL("image/png");
|
|
3324
|
-
resolve(pngDataUrl);
|
|
3325
|
-
};
|
|
3326
|
-
img.onerror = function(error) {
|
|
3327
|
-
reject(error);
|
|
3328
|
-
};
|
|
3329
|
-
img.src = url;
|
|
3330
|
-
});
|
|
3331
|
-
};
|
|
3332
|
-
var createSVGPathFromMarkerSymbol2 = (style) => {
|
|
3333
|
-
const {
|
|
3334
|
-
markerWidth = 24,
|
|
3335
|
-
markerDx = 0,
|
|
3336
|
-
markerDy = 0,
|
|
3337
|
-
// markerFill,
|
|
3338
|
-
markerPath,
|
|
3339
|
-
fill = "#000000"
|
|
3340
|
-
} = style;
|
|
3341
|
-
const scale2 = markerWidth / 24;
|
|
3342
|
-
const strokeWidth = 2;
|
|
3343
|
-
const halfStrokeWidth = 0.5 * strokeWidth;
|
|
3344
|
-
if (Array.isArray(markerPath)) {
|
|
3345
|
-
return markerPath.map(
|
|
3346
|
-
({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
|
|
3347
|
-
);
|
|
3348
|
-
}
|
|
3349
|
-
return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
|
|
3350
|
-
};
|
|
3351
|
-
var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
|
|
3352
|
-
const material = new SpriteMaterial4();
|
|
3353
|
-
try {
|
|
3354
|
-
const [base, icon] = labelSymbol ?? [{}, {}];
|
|
3355
|
-
const { markerWidth: baseWidth = 24 } = base;
|
|
3356
|
-
const { markerWidth: iconWidth = 24 } = icon;
|
|
3357
|
-
const viewBoxDimension = Math.max(baseWidth, iconWidth);
|
|
3358
|
-
const baseSVG = createSVGPathFromMarkerSymbol2(base);
|
|
3359
|
-
const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
|
|
3360
|
-
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
|
|
3361
|
-
const textureLoader = new TextureLoader3();
|
|
3362
|
-
const scaleFactor = 200 / 24;
|
|
3363
|
-
svgToDataURL(svg, scaleFactor).then((png) => {
|
|
3364
|
-
const texture = textureLoader.load(png, () => {
|
|
3365
|
-
material.map = texture;
|
|
3366
|
-
material.needsUpdate = true;
|
|
3367
|
-
});
|
|
3368
|
-
});
|
|
3369
|
-
} catch (error) {
|
|
3370
|
-
console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
|
|
3371
|
-
}
|
|
3372
|
-
return material;
|
|
3373
|
-
};
|
|
3374
|
-
|
|
3375
|
-
// src/IndoorMap/renderer/Element3DRenderer.ts
|
|
3376
|
-
var DEFAULT_POLYGON_OPTION = {
|
|
3377
|
-
color: "#FFFFFF",
|
|
3378
|
-
offset: 0,
|
|
3379
|
-
altitude: 0
|
|
3253
|
+
// src/IndoorMap/renderer/3d/Element3DRenderer.ts
|
|
3254
|
+
var DEFAULT_POLYGON_OPTION = {
|
|
3255
|
+
color: "#FFFFFF",
|
|
3256
|
+
offset: 0,
|
|
3257
|
+
altitude: 0
|
|
3380
3258
|
};
|
|
3381
3259
|
var HEIGHT_METER = 4;
|
|
3260
|
+
var MULTIORDINAL_HEIGHT_METER = 9;
|
|
3382
3261
|
var getGeometryOption = (feature2, options) => {
|
|
3383
3262
|
try {
|
|
3384
|
-
const option = options[feature2.feature_type];
|
|
3263
|
+
const option = options[feature2.feature_type] ?? element3DRendererOptions[feature2.feature_type];
|
|
3385
3264
|
const category = feature2.properties.category;
|
|
3386
3265
|
return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION;
|
|
3387
3266
|
} catch (err) {
|
|
@@ -3392,34 +3271,20 @@ var Element3DRenderer = class extends EventTarget {
|
|
|
3392
3271
|
options;
|
|
3393
3272
|
map;
|
|
3394
3273
|
threeLayer;
|
|
3395
|
-
|
|
3396
|
-
materialByKey;
|
|
3274
|
+
dracoLoader;
|
|
3397
3275
|
lineMaterial;
|
|
3276
|
+
materialByColorMap;
|
|
3277
|
+
markerRenderer;
|
|
3398
3278
|
// Renderer is Ready
|
|
3399
3279
|
isReady = false;
|
|
3400
|
-
constructor(map, options) {
|
|
3280
|
+
constructor(map, options, layer) {
|
|
3401
3281
|
super();
|
|
3402
3282
|
this.options = options;
|
|
3403
3283
|
this.map = map;
|
|
3404
|
-
this.
|
|
3405
|
-
|
|
3406
|
-
forceRenderOnRotating: true
|
|
3407
|
-
});
|
|
3408
|
-
const _this = this;
|
|
3409
|
-
this.threeLayer.prepareToDraw = function(gl, scene, camera) {
|
|
3410
|
-
const ambientLight = new THREE2.AmbientLight(16777215, 0.3);
|
|
3411
|
-
scene.add(ambientLight);
|
|
3412
|
-
const dirColor = 16777215;
|
|
3413
|
-
const dllight = new THREE2.DirectionalLight(dirColor, 0.8);
|
|
3414
|
-
dllight.position.set(0, -10, 10).normalize();
|
|
3415
|
-
scene.add(dllight);
|
|
3416
|
-
const hemi = new THREE2.HemisphereLight(16777215, 4473924, 0.4);
|
|
3417
|
-
scene.add(hemi);
|
|
3418
|
-
this.isReady = true;
|
|
3419
|
-
_this.dispatchEvent(new CustomEvent("threelayer:ready"));
|
|
3420
|
-
};
|
|
3284
|
+
this.dracoLoader = new DRACOLoader();
|
|
3285
|
+
this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.7/");
|
|
3421
3286
|
this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
|
|
3422
|
-
this.threeLayer
|
|
3287
|
+
this.threeLayer = layer;
|
|
3423
3288
|
this.render();
|
|
3424
3289
|
}
|
|
3425
3290
|
animation() {
|
|
@@ -3434,80 +3299,56 @@ var Element3DRenderer = class extends EventTarget {
|
|
|
3434
3299
|
if (!this.materialByColorMap) this.materialByColorMap = /* @__PURE__ */ new Map();
|
|
3435
3300
|
const existingMaterial = this.materialByColorMap.get(color);
|
|
3436
3301
|
if (existingMaterial) return existingMaterial;
|
|
3437
|
-
const created = new
|
|
3302
|
+
const created = new THREE2.MeshLambertMaterial({ color, transparent: true });
|
|
3438
3303
|
created.toneMapped = false;
|
|
3439
3304
|
this.materialByColorMap.set(color, created);
|
|
3440
3305
|
return created;
|
|
3441
3306
|
}
|
|
3442
|
-
getOrCreateIconMaterial(key) {
|
|
3443
|
-
if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
|
|
3444
|
-
const existingMaterial = this.materialByKey.get(key);
|
|
3445
|
-
if (existingMaterial) return existingMaterial;
|
|
3446
|
-
const baseSymbol = {
|
|
3447
|
-
markerType: "path",
|
|
3448
|
-
markerPath: [
|
|
3449
|
-
{
|
|
3450
|
-
path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
|
|
3451
|
-
fill: "#ff0000"
|
|
3452
|
-
}
|
|
3453
|
-
],
|
|
3454
|
-
markerPathWidth: 24,
|
|
3455
|
-
markerPathHeight: 24
|
|
3456
|
-
};
|
|
3457
|
-
const markerSymbol = {
|
|
3458
|
-
markerType: "path",
|
|
3459
|
-
markerPath: [],
|
|
3460
|
-
// TODO: Get Path by featureType.category
|
|
3461
|
-
// markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
|
|
3462
|
-
markerPathWidth: 24,
|
|
3463
|
-
markerPathHeight: 24,
|
|
3464
|
-
markerWidth: 24,
|
|
3465
|
-
markerHeight: 24,
|
|
3466
|
-
markerDy: 1.5,
|
|
3467
|
-
markerDx: 1.5
|
|
3468
|
-
};
|
|
3469
|
-
const created = createSpriteMaterialByLabelSymbol2([
|
|
3470
|
-
baseSymbol,
|
|
3471
|
-
markerSymbol
|
|
3472
|
-
]);
|
|
3473
|
-
this.materialByKey.set(key, created);
|
|
3474
|
-
return created;
|
|
3475
|
-
}
|
|
3476
3307
|
createGeometry = (feature2) => {
|
|
3477
|
-
const
|
|
3478
|
-
|
|
3308
|
+
const {
|
|
3309
|
+
offset = 0,
|
|
3310
|
+
height: heightOptions,
|
|
3311
|
+
bottomHeight: bottomHeightOptions,
|
|
3312
|
+
color: colorOptions,
|
|
3313
|
+
...options
|
|
3314
|
+
} = getGeometryOption(feature2, this.options);
|
|
3315
|
+
const _this = this;
|
|
3479
3316
|
const createPolygon = (geometry, feature3) => {
|
|
3480
3317
|
const [outerRing, ...innerRings] = geometry.coordinates;
|
|
3481
3318
|
const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
|
|
3482
|
-
const color =
|
|
3319
|
+
const color = feature3.properties.style.polygonFill ?? colorOptions ?? "#ffffff";
|
|
3483
3320
|
if (color === "transparent") return;
|
|
3484
3321
|
const material = this.getOrCreateMaterialByColor(color);
|
|
3485
3322
|
const altitude = feature3.properties.ordinal * HEIGHT_METER;
|
|
3486
|
-
const
|
|
3487
|
-
const
|
|
3323
|
+
const height = feature3.properties.height ?? heightOptions ?? HEIGHT_METER;
|
|
3324
|
+
const bottomHeight = feature3.properties.bottomHeight ?? bottomHeightOptions ?? 0;
|
|
3325
|
+
const extrudedPolygon = this.threeLayer.toExtrudePolygon(
|
|
3488
3326
|
offsetFeature,
|
|
3489
|
-
{ asynchronous: true, ...options, altitude },
|
|
3327
|
+
{ asynchronous: true, ...options, height, bottomHeight, altitude },
|
|
3490
3328
|
material
|
|
3491
3329
|
);
|
|
3330
|
+
extrudedPolygon.on("click", (e) => {
|
|
3331
|
+
console.log(e.target.options.polygon.id);
|
|
3332
|
+
});
|
|
3492
3333
|
const topLineStrings = [
|
|
3493
|
-
new
|
|
3494
|
-
...innerRings.map((innerRing) => new
|
|
3334
|
+
new maptalks4.LineString(outerRing),
|
|
3335
|
+
...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
|
|
3495
3336
|
];
|
|
3496
3337
|
const topLines = this.threeLayer.toLines(
|
|
3497
3338
|
topLineStrings,
|
|
3498
|
-
{ altitude:
|
|
3339
|
+
{ altitude, bottomHeight: bottomHeight + height + 1e-3, interactive: false },
|
|
3499
3340
|
this.lineMaterial
|
|
3500
3341
|
);
|
|
3501
3342
|
const bottomLineStrings = [
|
|
3502
|
-
new
|
|
3503
|
-
...innerRings.map((innerRing) => new
|
|
3343
|
+
new maptalks4.LineString(outerRing),
|
|
3344
|
+
...innerRings.map((innerRing) => new maptalks4.LineString(innerRing))
|
|
3504
3345
|
];
|
|
3505
3346
|
const bottomLines = this.threeLayer.toLines(
|
|
3506
3347
|
bottomLineStrings,
|
|
3507
3348
|
{ altitude, bottomHeight, interactive: false },
|
|
3508
3349
|
this.lineMaterial
|
|
3509
3350
|
);
|
|
3510
|
-
return [
|
|
3351
|
+
return [extrudedPolygon, topLines, bottomLines];
|
|
3511
3352
|
};
|
|
3512
3353
|
try {
|
|
3513
3354
|
switch (feature2.geometry.type) {
|
|
@@ -3530,49 +3371,111 @@ var Element3DRenderer = class extends EventTarget {
|
|
|
3530
3371
|
console.log(`error createGeometry`, { feature: feature2, options });
|
|
3531
3372
|
}
|
|
3532
3373
|
};
|
|
3533
|
-
|
|
3534
|
-
const
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3374
|
+
async createEscalator(f, coordinate, options) {
|
|
3375
|
+
const { direction: dir, angle } = options;
|
|
3376
|
+
const model = await this.loadModel3d({
|
|
3377
|
+
url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb",
|
|
3378
|
+
properties: {
|
|
3379
|
+
rotation: {
|
|
3380
|
+
x: 0.5 * Math.PI,
|
|
3381
|
+
// Rotate the model up (new_escalator.glb)
|
|
3382
|
+
y: 0,
|
|
3383
|
+
z: 0
|
|
3384
|
+
},
|
|
3385
|
+
position: { x: 0, y: 0, z: 0 },
|
|
3386
|
+
scale: 0.01
|
|
3387
|
+
}
|
|
3388
|
+
});
|
|
3389
|
+
model.rotation.y += dir === "up" ? Math.PI + angle : angle;
|
|
3390
|
+
const box = new THREE2.Box3().setFromObject(model);
|
|
3391
|
+
const pivotPoint = dir === "up" ? new THREE2.Vector3(0, 0, 0) : new THREE2.Vector3(
|
|
3392
|
+
1 * (box.min.x + box.max.x),
|
|
3393
|
+
1 * (box.min.y + box.max.y),
|
|
3394
|
+
0.6 * box.max.z
|
|
3549
3395
|
);
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3396
|
+
const pivot = new THREE2.Group();
|
|
3397
|
+
pivot.add(model);
|
|
3398
|
+
model.position.sub(pivotPoint);
|
|
3399
|
+
model.updateMatrixWorld(true);
|
|
3400
|
+
const altitude = f.properties.ordinal * HEIGHT_METER;
|
|
3401
|
+
const baseObjectModel = this.threeLayer.toModel(pivot, {
|
|
3402
|
+
coordinate,
|
|
3403
|
+
altitude
|
|
3404
|
+
});
|
|
3405
|
+
this.threeLayer.addMesh(baseObjectModel);
|
|
3406
|
+
return baseObjectModel;
|
|
3407
|
+
}
|
|
3408
|
+
async createTree(coordinate, ordinal) {
|
|
3409
|
+
const model = await this.loadModel3d({
|
|
3410
|
+
url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/arbol.glb",
|
|
3411
|
+
properties: {
|
|
3412
|
+
rotation: {
|
|
3413
|
+
x: 0.5 * Math.PI,
|
|
3414
|
+
// Rotate the model up (new_escalator.glb)
|
|
3415
|
+
y: 0,
|
|
3416
|
+
z: 0
|
|
3417
|
+
},
|
|
3418
|
+
position: { x: 0, y: 0, z: 0 },
|
|
3419
|
+
scale: 0.01
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3422
|
+
const altitude = ordinal * HEIGHT_METER;
|
|
3423
|
+
const baseObjectModel = this.threeLayer.toModel(model, {
|
|
3424
|
+
coordinate,
|
|
3425
|
+
altitude
|
|
3426
|
+
});
|
|
3427
|
+
this.threeLayer.addMesh(baseObjectModel);
|
|
3428
|
+
return baseObjectModel;
|
|
3429
|
+
}
|
|
3553
3430
|
createElement(f) {
|
|
3554
3431
|
switch (f.feature_type) {
|
|
3555
|
-
case "unit": {
|
|
3556
|
-
switch (f.properties.category) {
|
|
3557
|
-
case "escalator": {
|
|
3558
|
-
const mesh = new Escalator(
|
|
3559
|
-
f,
|
|
3560
|
-
{
|
|
3561
|
-
startAltitude: 0,
|
|
3562
|
-
endAltitude: 0.06
|
|
3563
|
-
},
|
|
3564
|
-
this.threeLayer
|
|
3565
|
-
);
|
|
3566
|
-
this.threeLayer.addMesh([mesh]);
|
|
3567
|
-
return [mesh];
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
break;
|
|
3571
|
-
}
|
|
3572
3432
|
default:
|
|
3573
3433
|
return null;
|
|
3574
3434
|
}
|
|
3575
3435
|
}
|
|
3436
|
+
showElements(elements, ordinalDiff = 0) {
|
|
3437
|
+
elements.forEach((element) => {
|
|
3438
|
+
element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER);
|
|
3439
|
+
element.show();
|
|
3440
|
+
});
|
|
3441
|
+
}
|
|
3442
|
+
hideElements(elements, ordinalDiff = 0) {
|
|
3443
|
+
elements.forEach((element) => {
|
|
3444
|
+
try {
|
|
3445
|
+
element.hide();
|
|
3446
|
+
} catch (err) {
|
|
3447
|
+
console.log(`cannot hide`, err, element);
|
|
3448
|
+
}
|
|
3449
|
+
});
|
|
3450
|
+
}
|
|
3451
|
+
async loadModel3d(model3d) {
|
|
3452
|
+
const loader = new GLTFLoader2();
|
|
3453
|
+
loader.setDRACOLoader(this.dracoLoader);
|
|
3454
|
+
const { url, properties: modelProperties } = model3d;
|
|
3455
|
+
const gltf = await loader.loadAsync(url);
|
|
3456
|
+
const model = gltf.scene;
|
|
3457
|
+
model.rotation.x = modelProperties.rotation.x;
|
|
3458
|
+
model.rotation.y = modelProperties.rotation.y;
|
|
3459
|
+
model.position.x = modelProperties.position.x;
|
|
3460
|
+
model.position.y = modelProperties.position.y;
|
|
3461
|
+
model.position.z = modelProperties.position.z;
|
|
3462
|
+
const scale2 = modelProperties.scale;
|
|
3463
|
+
model.scale.set(scale2, scale2, scale2);
|
|
3464
|
+
return model;
|
|
3465
|
+
}
|
|
3466
|
+
createMarker = (coordinates, ordinal, text) => {
|
|
3467
|
+
const options = {
|
|
3468
|
+
// scale: 0.05,
|
|
3469
|
+
// altitude: ordinal * HEIGHT_METER,
|
|
3470
|
+
text
|
|
3471
|
+
// interactive: true,
|
|
3472
|
+
};
|
|
3473
|
+
const marker = new TextSpriteMarker(coordinates, options, this.threeLayer);
|
|
3474
|
+
this.threeLayer.addMesh([marker]);
|
|
3475
|
+
return marker;
|
|
3476
|
+
};
|
|
3477
|
+
removeMarker = () => {
|
|
3478
|
+
};
|
|
3576
3479
|
render() {
|
|
3577
3480
|
this.threeLayer._needsUpdate = !this.threeLayer._needsUpdate;
|
|
3578
3481
|
if (this.threeLayer._needsUpdate) {
|
|
@@ -3582,9 +3485,34 @@ var Element3DRenderer = class extends EventTarget {
|
|
|
3582
3485
|
}
|
|
3583
3486
|
};
|
|
3584
3487
|
|
|
3585
|
-
// src/IndoorMap/renderer/Element2DRenderer.ts
|
|
3586
|
-
import * as
|
|
3587
|
-
|
|
3488
|
+
// src/IndoorMap/renderer/2d/Element2DRenderer.ts
|
|
3489
|
+
import * as maptalks5 from "maptalks";
|
|
3490
|
+
|
|
3491
|
+
// src/IndoorMap/renderer/2d/element2DRendererOptions.ts
|
|
3492
|
+
var element2DRendererOptions = {
|
|
3493
|
+
unit: {
|
|
3494
|
+
default: { symbol: { polygonFill: "#cccccc" } },
|
|
3495
|
+
byCategory: {
|
|
3496
|
+
room: { symbol: { polygonFill: "#fff" } },
|
|
3497
|
+
walkway: { symbol: { polygonFill: "#efefef", lineColor: "#dadada", lineWidth: 2 } },
|
|
3498
|
+
terrace: { symbol: { polygonFill: "#efefef" } },
|
|
3499
|
+
unenclosedarea: { symbol: { polygonFill: "#fff" } },
|
|
3500
|
+
nonpublic: { symbol: { polygonFill: "#999999" } }
|
|
3501
|
+
}
|
|
3502
|
+
},
|
|
3503
|
+
kiosk: {
|
|
3504
|
+
default: {}
|
|
3505
|
+
},
|
|
3506
|
+
fixture: {
|
|
3507
|
+
default: { symbol: { polygonFill: "#ffffff" } },
|
|
3508
|
+
byCategory: {
|
|
3509
|
+
water: { symbol: { polygonFill: "#ACD7EC" } },
|
|
3510
|
+
vegetation: { symbol: { polygonFill: "#91C499" } }
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
};
|
|
3514
|
+
|
|
3515
|
+
// src/IndoorMap/renderer/2d/Element2DRenderer.ts
|
|
3588
3516
|
var DEFAULT_POLYGON_OPTION2 = {
|
|
3589
3517
|
zIndex: 0,
|
|
3590
3518
|
symbol: {
|
|
@@ -3594,6 +3522,7 @@ var DEFAULT_POLYGON_OPTION2 = {
|
|
|
3594
3522
|
lineWidth: 2
|
|
3595
3523
|
}
|
|
3596
3524
|
};
|
|
3525
|
+
var MULTIORDINAL_HEIGHT_METER2 = 10;
|
|
3597
3526
|
var getGeometryProperties = (feature2) => ({
|
|
3598
3527
|
// Core
|
|
3599
3528
|
type: "Feature",
|
|
@@ -3603,11 +3532,11 @@ var getGeometryProperties = (feature2) => ({
|
|
|
3603
3532
|
// Extra
|
|
3604
3533
|
feature_type: feature2.feature_type,
|
|
3605
3534
|
category: feature2.properties.category,
|
|
3606
|
-
name: feature2.properties.name
|
|
3535
|
+
name: feature2.properties.name?.en
|
|
3607
3536
|
});
|
|
3608
3537
|
var getGeometryOption2 = (feature2, options) => {
|
|
3609
3538
|
try {
|
|
3610
|
-
const option = options[feature2.feature_type];
|
|
3539
|
+
const option = options[feature2.feature_type] ?? element2DRendererOptions[feature2.feature_type];
|
|
3611
3540
|
const category = feature2.properties.category;
|
|
3612
3541
|
return (category && option.byCategory?.[category]) ?? option?.default ?? DEFAULT_POLYGON_OPTION2;
|
|
3613
3542
|
} catch (err) {
|
|
@@ -3624,18 +3553,17 @@ var Element2DRenderer = class extends EventTarget {
|
|
|
3624
3553
|
super();
|
|
3625
3554
|
this.options = options;
|
|
3626
3555
|
this.map = map;
|
|
3627
|
-
this.elementLayer = new
|
|
3556
|
+
this.elementLayer = new maptalks5.VectorLayer("elements");
|
|
3628
3557
|
this.elementLayer.addTo(this.map);
|
|
3629
|
-
this.markerLayer = new
|
|
3558
|
+
this.markerLayer = new maptalks5.VectorLayer("markers");
|
|
3630
3559
|
this.markerLayer.addTo(this.map);
|
|
3631
3560
|
this.isReady = true;
|
|
3632
|
-
this.dispatchEvent(new CustomEvent("renderer:ready"));
|
|
3633
3561
|
}
|
|
3634
3562
|
createGeometry = (imdfFeature) => {
|
|
3635
3563
|
const feature2 = getGeometryProperties(imdfFeature);
|
|
3636
3564
|
const { symbol, ...options } = getGeometryOption2(imdfFeature, this.options);
|
|
3637
3565
|
const altitude = feature2.properties.ordinal * 10;
|
|
3638
|
-
const geometry =
|
|
3566
|
+
const geometry = maptalks5.Geometry.fromJSON({
|
|
3639
3567
|
feature: feature2,
|
|
3640
3568
|
symbol,
|
|
3641
3569
|
options: {
|
|
@@ -3646,42 +3574,235 @@ var Element2DRenderer = class extends EventTarget {
|
|
|
3646
3574
|
});
|
|
3647
3575
|
if (Array.isArray(geometry)) {
|
|
3648
3576
|
geometry.forEach((g) => g.addTo(this.elementLayer));
|
|
3649
|
-
return new
|
|
3577
|
+
return new maptalks5.GeometryCollection(geometry);
|
|
3650
3578
|
} else {
|
|
3651
3579
|
geometry.addTo(this.elementLayer);
|
|
3652
3580
|
return geometry;
|
|
3653
3581
|
}
|
|
3654
3582
|
};
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3583
|
+
async createEscalator(f, coordinates) {
|
|
3584
|
+
return Promise.resolve(null);
|
|
3585
|
+
}
|
|
3586
|
+
async createTree(f, coordinates) {
|
|
3587
|
+
return Promise.resolve(null);
|
|
3588
|
+
}
|
|
3589
|
+
createElement = (imdfFeature) => {
|
|
3590
|
+
switch (imdfFeature.feature_type) {
|
|
3591
|
+
default:
|
|
3592
|
+
return null;
|
|
3593
|
+
}
|
|
3594
|
+
};
|
|
3595
|
+
showElements(elements, ordinalDiff = 0) {
|
|
3596
|
+
elements.forEach((element) => {
|
|
3597
|
+
element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER2);
|
|
3598
|
+
element.show();
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
hideElements(elements, ordinalDiff = 0) {
|
|
3602
|
+
elements.forEach((element) => {
|
|
3603
|
+
element.hide();
|
|
3604
|
+
});
|
|
3605
|
+
}
|
|
3606
|
+
};
|
|
3607
|
+
|
|
3608
|
+
// src/IndoorMap/renderer/2d/Marker2DRenderer.ts
|
|
3609
|
+
import * as maptalks6 from "maptalks";
|
|
3610
|
+
var Marker2DRenderer = class extends EventTarget {
|
|
3611
|
+
isReady = false;
|
|
3612
|
+
map;
|
|
3613
|
+
markerLayer;
|
|
3614
|
+
constructor(map) {
|
|
3615
|
+
super();
|
|
3616
|
+
}
|
|
3617
|
+
createMarker = (coordinates, ordinal, content) => {
|
|
3666
3618
|
const marker = new maptalks6.ui.UIMarker(coordinates, {
|
|
3667
|
-
content
|
|
3668
|
-
style,
|
|
3669
|
-
textContent: label,
|
|
3670
|
-
className: OCCUPANT_TEXT_MARKER_CLASSNAME2
|
|
3671
|
-
}),
|
|
3619
|
+
content,
|
|
3672
3620
|
collision: true,
|
|
3673
|
-
collisionFadeIn: true
|
|
3674
|
-
|
|
3621
|
+
collisionFadeIn: true,
|
|
3622
|
+
altitude: 0
|
|
3675
3623
|
});
|
|
3676
3624
|
marker.addTo(this.map);
|
|
3677
3625
|
return marker;
|
|
3678
3626
|
};
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3627
|
+
removeMarker = (marker) => {
|
|
3628
|
+
marker.remove();
|
|
3629
|
+
};
|
|
3630
|
+
showMarkers(elements, ordinalDiff = 0) {
|
|
3631
|
+
}
|
|
3632
|
+
hideMarkers(elements, ordinalDiff = 0) {
|
|
3633
|
+
}
|
|
3634
|
+
};
|
|
3635
|
+
|
|
3636
|
+
// src/IndoorMap/renderer/3d/Marker3DRenderer.ts
|
|
3637
|
+
import * as maptalks7 from "maptalks";
|
|
3638
|
+
|
|
3639
|
+
// src/IndoorMap/renderer/utils/svg2material.ts
|
|
3640
|
+
import { SpriteMaterial as SpriteMaterial5, TextureLoader as TextureLoader3 } from "three";
|
|
3641
|
+
var svgToDataURL = (svgString, scaleFactor = 1) => {
|
|
3642
|
+
const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
|
|
3643
|
+
const url = URL.createObjectURL(svgBlob);
|
|
3644
|
+
const img = new Image();
|
|
3645
|
+
return new Promise((resolve, reject) => {
|
|
3646
|
+
img.onload = function() {
|
|
3647
|
+
const newWidth = img.width * scaleFactor;
|
|
3648
|
+
const newHeight = img.height * scaleFactor;
|
|
3649
|
+
const canvas = document.createElement("canvas");
|
|
3650
|
+
canvas.width = newWidth;
|
|
3651
|
+
canvas.height = newHeight;
|
|
3652
|
+
const ctx = canvas.getContext("2d");
|
|
3653
|
+
ctx.drawImage(img, 0, 0, newWidth, newHeight);
|
|
3654
|
+
const pngDataUrl = canvas.toDataURL("image/png");
|
|
3655
|
+
resolve(pngDataUrl);
|
|
3656
|
+
};
|
|
3657
|
+
img.onerror = function(error) {
|
|
3658
|
+
reject(error);
|
|
3659
|
+
};
|
|
3660
|
+
img.src = url;
|
|
3661
|
+
});
|
|
3662
|
+
};
|
|
3663
|
+
var createSVGPathFromMarkerSymbol2 = (style) => {
|
|
3664
|
+
const {
|
|
3665
|
+
markerWidth = 24,
|
|
3666
|
+
markerDx = 0,
|
|
3667
|
+
markerDy = 0,
|
|
3668
|
+
// markerFill,
|
|
3669
|
+
markerPath,
|
|
3670
|
+
fill = "#000000"
|
|
3671
|
+
} = style;
|
|
3672
|
+
const scale2 = markerWidth / 24;
|
|
3673
|
+
const strokeWidth = 2;
|
|
3674
|
+
const halfStrokeWidth = 0.5 * strokeWidth;
|
|
3675
|
+
if (Array.isArray(markerPath)) {
|
|
3676
|
+
return markerPath.map(
|
|
3677
|
+
({ path, fill: fill2 }) => `<path d="${path}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill2}" stroke="#ffffff" stroke-width="${strokeWidth}" />`
|
|
3678
|
+
);
|
|
3679
|
+
}
|
|
3680
|
+
return `<path d="${markerPath}" style="transform:translate(${markerDx}px, ${markerDy}px) scale(${scale2})" fill="${fill}" />`;
|
|
3681
|
+
};
|
|
3682
|
+
var createSpriteMaterialByLabelSymbol2 = (labelSymbol) => {
|
|
3683
|
+
const material = new SpriteMaterial5();
|
|
3684
|
+
try {
|
|
3685
|
+
const [base, icon] = labelSymbol ?? [{}, {}];
|
|
3686
|
+
const { markerWidth: baseWidth = 24 } = base;
|
|
3687
|
+
const { markerWidth: iconWidth = 24 } = icon;
|
|
3688
|
+
const viewBoxDimension = Math.max(baseWidth, iconWidth);
|
|
3689
|
+
const baseSVG = createSVGPathFromMarkerSymbol2(base);
|
|
3690
|
+
const iconSVG = icon ? createSVGPathFromMarkerSymbol2(icon) : "";
|
|
3691
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${viewBoxDimension}" height="${viewBoxDimension}">${baseSVG}${iconSVG}</svg>`;
|
|
3692
|
+
const textureLoader = new TextureLoader3();
|
|
3693
|
+
const scaleFactor = 200 / 24;
|
|
3694
|
+
svgToDataURL(svg, scaleFactor).then((png) => {
|
|
3695
|
+
const texture = textureLoader.load(png, () => {
|
|
3696
|
+
material.map = texture;
|
|
3697
|
+
material.needsUpdate = true;
|
|
3698
|
+
});
|
|
3699
|
+
});
|
|
3700
|
+
} catch (error) {
|
|
3701
|
+
console.warn(`Error createSpriteMaterialByLabelSymbol: `, labelSymbol);
|
|
3702
|
+
}
|
|
3703
|
+
return material;
|
|
3704
|
+
};
|
|
3705
|
+
|
|
3706
|
+
// src/IndoorMap/renderer/3d/Marker3DRenderer.ts
|
|
3707
|
+
var HEIGHT_METER2 = 4;
|
|
3708
|
+
var MULTIORDINAL_HEIGHT_METER3 = 9;
|
|
3709
|
+
var Marker3DRenderer = class extends EventTarget {
|
|
3710
|
+
isReady = false;
|
|
3711
|
+
threeLayer;
|
|
3712
|
+
map;
|
|
3713
|
+
materialByKey;
|
|
3714
|
+
constructor(map, options, layer) {
|
|
3715
|
+
super();
|
|
3716
|
+
this.map = map;
|
|
3717
|
+
this.threeLayer = layer;
|
|
3718
|
+
}
|
|
3719
|
+
createTextMarker = (position, ordinal, label, options) => {
|
|
3720
|
+
const combinedOptions = {
|
|
3721
|
+
altitude: ordinal * HEIGHT_METER2,
|
|
3722
|
+
text: label,
|
|
3723
|
+
...options ?? {}
|
|
3724
|
+
};
|
|
3725
|
+
const [lng, lat] = position;
|
|
3726
|
+
const marker = new TextSpriteMarker(new maptalks7.Coordinate(lng, lat), combinedOptions, this.threeLayer);
|
|
3727
|
+
this.threeLayer.addMesh([marker]);
|
|
3728
|
+
return marker;
|
|
3729
|
+
};
|
|
3730
|
+
createImageMarker = () => {
|
|
3731
|
+
};
|
|
3732
|
+
createMarker = (coordinates, ordinal, label, options) => {
|
|
3733
|
+
return this.createTextMarker(coordinates, ordinal, label, options);
|
|
3684
3734
|
};
|
|
3735
|
+
removeMarker = (marker) => {
|
|
3736
|
+
marker.remove();
|
|
3737
|
+
};
|
|
3738
|
+
showMarkers(elements, ordinalDiff = 0) {
|
|
3739
|
+
elements.forEach((element) => {
|
|
3740
|
+
element.setAltitude(ordinalDiff * MULTIORDINAL_HEIGHT_METER3);
|
|
3741
|
+
element.show();
|
|
3742
|
+
});
|
|
3743
|
+
}
|
|
3744
|
+
hideMarkers(elements, ordinalDiff = 0) {
|
|
3745
|
+
elements.forEach((element) => {
|
|
3746
|
+
try {
|
|
3747
|
+
element.hide();
|
|
3748
|
+
} catch (err) {
|
|
3749
|
+
console.log(`cannot hide`, err, element);
|
|
3750
|
+
}
|
|
3751
|
+
});
|
|
3752
|
+
}
|
|
3753
|
+
/** Marker */
|
|
3754
|
+
getOrCreateIconMaterial(key) {
|
|
3755
|
+
if (!this.materialByKey) this.materialByKey = /* @__PURE__ */ new Map();
|
|
3756
|
+
const existingMaterial = this.materialByKey.get(key);
|
|
3757
|
+
if (existingMaterial) return existingMaterial;
|
|
3758
|
+
const baseSymbol = {
|
|
3759
|
+
markerType: "path",
|
|
3760
|
+
markerPath: [
|
|
3761
|
+
{
|
|
3762
|
+
path: "M20.775 1.2H1.225V20.35H8.215L11.3 22.8L14.385 20.35H20.775V1.2Z",
|
|
3763
|
+
fill: "#ff0000"
|
|
3764
|
+
}
|
|
3765
|
+
],
|
|
3766
|
+
markerPathWidth: 24,
|
|
3767
|
+
markerPathHeight: 24
|
|
3768
|
+
};
|
|
3769
|
+
const markerSymbol = {
|
|
3770
|
+
markerType: "path",
|
|
3771
|
+
markerPath: [],
|
|
3772
|
+
// TODO: Get Path by featureType.category
|
|
3773
|
+
// markerPath: [{ fill: "#FFFFFF", path: "M 19 3 H 5 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m -2 6 h -1.7 l -5 9 H 7 c -0.83 0 -1.5 -0.67 -1.5 -1.5 S 6.17 15 7 15 h 1.7 l 5 -9 H 17 c 0.83 0 1.5 0.67 1.5 1.5 S 17.83 9 17 9 Z" }],
|
|
3774
|
+
markerPathWidth: 24,
|
|
3775
|
+
markerPathHeight: 24,
|
|
3776
|
+
markerWidth: 24,
|
|
3777
|
+
markerHeight: 24,
|
|
3778
|
+
markerDy: 1.5,
|
|
3779
|
+
markerDx: 1.5
|
|
3780
|
+
};
|
|
3781
|
+
const created = createSpriteMaterialByLabelSymbol2([
|
|
3782
|
+
baseSymbol,
|
|
3783
|
+
markerSymbol
|
|
3784
|
+
]);
|
|
3785
|
+
this.materialByKey.set(key, created);
|
|
3786
|
+
return created;
|
|
3787
|
+
}
|
|
3788
|
+
};
|
|
3789
|
+
|
|
3790
|
+
// src/IndoorMap/renderer/utils/angleBetweenLineString.ts
|
|
3791
|
+
var getLineCenter = (line) => {
|
|
3792
|
+
let x = 0, y = 0;
|
|
3793
|
+
for (const [lx, ly] of line) {
|
|
3794
|
+
x += lx;
|
|
3795
|
+
y += ly;
|
|
3796
|
+
}
|
|
3797
|
+
const len = line.length;
|
|
3798
|
+
return [x / len, y / len];
|
|
3799
|
+
};
|
|
3800
|
+
var angleBetweenLineStrings = (line1, line2) => {
|
|
3801
|
+
const [x1, y1] = getLineCenter(line1);
|
|
3802
|
+
const [x2, y2] = getLineCenter(line2);
|
|
3803
|
+
const dx = x2 - x1;
|
|
3804
|
+
const dy = y2 - y1;
|
|
3805
|
+
return Math.atan2(dy, dx);
|
|
3685
3806
|
};
|
|
3686
3807
|
|
|
3687
3808
|
// src/IndoorMap/renderer/RendererManager.ts
|
|
@@ -3692,25 +3813,48 @@ var RendererManager = class extends EventTarget {
|
|
|
3692
3813
|
#dataClient;
|
|
3693
3814
|
/** Elements: Responsible for converting feature info elements and add to map */
|
|
3694
3815
|
elementRenderer;
|
|
3816
|
+
markerRenderer;
|
|
3695
3817
|
elementsMap;
|
|
3696
3818
|
elementsByOrdinal;
|
|
3697
|
-
|
|
3819
|
+
currentOrdinals;
|
|
3820
|
+
markersMap;
|
|
3821
|
+
markersByOrdinal;
|
|
3822
|
+
constructor(map, dataClient, options) {
|
|
3698
3823
|
super();
|
|
3699
3824
|
this.map = map;
|
|
3700
3825
|
this.options = options;
|
|
3701
3826
|
this.elementsMap = /* @__PURE__ */ new Map();
|
|
3702
3827
|
this.elementsByOrdinal = /* @__PURE__ */ new Map();
|
|
3703
|
-
this.
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
this.elementRenderer.addEventListener("threelayer:ready", (e) => {
|
|
3711
|
-
this.dispatchEvent(new CustomEvent("renderermanager:ready"));
|
|
3712
|
-
this.#createElements();
|
|
3828
|
+
this.markersMap = /* @__PURE__ */ new Map();
|
|
3829
|
+
this.markersByOrdinal = /* @__PURE__ */ new Map();
|
|
3830
|
+
this.#dataClient = dataClient;
|
|
3831
|
+
if (options.type === "3D") {
|
|
3832
|
+
const threeLayer = new ThreeLayer3("elements", {
|
|
3833
|
+
forceRenderOnMoving: true,
|
|
3834
|
+
forceRenderOnRotating: true
|
|
3713
3835
|
});
|
|
3836
|
+
const _this = this;
|
|
3837
|
+
threeLayer.prepareToDraw = function(gl, scene, camera) {
|
|
3838
|
+
const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
|
|
3839
|
+
scene.add(ambientLight);
|
|
3840
|
+
const dirColor = 16777215;
|
|
3841
|
+
const dllight = new THREE3.DirectionalLight(dirColor, 0.8);
|
|
3842
|
+
dllight.position.set(0, -10, 10).normalize();
|
|
3843
|
+
scene.add(dllight);
|
|
3844
|
+
const hemi = new THREE3.HemisphereLight(16777215, 4473924, 0.4);
|
|
3845
|
+
scene.add(hemi);
|
|
3846
|
+
_this.elementRenderer = new Element3DRenderer(map, options.elements, threeLayer);
|
|
3847
|
+
_this.markerRenderer = new Marker3DRenderer(map, {}, threeLayer);
|
|
3848
|
+
if (typeof options.onRendererReady === "function") {
|
|
3849
|
+
options.onRendererReady();
|
|
3850
|
+
}
|
|
3851
|
+
_this.#createElements();
|
|
3852
|
+
};
|
|
3853
|
+
threeLayer.addTo(this.map);
|
|
3854
|
+
} else {
|
|
3855
|
+
this.elementRenderer = new Element2DRenderer(map, options.elements);
|
|
3856
|
+
this.markerRenderer = new Marker2DRenderer(map);
|
|
3857
|
+
this.#createElements();
|
|
3714
3858
|
}
|
|
3715
3859
|
}
|
|
3716
3860
|
getElementsByOrdinal = (ordinal) => {
|
|
@@ -3718,19 +3862,46 @@ var RendererManager = class extends EventTarget {
|
|
|
3718
3862
|
if (!exist) this.elementsByOrdinal.set(ordinal, []);
|
|
3719
3863
|
return this.elementsByOrdinal.get(ordinal);
|
|
3720
3864
|
};
|
|
3865
|
+
getMarkersByOrdinal = (ordinal) => {
|
|
3866
|
+
const exist = this.markersByOrdinal.get(ordinal);
|
|
3867
|
+
if (!exist) this.markersByOrdinal.set(ordinal, []);
|
|
3868
|
+
return this.markersByOrdinal.get(ordinal);
|
|
3869
|
+
};
|
|
3870
|
+
addElementsToManager = (id, elements, ordinal) => {
|
|
3871
|
+
this.elementsMap.set(id, elements);
|
|
3872
|
+
elements.forEach((el) => {
|
|
3873
|
+
this.getElementsByOrdinal(ordinal).push(el);
|
|
3874
|
+
});
|
|
3875
|
+
const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
|
|
3876
|
+
if (inOrdinal) {
|
|
3877
|
+
this.elementRenderer.showElements(elements, ordinal);
|
|
3878
|
+
} else {
|
|
3879
|
+
this.elementRenderer.hideElements(elements, ordinal);
|
|
3880
|
+
}
|
|
3881
|
+
};
|
|
3882
|
+
addMarkersToManager = (id, markers, ordinal) => {
|
|
3883
|
+
this.markersMap.set(id, markers);
|
|
3884
|
+
markers.forEach((el) => {
|
|
3885
|
+
this.getMarkersByOrdinal(ordinal).push(el);
|
|
3886
|
+
});
|
|
3887
|
+
const inOrdinal = Array.isArray(this.currentOrdinals) ? this.currentOrdinals.includes(ordinal) : ordinal === this.currentOrdinals;
|
|
3888
|
+
if (inOrdinal) {
|
|
3889
|
+
this.markerRenderer.showMarkers(markers, ordinal);
|
|
3890
|
+
} else {
|
|
3891
|
+
this.markerRenderer.hideMarkers(markers, ordinal);
|
|
3892
|
+
}
|
|
3893
|
+
};
|
|
3721
3894
|
async #createElements() {
|
|
3722
3895
|
const levels = await this.#dataClient.filterByType("level", {
|
|
3723
3896
|
populate: true
|
|
3724
3897
|
});
|
|
3898
|
+
const relationships = await this.#dataClient.filterByType("relationship");
|
|
3725
3899
|
const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
|
|
3726
3900
|
fixtures.forEach((fixture) => {
|
|
3727
3901
|
const element = this.elementRenderer.createGeometry(fixture);
|
|
3728
3902
|
if (element) {
|
|
3729
3903
|
const _elements = Array.isArray(element) ? element : [element];
|
|
3730
|
-
|
|
3731
|
-
this.elementsMap.set(fixture.id, el);
|
|
3732
|
-
this.getElementsByOrdinal(fixture.properties.level.properties.ordinal).push(el);
|
|
3733
|
-
});
|
|
3904
|
+
this.addElementsToManager(fixture.id, _elements, fixture.properties.level.properties.ordinal);
|
|
3734
3905
|
}
|
|
3735
3906
|
});
|
|
3736
3907
|
const units = await this.#dataClient.filterByType("unit", {
|
|
@@ -3742,10 +3913,7 @@ var RendererManager = class extends EventTarget {
|
|
|
3742
3913
|
const element = this.elementRenderer.createGeometry(unit);
|
|
3743
3914
|
if (element) {
|
|
3744
3915
|
const _elements = Array.isArray(element) ? element : [element];
|
|
3745
|
-
|
|
3746
|
-
this.elementsMap.set(unit.id, el);
|
|
3747
|
-
this.getElementsByOrdinal(unit.properties.level.properties.ordinal).push(el);
|
|
3748
|
-
});
|
|
3916
|
+
this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
|
|
3749
3917
|
}
|
|
3750
3918
|
});
|
|
3751
3919
|
const kiosks = await this.#dataClient.filterByType("kiosk", {
|
|
@@ -3755,32 +3923,85 @@ var RendererManager = class extends EventTarget {
|
|
|
3755
3923
|
const element = this.elementRenderer.createGeometry(kiosk);
|
|
3756
3924
|
if (element) {
|
|
3757
3925
|
const _elements = Array.isArray(element) ? element : [element];
|
|
3758
|
-
|
|
3759
|
-
this.elementsMap.set(kiosk.id, el);
|
|
3760
|
-
this.getElementsByOrdinal(kiosk.properties.level.properties.ordinal).push(el);
|
|
3761
|
-
});
|
|
3926
|
+
this.addElementsToManager(kiosk.id, _elements, kiosk.properties.level.properties.ordinal);
|
|
3762
3927
|
}
|
|
3763
3928
|
});
|
|
3929
|
+
const escalators = units.filter((u) => u.properties.category === "escalator");
|
|
3930
|
+
for (const escalator of escalators) {
|
|
3931
|
+
try {
|
|
3932
|
+
const escalatorRelationships = relationships.filter((r) => (r.properties?.intermediary || []).some((inter) => inter.id === escalator.id));
|
|
3933
|
+
if (escalatorRelationships.length === 0) {
|
|
3934
|
+
throw new Error("Cannot find escalator relationship");
|
|
3935
|
+
}
|
|
3936
|
+
if (escalatorRelationships.length > 1) {
|
|
3937
|
+
throw new Error("Found more than one relationship");
|
|
3938
|
+
}
|
|
3939
|
+
const thisOrdinal = escalator.properties.ordinal;
|
|
3940
|
+
const relationship = escalatorRelationships[0];
|
|
3941
|
+
const bothOpeningIds = [relationship.properties.origin.id, relationship.properties.destination.id];
|
|
3942
|
+
const bothOpenings = await Promise.all(
|
|
3943
|
+
bothOpeningIds.map((id) => this.#dataClient.findById("opening", id, { populate: true }))
|
|
3944
|
+
);
|
|
3945
|
+
const thisLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal === thisOrdinal);
|
|
3946
|
+
const thatLevelOpening = bothOpenings.find((opening) => opening.properties.ordinal !== thisOrdinal);
|
|
3947
|
+
const angle = angleBetweenLineStrings(thisLevelOpening.geometry.coordinates, thatLevelOpening.geometry.coordinates);
|
|
3948
|
+
const direction = thisOrdinal < thatLevelOpening.properties.ordinal ? "up" : "down";
|
|
3949
|
+
const escalatorEntryPoint = turfCenter2(thisLevelOpening).geometry.coordinates;
|
|
3950
|
+
const element = await this.elementRenderer.createEscalator(escalator, escalatorEntryPoint, { direction, angle });
|
|
3951
|
+
if (element) {
|
|
3952
|
+
const _elements = Array.isArray(element) ? element : [element];
|
|
3953
|
+
this.addElementsToManager(escalator.id, _elements, escalator.properties.ordinal);
|
|
3954
|
+
}
|
|
3955
|
+
} catch (err) {
|
|
3956
|
+
console.log(`cannot create escalator`, err);
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
this.changeLevelByOrdinal(this.currentOrdinals);
|
|
3764
3960
|
this.dispatchEvent(new CustomEvent("renderermanager:elements_created"));
|
|
3765
3961
|
}
|
|
3766
3962
|
changeLevelByOrdinal(targetOrdinal) {
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3963
|
+
this.currentOrdinals = targetOrdinal;
|
|
3964
|
+
if (targetOrdinal === null) {
|
|
3965
|
+
const baseOrdinal = 0;
|
|
3966
|
+
for (const [ordinal, elements] of this.elementsByOrdinal) {
|
|
3967
|
+
this.elementRenderer.showElements(elements, ordinal - baseOrdinal);
|
|
3968
|
+
}
|
|
3969
|
+
for (const [ordinal, markers] of this.markersByOrdinal) {
|
|
3970
|
+
this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
|
|
3971
|
+
}
|
|
3972
|
+
} else {
|
|
3973
|
+
const baseOrdinal = Array.isArray(targetOrdinal) ? _min(targetOrdinal) : targetOrdinal;
|
|
3974
|
+
for (const [ordinal, elements] of this.elementsByOrdinal) {
|
|
3975
|
+
const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
|
|
3976
|
+
if (inOrdinal) {
|
|
3977
|
+
this.elementRenderer.showElements(elements, ordinal - baseOrdinal);
|
|
3978
|
+
} else {
|
|
3979
|
+
this.elementRenderer.hideElements(elements, ordinal - baseOrdinal);
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
for (const [ordinal, markers] of this.markersByOrdinal) {
|
|
3983
|
+
const inOrdinal = Array.isArray(targetOrdinal) ? targetOrdinal.includes(ordinal) : ordinal === targetOrdinal;
|
|
3984
|
+
if (inOrdinal) {
|
|
3985
|
+
this.markerRenderer.showMarkers(markers, ordinal - baseOrdinal);
|
|
3986
|
+
} else {
|
|
3987
|
+
this.markerRenderer.hideMarkers(markers, ordinal - baseOrdinal);
|
|
3988
|
+
}
|
|
3777
3989
|
}
|
|
3778
3990
|
}
|
|
3779
3991
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3992
|
+
/**
|
|
3993
|
+
* ========================================================================
|
|
3994
|
+
* Markers
|
|
3995
|
+
* ======================================================================== */
|
|
3996
|
+
createMarker(coordinate, ordinal, text, options) {
|
|
3997
|
+
const marker = this.markerRenderer.createMarker(coordinate, ordinal, text, options);
|
|
3998
|
+
const markerId = `${this.markersMap.size + 1}`;
|
|
3999
|
+
this.addMarkersToManager(markerId, [marker], ordinal);
|
|
4000
|
+
}
|
|
4001
|
+
clearMarkers() {
|
|
4002
|
+
for (const [markerId, marker] of this.markersMap) {
|
|
4003
|
+
this.markerRenderer.removeMarker(marker);
|
|
4004
|
+
}
|
|
3784
4005
|
}
|
|
3785
4006
|
};
|
|
3786
4007
|
|
|
@@ -3855,6 +4076,7 @@ var IndoorMap = class extends EventTarget {
|
|
|
3855
4076
|
center: INITIAL_CENTER,
|
|
3856
4077
|
zoom: INITIAL_ZOOM,
|
|
3857
4078
|
clickTimeThreshold: 600,
|
|
4079
|
+
centerCross: options.centerCross ?? false,
|
|
3858
4080
|
baseLayer: new TileLayer("base", {
|
|
3859
4081
|
urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
|
3860
4082
|
subdomains: ["a", "b", "c", "d"],
|
|
@@ -3866,13 +4088,7 @@ var IndoorMap = class extends EventTarget {
|
|
|
3866
4088
|
}),
|
|
3867
4089
|
layers: []
|
|
3868
4090
|
});
|
|
3869
|
-
this.rendererManager = new RendererManager(this.map, options.renderer);
|
|
3870
|
-
this.rendererManager.addEventListener("renderermanager:ready", (e) => {
|
|
3871
|
-
this.dispatchEvent(new CustomEvent("renderer:ready"));
|
|
3872
|
-
});
|
|
3873
|
-
this.rendererManager.addEventListener("renderermanager:elements_created", (e) => {
|
|
3874
|
-
this.dispatchEvent(new CustomEvent("renderer:elements_created"));
|
|
3875
|
-
});
|
|
4091
|
+
this.rendererManager = new RendererManager(this.map, options.dataClient, options.renderer);
|
|
3876
4092
|
this.camera = new CameraManager(this.map);
|
|
3877
4093
|
this.locale = locale;
|
|
3878
4094
|
this.pixelRatio = pixelRatio;
|
|
@@ -3885,12 +4101,14 @@ var IndoorMap = class extends EventTarget {
|
|
|
3885
4101
|
set dataClient(value) {
|
|
3886
4102
|
this.#dataClient = value;
|
|
3887
4103
|
this.#dataClient.filterByType("venue").then((venues) => {
|
|
3888
|
-
const venueCenters =
|
|
4104
|
+
const venueCenters = turfCenter3(featureCollection(venues));
|
|
3889
4105
|
const [x, y] = venueCenters.geometry.coordinates;
|
|
3890
|
-
const center2 = new
|
|
4106
|
+
const center2 = new Coordinate4(x, y);
|
|
3891
4107
|
this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
|
|
3892
4108
|
});
|
|
3893
|
-
|
|
4109
|
+
}
|
|
4110
|
+
on(eventName, handler) {
|
|
4111
|
+
this.map.on(eventName, handler);
|
|
3894
4112
|
}
|
|
3895
4113
|
/**
|
|
3896
4114
|
* Events
|
|
@@ -4011,31 +4229,6 @@ var IndoorMap = class extends EventTarget {
|
|
|
4011
4229
|
);
|
|
4012
4230
|
}
|
|
4013
4231
|
}
|
|
4014
|
-
#createLayers() {
|
|
4015
|
-
const map = this.map;
|
|
4016
|
-
if (!this.ordinals || this.ordinals.length === 0) return;
|
|
4017
|
-
LAYERS.forEach((layerKey) => {
|
|
4018
|
-
const layerID = layerKey;
|
|
4019
|
-
const option = LAYER_OPTIONS[layerKey];
|
|
4020
|
-
const layer = new VectorLayer2(layerID, option);
|
|
4021
|
-
map.addLayer(layer);
|
|
4022
|
-
});
|
|
4023
|
-
const threeLayer = new ThreeLayer4("t_building", {
|
|
4024
|
-
forceRenderOnMoving: true,
|
|
4025
|
-
forceRenderOnRotating: true
|
|
4026
|
-
});
|
|
4027
|
-
this.threeLayer = threeLayer;
|
|
4028
|
-
threeLayer.addTo(this.map);
|
|
4029
|
-
}
|
|
4030
|
-
#initMapElements() {
|
|
4031
|
-
this.#createLayers();
|
|
4032
|
-
const threeLayer = this.threeLayer;
|
|
4033
|
-
if (threeLayer) {
|
|
4034
|
-
this.threeLayer.prepareToDraw = async (gl, scene, camera) => {
|
|
4035
|
-
await this.#createElements();
|
|
4036
|
-
};
|
|
4037
|
-
}
|
|
4038
|
-
}
|
|
4039
4232
|
handleClickElement = (e) => {
|
|
4040
4233
|
if (this.#isClicked) return;
|
|
4041
4234
|
this.#isClicked = true;
|
|
@@ -4047,29 +4240,22 @@ var IndoorMap = class extends EventTarget {
|
|
|
4047
4240
|
setCenter(center2, padding) {
|
|
4048
4241
|
this.map.setCenter(center2, padding);
|
|
4049
4242
|
}
|
|
4050
|
-
async #
|
|
4243
|
+
async #legacy_createElements() {
|
|
4051
4244
|
const {
|
|
4052
4245
|
// 2D
|
|
4053
4246
|
createVenue,
|
|
4054
|
-
createLevel,
|
|
4055
|
-
createUnit,
|
|
4056
4247
|
createOpening,
|
|
4057
4248
|
createSection,
|
|
4058
4249
|
createFixture,
|
|
4059
|
-
createKiosk,
|
|
4060
4250
|
createOccupant,
|
|
4061
4251
|
createDecoration,
|
|
4062
4252
|
// 3D
|
|
4063
4253
|
create3DFootprint,
|
|
4064
4254
|
create3DGroundLabel,
|
|
4065
4255
|
create3DBillboard,
|
|
4066
|
-
create3DUnit,
|
|
4067
|
-
create3DKiosk,
|
|
4068
4256
|
createVenue3DModel,
|
|
4069
4257
|
createExtrudedUnit,
|
|
4070
|
-
createExtrudedLevel,
|
|
4071
4258
|
create3DFixture,
|
|
4072
|
-
createExtrudedKiosk,
|
|
4073
4259
|
create3DAmenityMarker,
|
|
4074
4260
|
create3DOccupantAmenityMarker,
|
|
4075
4261
|
create3DOpeningMarker,
|
|
@@ -4126,53 +4312,6 @@ var IndoorMap = class extends EventTarget {
|
|
|
4126
4312
|
});
|
|
4127
4313
|
break;
|
|
4128
4314
|
}
|
|
4129
|
-
case "level": {
|
|
4130
|
-
const extrudedLevel = createExtrudedLevel(
|
|
4131
|
-
feature2,
|
|
4132
|
-
this.threeLayer,
|
|
4133
|
-
featureExtrudeConfig
|
|
4134
|
-
);
|
|
4135
|
-
if (extrudedLevel) {
|
|
4136
|
-
extrudedLevel.on("click", this.handleClickElement);
|
|
4137
|
-
object3ds.push(extrudedLevel);
|
|
4138
|
-
} else {
|
|
4139
|
-
geometry = createLevel(feature2).addTo(layer);
|
|
4140
|
-
}
|
|
4141
|
-
break;
|
|
4142
|
-
}
|
|
4143
|
-
case "unit": {
|
|
4144
|
-
const models = await create3DUnit(feature2, this.threeLayer);
|
|
4145
|
-
models.forEach((model) => {
|
|
4146
|
-
model.on("click", this.handleClickElement);
|
|
4147
|
-
object3ds.push(model);
|
|
4148
|
-
this.#glbObjects.push(model);
|
|
4149
|
-
});
|
|
4150
|
-
const locatedLevel = feature2?.properties?.level;
|
|
4151
|
-
const levelExtrudeConfig = getExtrudeConfigByFeature(
|
|
4152
|
-
extrudeConfig,
|
|
4153
|
-
locatedLevel
|
|
4154
|
-
);
|
|
4155
|
-
const levelHeight = levelExtrudeConfig?.height ?? 0;
|
|
4156
|
-
const option = { ...featureExtrudeConfig, altitude: levelHeight };
|
|
4157
|
-
const hasAddedModel3d = models?.length > 0;
|
|
4158
|
-
if (hasAddedModel3d || !featureExtrudeConfig) {
|
|
4159
|
-
geometry = createUnit(feature2)?.on("click", this.handleClickElement).addTo(layer);
|
|
4160
|
-
} else {
|
|
4161
|
-
const extrudedUnit = createExtrudedUnit(
|
|
4162
|
-
feature2,
|
|
4163
|
-
this.threeLayer,
|
|
4164
|
-
option
|
|
4165
|
-
);
|
|
4166
|
-
extrudedUnit.on("click", this.handleClickElement);
|
|
4167
|
-
extrudedUnit.on("touchstart", (e) => {
|
|
4168
|
-
this.#touchStartTarget = e.target;
|
|
4169
|
-
this.#touchStartPoint = e.containerPoint;
|
|
4170
|
-
this.map.on("touchend", this.handleMapTouchEnd);
|
|
4171
|
-
});
|
|
4172
|
-
object3ds.push(extrudedUnit);
|
|
4173
|
-
}
|
|
4174
|
-
break;
|
|
4175
|
-
}
|
|
4176
4315
|
case "amenity": {
|
|
4177
4316
|
if (feature2.properties.is_featured) {
|
|
4178
4317
|
const billboardObj = create3DBillboard(feature2, this.threeLayer);
|
|
@@ -4195,7 +4334,7 @@ var IndoorMap = class extends EventTarget {
|
|
|
4195
4334
|
case "opening": {
|
|
4196
4335
|
switch (category) {
|
|
4197
4336
|
case "emergencyexit":
|
|
4198
|
-
const { geometry: geometry2 } =
|
|
4337
|
+
const { geometry: geometry2 } = turfCenter3(feature2);
|
|
4199
4338
|
const markerFeature = {
|
|
4200
4339
|
...feature2,
|
|
4201
4340
|
geometry: geometry2
|
|
@@ -4311,34 +4450,6 @@ var IndoorMap = class extends EventTarget {
|
|
|
4311
4450
|
}
|
|
4312
4451
|
break;
|
|
4313
4452
|
}
|
|
4314
|
-
case "kiosk": {
|
|
4315
|
-
const models = await create3DKiosk(feature2, this.threeLayer);
|
|
4316
|
-
models.forEach((model) => {
|
|
4317
|
-
model.on("click", this.handleClickElement);
|
|
4318
|
-
object3ds.push(model);
|
|
4319
|
-
this.#glbObjects.push(model);
|
|
4320
|
-
});
|
|
4321
|
-
const locatedLevel = feature2?.properties?.level;
|
|
4322
|
-
const levelExtrudeConfig = getExtrudeConfigByFeature(
|
|
4323
|
-
extrudeConfig,
|
|
4324
|
-
locatedLevel
|
|
4325
|
-
);
|
|
4326
|
-
const levelHeight = _6.get(levelExtrudeConfig, "height", 0);
|
|
4327
|
-
const option = { ...featureExtrudeConfig, altitude: levelHeight };
|
|
4328
|
-
const hasAddedModel3d = models?.length > 0;
|
|
4329
|
-
if (hasAddedModel3d || !featureExtrudeConfig) {
|
|
4330
|
-
geometry = createKiosk(feature2)?.on("click", this.handleClickElement).addTo(layer);
|
|
4331
|
-
} else {
|
|
4332
|
-
const extrudedKiosk = createExtrudedKiosk(
|
|
4333
|
-
feature2,
|
|
4334
|
-
this.threeLayer,
|
|
4335
|
-
option
|
|
4336
|
-
);
|
|
4337
|
-
extrudedKiosk.on("click", this.handleClickElement);
|
|
4338
|
-
object3ds.push(extrudedKiosk);
|
|
4339
|
-
}
|
|
4340
|
-
break;
|
|
4341
|
-
}
|
|
4342
4453
|
case "footprint": {
|
|
4343
4454
|
const objects = await create3DFootprint(
|
|
4344
4455
|
feature2,
|
|
@@ -4349,7 +4460,7 @@ var IndoorMap = class extends EventTarget {
|
|
|
4349
4460
|
object.on("click", () => {
|
|
4350
4461
|
const {
|
|
4351
4462
|
geometry: { coordinates }
|
|
4352
|
-
} =
|
|
4463
|
+
} = turfCenter3(feature2);
|
|
4353
4464
|
this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
|
|
4354
4465
|
});
|
|
4355
4466
|
object3ds.push(object);
|
|
@@ -4417,7 +4528,6 @@ var IndoorMap = class extends EventTarget {
|
|
|
4417
4528
|
);
|
|
4418
4529
|
}
|
|
4419
4530
|
});
|
|
4420
|
-
this.render();
|
|
4421
4531
|
this.#elements = elements;
|
|
4422
4532
|
this.#elementsLoaded = true;
|
|
4423
4533
|
this.#featuresInitted = true;
|
|
@@ -4428,39 +4538,6 @@ var IndoorMap = class extends EventTarget {
|
|
|
4428
4538
|
const layer = this.map.getLayer(layerName);
|
|
4429
4539
|
if (layer) layer.clear();
|
|
4430
4540
|
};
|
|
4431
|
-
#showGeometriesByOrdinal(ordinal) {
|
|
4432
|
-
_6(this.#elements).filter((element) => !!_6.get(element, "geometry")).forEach(({ featureType, geometry, properties }) => {
|
|
4433
|
-
const show = ordinal === null || properties?.ordinal === ordinal || featureType === "venue";
|
|
4434
|
-
const layerName = _6.get(
|
|
4435
|
-
LAYER_FEATURE_TYPE_OBJ,
|
|
4436
|
-
featureType,
|
|
4437
|
-
featureType
|
|
4438
|
-
);
|
|
4439
|
-
const layer = this.map.getLayer(layerName);
|
|
4440
|
-
if (!layer) return;
|
|
4441
|
-
if (geometry instanceof ui3.UIMarker)
|
|
4442
|
-
return show ? geometry?.addTo(this.map) : geometry.remove();
|
|
4443
|
-
show ? layer.addGeometry(geometry) : layer.removeGeometry(geometry);
|
|
4444
|
-
if (geometry._animPlayer instanceof animation.Player) {
|
|
4445
|
-
const animPlayer = geometry?._animPlayer;
|
|
4446
|
-
show ? animPlayer.play() : animPlayer.cancel();
|
|
4447
|
-
}
|
|
4448
|
-
});
|
|
4449
|
-
}
|
|
4450
|
-
#showThreeObjectByOrdinal = (ordinal) => {
|
|
4451
|
-
const threeLayer = this.threeLayer;
|
|
4452
|
-
const objectsToAdd = [];
|
|
4453
|
-
const objects = this.#object3ds || [];
|
|
4454
|
-
objects?.forEach((baseObject) => {
|
|
4455
|
-
const objectOrdinal = _6.get(baseObject, "properties.ordinal");
|
|
4456
|
-
const featureType = _6.get(baseObject, "properties.feature_type");
|
|
4457
|
-
const isAdd = _6.get(baseObject, "isAdd");
|
|
4458
|
-
const show = Boolean(objectOrdinal === ordinal) || ALWAYS_VISIBLE_FEATURE_TYPES.includes(featureType);
|
|
4459
|
-
if (show) return objectsToAdd.push(baseObject);
|
|
4460
|
-
if (isAdd) return threeLayer.removeMesh(baseObject);
|
|
4461
|
-
});
|
|
4462
|
-
threeLayer.addMesh(objectsToAdd);
|
|
4463
|
-
};
|
|
4464
4541
|
/**
|
|
4465
4542
|
* Change Level & animate to path / geometry / view / etc.
|
|
4466
4543
|
* ================================== */
|
|
@@ -4468,8 +4545,8 @@ var IndoorMap = class extends EventTarget {
|
|
|
4468
4545
|
this.rendererManager.changeLevelByOrdinal(ordinal);
|
|
4469
4546
|
}
|
|
4470
4547
|
getFeatureExtent = (feature2, scaleFactor = 1) => {
|
|
4471
|
-
const [minX, minY, maxX, maxY] =
|
|
4472
|
-
scale(bboxPolygon(
|
|
4548
|
+
const [minX, minY, maxX, maxY] = index_default(
|
|
4549
|
+
scale(bboxPolygon(index_default(feature2)), scaleFactor)
|
|
4473
4550
|
);
|
|
4474
4551
|
return new Extent(minX, minY, maxX, maxY);
|
|
4475
4552
|
};
|
|
@@ -4512,12 +4589,12 @@ var IndoorMap = class extends EventTarget {
|
|
|
4512
4589
|
);
|
|
4513
4590
|
};
|
|
4514
4591
|
//map animation
|
|
4515
|
-
addAnimations(
|
|
4516
|
-
this.#animationsToRun.push(
|
|
4592
|
+
addAnimations(animation) {
|
|
4593
|
+
this.#animationsToRun.push(animation);
|
|
4517
4594
|
}
|
|
4518
4595
|
removeAnimationById(id) {
|
|
4519
4596
|
this.#animationsToRun = this.#animationsToRun.filter(
|
|
4520
|
-
(
|
|
4597
|
+
(animation) => animation.id !== id
|
|
4521
4598
|
);
|
|
4522
4599
|
}
|
|
4523
4600
|
clearAnimations() {
|
|
@@ -5146,5 +5223,4 @@ export {
|
|
|
5146
5223
|
styledFeatureGenerator
|
|
5147
5224
|
};
|
|
5148
5225
|
//! Use outerHTML to return HTML string instead of element object to avoid DOM event warnings from Maptalks.js.
|
|
5149
|
-
//! Prevent animating geometry from stopping after being removed and re-added to the layer.
|
|
5150
5226
|
//# sourceMappingURL=index.mjs.map
|