@mapless/core 0.1.0 → 1.0.11
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.js +904 -141
- package/dist/types/Mapless/icons/icons.d.ts +1 -0
- package/dist/types/Mapless/icons/icons.d.ts.map +1 -1
- package/dist/types/Mapless/mana/movable.d.ts +19 -3
- package/dist/types/Mapless/mana/movable.d.ts.map +1 -1
- package/dist/types/Mapless/mana/newstation.d.ts.map +1 -1
- package/dist/types/Mapless/mana-3d/airspace.d.ts +41 -12
- package/dist/types/Mapless/mana-3d/airspace.d.ts.map +1 -1
- package/dist/types/Mapless/mana-3d/index.d.ts +4 -3
- package/dist/types/Mapless/mana-3d/index.d.ts.map +1 -1
- package/dist/types/Mapless/mana-3d/mapModel.d.ts +103 -3
- package/dist/types/Mapless/mana-3d/mapModel.d.ts.map +1 -1
- package/dist/types/Mapless/mana-three/index.d.ts +2 -1
- package/dist/types/Mapless/mana-three/index.d.ts.map +1 -1
- package/dist/types/Mapless/mana-three/instancedModel.d.ts +127 -0
- package/dist/types/Mapless/mana-three/instancedModel.d.ts.map +1 -0
- package/dist/types/Mapless/mana-three/line2Manager.d.ts +1 -1
- package/dist/types/Mapless/mana-three/line2Manager.d.ts.map +1 -1
- package/dist/types/Mapless/mana-three/three.d.ts +99 -1
- package/dist/types/Mapless/mana-three/three.d.ts.map +1 -1
- package/dist/types/Mapless/path/PathTracker.d.ts.map +1 -1
- package/dist/types/Mapless/path/attach.d.ts +1 -1
- package/dist/types/Mapless/path/attach.d.ts.map +1 -1
- package/dist/types/Mapless/path/strategies/click.d.ts.map +1 -1
- package/dist/types/Mapless/path/strategies/free.d.ts.map +1 -1
- package/dist/types/Mapless/types.d.ts +20 -0
- package/dist/types/Mapless/types.d.ts.map +1 -1
- package/dist/types/Three/MapThree.d.ts +39 -0
- package/dist/types/Three/MapThree.d.ts.map +1 -1
- package/dist/types/Three/ModelCache.d.ts +68 -0
- package/dist/types/Three/ModelCache.d.ts.map +1 -0
- package/dist/types/Three/types.d.ts +7 -12
- package/dist/types/Three/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { area as turf_area, center as turf_center, centroid, circle, distance as turf_distance, ellipse, length as turf_length, pointsWithinPolygon, polygon as turf_polygon } from "@turf/turf";
|
|
2
2
|
import mapbox_gl, { LngLat, MapMouseEvent, Marker, MercatorCoordinate, Popup } from "mapbox-gl";
|
|
3
|
-
import { AmbientLight, AnimationMixer, BoxGeometry, BufferGeometry, CatmullRomCurve3, Clock, Color, ConeGeometry, CurvePath, CylinderGeometry, DirectionalLight, DoubleSide, Group, Line, LineBasicMaterial, LineCurve3, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, PerspectiveCamera, PointLight, Scene, SphereGeometry, SpotLight, TorusGeometry, TubeGeometry, Vector3, WebGLRenderer } from "three";
|
|
3
|
+
import { AmbientLight, AnimationMixer, BoxGeometry, BoxHelper, BufferGeometry, CatmullRomCurve3, Clock, Color, ConeGeometry, CurvePath, CylinderGeometry, DirectionalLight, DoubleSide, Group, InstancedMesh, Line, LineBasicMaterial, LineCurve3, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, Object3D, PerspectiveCamera, PointLight, Raycaster, Scene, SphereGeometry, SpotLight, TorusGeometry, TubeGeometry, Vector3, Vector4, WebGLRenderer } from "three";
|
|
4
4
|
import gcoord from "gcoord";
|
|
5
5
|
import mapbox_gl_draw from "@mapbox/mapbox-gl-draw";
|
|
6
6
|
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
|
|
7
|
-
import { GLTFLoader, Line2, LineGeometry, LineMaterial } from "three-stdlib";
|
|
7
|
+
import { DRACOLoader, GLTFLoader, Line2, LineGeometry, LineMaterial } from "three-stdlib";
|
|
8
8
|
class MapThree {
|
|
9
9
|
mapless = void 0;
|
|
10
10
|
scene = null;
|
|
@@ -16,6 +16,7 @@ class MapThree {
|
|
|
16
16
|
renderableObjects = new Map();
|
|
17
17
|
isInitialized = false;
|
|
18
18
|
customLayerId = null;
|
|
19
|
+
lastProjectionMatrix = null;
|
|
19
20
|
constructor(props){
|
|
20
21
|
const { mapless } = props;
|
|
21
22
|
this.mapless = mapless;
|
|
@@ -54,6 +55,7 @@ class MapThree {
|
|
|
54
55
|
renderableObj.mesh.visible = false;
|
|
55
56
|
});
|
|
56
57
|
this.camera.projectionMatrix = m;
|
|
58
|
+
this.lastProjectionMatrix = m.clone();
|
|
57
59
|
this.renderer.resetState();
|
|
58
60
|
this.renderer.render(this.scene, this.camera);
|
|
59
61
|
this.renderableObjects.forEach((renderableObj)=>{
|
|
@@ -317,6 +319,140 @@ class MapThree {
|
|
|
317
319
|
this.removeRenderableObject(id);
|
|
318
320
|
});
|
|
319
321
|
}
|
|
322
|
+
raycast(point, objects, tolerance = 30) {
|
|
323
|
+
if (!this.camera || !this.scene || !this.renderer) return null;
|
|
324
|
+
const map = this.mapless?.map;
|
|
325
|
+
if (!map) return null;
|
|
326
|
+
const mapContainer = map.getCanvas();
|
|
327
|
+
const ndcX = point.x / mapContainer.width * 2 - 1;
|
|
328
|
+
const ndcY = 2 * -(point.y / mapContainer.height) + 1;
|
|
329
|
+
const targetObjects = objects || Array.from(this.renderableObjects.values()).map((obj)=>obj.mesh);
|
|
330
|
+
let closestHit = null;
|
|
331
|
+
let minDistance = 1 / 0;
|
|
332
|
+
const screenPositions = new Map();
|
|
333
|
+
for (const targetObj of targetObjects){
|
|
334
|
+
const renderableObj = Array.from(this.renderableObjects.values()).find((obj)=>obj.mesh === targetObj);
|
|
335
|
+
if (renderableObj && this.lastProjectionMatrix) {
|
|
336
|
+
let l;
|
|
337
|
+
if (renderableObj.transform.matrix) l = renderableObj.transform.matrix.clone();
|
|
338
|
+
else {
|
|
339
|
+
l = new Matrix4().makeTranslation(renderableObj.transform.translateX, renderableObj.transform.translateY, renderableObj.transform.translateZ).scale(new Vector3(renderableObj.transform.scale, -renderableObj.transform.scale, renderableObj.transform.scale));
|
|
340
|
+
if (void 0 !== renderableObj.transform.rotateX || void 0 !== renderableObj.transform.rotateY || void 0 !== renderableObj.transform.rotateZ) {
|
|
341
|
+
const rotationX = new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), renderableObj.transform.rotateX || 0);
|
|
342
|
+
const rotationY = new Matrix4().makeRotationAxis(new Vector3(0, 1, 0), renderableObj.transform.rotateY || 0);
|
|
343
|
+
const rotationZ = new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), renderableObj.transform.rotateZ || 0);
|
|
344
|
+
l.multiply(rotationX).multiply(rotationY).multiply(rotationZ);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const mvpMatrix = this.lastProjectionMatrix.clone().multiply(l);
|
|
348
|
+
const inverseMVP = mvpMatrix.invert();
|
|
349
|
+
const nearPoint = new Vector4(ndcX, ndcY, -1, 1).applyMatrix4(inverseMVP);
|
|
350
|
+
nearPoint.divideScalar(nearPoint.w);
|
|
351
|
+
const farPoint = new Vector4(ndcX, ndcY, 1, 1).applyMatrix4(inverseMVP);
|
|
352
|
+
farPoint.divideScalar(farPoint.w);
|
|
353
|
+
const origin = new Vector3(nearPoint.x, nearPoint.y, nearPoint.z);
|
|
354
|
+
const direction = new Vector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z).normalize();
|
|
355
|
+
const raycaster = new Raycaster(origin, direction);
|
|
356
|
+
const intersects = raycaster.intersectObject(targetObj, true);
|
|
357
|
+
const centerPoint = new Vector4(0, 0, 0, 1).applyMatrix4(mvpMatrix);
|
|
358
|
+
const screenX = (centerPoint.x / centerPoint.w + 1) * 0.5 * mapContainer.width;
|
|
359
|
+
const screenY = (-centerPoint.y / centerPoint.w + 1) * 0.5 * mapContainer.height;
|
|
360
|
+
const depth = centerPoint.z / centerPoint.w;
|
|
361
|
+
const scale = renderableObj.transform.scale;
|
|
362
|
+
const screenRadius = 50 * scale / Math.abs(depth);
|
|
363
|
+
screenPositions.set(targetObj, {
|
|
364
|
+
x: screenX,
|
|
365
|
+
y: screenY,
|
|
366
|
+
radius: screenRadius
|
|
367
|
+
});
|
|
368
|
+
if (intersects.length > 0 && intersects[0].distance < minDistance) {
|
|
369
|
+
minDistance = intersects[0].distance;
|
|
370
|
+
closestHit = {
|
|
371
|
+
object: intersects[0].object,
|
|
372
|
+
distance: intersects[0].distance,
|
|
373
|
+
point: intersects[0].point
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
if (!closestHit) for (const [obj, screenPos] of screenPositions){
|
|
379
|
+
const dx = screenPos.x - point.x;
|
|
380
|
+
const dy = screenPos.y - point.y;
|
|
381
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
382
|
+
if (distance < Math.max(screenPos.radius, tolerance)) return {
|
|
383
|
+
object: obj,
|
|
384
|
+
distance: 0,
|
|
385
|
+
point: new Vector3()
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return closestHit;
|
|
389
|
+
}
|
|
390
|
+
registerRenderableObjectClick(id, onClick, tolerance = 30) {
|
|
391
|
+
const renderableObj = this.renderableObjects.get(id);
|
|
392
|
+
if (!renderableObj) {
|
|
393
|
+
console.warn(`RenderableObject with id "${id}" not found`);
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
const map = this.mapless?.map;
|
|
397
|
+
if (!map) {
|
|
398
|
+
console.warn('Map not initialized');
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
const handleClick = (e)=>{
|
|
402
|
+
map.triggerRepaint();
|
|
403
|
+
requestAnimationFrame(()=>{
|
|
404
|
+
const point = {
|
|
405
|
+
x: e.point.x,
|
|
406
|
+
y: e.point.y
|
|
407
|
+
};
|
|
408
|
+
const hit = this.raycast(point, [
|
|
409
|
+
renderableObj.mesh
|
|
410
|
+
], tolerance);
|
|
411
|
+
if (hit?.object) onClick(hit.object, hit.point);
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
map.on('click', handleClick);
|
|
415
|
+
return ()=>{
|
|
416
|
+
map.off('click', handleClick);
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
registerGlobalClick(onClick) {
|
|
420
|
+
const map = this.mapless?.map;
|
|
421
|
+
if (!map) {
|
|
422
|
+
console.warn('Map not initialized');
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
const handleClick = (e)=>{
|
|
426
|
+
const point = {
|
|
427
|
+
x: e.point.x,
|
|
428
|
+
y: e.point.y
|
|
429
|
+
};
|
|
430
|
+
const hit = this.raycast(point);
|
|
431
|
+
if (hit) {
|
|
432
|
+
let renderableId;
|
|
433
|
+
for (const [id, obj] of this.renderableObjects)if (this.isObjectInHierarchy(hit.object, obj.mesh)) {
|
|
434
|
+
renderableId = id;
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
onClick({
|
|
438
|
+
...hit,
|
|
439
|
+
renderableId
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
map.on('click', handleClick);
|
|
444
|
+
return ()=>{
|
|
445
|
+
map.off('click', handleClick);
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
isObjectInHierarchy(obj, root) {
|
|
449
|
+
let current = obj;
|
|
450
|
+
while(current){
|
|
451
|
+
if (current === root) return true;
|
|
452
|
+
current = current.parent;
|
|
453
|
+
}
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
320
456
|
dispose() {
|
|
321
457
|
this.clear();
|
|
322
458
|
this.clearRenderableObjects();
|
|
@@ -832,6 +968,7 @@ const mona_loading_default_namespaceObject = "data:image/gif;base64,R0lGODlhgAGA
|
|
|
832
968
|
const center_namespaceObject = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjIxMTZBRkZCNkJFRDExRUY4RTc4ODI1OTI5RDg2NEIzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjIxMTZBRkZDNkJFRDExRUY4RTc4ODI1OTI5RDg2NEIzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MjExNkFGRjk2QkVEMTFFRjhFNzg4MjU5MjlEODY0QjMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MjExNkFGRkE2QkVEMTFFRjhFNzg4MjU5MjlEODY0QjMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7kzyMtAAAGuElEQVR42uxd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";
|
|
833
969
|
const fly_namespaceObject = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjFGODkyQTNFNkJFRDExRUZCQzQzOTRDMjJCMTlEMDU3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjFGODkyQTNGNkJFRDExRUZCQzQzOTRDMjJCMTlEMDU3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MUY4OTJBM0M2QkVEMTFFRkJDNDM5NEMyMkIxOUQwNTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MUY4OTJBM0Q2QkVEMTFFRkJDNDM5NEMyMkIxOUQwNTciLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6Kn+fFAAAJmElEQVR42uxd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";
|
|
834
970
|
const car_namespaceObject = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjFFQjNCNEQ4NkJFRDExRUY5RDFCQzVGRTFERTM5QURDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjFFQjNCNEQ5NkJFRDExRUY5RDFCQzVGRTFERTM5QURDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MUVCM0I0RDY2QkVEMTFFRjlEMUJDNUZFMURFMzlBREMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MUVCM0I0RDc2QkVEMTFFRjlEMUJDNUZFMURFMzlBREMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4N8EJcAAAKr0lEQVR42uxd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";
|
|
971
|
+
const controller_namespaceObject = "data:image/png;base64,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";
|
|
835
972
|
const flight_namespaceObject = "data:image/png;base64,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";
|
|
836
973
|
const ship_namespaceObject = "data:image/png;base64,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";
|
|
837
974
|
const circle_namespaceObject = "data:image/png;base64,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";
|
|
@@ -879,7 +1016,8 @@ const icons = {
|
|
|
879
1016
|
mobileRect: mobile_rect_namespaceObject,
|
|
880
1017
|
otherCircle: other_circle_namespaceObject,
|
|
881
1018
|
movableRect: movable_rect_namespaceObject,
|
|
882
|
-
portableRect: portable_rect_namespaceObject
|
|
1019
|
+
portableRect: portable_rect_namespaceObject,
|
|
1020
|
+
controllerRect: controller_namespaceObject
|
|
883
1021
|
};
|
|
884
1022
|
const borderIcon = {
|
|
885
1023
|
circle: {
|
|
@@ -13779,8 +13917,15 @@ const stateColorRule = [
|
|
|
13779
13917
|
];
|
|
13780
13918
|
class MovableManager extends EmitManager {
|
|
13781
13919
|
movables = void 0;
|
|
13920
|
+
iconRotationAlignment = 'map';
|
|
13921
|
+
showNameByDefault;
|
|
13922
|
+
iconBaseSize;
|
|
13923
|
+
circleBaseRadius;
|
|
13782
13924
|
constructor(mapless, options){
|
|
13783
13925
|
super(mapless, options, 'movable');
|
|
13926
|
+
this.showNameByDefault = options?.showNameByDefault ?? false;
|
|
13927
|
+
this.iconBaseSize = options?.iconBaseSize ?? 0.3;
|
|
13928
|
+
this.circleBaseRadius = options?.circleBaseRadius ?? 8;
|
|
13784
13929
|
this.onInitialized();
|
|
13785
13930
|
this.setupClickHandler();
|
|
13786
13931
|
this.setupHoverHandler();
|
|
@@ -13847,8 +13992,8 @@ class MovableManager extends EmitManager {
|
|
|
13847
13992
|
],
|
|
13848
13993
|
true
|
|
13849
13994
|
],
|
|
13850
|
-
0.
|
|
13851
|
-
|
|
13995
|
+
this.iconBaseSize + 0.1,
|
|
13996
|
+
this.iconBaseSize
|
|
13852
13997
|
],
|
|
13853
13998
|
'icon-rotate': [
|
|
13854
13999
|
'get',
|
|
@@ -13856,8 +14001,11 @@ class MovableManager extends EmitManager {
|
|
|
13856
14001
|
],
|
|
13857
14002
|
'icon-allow-overlap': true,
|
|
13858
14003
|
'icon-ignore-placement': true,
|
|
13859
|
-
'icon-rotation-alignment':
|
|
13860
|
-
'text-field': [
|
|
14004
|
+
'icon-rotation-alignment': this.iconRotationAlignment,
|
|
14005
|
+
'text-field': this.showNameByDefault ? [
|
|
14006
|
+
'get',
|
|
14007
|
+
'name'
|
|
14008
|
+
] : [
|
|
13861
14009
|
'case',
|
|
13862
14010
|
[
|
|
13863
14011
|
'==',
|
|
@@ -13925,8 +14073,8 @@ class MovableManager extends EmitManager {
|
|
|
13925
14073
|
],
|
|
13926
14074
|
true
|
|
13927
14075
|
],
|
|
13928
|
-
|
|
13929
|
-
|
|
14076
|
+
this.circleBaseRadius + 2,
|
|
14077
|
+
this.circleBaseRadius
|
|
13930
14078
|
],
|
|
13931
14079
|
'circle-color': stateColorRule,
|
|
13932
14080
|
'circle-stroke-width': [
|
|
@@ -14109,12 +14257,19 @@ class MovableManager extends EmitManager {
|
|
|
14109
14257
|
padding: padding ?? 50
|
|
14110
14258
|
});
|
|
14111
14259
|
}
|
|
14260
|
+
setIconRotationAlignment(alignment) {
|
|
14261
|
+
this.iconRotationAlignment = alignment;
|
|
14262
|
+
if (this.map && this.idHub?.detailLayerId) this.map.setLayoutProperty(this.idHub.detailLayerId, 'icon-rotation-alignment', alignment);
|
|
14263
|
+
}
|
|
14264
|
+
getIconRotationAlignment() {
|
|
14265
|
+
return this.iconRotationAlignment;
|
|
14266
|
+
}
|
|
14112
14267
|
destroy() {
|
|
14113
14268
|
super.destroy();
|
|
14114
14269
|
this.movables = void 0;
|
|
14115
14270
|
}
|
|
14116
14271
|
}
|
|
14117
|
-
const attachMovable = (mapless, name)=>mapless?.use(MovableManager, name);
|
|
14272
|
+
const attachMovable = (mapless, name, options)=>mapless?.use(MovableManager, name, options);
|
|
14118
14273
|
const getMovable = (mapless, name)=>mapless?.get(MovableManager, name);
|
|
14119
14274
|
const detachMovable = (mapless, name)=>mapless?.unuse(MovableManager, name);
|
|
14120
14275
|
const hasAzimuth = (station)=>maplessPreset.movableTypes.includes(station.category || '');
|
|
@@ -14511,6 +14666,7 @@ class NewStationManager extends EmitManager {
|
|
|
14511
14666
|
'portable',
|
|
14512
14667
|
'movable'
|
|
14513
14668
|
].includes(station.category?.toLowerCase())) return station.category?.toLowerCase() || '';
|
|
14669
|
+
if (station.category && 'controller' === station.category.toLowerCase()) return 'controller';
|
|
14514
14670
|
return 'other';
|
|
14515
14671
|
};
|
|
14516
14672
|
getFeatures = (stations)=>stations.filter((station)=>{
|
|
@@ -16425,36 +16581,26 @@ const getTrack = (mapless, name)=>mapless?.get(TrackManager, name);
|
|
|
16425
16581
|
const detachTrack = (mapless, name)=>mapless?.unuse(TrackManager, name);
|
|
16426
16582
|
class AirspaceManager extends manager_Manager {
|
|
16427
16583
|
zones = {};
|
|
16428
|
-
config
|
|
16584
|
+
config = {
|
|
16585
|
+
opacity: 0.3,
|
|
16586
|
+
defaultColor: '#4a90e2',
|
|
16587
|
+
defaultEdgeColor: '#ff00ff',
|
|
16588
|
+
defaultEdgeOpacity: 0.8,
|
|
16589
|
+
defaultEdgeWidth: 2,
|
|
16590
|
+
defaultMinAltitude: 0,
|
|
16591
|
+
defaultMaxAltitude: 1000,
|
|
16592
|
+
defaultFillColor: 'rgba(74, 144, 226, 0.3)',
|
|
16593
|
+
defaultFillOpacity: 0.3
|
|
16594
|
+
};
|
|
16429
16595
|
originalProperties = {};
|
|
16430
16596
|
constructor(mapless, options){
|
|
16431
16597
|
super(mapless, options, 'airspace');
|
|
16432
|
-
this.config = {
|
|
16433
|
-
minAltitude: 0,
|
|
16434
|
-
maxAltitude: 1000,
|
|
16435
|
-
color: 0x4a90e2,
|
|
16436
|
-
opacity: 0.3,
|
|
16437
|
-
edgeColor: 0xff00ff,
|
|
16438
|
-
edgeOpacity: 0.8,
|
|
16439
|
-
edgeWidth: 2
|
|
16440
|
-
};
|
|
16441
16598
|
this.onInitialized();
|
|
16442
16599
|
}
|
|
16443
|
-
setConfig(
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
color: config.color ?? this.config.color,
|
|
16448
|
-
opacity: config.opacity ?? this.config.opacity,
|
|
16449
|
-
edgeColor: config.edgeColor ?? this.config.edgeColor,
|
|
16450
|
-
edgeOpacity: config.edgeOpacity ?? this.config.edgeOpacity,
|
|
16451
|
-
edgeWidth: config.edgeWidth ?? this.config.edgeWidth
|
|
16452
|
-
};
|
|
16453
|
-
if (this.map && this.idHub?.lineLayerId) {
|
|
16454
|
-
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-color', this.numberToColor(this.config.edgeColor));
|
|
16455
|
-
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-opacity', this.config.edgeOpacity);
|
|
16456
|
-
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-width', this.config.edgeWidth);
|
|
16457
|
-
this.map.setPaintProperty(this.idHub.fillLayerId, 'fill-extrusion-opacity', this.config.opacity);
|
|
16600
|
+
setConfig(options) {
|
|
16601
|
+
if (void 0 !== options.opacity) {
|
|
16602
|
+
this.config.opacity = options.opacity;
|
|
16603
|
+
if (this.map && this.idHub?.fillLayerId) this.map.setPaintProperty(this.idHub.fillLayerId, 'fill-extrusion-opacity', this.config.opacity);
|
|
16458
16604
|
}
|
|
16459
16605
|
}
|
|
16460
16606
|
handleCoordSystemChange(_system) {
|
|
@@ -16467,6 +16613,7 @@ class AirspaceManager extends manager_Manager {
|
|
|
16467
16613
|
const newHub = new core_IdHub({
|
|
16468
16614
|
layers: {
|
|
16469
16615
|
fillLayerId: 'dzmap-airspace-fill-layer',
|
|
16616
|
+
fill2DLayerId: 'dzmap-airspace-fill-2d-layer',
|
|
16470
16617
|
lineLayerId: 'dzmap-airspace-line-layer'
|
|
16471
16618
|
},
|
|
16472
16619
|
sources: {
|
|
@@ -16479,14 +16626,38 @@ class AirspaceManager extends manager_Manager {
|
|
|
16479
16626
|
if (!this.mapless) return;
|
|
16480
16627
|
const sid = this.idHub?.sourceId;
|
|
16481
16628
|
this.mapless.addEmptySource(sid);
|
|
16629
|
+
this.mapless.addLayer({
|
|
16630
|
+
id: this.idHub?.fill2DLayerId,
|
|
16631
|
+
type: 'fill',
|
|
16632
|
+
source: sid,
|
|
16633
|
+
paint: {
|
|
16634
|
+
'fill-color': [
|
|
16635
|
+
'get',
|
|
16636
|
+
'fillColor'
|
|
16637
|
+
],
|
|
16638
|
+
'fill-opacity': [
|
|
16639
|
+
'get',
|
|
16640
|
+
'fillOpacity'
|
|
16641
|
+
]
|
|
16642
|
+
}
|
|
16643
|
+
});
|
|
16482
16644
|
this.mapless.addLayer({
|
|
16483
16645
|
id: this.idHub?.lineLayerId,
|
|
16484
16646
|
type: 'line',
|
|
16485
16647
|
source: sid,
|
|
16486
16648
|
paint: {
|
|
16487
|
-
'line-color':
|
|
16488
|
-
|
|
16489
|
-
|
|
16649
|
+
'line-color': [
|
|
16650
|
+
'get',
|
|
16651
|
+
'edgeColor'
|
|
16652
|
+
],
|
|
16653
|
+
'line-opacity': [
|
|
16654
|
+
'get',
|
|
16655
|
+
'edgeOpacity'
|
|
16656
|
+
],
|
|
16657
|
+
'line-width': [
|
|
16658
|
+
'get',
|
|
16659
|
+
'edgeWidth'
|
|
16660
|
+
]
|
|
16490
16661
|
}
|
|
16491
16662
|
});
|
|
16492
16663
|
this.mapless.addLayer({
|
|
@@ -16498,7 +16669,7 @@ class AirspaceManager extends manager_Manager {
|
|
|
16498
16669
|
'get',
|
|
16499
16670
|
'color'
|
|
16500
16671
|
],
|
|
16501
|
-
'fill-extrusion-opacity': this.config.opacity
|
|
16672
|
+
'fill-extrusion-opacity': this.config.opacity,
|
|
16502
16673
|
'fill-extrusion-height': [
|
|
16503
16674
|
'get',
|
|
16504
16675
|
'maxAltitude'
|
|
@@ -16510,15 +16681,11 @@ class AirspaceManager extends manager_Manager {
|
|
|
16510
16681
|
}
|
|
16511
16682
|
});
|
|
16512
16683
|
}
|
|
16513
|
-
numberToColor(num) {
|
|
16514
|
-
return `#${num.toString(16).padStart(6, '0')}`;
|
|
16515
|
-
}
|
|
16516
16684
|
generateId() {
|
|
16517
16685
|
return `airspace-${Object.keys(this.zones).length}`;
|
|
16518
16686
|
}
|
|
16519
16687
|
drawZone(id, options) {
|
|
16520
|
-
const { name = '', geometry, minAltitude = this.config.
|
|
16521
|
-
const zoneColor = this.numberToColor(color);
|
|
16688
|
+
const { name = '', geometry, minAltitude = this.config.defaultMinAltitude, maxAltitude = this.config.defaultMaxAltitude, color = this.config.defaultColor, edgeColor = this.config.defaultEdgeColor, edgeOpacity = this.config.defaultEdgeOpacity, edgeWidth = this.config.defaultEdgeWidth, fillColor = this.config.defaultFillColor, fillOpacity = this.config.defaultFillOpacity } = options;
|
|
16522
16689
|
const feature = {
|
|
16523
16690
|
type: 'Feature',
|
|
16524
16691
|
geometry: {
|
|
@@ -16530,8 +16697,12 @@ class AirspaceManager extends manager_Manager {
|
|
|
16530
16697
|
name,
|
|
16531
16698
|
minAltitude,
|
|
16532
16699
|
maxAltitude,
|
|
16533
|
-
color
|
|
16534
|
-
|
|
16700
|
+
color,
|
|
16701
|
+
edgeColor,
|
|
16702
|
+
edgeOpacity,
|
|
16703
|
+
edgeWidth,
|
|
16704
|
+
fillColor,
|
|
16705
|
+
fillOpacity
|
|
16535
16706
|
}
|
|
16536
16707
|
};
|
|
16537
16708
|
this.zones[id] = {
|
|
@@ -16541,20 +16712,38 @@ class AirspaceManager extends manager_Manager {
|
|
|
16541
16712
|
minAltitude,
|
|
16542
16713
|
maxAltitude,
|
|
16543
16714
|
color,
|
|
16544
|
-
|
|
16715
|
+
edgeColor,
|
|
16716
|
+
edgeOpacity,
|
|
16717
|
+
edgeWidth,
|
|
16718
|
+
fillColor,
|
|
16719
|
+
fillOpacity,
|
|
16545
16720
|
feature
|
|
16546
16721
|
};
|
|
16547
16722
|
this.originalProperties[id] = {
|
|
16548
|
-
color
|
|
16549
|
-
opacity
|
|
16723
|
+
color
|
|
16550
16724
|
};
|
|
16551
16725
|
this.updateSource();
|
|
16552
16726
|
}
|
|
16553
16727
|
updateSource() {
|
|
16554
|
-
|
|
16728
|
+
const featureCollection = {
|
|
16555
16729
|
type: 'FeatureCollection',
|
|
16556
16730
|
features: Object.values(this.zones).map((z)=>z.feature)
|
|
16557
|
-
}
|
|
16731
|
+
};
|
|
16732
|
+
this.mapless?.setData(this.idHub?.sourceId, featureCollection);
|
|
16733
|
+
if (this.map && this.idHub?.lineLayerId && Object.keys(this.zones).length > 0) {
|
|
16734
|
+
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-color', [
|
|
16735
|
+
'get',
|
|
16736
|
+
'edgeColor'
|
|
16737
|
+
]);
|
|
16738
|
+
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-opacity', [
|
|
16739
|
+
'get',
|
|
16740
|
+
'edgeOpacity'
|
|
16741
|
+
]);
|
|
16742
|
+
this.map.setPaintProperty(this.idHub.lineLayerId, 'line-width', [
|
|
16743
|
+
'get',
|
|
16744
|
+
'edgeWidth'
|
|
16745
|
+
]);
|
|
16746
|
+
}
|
|
16558
16747
|
}
|
|
16559
16748
|
addZone(options) {
|
|
16560
16749
|
const id = options.id || this.generateId();
|
|
@@ -16575,44 +16764,36 @@ class AirspaceManager extends manager_Manager {
|
|
|
16575
16764
|
this.originalProperties = {};
|
|
16576
16765
|
this.mapless?.setEmptyData(this.idHub?.sourceId);
|
|
16577
16766
|
}
|
|
16578
|
-
|
|
16767
|
+
updateZone(id, options) {
|
|
16579
16768
|
const zone = this.zones[id];
|
|
16580
16769
|
if (!zone) return;
|
|
16581
|
-
zone
|
|
16582
|
-
|
|
16583
|
-
if (
|
|
16770
|
+
Object.assign(zone, options);
|
|
16771
|
+
if (zone.feature.properties) Object.assign(zone.feature.properties, options);
|
|
16772
|
+
if (options.color && !this.originalProperties[id]) this.originalProperties[id] = {
|
|
16773
|
+
color: zone.color
|
|
16774
|
+
};
|
|
16584
16775
|
this.updateSource();
|
|
16585
16776
|
}
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
if (zone.feature.properties) zone.feature.properties.opacity = opacity;
|
|
16591
|
-
this.updateSource();
|
|
16777
|
+
updateZoneColor(id, color) {
|
|
16778
|
+
this.updateZone(id, {
|
|
16779
|
+
color
|
|
16780
|
+
});
|
|
16592
16781
|
}
|
|
16593
16782
|
updateZoneAltitude(id, minAltitude, maxAltitude) {
|
|
16594
|
-
|
|
16595
|
-
|
|
16596
|
-
|
|
16597
|
-
|
|
16598
|
-
if (zone.feature.properties) {
|
|
16599
|
-
zone.feature.properties.minAltitude = minAltitude;
|
|
16600
|
-
zone.feature.properties.maxAltitude = maxAltitude;
|
|
16601
|
-
}
|
|
16602
|
-
this.updateSource();
|
|
16783
|
+
this.updateZone(id, {
|
|
16784
|
+
minAltitude,
|
|
16785
|
+
maxAltitude
|
|
16786
|
+
});
|
|
16603
16787
|
}
|
|
16604
16788
|
highlightZone(id, highlighted = true) {
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
this.updateZoneOpacity(id, 0.6);
|
|
16610
|
-
} else {
|
|
16789
|
+
if (highlighted) this.updateZone(id, {
|
|
16790
|
+
color: '#ff0000'
|
|
16791
|
+
});
|
|
16792
|
+
else {
|
|
16611
16793
|
const original = this.originalProperties[id];
|
|
16612
|
-
if (original) {
|
|
16613
|
-
|
|
16614
|
-
|
|
16615
|
-
}
|
|
16794
|
+
if (original) this.updateZone(id, {
|
|
16795
|
+
color: original.color
|
|
16796
|
+
});
|
|
16616
16797
|
}
|
|
16617
16798
|
}
|
|
16618
16799
|
getZone(id) {
|
|
@@ -16646,6 +16827,21 @@ class AirspaceManager extends manager_Manager {
|
|
|
16646
16827
|
});
|
|
16647
16828
|
}
|
|
16648
16829
|
}
|
|
16830
|
+
setFillExtrusionVisible(visible) {
|
|
16831
|
+
if (this.map && this.idHub?.fillLayerId) this.map.setLayoutProperty(this.idHub.fillLayerId, 'visibility', visible ? 'visible' : 'none');
|
|
16832
|
+
}
|
|
16833
|
+
isFillExtrusionVisible() {
|
|
16834
|
+
if (this.map && this.idHub?.fillLayerId) {
|
|
16835
|
+
const visibility = this.map.getLayoutProperty(this.idHub.fillLayerId, 'visibility');
|
|
16836
|
+
return 'none' !== visibility;
|
|
16837
|
+
}
|
|
16838
|
+
return true;
|
|
16839
|
+
}
|
|
16840
|
+
toggleFillExtrusion() {
|
|
16841
|
+
const currentState = this.isFillExtrusionVisible();
|
|
16842
|
+
this.setFillExtrusionVisible(!currentState);
|
|
16843
|
+
return !currentState;
|
|
16844
|
+
}
|
|
16649
16845
|
destroy() {
|
|
16650
16846
|
super.destroy();
|
|
16651
16847
|
this.zones = {};
|
|
@@ -16798,10 +16994,18 @@ const elevatedLine = ElevatedLineManager;
|
|
|
16798
16994
|
const attachElevatedLine = (mapless, name, options)=>mapless?.use(ElevatedLineManager, name, options);
|
|
16799
16995
|
const getElevatedLine = (mapless, name)=>mapless?.get(ElevatedLineManager, name);
|
|
16800
16996
|
const detachElevatedLine = (mapless, name)=>mapless?.unuse(ElevatedLineManager, name);
|
|
16801
|
-
class MapModelManager extends
|
|
16997
|
+
class MapModelManager extends EmitManager {
|
|
16802
16998
|
models = new Map();
|
|
16803
16999
|
modelCounter = 0;
|
|
16804
17000
|
_idHub;
|
|
17001
|
+
globalClickHandler;
|
|
17002
|
+
selectedModelId = null;
|
|
17003
|
+
defaultSelectedColor = [
|
|
17004
|
+
1,
|
|
17005
|
+
0,
|
|
17006
|
+
0
|
|
17007
|
+
];
|
|
17008
|
+
themeColorModels = new Set();
|
|
16805
17009
|
constructor(mapless, options){
|
|
16806
17010
|
super(mapless, options, 'mapModel');
|
|
16807
17011
|
this.map = mapless.map;
|
|
@@ -16809,11 +17013,76 @@ class MapModelManager extends manager_Manager {
|
|
|
16809
17013
|
sources: {},
|
|
16810
17014
|
layers: {}
|
|
16811
17015
|
});
|
|
16812
|
-
this.
|
|
17016
|
+
this.onInitialized();
|
|
17017
|
+
this.setupGlobalClickHandler();
|
|
16813
17018
|
}
|
|
16814
|
-
|
|
16815
|
-
if (!this.map)
|
|
17019
|
+
setupGlobalClickHandler() {
|
|
17020
|
+
if (!this.map) return;
|
|
17021
|
+
this.globalClickHandler = (e)=>{
|
|
17022
|
+
if (!this.map) return;
|
|
17023
|
+
const modelLayerIds = Array.from(this.models.values()).map((m)=>m.layerId);
|
|
17024
|
+
if (0 === modelLayerIds.length) return;
|
|
17025
|
+
const features = this.map.queryRenderedFeatures(e.point, {
|
|
17026
|
+
layers: modelLayerIds
|
|
17027
|
+
});
|
|
17028
|
+
if (!features || 0 === features.length) return;
|
|
17029
|
+
const feature = features[0];
|
|
17030
|
+
const layerId = feature.layer?.id;
|
|
17031
|
+
const modelData = Array.from(this.models.values()).find((m)=>m.layerId === layerId);
|
|
17032
|
+
if (modelData) {
|
|
17033
|
+
const clickEvent = {
|
|
17034
|
+
id: modelData.id,
|
|
17035
|
+
url: modelData.url,
|
|
17036
|
+
lngLat: modelData.config.position || modelData.config.lngLat || [
|
|
17037
|
+
0,
|
|
17038
|
+
0
|
|
17039
|
+
],
|
|
17040
|
+
altitude: modelData.config.altitude || 0,
|
|
17041
|
+
rotation: modelData.config.orientation,
|
|
17042
|
+
scale: modelData.config.scale,
|
|
17043
|
+
originalEvent: e
|
|
17044
|
+
};
|
|
17045
|
+
this.emit('modelClick', clickEvent);
|
|
17046
|
+
}
|
|
17047
|
+
};
|
|
17048
|
+
this.map.on('click', this.globalClickHandler);
|
|
17049
|
+
}
|
|
17050
|
+
getDefaultThemeColor() {
|
|
17051
|
+
const isDark = this.mapless?.isDark();
|
|
17052
|
+
if (isDark) return [
|
|
17053
|
+
68 / 255,
|
|
17054
|
+
233 / 255,
|
|
17055
|
+
234 / 255
|
|
17056
|
+
];
|
|
17057
|
+
return null;
|
|
17058
|
+
}
|
|
17059
|
+
removeModelColor(id) {
|
|
17060
|
+
const modelData = this.models.get(id);
|
|
17061
|
+
if (!modelData) return;
|
|
17062
|
+
if (!this.map) return;
|
|
17063
|
+
if (this.map.getLayer(modelData.layerId)) {
|
|
17064
|
+
this.map.setPaintProperty(modelData.layerId, 'model-color', void 0);
|
|
17065
|
+
this.map.setPaintProperty(modelData.layerId, 'model-color-mix-intensity', void 0);
|
|
17066
|
+
}
|
|
16816
17067
|
}
|
|
17068
|
+
updateAllModelsThemeColor() {
|
|
17069
|
+
const themeColor = this.getDefaultThemeColor();
|
|
17070
|
+
this.themeColorModels.forEach((modelId)=>{
|
|
17071
|
+
const modelData = this.models.get(modelId);
|
|
17072
|
+
if (!modelData) return void this.themeColorModels.delete(modelId);
|
|
17073
|
+
if (modelId !== this.selectedModelId) if (themeColor) this.updateModelColor(modelId, themeColor, 0.8);
|
|
17074
|
+
else this.removeModelColor(modelId);
|
|
17075
|
+
});
|
|
17076
|
+
}
|
|
17077
|
+
onStyleChanged = (_tag)=>{
|
|
17078
|
+
if (!this.map) return;
|
|
17079
|
+
this.updateAllModelsThemeColor();
|
|
17080
|
+
this.map.once('style.load', ()=>{
|
|
17081
|
+
setTimeout(()=>{
|
|
17082
|
+
this.updateAllModelsThemeColor();
|
|
17083
|
+
}, 100);
|
|
17084
|
+
});
|
|
17085
|
+
};
|
|
16817
17086
|
generateSourceId() {
|
|
16818
17087
|
const id = `dzmap-model-source-${this.modelCounter}`;
|
|
16819
17088
|
this._idHub.addSource(`model-${this.modelCounter}`, id);
|
|
@@ -16841,7 +17110,6 @@ class MapModelManager extends manager_Manager {
|
|
|
16841
17110
|
};
|
|
16842
17111
|
if (materialOverrides && Object.keys(materialOverrides).length > 0) sourceConfig.models[modelId].materialOverrideNames = Object.keys(materialOverrides);
|
|
16843
17112
|
if (nodeOverrides && Object.keys(nodeOverrides).length > 0) sourceConfig.models[modelId].nodeOverrideNames = Object.keys(nodeOverrides);
|
|
16844
|
-
console.log('Adding model source:', sourceConfig);
|
|
16845
17113
|
this.map.addSource(sourceId, sourceConfig);
|
|
16846
17114
|
const layerConfig = {
|
|
16847
17115
|
id: layerId,
|
|
@@ -16949,7 +17217,6 @@ class MapModelManager extends manager_Manager {
|
|
|
16949
17217
|
rotationMatch.push(defaultRotation);
|
|
16950
17218
|
layerConfig.paint['model-rotation'] = rotationMatch;
|
|
16951
17219
|
}
|
|
16952
|
-
console.log('Adding model layer:', layerConfig);
|
|
16953
17220
|
this.map.addLayer(layerConfig);
|
|
16954
17221
|
return {
|
|
16955
17222
|
sourceId,
|
|
@@ -16964,34 +17231,27 @@ class MapModelManager extends manager_Manager {
|
|
|
16964
17231
|
0
|
|
16965
17232
|
], scale = 1, materialOverrides, nodeOverrides } = options;
|
|
16966
17233
|
this.removeModel(id);
|
|
16967
|
-
|
|
16968
|
-
|
|
16969
|
-
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
|
|
16973
|
-
|
|
16974
|
-
|
|
16975
|
-
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
altitude,
|
|
16989
|
-
rotation,
|
|
16990
|
-
scale
|
|
16991
|
-
});
|
|
16992
|
-
} catch (error) {
|
|
16993
|
-
console.error(`Failed to add model ${id}:`, error);
|
|
16994
|
-
throw error;
|
|
17234
|
+
const mainConfig = {
|
|
17235
|
+
uri: url,
|
|
17236
|
+
position: lngLat,
|
|
17237
|
+
altitude,
|
|
17238
|
+
orientation: rotation,
|
|
17239
|
+
scale
|
|
17240
|
+
};
|
|
17241
|
+
const { sourceId, layerId } = this.addSingleModel(id, mainConfig, materialOverrides, nodeOverrides);
|
|
17242
|
+
this.models.set(id, {
|
|
17243
|
+
id,
|
|
17244
|
+
sourceId,
|
|
17245
|
+
layerId,
|
|
17246
|
+
url,
|
|
17247
|
+
config: mainConfig,
|
|
17248
|
+
materialOverrides,
|
|
17249
|
+
nodeOverrides
|
|
17250
|
+
});
|
|
17251
|
+
if (!materialOverrides || 0 === Object.keys(materialOverrides).length) {
|
|
17252
|
+
this.themeColorModels.add(id);
|
|
17253
|
+
const themeColor = this.getDefaultThemeColor();
|
|
17254
|
+
if (themeColor) this.updateModelColor(id, themeColor, 0.8);
|
|
16995
17255
|
}
|
|
16996
17256
|
}
|
|
16997
17257
|
addModels(models) {
|
|
@@ -17001,7 +17261,7 @@ class MapModelManager extends manager_Manager {
|
|
|
17001
17261
|
}
|
|
17002
17262
|
updateModelPosition(id, lngLat, altitude = 0) {
|
|
17003
17263
|
const modelData = this.models.get(id);
|
|
17004
|
-
if (!modelData) return
|
|
17264
|
+
if (!modelData) return;
|
|
17005
17265
|
if (!this.map) return;
|
|
17006
17266
|
const source = this.map.getSource(modelData.sourceId);
|
|
17007
17267
|
if (source?.models?.[id]) {
|
|
@@ -17013,25 +17273,18 @@ class MapModelManager extends manager_Manager {
|
|
|
17013
17273
|
0,
|
|
17014
17274
|
altitude
|
|
17015
17275
|
]);
|
|
17016
|
-
console.log(`MapModel position updated: ${id}`, {
|
|
17017
|
-
lngLat,
|
|
17018
|
-
altitude
|
|
17019
|
-
});
|
|
17020
17276
|
}
|
|
17021
17277
|
updateModelRotation(id, rotation) {
|
|
17022
17278
|
const modelData = this.models.get(id);
|
|
17023
|
-
if (!modelData) return
|
|
17279
|
+
if (!modelData) return;
|
|
17024
17280
|
if (!this.map) return;
|
|
17025
17281
|
const source = this.map.getSource(modelData.sourceId);
|
|
17026
17282
|
if (source?.models?.[id]) source.models[id].orientation = rotation;
|
|
17027
17283
|
if (this.map.getLayer(modelData.layerId)) this.map.setPaintProperty(modelData.layerId, 'model-rotation', rotation);
|
|
17028
|
-
console.log(`MapModel rotation updated: ${id}`, {
|
|
17029
|
-
rotation
|
|
17030
|
-
});
|
|
17031
17284
|
}
|
|
17032
17285
|
updateModelScale(id, scale) {
|
|
17033
17286
|
const modelData = this.models.get(id);
|
|
17034
|
-
if (!modelData) return
|
|
17287
|
+
if (!modelData) return;
|
|
17035
17288
|
if (!this.map) return;
|
|
17036
17289
|
const source = this.map.getSource(modelData.sourceId);
|
|
17037
17290
|
if (source?.models?.[id]) source.models[id].scale = scale;
|
|
@@ -17040,9 +17293,6 @@ class MapModelManager extends manager_Manager {
|
|
|
17040
17293
|
scale,
|
|
17041
17294
|
scale
|
|
17042
17295
|
]);
|
|
17043
|
-
console.log(`MapModel scale updated: ${id}`, {
|
|
17044
|
-
scale
|
|
17045
|
-
});
|
|
17046
17296
|
}
|
|
17047
17297
|
removeModel(id) {
|
|
17048
17298
|
const modelData = this.models.get(id);
|
|
@@ -17051,7 +17301,8 @@ class MapModelManager extends manager_Manager {
|
|
|
17051
17301
|
if (this.map.getLayer(modelData.layerId)) this.map.removeLayer(modelData.layerId);
|
|
17052
17302
|
if (this.map.getSource(modelData.sourceId)) this.map.removeSource(modelData.sourceId);
|
|
17053
17303
|
this.models.delete(id);
|
|
17054
|
-
|
|
17304
|
+
this.themeColorModels.delete(id);
|
|
17305
|
+
if (this.selectedModelId === id) this.selectedModelId = null;
|
|
17055
17306
|
}
|
|
17056
17307
|
clearModels() {
|
|
17057
17308
|
const modelIds = Array.from(this.models.keys());
|
|
@@ -17059,7 +17310,6 @@ class MapModelManager extends manager_Manager {
|
|
|
17059
17310
|
this.removeModel(id);
|
|
17060
17311
|
});
|
|
17061
17312
|
this.models.clear();
|
|
17062
|
-
console.log('All MapModels cleared');
|
|
17063
17313
|
}
|
|
17064
17314
|
getModelCount() {
|
|
17065
17315
|
return this.models.size;
|
|
@@ -17070,7 +17320,81 @@ class MapModelManager extends manager_Manager {
|
|
|
17070
17320
|
getModelIds() {
|
|
17071
17321
|
return Array.from(this.models.keys());
|
|
17072
17322
|
}
|
|
17323
|
+
updateModelColor(id, color, intensity = 1) {
|
|
17324
|
+
const modelData = this.models.get(id);
|
|
17325
|
+
if (!modelData) return;
|
|
17326
|
+
if (!this.map) return;
|
|
17327
|
+
if (this.map.getLayer(modelData.layerId)) {
|
|
17328
|
+
this.map.setPaintProperty(modelData.layerId, 'model-color', `rgb(${255 * color[0]}, ${255 * color[1]}, ${255 * color[2]})`);
|
|
17329
|
+
this.map.setPaintProperty(modelData.layerId, 'model-color-mix-intensity', intensity);
|
|
17330
|
+
}
|
|
17331
|
+
}
|
|
17332
|
+
setDefaultSelectedColor(color) {
|
|
17333
|
+
this.defaultSelectedColor = color;
|
|
17334
|
+
}
|
|
17335
|
+
getSelectedModelId() {
|
|
17336
|
+
return this.selectedModelId;
|
|
17337
|
+
}
|
|
17338
|
+
selectModel(id, color) {
|
|
17339
|
+
const previousId = this.selectedModelId;
|
|
17340
|
+
const selectColor = color || this.defaultSelectedColor;
|
|
17341
|
+
if (previousId && previousId !== id) if (this.themeColorModels.has(previousId)) {
|
|
17342
|
+
const themeColor = this.getDefaultThemeColor();
|
|
17343
|
+
if (themeColor) this.updateModelColor(previousId, themeColor, 0.8);
|
|
17344
|
+
else this.removeModelColor(previousId);
|
|
17345
|
+
} else this.removeModelColor(previousId);
|
|
17346
|
+
this.selectedModelId = id;
|
|
17347
|
+
if (id) this.updateModelColor(id, selectColor, 1);
|
|
17348
|
+
this.emit('modelSelect', {
|
|
17349
|
+
id,
|
|
17350
|
+
previousId
|
|
17351
|
+
});
|
|
17352
|
+
}
|
|
17353
|
+
hideLayer(id) {
|
|
17354
|
+
if (void 0 === id) return void this.models.forEach((modelData)=>{
|
|
17355
|
+
if (this.map?.getLayer(modelData.layerId)) this.map?.setLayoutProperty(modelData.layerId, 'visibility', 'none');
|
|
17356
|
+
});
|
|
17357
|
+
const modelData = this.models.get(id);
|
|
17358
|
+
if (!modelData) return;
|
|
17359
|
+
if (!this.map) return;
|
|
17360
|
+
if (this.map.getLayer(modelData.layerId)) this.map.setLayoutProperty(modelData.layerId, 'visibility', 'none');
|
|
17361
|
+
}
|
|
17362
|
+
showLayer(id) {
|
|
17363
|
+
if (void 0 === id) return void this.models.forEach((modelData)=>{
|
|
17364
|
+
if (this.map?.getLayer(modelData.layerId)) this.map?.setLayoutProperty(modelData.layerId, 'visibility', 'visible');
|
|
17365
|
+
});
|
|
17366
|
+
const modelData = this.models.get(id);
|
|
17367
|
+
if (!modelData) return;
|
|
17368
|
+
if (!this.map) return;
|
|
17369
|
+
if (this.map.getLayer(modelData.layerId)) this.map.setLayoutProperty(modelData.layerId, 'visibility', 'visible');
|
|
17370
|
+
}
|
|
17371
|
+
toggleLayer(id) {
|
|
17372
|
+
if (void 0 === id) {
|
|
17373
|
+
this.models.forEach((modelData)=>{
|
|
17374
|
+
const isVisible = this.isLayerVisible(modelData.id);
|
|
17375
|
+
if (isVisible) this.hideLayer(modelData.id);
|
|
17376
|
+
else this.showLayer(modelData.id);
|
|
17377
|
+
});
|
|
17378
|
+
return true;
|
|
17379
|
+
}
|
|
17380
|
+
const isVisible = this.isLayerVisible(id);
|
|
17381
|
+
if (isVisible) this.hideLayer(id);
|
|
17382
|
+
else this.showLayer(id);
|
|
17383
|
+
return !isVisible;
|
|
17384
|
+
}
|
|
17385
|
+
isLayerVisible(id) {
|
|
17386
|
+
const modelData = this.models.get(id);
|
|
17387
|
+
if (!modelData) return false;
|
|
17388
|
+
if (!this.map) return false;
|
|
17389
|
+
const layer = this.map.getLayer(modelData.layerId);
|
|
17390
|
+
if (!layer) return false;
|
|
17391
|
+
const visibility = layer.visibility;
|
|
17392
|
+
return 'none' !== visibility;
|
|
17393
|
+
}
|
|
17073
17394
|
destroy() {
|
|
17395
|
+
if (this.map && this.globalClickHandler) this.map.off('click', this.globalClickHandler);
|
|
17396
|
+
this.selectedModelId = null;
|
|
17397
|
+
this.themeColorModels.clear();
|
|
17074
17398
|
this.clearModels();
|
|
17075
17399
|
}
|
|
17076
17400
|
}
|
|
@@ -17485,6 +17809,260 @@ const curve3d = Curve3DManager;
|
|
|
17485
17809
|
const attachCurve3D = (mapless, name, options)=>mapless?.use(Curve3DManager, name, options);
|
|
17486
17810
|
const getCurve3D = (mapless, name)=>mapless?.get(Curve3DManager, name);
|
|
17487
17811
|
const detachCurve3D = (mapless, name)=>mapless?.unuse(Curve3DManager, name);
|
|
17812
|
+
class InstancedModelManager extends manager_Manager {
|
|
17813
|
+
scene = null;
|
|
17814
|
+
camera = null;
|
|
17815
|
+
renderer = null;
|
|
17816
|
+
customLayerId;
|
|
17817
|
+
isInitialized = false;
|
|
17818
|
+
instancedMeshes = new Map();
|
|
17819
|
+
rotationAngles = new Map();
|
|
17820
|
+
autoRotateEnabled = new Map();
|
|
17821
|
+
rotationSpeeds = new Map();
|
|
17822
|
+
renderCount = 0;
|
|
17823
|
+
constructor(mapless){
|
|
17824
|
+
super(mapless);
|
|
17825
|
+
this.map = mapless.map;
|
|
17826
|
+
this.customLayerId = `instanced-model-layer-${this.gmid}`;
|
|
17827
|
+
}
|
|
17828
|
+
initThree() {
|
|
17829
|
+
if (this.isInitialized || !this.map) return;
|
|
17830
|
+
const canvas = this.map.getCanvas();
|
|
17831
|
+
const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
|
|
17832
|
+
if (!gl) return void console.error('InstancedModelManager: WebGL context not available');
|
|
17833
|
+
this.scene = new Scene();
|
|
17834
|
+
this.camera = new PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 10000);
|
|
17835
|
+
this.renderer = new WebGLRenderer({
|
|
17836
|
+
canvas: canvas,
|
|
17837
|
+
context: gl,
|
|
17838
|
+
antialias: false
|
|
17839
|
+
});
|
|
17840
|
+
this.renderer.autoClear = false;
|
|
17841
|
+
this.renderer.setClearColor(0x000000, 0);
|
|
17842
|
+
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
17843
|
+
const ambientLight = new AmbientLight(0xffffff, 0.6);
|
|
17844
|
+
this.scene.add(ambientLight);
|
|
17845
|
+
const directionalLight = new DirectionalLight(0xffffff, 0.8);
|
|
17846
|
+
directionalLight.position.set(0, -70, 100);
|
|
17847
|
+
this.scene.add(directionalLight);
|
|
17848
|
+
const directionalLight2 = new DirectionalLight(0xffffff, 0.5);
|
|
17849
|
+
directionalLight2.position.set(0, 70, 100);
|
|
17850
|
+
this.scene.add(directionalLight2);
|
|
17851
|
+
this.setupCustomLayer();
|
|
17852
|
+
this.isInitialized = true;
|
|
17853
|
+
console.log('InstancedModelManager: Initialized', {
|
|
17854
|
+
canvas: `${canvas.width}x${canvas.height}`,
|
|
17855
|
+
customLayerId: this.customLayerId
|
|
17856
|
+
});
|
|
17857
|
+
}
|
|
17858
|
+
setupCustomLayer() {
|
|
17859
|
+
if (!this.map) return;
|
|
17860
|
+
const customLayer = {
|
|
17861
|
+
id: this.customLayerId,
|
|
17862
|
+
type: 'custom',
|
|
17863
|
+
renderingMode: '3d',
|
|
17864
|
+
onAdd: ()=>{
|
|
17865
|
+
console.log('InstancedModelManager: Custom layer added');
|
|
17866
|
+
},
|
|
17867
|
+
render: (_gl, matrix)=>{
|
|
17868
|
+
if (!this.camera || !this.renderer || !this.scene) return;
|
|
17869
|
+
this.renderCount++;
|
|
17870
|
+
if (this.renderCount % 60 === 0) console.log('InstancedModelManager: Rendering', {
|
|
17871
|
+
frame: this.renderCount,
|
|
17872
|
+
instanceCount: this.instancedMeshes.size
|
|
17873
|
+
});
|
|
17874
|
+
this.updateAutoRotate();
|
|
17875
|
+
this.camera.projectionMatrix = new Matrix4().fromArray(matrix);
|
|
17876
|
+
_gl.enable(_gl.DEPTH_TEST);
|
|
17877
|
+
this.renderer.resetState();
|
|
17878
|
+
this.renderer.render(this.scene, this.camera);
|
|
17879
|
+
if (this.map) this.map.triggerRepaint();
|
|
17880
|
+
}
|
|
17881
|
+
};
|
|
17882
|
+
this.map.addLayer(customLayer);
|
|
17883
|
+
}
|
|
17884
|
+
updateAutoRotate() {
|
|
17885
|
+
this.autoRotateEnabled.forEach((enabled, id)=>{
|
|
17886
|
+
if (!enabled) return;
|
|
17887
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
17888
|
+
const angles = this.rotationAngles.get(id);
|
|
17889
|
+
const speed = this.rotationSpeeds.get(id) || 0.01;
|
|
17890
|
+
if (!instancedMesh || !angles) return;
|
|
17891
|
+
const dummy = new Object3D();
|
|
17892
|
+
const count = instancedMesh.count;
|
|
17893
|
+
for(let i = 0; i < count; i++){
|
|
17894
|
+
instancedMesh.getMatrixAt(i, dummy.matrix);
|
|
17895
|
+
dummy.matrix.decompose(dummy.position, dummy.quaternion, dummy.scale);
|
|
17896
|
+
angles[i] += speed;
|
|
17897
|
+
dummy.rotation.set(0, 0, angles[i]);
|
|
17898
|
+
dummy.updateMatrix();
|
|
17899
|
+
instancedMesh.setMatrixAt(i, dummy.matrix);
|
|
17900
|
+
}
|
|
17901
|
+
instancedMesh.instanceMatrix.needsUpdate = true;
|
|
17902
|
+
});
|
|
17903
|
+
}
|
|
17904
|
+
generateInstances(config) {
|
|
17905
|
+
const instances = [];
|
|
17906
|
+
for(let i = 0; i < config.count; i++){
|
|
17907
|
+
const lngOffset = (Math.random() - 0.5) * config.spread * 2;
|
|
17908
|
+
const latOffset = (Math.random() - 0.5) * config.spread * 2;
|
|
17909
|
+
const altitude = 100 * Math.random() + 50;
|
|
17910
|
+
const rotation = Math.random() * Math.PI * 2;
|
|
17911
|
+
const scaleVariation = 0.8 + 0.4 * Math.random();
|
|
17912
|
+
instances.push({
|
|
17913
|
+
lngLat: [
|
|
17914
|
+
config.center[0] + lngOffset,
|
|
17915
|
+
config.center[1] + latOffset
|
|
17916
|
+
],
|
|
17917
|
+
altitude,
|
|
17918
|
+
rotation,
|
|
17919
|
+
scale: scaleVariation
|
|
17920
|
+
});
|
|
17921
|
+
}
|
|
17922
|
+
return instances;
|
|
17923
|
+
}
|
|
17924
|
+
async load(id, config) {
|
|
17925
|
+
this.initThree();
|
|
17926
|
+
if (!this.scene || !this.map) throw new Error('Three.js scene not initialized');
|
|
17927
|
+
this.remove(id);
|
|
17928
|
+
const dracoLoader = new DRACOLoader();
|
|
17929
|
+
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.6/');
|
|
17930
|
+
const loader = new GLTFLoader();
|
|
17931
|
+
loader.setDRACOLoader(dracoLoader);
|
|
17932
|
+
try {
|
|
17933
|
+
console.log('InstancedModel: Loading model', config.url);
|
|
17934
|
+
const gltf = await new Promise((resolve, reject)=>{
|
|
17935
|
+
loader.load(config.url, resolve, void 0, reject);
|
|
17936
|
+
});
|
|
17937
|
+
const gltfScene = gltf.scene;
|
|
17938
|
+
let meshToUse = null;
|
|
17939
|
+
gltfScene.traverse((object)=>{
|
|
17940
|
+
if (object instanceof Mesh && !meshToUse) meshToUse = object;
|
|
17941
|
+
});
|
|
17942
|
+
if (!meshToUse) throw new Error('No mesh found in model');
|
|
17943
|
+
const mesh = meshToUse;
|
|
17944
|
+
const materialToUse = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material;
|
|
17945
|
+
const instancedMesh = new InstancedMesh(mesh.geometry.clone(), materialToUse.clone(), config.count);
|
|
17946
|
+
instancedMesh.castShadow = true;
|
|
17947
|
+
instancedMesh.receiveShadow = true;
|
|
17948
|
+
if ('side' in instancedMesh.material) instancedMesh.material.side = DoubleSide;
|
|
17949
|
+
const instances = this.generateInstances(config);
|
|
17950
|
+
const angles = new Float32Array(config.count);
|
|
17951
|
+
const meterInMercator = mapbox_gl.MercatorCoordinate.fromLngLat(config.center, 0).meterInMercatorCoordinateUnits();
|
|
17952
|
+
console.log('InstancedModel: Creating instances', {
|
|
17953
|
+
instanceCount: config.count,
|
|
17954
|
+
center: config.center,
|
|
17955
|
+
scale: config.scale,
|
|
17956
|
+
meterInMercator,
|
|
17957
|
+
firstInstanceLngLat: instances[0].lngLat,
|
|
17958
|
+
firstInstanceAlt: instances[0].altitude
|
|
17959
|
+
});
|
|
17960
|
+
const dummy = new Object3D();
|
|
17961
|
+
instances.forEach((instance, i)=>{
|
|
17962
|
+
const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(instance.lngLat, instance.altitude);
|
|
17963
|
+
dummy.position.set(mercator.x, mercator.y, mercator.z);
|
|
17964
|
+
dummy.rotation.set(0, 0, instance.rotation);
|
|
17965
|
+
const scale = meterInMercator * config.scale * instance.scale;
|
|
17966
|
+
dummy.scale.set(scale, -scale, scale);
|
|
17967
|
+
dummy.updateMatrix();
|
|
17968
|
+
instancedMesh.setMatrixAt(i, dummy.matrix);
|
|
17969
|
+
angles[i] = instance.rotation;
|
|
17970
|
+
});
|
|
17971
|
+
instancedMesh.instanceMatrix.needsUpdate = true;
|
|
17972
|
+
this.scene.add(instancedMesh);
|
|
17973
|
+
this.instancedMeshes.set(id, instancedMesh);
|
|
17974
|
+
this.rotationAngles.set(id, angles);
|
|
17975
|
+
this.autoRotateEnabled.set(id, config.autoRotate || false);
|
|
17976
|
+
this.rotationSpeeds.set(id, config.rotationSpeed || 0.01);
|
|
17977
|
+
console.log(`InstancedModel "${id}" loaded with ${config.count} instances`);
|
|
17978
|
+
} catch (error) {
|
|
17979
|
+
console.error(`Failed to load instanced model "${id}":`, error);
|
|
17980
|
+
throw error;
|
|
17981
|
+
}
|
|
17982
|
+
}
|
|
17983
|
+
enableAutoRotate(id, speed = 0.01) {
|
|
17984
|
+
this.autoRotateEnabled.set(id, true);
|
|
17985
|
+
this.rotationSpeeds.set(id, speed);
|
|
17986
|
+
}
|
|
17987
|
+
disableAutoRotate(id) {
|
|
17988
|
+
this.autoRotateEnabled.set(id, false);
|
|
17989
|
+
}
|
|
17990
|
+
updateInstance(id, index, lngLat, altitude) {
|
|
17991
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
17992
|
+
if (!instancedMesh) return;
|
|
17993
|
+
const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
|
|
17994
|
+
const dummy = new Object3D();
|
|
17995
|
+
instancedMesh.getMatrixAt(index, dummy.matrix);
|
|
17996
|
+
dummy.matrix.decompose(dummy.position, dummy.quaternion, dummy.scale);
|
|
17997
|
+
dummy.position.set(mercator.x, mercator.y, mercator.z);
|
|
17998
|
+
dummy.updateMatrix();
|
|
17999
|
+
instancedMesh.setMatrixAt(index, dummy.matrix);
|
|
18000
|
+
instancedMesh.instanceMatrix.needsUpdate = true;
|
|
18001
|
+
}
|
|
18002
|
+
setInstanceVisible(id, visible) {
|
|
18003
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
18004
|
+
if (instancedMesh) instancedMesh.visible = visible;
|
|
18005
|
+
}
|
|
18006
|
+
setVisible(visible) {
|
|
18007
|
+
this.IsVisible = visible;
|
|
18008
|
+
this.instancedMeshes.forEach((mesh)=>{
|
|
18009
|
+
mesh.visible = visible;
|
|
18010
|
+
});
|
|
18011
|
+
}
|
|
18012
|
+
getInstanceCount(id) {
|
|
18013
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
18014
|
+
return instancedMesh?.count || 0;
|
|
18015
|
+
}
|
|
18016
|
+
getIds() {
|
|
18017
|
+
return Array.from(this.instancedMeshes.keys());
|
|
18018
|
+
}
|
|
18019
|
+
remove(id) {
|
|
18020
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
18021
|
+
if (!instancedMesh) return;
|
|
18022
|
+
if (this.scene) this.scene.remove(instancedMesh);
|
|
18023
|
+
instancedMesh.geometry.dispose();
|
|
18024
|
+
if (Array.isArray(instancedMesh.material)) instancedMesh.material.forEach((m)=>{
|
|
18025
|
+
m.dispose();
|
|
18026
|
+
});
|
|
18027
|
+
else instancedMesh.material.dispose();
|
|
18028
|
+
this.instancedMeshes.delete(id);
|
|
18029
|
+
this.rotationAngles.delete(id);
|
|
18030
|
+
this.autoRotateEnabled.delete(id);
|
|
18031
|
+
this.rotationSpeeds.delete(id);
|
|
18032
|
+
}
|
|
18033
|
+
clear() {
|
|
18034
|
+
const ids = this.getIds();
|
|
18035
|
+
ids.forEach((id)=>{
|
|
18036
|
+
this.remove(id);
|
|
18037
|
+
});
|
|
18038
|
+
}
|
|
18039
|
+
setColor(id, color) {
|
|
18040
|
+
const instancedMesh = this.instancedMeshes.get(id);
|
|
18041
|
+
if (!instancedMesh) return;
|
|
18042
|
+
const meshColor = 'string' == typeof color ? new Color(color) : color;
|
|
18043
|
+
if (Array.isArray(instancedMesh.material)) instancedMesh.material.forEach((m)=>{
|
|
18044
|
+
if ('color' in m) m.color.set(meshColor);
|
|
18045
|
+
});
|
|
18046
|
+
else if ('color' in instancedMesh.material) instancedMesh.material.color.set(meshColor);
|
|
18047
|
+
}
|
|
18048
|
+
destroy() {
|
|
18049
|
+
this.clear();
|
|
18050
|
+
if (this.map && this.customLayerId) try {
|
|
18051
|
+
this.map.removeLayer(this.customLayerId);
|
|
18052
|
+
} catch {}
|
|
18053
|
+
if (this.renderer) {
|
|
18054
|
+
this.renderer.dispose();
|
|
18055
|
+
this.renderer = null;
|
|
18056
|
+
}
|
|
18057
|
+
this.scene = null;
|
|
18058
|
+
this.camera = null;
|
|
18059
|
+
this.isInitialized = false;
|
|
18060
|
+
}
|
|
18061
|
+
}
|
|
18062
|
+
const instancedModel = InstancedModelManager;
|
|
18063
|
+
const attachInstancedModel = (mapless, name)=>mapless?.use(InstancedModelManager, name);
|
|
18064
|
+
const getInstancedModel = (mapless, name)=>mapless?.get(InstancedModelManager, name);
|
|
18065
|
+
const detachInstancedModel = (mapless, name)=>mapless?.unuse(InstancedModelManager, name);
|
|
17488
18066
|
class Line2Manager extends manager_Manager {
|
|
17489
18067
|
mapThree = null;
|
|
17490
18068
|
lines = new Map();
|
|
@@ -17632,11 +18210,6 @@ class Line2Manager extends manager_Manager {
|
|
|
17632
18210
|
points: config.points,
|
|
17633
18211
|
transform
|
|
17634
18212
|
});
|
|
17635
|
-
console.log(`Line2 added: ${id}`, {
|
|
17636
|
-
pointsCount: config.points.length,
|
|
17637
|
-
linewidth: lineConfig.linewidth,
|
|
17638
|
-
color: lineConfig.color
|
|
17639
|
-
});
|
|
17640
18213
|
}
|
|
17641
18214
|
addLines(lines) {
|
|
17642
18215
|
lines.forEach((line)=>{
|
|
@@ -18168,6 +18741,19 @@ class ThreeManager extends manager_Manager {
|
|
|
18168
18741
|
scale: 1
|
|
18169
18742
|
};
|
|
18170
18743
|
userScale = 1;
|
|
18744
|
+
baseRotation = [
|
|
18745
|
+
0,
|
|
18746
|
+
0,
|
|
18747
|
+
0
|
|
18748
|
+
];
|
|
18749
|
+
currentOrientation = {
|
|
18750
|
+
heading: 0,
|
|
18751
|
+
pitch: 0,
|
|
18752
|
+
roll: 0
|
|
18753
|
+
};
|
|
18754
|
+
boxHelper = null;
|
|
18755
|
+
isSelected = false;
|
|
18756
|
+
clickCleanup = null;
|
|
18171
18757
|
constructor(mapless){
|
|
18172
18758
|
super(mapless);
|
|
18173
18759
|
this.map = mapless.map;
|
|
@@ -18193,34 +18779,40 @@ class ThreeManager extends manager_Manager {
|
|
|
18193
18779
|
0,
|
|
18194
18780
|
0,
|
|
18195
18781
|
0
|
|
18196
|
-
], scale = 1) {
|
|
18782
|
+
], scale = 1, color) {
|
|
18197
18783
|
const mapThree = this.getMapThree();
|
|
18198
18784
|
if (!mapThree) throw new Error('MapThree not initialized. Call useThree first.');
|
|
18199
18785
|
const loader = new GLTFLoader();
|
|
18200
18786
|
return new Promise((resolve, reject)=>{
|
|
18201
18787
|
loader.load(url, (gltf)=>{
|
|
18202
18788
|
this.model = gltf.scene;
|
|
18203
|
-
this.model.traverse((child)=>{
|
|
18789
|
+
if (color) this.model.traverse((child)=>{
|
|
18204
18790
|
if (child instanceof Mesh) {
|
|
18205
18791
|
const material = child.material;
|
|
18206
18792
|
if (material.emissive) {
|
|
18207
|
-
material.emissive = new Color(
|
|
18793
|
+
material.emissive = new Color(color);
|
|
18208
18794
|
material.emissiveIntensity = 0.5;
|
|
18209
18795
|
}
|
|
18210
18796
|
}
|
|
18211
18797
|
});
|
|
18212
18798
|
this.userScale = scale;
|
|
18799
|
+
this.baseRotation = [
|
|
18800
|
+
...rotation
|
|
18801
|
+
];
|
|
18213
18802
|
const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
|
|
18214
18803
|
this.modelTransform = {
|
|
18215
18804
|
translateX: modelAsMercator.x,
|
|
18216
18805
|
translateY: modelAsMercator.y,
|
|
18217
18806
|
translateZ: modelAsMercator.z,
|
|
18218
|
-
rotateX: rotation[0],
|
|
18219
|
-
rotateY: rotation[1],
|
|
18220
|
-
rotateZ: rotation[2],
|
|
18221
18807
|
scale: modelAsMercator.meterInMercatorCoordinateUnits() * scale
|
|
18222
18808
|
};
|
|
18809
|
+
this.currentOrientation = {
|
|
18810
|
+
heading: 0,
|
|
18811
|
+
pitch: 0,
|
|
18812
|
+
roll: 0
|
|
18813
|
+
};
|
|
18223
18814
|
mapThree.addRenderableObject(this.modelId, this.model, this.modelTransform);
|
|
18815
|
+
this._applyBaseRotation();
|
|
18224
18816
|
this.animations = gltf.animations || [];
|
|
18225
18817
|
if (this.animations.length > 0) {
|
|
18226
18818
|
this.mixer = new AnimationMixer(gltf.scene);
|
|
@@ -18253,6 +18845,21 @@ class ThreeManager extends manager_Manager {
|
|
|
18253
18845
|
this.currentAction = action;
|
|
18254
18846
|
console.log(`Playing animation: ${animationName}`);
|
|
18255
18847
|
}
|
|
18848
|
+
stopAnimation() {
|
|
18849
|
+
if (!this.mixer || !this.currentAction) return void console.warn('No animation to stop');
|
|
18850
|
+
this.currentAction.stop();
|
|
18851
|
+
console.log('Animation stopped');
|
|
18852
|
+
}
|
|
18853
|
+
pauseAnimation() {
|
|
18854
|
+
if (!this.currentAction) return void console.warn('No animation to pause');
|
|
18855
|
+
this.currentAction.paused = true;
|
|
18856
|
+
console.log('Animation paused');
|
|
18857
|
+
}
|
|
18858
|
+
resumeAnimation() {
|
|
18859
|
+
if (!this.currentAction) return void console.warn('No animation to resume');
|
|
18860
|
+
this.currentAction.paused = false;
|
|
18861
|
+
console.log('Animation resumed');
|
|
18862
|
+
}
|
|
18256
18863
|
updatePosition(lngLat, altitude = 0) {
|
|
18257
18864
|
const mapThree = this.getMapThree();
|
|
18258
18865
|
if (!mapThree || !this.model) return;
|
|
@@ -18261,8 +18868,98 @@ class ThreeManager extends manager_Manager {
|
|
|
18261
18868
|
this.modelTransform.translateY = modelAsMercator.y;
|
|
18262
18869
|
this.modelTransform.translateZ = modelAsMercator.z;
|
|
18263
18870
|
this.modelTransform.scale = modelAsMercator.meterInMercatorCoordinateUnits() * this.userScale;
|
|
18871
|
+
this._buildFullTransformMatrix(this.currentOrientation.heading, this.currentOrientation.pitch, this.currentOrientation.roll);
|
|
18872
|
+
}
|
|
18873
|
+
_applyBaseRotation() {
|
|
18874
|
+
const mapThree = this.getMapThree();
|
|
18875
|
+
if (!mapThree || !this.model) return;
|
|
18876
|
+
const fullTransform = new Matrix4();
|
|
18877
|
+
fullTransform.makeTranslation(this.modelTransform.translateX, this.modelTransform.translateY, this.modelTransform.translateZ);
|
|
18878
|
+
const scaleVec = new Vector3(this.modelTransform.scale, -this.modelTransform.scale, this.modelTransform.scale);
|
|
18879
|
+
fullTransform.scale(scaleVec);
|
|
18880
|
+
const baseRotationMatrix = new Matrix4();
|
|
18881
|
+
if (0 !== this.baseRotation[0]) baseRotationMatrix.multiply(new Matrix4().makeRotationX(this.baseRotation[0]));
|
|
18882
|
+
if (0 !== this.baseRotation[1]) baseRotationMatrix.multiply(new Matrix4().makeRotationY(this.baseRotation[1]));
|
|
18883
|
+
if (0 !== this.baseRotation[2]) baseRotationMatrix.multiply(new Matrix4().makeRotationZ(this.baseRotation[2]));
|
|
18884
|
+
const headingRad = -this.currentOrientation.heading * Math.PI / 180;
|
|
18885
|
+
const pitchRad = this.currentOrientation.pitch * Math.PI / 180;
|
|
18886
|
+
const rollRad = this.currentOrientation.roll * Math.PI / 180;
|
|
18887
|
+
const headingMatrix = new Matrix4().makeRotationZ(headingRad);
|
|
18888
|
+
const pitchMatrix = new Matrix4().makeRotationX(pitchRad);
|
|
18889
|
+
const rollMatrix = new Matrix4().makeRotationY(rollRad);
|
|
18890
|
+
const orientationMatrix = new Matrix4();
|
|
18891
|
+
orientationMatrix.multiply(rollMatrix).multiply(pitchMatrix).multiply(headingMatrix);
|
|
18892
|
+
const fullRotation = new Matrix4();
|
|
18893
|
+
fullRotation.multiply(orientationMatrix).multiply(baseRotationMatrix);
|
|
18894
|
+
fullTransform.multiply(fullRotation);
|
|
18895
|
+
this.modelTransform.matrix = fullTransform;
|
|
18896
|
+
this.modelTransform.rotateX = void 0;
|
|
18897
|
+
this.modelTransform.rotateY = void 0;
|
|
18898
|
+
this.modelTransform.rotateZ = void 0;
|
|
18264
18899
|
mapThree.updateRenderableObjectTransform(this.modelId, this.modelTransform);
|
|
18265
18900
|
}
|
|
18901
|
+
_buildFullTransformMatrix(heading, pitch, roll) {
|
|
18902
|
+
const mapThree = this.getMapThree();
|
|
18903
|
+
if (!mapThree || !this.model) return;
|
|
18904
|
+
this.currentOrientation = {
|
|
18905
|
+
heading,
|
|
18906
|
+
pitch,
|
|
18907
|
+
roll
|
|
18908
|
+
};
|
|
18909
|
+
const fullTransform = new Matrix4();
|
|
18910
|
+
fullTransform.makeTranslation(this.modelTransform.translateX, this.modelTransform.translateY, this.modelTransform.translateZ);
|
|
18911
|
+
const scaleVec = new Vector3(this.modelTransform.scale, -this.modelTransform.scale, this.modelTransform.scale);
|
|
18912
|
+
fullTransform.scale(scaleVec);
|
|
18913
|
+
const baseRotationMatrix = new Matrix4();
|
|
18914
|
+
if (0 !== this.baseRotation[0]) baseRotationMatrix.multiply(new Matrix4().makeRotationX(this.baseRotation[0]));
|
|
18915
|
+
if (0 !== this.baseRotation[1]) baseRotationMatrix.multiply(new Matrix4().makeRotationY(this.baseRotation[1]));
|
|
18916
|
+
if (0 !== this.baseRotation[2]) baseRotationMatrix.multiply(new Matrix4().makeRotationZ(this.baseRotation[2]));
|
|
18917
|
+
const headingRad = -heading * Math.PI / 180;
|
|
18918
|
+
const pitchRad = pitch * Math.PI / 180;
|
|
18919
|
+
const rollRad = roll * Math.PI / 180;
|
|
18920
|
+
const headingMatrix = new Matrix4().makeRotationZ(headingRad);
|
|
18921
|
+
const pitchMatrix = new Matrix4().makeRotationX(pitchRad);
|
|
18922
|
+
const rollMatrix = new Matrix4().makeRotationY(rollRad);
|
|
18923
|
+
const orientationMatrix = new Matrix4();
|
|
18924
|
+
orientationMatrix.multiply(rollMatrix).multiply(pitchMatrix).multiply(headingMatrix);
|
|
18925
|
+
const fullRotation = new Matrix4();
|
|
18926
|
+
fullRotation.multiply(orientationMatrix).multiply(baseRotationMatrix);
|
|
18927
|
+
fullTransform.multiply(fullRotation);
|
|
18928
|
+
this.modelTransform.matrix = fullTransform;
|
|
18929
|
+
this.modelTransform.rotateX = void 0;
|
|
18930
|
+
this.modelTransform.rotateY = void 0;
|
|
18931
|
+
this.modelTransform.rotateZ = void 0;
|
|
18932
|
+
mapThree.updateRenderableObjectTransform(this.modelId, this.modelTransform);
|
|
18933
|
+
}
|
|
18934
|
+
setRotation(rotation) {
|
|
18935
|
+
const mapThree = this.getMapThree();
|
|
18936
|
+
if (!mapThree || !this.model) return;
|
|
18937
|
+
this.modelTransform.rotateX = rotation[0];
|
|
18938
|
+
this.modelTransform.rotateY = rotation[1];
|
|
18939
|
+
this.modelTransform.rotateZ = rotation[2];
|
|
18940
|
+
mapThree.updateRenderableObjectTransform(this.modelId, this.modelTransform);
|
|
18941
|
+
}
|
|
18942
|
+
setOrientation(heading, pitch, roll) {
|
|
18943
|
+
this._buildFullTransformMatrix(heading, pitch, roll);
|
|
18944
|
+
}
|
|
18945
|
+
resetToBaseOrientation() {
|
|
18946
|
+
this.currentOrientation = {
|
|
18947
|
+
heading: 0,
|
|
18948
|
+
pitch: 0,
|
|
18949
|
+
roll: 0
|
|
18950
|
+
};
|
|
18951
|
+
this._applyBaseRotation();
|
|
18952
|
+
}
|
|
18953
|
+
getBaseRotation() {
|
|
18954
|
+
return [
|
|
18955
|
+
...this.baseRotation
|
|
18956
|
+
];
|
|
18957
|
+
}
|
|
18958
|
+
getOrientation() {
|
|
18959
|
+
return {
|
|
18960
|
+
...this.currentOrientation
|
|
18961
|
+
};
|
|
18962
|
+
}
|
|
18266
18963
|
enable() {
|
|
18267
18964
|
const mapThree = this.getMapThree();
|
|
18268
18965
|
if (mapThree) mapThree.setRenderableObjectVisible(this.modelId, true);
|
|
@@ -18271,7 +18968,62 @@ class ThreeManager extends manager_Manager {
|
|
|
18271
18968
|
const mapThree = this.getMapThree();
|
|
18272
18969
|
if (mapThree) mapThree.setRenderableObjectVisible(this.modelId, false);
|
|
18273
18970
|
}
|
|
18971
|
+
select() {
|
|
18972
|
+
if (!this.model || this.isSelected) return;
|
|
18973
|
+
this.boxHelper = new BoxHelper(this.model, 0xffff00);
|
|
18974
|
+
this.model.add(this.boxHelper);
|
|
18975
|
+
this.isSelected = true;
|
|
18976
|
+
this._updateBoxHelper();
|
|
18977
|
+
}
|
|
18978
|
+
deselect() {
|
|
18979
|
+
if (!this.isSelected || !this.boxHelper) return;
|
|
18980
|
+
if (this.model) this.model.remove(this.boxHelper);
|
|
18981
|
+
this.boxHelper = null;
|
|
18982
|
+
this.isSelected = false;
|
|
18983
|
+
}
|
|
18984
|
+
toggleSelect() {
|
|
18985
|
+
if (this.isSelected) this.deselect();
|
|
18986
|
+
else this.select();
|
|
18987
|
+
}
|
|
18988
|
+
setSelectionColor(color) {
|
|
18989
|
+
if (this.boxHelper) {
|
|
18990
|
+
const boxColor = 'string' == typeof color ? new Color(color) : color;
|
|
18991
|
+
const material = this.boxHelper.material;
|
|
18992
|
+
if (material) material.color.set(boxColor);
|
|
18993
|
+
}
|
|
18994
|
+
}
|
|
18995
|
+
getSelected() {
|
|
18996
|
+
return this.isSelected;
|
|
18997
|
+
}
|
|
18998
|
+
_updateBoxHelper() {
|
|
18999
|
+
if (!this.boxHelper || !this.model) return;
|
|
19000
|
+
this.boxHelper.update();
|
|
19001
|
+
}
|
|
19002
|
+
registerClick(onClick, tolerance = 30) {
|
|
19003
|
+
const mapThree = this.getMapThree();
|
|
19004
|
+
if (!mapThree || !this.modelId) {
|
|
19005
|
+
console.warn('ThreeManager: Cannot register click, MapThree or modelId not available');
|
|
19006
|
+
return null;
|
|
19007
|
+
}
|
|
19008
|
+
if (this.clickCleanup) {
|
|
19009
|
+
this.clickCleanup();
|
|
19010
|
+
this.clickCleanup = null;
|
|
19011
|
+
}
|
|
19012
|
+
const cleanup = mapThree.registerRenderableObjectClick(this.modelId, (_object, point)=>{
|
|
19013
|
+
if (onClick && this.model) onClick(this.model, point);
|
|
19014
|
+
}, tolerance);
|
|
19015
|
+
this.clickCleanup = cleanup;
|
|
19016
|
+
return cleanup;
|
|
19017
|
+
}
|
|
19018
|
+
unregisterClick() {
|
|
19019
|
+
if (this.clickCleanup) {
|
|
19020
|
+
this.clickCleanup();
|
|
19021
|
+
this.clickCleanup = null;
|
|
19022
|
+
}
|
|
19023
|
+
}
|
|
18274
19024
|
dispose() {
|
|
19025
|
+
this.unregisterClick();
|
|
19026
|
+
this.deselect();
|
|
18275
19027
|
const mapThree = this.getMapThree();
|
|
18276
19028
|
if (mapThree && this.modelId) mapThree.removeRenderableObject(this.modelId);
|
|
18277
19029
|
this.model = null;
|
|
@@ -19549,6 +20301,8 @@ class ClickStrategy extends PathCollectionStrategy {
|
|
|
19549
20301
|
onStopCollection() {
|
|
19550
20302
|
if (!this.map) return;
|
|
19551
20303
|
this.map.getCanvas().style.cursor = '';
|
|
20304
|
+
this.clearPoints();
|
|
20305
|
+
this.updateLayers();
|
|
19552
20306
|
}
|
|
19553
20307
|
handleClick = (e)=>{
|
|
19554
20308
|
if (!this.isActive) return void console.log('[ClickStrategy] Click ignored, not active');
|
|
@@ -19709,6 +20463,9 @@ class FreeStrategy extends PathCollectionStrategy {
|
|
|
19709
20463
|
if (!this.map) return;
|
|
19710
20464
|
this.map.getCanvas().style.cursor = '';
|
|
19711
20465
|
this.isDragging = false;
|
|
20466
|
+
this.clearPoints();
|
|
20467
|
+
this.lastPoint = null;
|
|
20468
|
+
this.updateLayer();
|
|
19712
20469
|
}
|
|
19713
20470
|
handleMouseDown = (e)=>{
|
|
19714
20471
|
if (!this.isActive || !this.map) return;
|
|
@@ -19937,6 +20694,9 @@ class PathTracker {
|
|
|
19937
20694
|
type: pathType,
|
|
19938
20695
|
segments: [],
|
|
19939
20696
|
style: {
|
|
20697
|
+
color: '#1890ff',
|
|
20698
|
+
width: 2,
|
|
20699
|
+
opacity: 0.8,
|
|
19940
20700
|
...this.options.defaultStyle
|
|
19941
20701
|
}
|
|
19942
20702
|
};
|
|
@@ -19995,10 +20755,12 @@ class PathTracker {
|
|
|
19995
20755
|
if (0 === this.currentPath.segments.length) {
|
|
19996
20756
|
this.currentPath = null;
|
|
19997
20757
|
this.isTracking = false;
|
|
20758
|
+
this.updateResultLayer();
|
|
19998
20759
|
}
|
|
19999
20760
|
} else {
|
|
20000
20761
|
this.currentPath = null;
|
|
20001
20762
|
this.isTracking = false;
|
|
20763
|
+
this.updateResultLayer();
|
|
20002
20764
|
}
|
|
20003
20765
|
this.callbacks.onCancel?.();
|
|
20004
20766
|
}
|
|
@@ -20052,6 +20814,7 @@ class PathTracker {
|
|
|
20052
20814
|
cancelTracking() {
|
|
20053
20815
|
this.stopTracking();
|
|
20054
20816
|
this.currentPath = null;
|
|
20817
|
+
this.updateResultLayer();
|
|
20055
20818
|
}
|
|
20056
20819
|
clearPaths() {
|
|
20057
20820
|
this.triggerOnClear();
|
|
@@ -20206,4 +20969,4 @@ function detachPathTracker(mapless) {
|
|
|
20206
20969
|
pathTrackerManagers.delete(mapless);
|
|
20207
20970
|
}
|
|
20208
20971
|
}
|
|
20209
|
-
export { AirspaceManager, basicObject as BasicThreeObjectManager, ClickStrategy, CoordTransformer, curve3d as Curve3DManager, Draw, elevatedLine as ElevatedLineManager, EmitManager, FixedRectangleLayer as FixedRectangleLayerManager, FreeStrategy, Lang, line2Manager as Line2Manager, LngLat, manager_Manager as Manager, mapModel as MapModelManager, MapMouseEvent, Mapless_Base as Mapless, Marker, MercatorCoordinate, mana_three_model as ModelManager, MultiCoordTransformer, OldStationManager, paint_PaintBoard as PaintBoard, PathCollectionStrategy, path_PathTracker as PathTracker, Popup, PositionMarker, PositionMouse, QuickTrans, RectangleLayer as RectangleLayerManager, icons_Singleton as Singleton, three as ThreeManager, adjustMapConfigByCoord, attachAirspace, attachBasicObject, attachBoundary, attachCluster, attachCurve, attachCurve3D, attachElevatedLine, attachFixedRectangleLayer, attachHeatmap, attachImageData, attachLine, attachLine2, attachMapModel, attachMarker, attachModel, attachMovable, attachNewStation, attachNode, attachOldStation, attachPathTracker, attachPolygon, attachRectangleLayer, attachRoutes, attachShape, attachStep, attachText, attachThree, attachTrack, buildTileUrl, calculateObjectsInPolygon, createCoordTransformer, darkFog, darkSource, defaultSource, detachAirspace, detachBasicObject, detachBoundary, detachCluster, detachCurve, detachCurve3D, detachElevatedLine, detachFixedRectangleLayer, detachHeatmap, detachImageData, detachLine, detachLine2, detachMapModel, detachMarker, detachModel, detachMovable, detachNewStation, detachNode, detachOldStation, detachPathTracker, detachPolygon, detachRectangleLayer, detachRoutes, detachShape, detachStep, detachText, detachThree, detachTrack, ellipse, genPrefixId, getAirspace, getAllSourceCoordSystems, getBasicObject, getBoundary, getCluster, getCoordDisplayName, getCurve, getCurve3D, getElevatedLine, getFixedRectangleLayer, getHeatmap, getImageData, getLine, getLine2, getMapModel, getMarker, getModel, getMovable, getNewStation, getNode, getOldStation, getPaintCenter, getPaintCenterNRadius, getPaintPolygon, getPathTracker, getPolygon, getRectangleLayer, getRoutes, getShape, getSourceCoordSystem, getSourcesByCoordSystem, getStep, getText, getThree, getTrack, isValidCoordinate, lightFog, lightSource, lite, mapbox_gl as mapboxgl, maplessPreset, point2Feature, propwmsTransformRequest, sourcesMap, newstation_stateColorRule as stateColorRule, test2Point, throttle, transformCoordinate, transformCoordinateBetweenSources, transformCoordinates, transformMapCenter, tryFunc, tryTrans };
|
|
20972
|
+
export { AirspaceManager, basicObject as BasicThreeObjectManager, ClickStrategy, CoordTransformer, curve3d as Curve3DManager, Draw, elevatedLine as ElevatedLineManager, EmitManager, FixedRectangleLayer as FixedRectangleLayerManager, FreeStrategy, instancedModel as InstancedModelManager, Lang, line2Manager as Line2Manager, LngLat, manager_Manager as Manager, mapModel as MapModelManager, MapMouseEvent, Mapless_Base as Mapless, Marker, MercatorCoordinate, mana_three_model as ModelManager, MultiCoordTransformer, OldStationManager, paint_PaintBoard as PaintBoard, PathCollectionStrategy, path_PathTracker as PathTracker, Popup, PositionMarker, PositionMouse, QuickTrans, RectangleLayer as RectangleLayerManager, icons_Singleton as Singleton, three as ThreeManager, adjustMapConfigByCoord, attachAirspace, attachBasicObject, attachBoundary, attachCluster, attachCurve, attachCurve3D, attachElevatedLine, attachFixedRectangleLayer, attachHeatmap, attachImageData, attachInstancedModel, attachLine, attachLine2, attachMapModel, attachMarker, attachModel, attachMovable, attachNewStation, attachNode, attachOldStation, attachPathTracker, attachPolygon, attachRectangleLayer, attachRoutes, attachShape, attachStep, attachText, attachThree, attachTrack, buildTileUrl, calculateObjectsInPolygon, createCoordTransformer, darkFog, darkSource, defaultSource, detachAirspace, detachBasicObject, detachBoundary, detachCluster, detachCurve, detachCurve3D, detachElevatedLine, detachFixedRectangleLayer, detachHeatmap, detachImageData, detachInstancedModel, detachLine, detachLine2, detachMapModel, detachMarker, detachModel, detachMovable, detachNewStation, detachNode, detachOldStation, detachPathTracker, detachPolygon, detachRectangleLayer, detachRoutes, detachShape, detachStep, detachText, detachThree, detachTrack, ellipse, genPrefixId, getAirspace, getAllSourceCoordSystems, getBasicObject, getBoundary, getCluster, getCoordDisplayName, getCurve, getCurve3D, getElevatedLine, getFixedRectangleLayer, getHeatmap, getImageData, getInstancedModel, getLine, getLine2, getMapModel, getMarker, getModel, getMovable, getNewStation, getNode, getOldStation, getPaintCenter, getPaintCenterNRadius, getPaintPolygon, getPathTracker, getPolygon, getRectangleLayer, getRoutes, getShape, getSourceCoordSystem, getSourcesByCoordSystem, getStep, getText, getThree, getTrack, isValidCoordinate, lightFog, lightSource, lite, mapbox_gl as mapboxgl, maplessPreset, point2Feature, propwmsTransformRequest, sourcesMap, newstation_stateColorRule as stateColorRule, test2Point, throttle, transformCoordinate, transformCoordinateBetweenSources, transformCoordinates, transformMapCenter, tryFunc, tryTrans };
|