@mapless/core 1.0.7 → 1.0.12

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.
Files changed (29) hide show
  1. package/dist/index.js +822 -36
  2. package/dist/types/Mapless/Base.d.ts +5 -0
  3. package/dist/types/Mapless/Base.d.ts.map +1 -1
  4. package/dist/types/Mapless/mana/movable.d.ts +19 -3
  5. package/dist/types/Mapless/mana/movable.d.ts.map +1 -1
  6. package/dist/types/Mapless/mana-3d/airspace.d.ts +14 -0
  7. package/dist/types/Mapless/mana-3d/airspace.d.ts.map +1 -1
  8. package/dist/types/Mapless/mana-3d/elevatedLine.d.ts.map +1 -1
  9. package/dist/types/Mapless/mana-3d/mapModel.d.ts +27 -0
  10. package/dist/types/Mapless/mana-3d/mapModel.d.ts.map +1 -1
  11. package/dist/types/Mapless/mana-three/basicObject.d.ts +4 -0
  12. package/dist/types/Mapless/mana-three/basicObject.d.ts.map +1 -1
  13. package/dist/types/Mapless/mana-three/curve3d.d.ts +4 -0
  14. package/dist/types/Mapless/mana-three/curve3d.d.ts.map +1 -1
  15. package/dist/types/Mapless/mana-three/index.d.ts +2 -1
  16. package/dist/types/Mapless/mana-three/index.d.ts.map +1 -1
  17. package/dist/types/Mapless/mana-three/instancedModel.d.ts +158 -0
  18. package/dist/types/Mapless/mana-three/instancedModel.d.ts.map +1 -0
  19. package/dist/types/Mapless/mana-three/line2Manager.d.ts +4 -0
  20. package/dist/types/Mapless/mana-three/line2Manager.d.ts.map +1 -1
  21. package/dist/types/Mapless/mana-three/model.d.ts +5 -0
  22. package/dist/types/Mapless/mana-three/model.d.ts.map +1 -1
  23. package/dist/types/Mapless/mana-three/three.d.ts +18 -1
  24. package/dist/types/Mapless/mana-three/three.d.ts.map +1 -1
  25. package/dist/types/Mapless/types.d.ts +20 -0
  26. package/dist/types/Mapless/types.d.ts.map +1 -1
  27. package/dist/types/Three/MapThree.d.ts +39 -0
  28. package/dist/types/Three/MapThree.d.ts.map +1 -1
  29. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,9 +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, BoxHelper, 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 { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
7
8
  import { GLTFLoader, Line2, LineGeometry, LineMaterial } from "three-stdlib";
8
9
  class MapThree {
9
10
  mapless = void 0;
@@ -16,6 +17,7 @@ class MapThree {
16
17
  renderableObjects = new Map();
17
18
  isInitialized = false;
18
19
  customLayerId = null;
20
+ lastProjectionMatrix = null;
19
21
  constructor(props){
20
22
  const { mapless } = props;
21
23
  this.mapless = mapless;
@@ -54,6 +56,7 @@ class MapThree {
54
56
  renderableObj.mesh.visible = false;
55
57
  });
56
58
  this.camera.projectionMatrix = m;
59
+ this.lastProjectionMatrix = m.clone();
57
60
  this.renderer.resetState();
58
61
  this.renderer.render(this.scene, this.camera);
59
62
  this.renderableObjects.forEach((renderableObj)=>{
@@ -317,6 +320,140 @@ class MapThree {
317
320
  this.removeRenderableObject(id);
318
321
  });
319
322
  }
323
+ raycast(point, objects, tolerance = 30) {
324
+ if (!this.camera || !this.scene || !this.renderer) return null;
325
+ const map = this.mapless?.map;
326
+ if (!map) return null;
327
+ const mapContainer = map.getCanvas();
328
+ const ndcX = point.x / mapContainer.width * 2 - 1;
329
+ const ndcY = 2 * -(point.y / mapContainer.height) + 1;
330
+ const targetObjects = objects || Array.from(this.renderableObjects.values()).map((obj)=>obj.mesh);
331
+ let closestHit = null;
332
+ let minDistance = 1 / 0;
333
+ const screenPositions = new Map();
334
+ for (const targetObj of targetObjects){
335
+ const renderableObj = Array.from(this.renderableObjects.values()).find((obj)=>obj.mesh === targetObj);
336
+ if (renderableObj && this.lastProjectionMatrix) {
337
+ let l;
338
+ if (renderableObj.transform.matrix) l = renderableObj.transform.matrix.clone();
339
+ else {
340
+ 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));
341
+ if (void 0 !== renderableObj.transform.rotateX || void 0 !== renderableObj.transform.rotateY || void 0 !== renderableObj.transform.rotateZ) {
342
+ const rotationX = new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), renderableObj.transform.rotateX || 0);
343
+ const rotationY = new Matrix4().makeRotationAxis(new Vector3(0, 1, 0), renderableObj.transform.rotateY || 0);
344
+ const rotationZ = new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), renderableObj.transform.rotateZ || 0);
345
+ l.multiply(rotationX).multiply(rotationY).multiply(rotationZ);
346
+ }
347
+ }
348
+ const mvpMatrix = this.lastProjectionMatrix.clone().multiply(l);
349
+ const inverseMVP = mvpMatrix.invert();
350
+ const nearPoint = new Vector4(ndcX, ndcY, -1, 1).applyMatrix4(inverseMVP);
351
+ nearPoint.divideScalar(nearPoint.w);
352
+ const farPoint = new Vector4(ndcX, ndcY, 1, 1).applyMatrix4(inverseMVP);
353
+ farPoint.divideScalar(farPoint.w);
354
+ const origin = new Vector3(nearPoint.x, nearPoint.y, nearPoint.z);
355
+ const direction = new Vector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z).normalize();
356
+ const raycaster = new Raycaster(origin, direction);
357
+ const intersects = raycaster.intersectObject(targetObj, true);
358
+ const centerPoint = new Vector4(0, 0, 0, 1).applyMatrix4(mvpMatrix);
359
+ const screenX = (centerPoint.x / centerPoint.w + 1) * 0.5 * mapContainer.width;
360
+ const screenY = (-centerPoint.y / centerPoint.w + 1) * 0.5 * mapContainer.height;
361
+ const depth = centerPoint.z / centerPoint.w;
362
+ const scale = renderableObj.transform.scale;
363
+ const screenRadius = 50 * scale / Math.abs(depth);
364
+ screenPositions.set(targetObj, {
365
+ x: screenX,
366
+ y: screenY,
367
+ radius: screenRadius
368
+ });
369
+ if (intersects.length > 0 && intersects[0].distance < minDistance) {
370
+ minDistance = intersects[0].distance;
371
+ closestHit = {
372
+ object: intersects[0].object,
373
+ distance: intersects[0].distance,
374
+ point: intersects[0].point
375
+ };
376
+ }
377
+ }
378
+ }
379
+ if (!closestHit) for (const [obj, screenPos] of screenPositions){
380
+ const dx = screenPos.x - point.x;
381
+ const dy = screenPos.y - point.y;
382
+ const distance = Math.sqrt(dx * dx + dy * dy);
383
+ if (distance < Math.max(screenPos.radius, tolerance)) return {
384
+ object: obj,
385
+ distance: 0,
386
+ point: new Vector3()
387
+ };
388
+ }
389
+ return closestHit;
390
+ }
391
+ registerRenderableObjectClick(id, onClick, tolerance = 30) {
392
+ const renderableObj = this.renderableObjects.get(id);
393
+ if (!renderableObj) {
394
+ console.warn(`RenderableObject with id "${id}" not found`);
395
+ return null;
396
+ }
397
+ const map = this.mapless?.map;
398
+ if (!map) {
399
+ console.warn('Map not initialized');
400
+ return null;
401
+ }
402
+ const handleClick = (e)=>{
403
+ map.triggerRepaint();
404
+ requestAnimationFrame(()=>{
405
+ const point = {
406
+ x: e.point.x,
407
+ y: e.point.y
408
+ };
409
+ const hit = this.raycast(point, [
410
+ renderableObj.mesh
411
+ ], tolerance);
412
+ if (hit?.object) onClick(hit.object, hit.point);
413
+ });
414
+ };
415
+ map.on('click', handleClick);
416
+ return ()=>{
417
+ map.off('click', handleClick);
418
+ };
419
+ }
420
+ registerGlobalClick(onClick) {
421
+ const map = this.mapless?.map;
422
+ if (!map) {
423
+ console.warn('Map not initialized');
424
+ return null;
425
+ }
426
+ const handleClick = (e)=>{
427
+ const point = {
428
+ x: e.point.x,
429
+ y: e.point.y
430
+ };
431
+ const hit = this.raycast(point);
432
+ if (hit) {
433
+ let renderableId;
434
+ for (const [id, obj] of this.renderableObjects)if (this.isObjectInHierarchy(hit.object, obj.mesh)) {
435
+ renderableId = id;
436
+ break;
437
+ }
438
+ onClick({
439
+ ...hit,
440
+ renderableId
441
+ });
442
+ }
443
+ };
444
+ map.on('click', handleClick);
445
+ return ()=>{
446
+ map.off('click', handleClick);
447
+ };
448
+ }
449
+ isObjectInHierarchy(obj, root) {
450
+ let current = obj;
451
+ while(current){
452
+ if (current === root) return true;
453
+ current = current.parent;
454
+ }
455
+ return false;
456
+ }
320
457
  dispose() {
321
458
  this.clear();
322
459
  this.clearRenderableObjects();
@@ -11224,6 +11361,17 @@ class Mapless extends Base {
11224
11361
  pitch: 0
11225
11362
  });
11226
11363
  }
11364
+ setCoordSystem(coordSystem) {
11365
+ if (!this.CoordTrans) return;
11366
+ const prevSystem = this.CoordSystem || 'wgs84';
11367
+ if (prevSystem === coordSystem) return;
11368
+ this.CoordTrans = createCoordTransformer({
11369
+ dataSystem: coordSystem,
11370
+ tileSystem: this.CoordTrans.TileSystem
11371
+ });
11372
+ this.emitterless.emit('coordSystemChange', coordSystem, prevSystem);
11373
+ console.log(`CoordSystem changed: ${prevSystem} -> ${coordSystem}`);
11374
+ }
11227
11375
  fitBounds(coordinates, padding = 20) {
11228
11376
  if (!this.map || !coordinates.length) return;
11229
11377
  const bounds = coordinates.reduce((bounds, coord)=>bounds.extend(coord), new mapbox_gl.LngLatBounds(coordinates[0], coordinates[0]));
@@ -13781,8 +13929,15 @@ const stateColorRule = [
13781
13929
  ];
13782
13930
  class MovableManager extends EmitManager {
13783
13931
  movables = void 0;
13932
+ iconRotationAlignment = 'map';
13933
+ showNameByDefault;
13934
+ iconBaseSize;
13935
+ circleBaseRadius;
13784
13936
  constructor(mapless, options){
13785
13937
  super(mapless, options, 'movable');
13938
+ this.showNameByDefault = options?.showNameByDefault ?? false;
13939
+ this.iconBaseSize = options?.iconBaseSize ?? 0.3;
13940
+ this.circleBaseRadius = options?.circleBaseRadius ?? 8;
13786
13941
  this.onInitialized();
13787
13942
  this.setupClickHandler();
13788
13943
  this.setupHoverHandler();
@@ -13849,8 +14004,8 @@ class MovableManager extends EmitManager {
13849
14004
  ],
13850
14005
  true
13851
14006
  ],
13852
- 0.4,
13853
- 0.3
14007
+ this.iconBaseSize + 0.1,
14008
+ this.iconBaseSize
13854
14009
  ],
13855
14010
  'icon-rotate': [
13856
14011
  'get',
@@ -13858,8 +14013,11 @@ class MovableManager extends EmitManager {
13858
14013
  ],
13859
14014
  'icon-allow-overlap': true,
13860
14015
  'icon-ignore-placement': true,
13861
- 'icon-rotation-alignment': 'map',
13862
- 'text-field': [
14016
+ 'icon-rotation-alignment': this.iconRotationAlignment,
14017
+ 'text-field': this.showNameByDefault ? [
14018
+ 'get',
14019
+ 'name'
14020
+ ] : [
13863
14021
  'case',
13864
14022
  [
13865
14023
  '==',
@@ -13927,8 +14085,8 @@ class MovableManager extends EmitManager {
13927
14085
  ],
13928
14086
  true
13929
14087
  ],
13930
- 10,
13931
- 8
14088
+ this.circleBaseRadius + 2,
14089
+ this.circleBaseRadius
13932
14090
  ],
13933
14091
  'circle-color': stateColorRule,
13934
14092
  'circle-stroke-width': [
@@ -14111,12 +14269,19 @@ class MovableManager extends EmitManager {
14111
14269
  padding: padding ?? 50
14112
14270
  });
14113
14271
  }
14272
+ setIconRotationAlignment(alignment) {
14273
+ this.iconRotationAlignment = alignment;
14274
+ if (this.map && this.idHub?.detailLayerId) this.map.setLayoutProperty(this.idHub.detailLayerId, 'icon-rotation-alignment', alignment);
14275
+ }
14276
+ getIconRotationAlignment() {
14277
+ return this.iconRotationAlignment;
14278
+ }
14114
14279
  destroy() {
14115
14280
  super.destroy();
14116
14281
  this.movables = void 0;
14117
14282
  }
14118
14283
  }
14119
- const attachMovable = (mapless, name)=>mapless?.use(MovableManager, name);
14284
+ const attachMovable = (mapless, name, options)=>mapless?.use(MovableManager, name, options);
14120
14285
  const getMovable = (mapless, name)=>mapless?.get(MovableManager, name);
14121
14286
  const detachMovable = (mapless, name)=>mapless?.unuse(MovableManager, name);
14122
14287
  const hasAzimuth = (station)=>maplessPreset.movableTypes.includes(station.category || '');
@@ -16440,6 +16605,7 @@ class AirspaceManager extends manager_Manager {
16440
16605
  defaultFillOpacity: 0.3
16441
16606
  };
16442
16607
  originalProperties = {};
16608
+ originalGeometries = {};
16443
16609
  constructor(mapless, options){
16444
16610
  super(mapless, options, 'airspace');
16445
16611
  this.onInitialized();
@@ -16453,7 +16619,19 @@ class AirspaceManager extends manager_Manager {
16453
16619
  handleCoordSystemChange(_system) {
16454
16620
  if (this.zones) Object.keys(this.zones).forEach((id)=>{
16455
16621
  const zone = this.zones[id];
16456
- this.drawZone(id, zone);
16622
+ const originalGeometry = this.originalGeometries[id];
16623
+ if (originalGeometry) this.drawZone(id, {
16624
+ name: zone.name,
16625
+ geometry: originalGeometry,
16626
+ minAltitude: zone.minAltitude,
16627
+ maxAltitude: zone.maxAltitude,
16628
+ color: zone.color,
16629
+ edgeColor: zone.edgeColor,
16630
+ edgeOpacity: zone.edgeOpacity,
16631
+ edgeWidth: zone.edgeWidth,
16632
+ fillColor: zone.fillColor,
16633
+ fillOpacity: zone.fillOpacity
16634
+ });
16457
16635
  });
16458
16636
  }
16459
16637
  createIdHub(_idHub) {
@@ -16533,11 +16711,16 @@ class AirspaceManager extends manager_Manager {
16533
16711
  }
16534
16712
  drawZone(id, options) {
16535
16713
  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;
16714
+ this.originalGeometries[id] = geometry;
16715
+ const transformedGeometry = geometry.map((polygon)=>polygon.map((coord)=>this.mapless?.coordTrans('dataToTile', [
16716
+ coord[0],
16717
+ coord[1]
16718
+ ])));
16536
16719
  const feature = {
16537
16720
  type: 'Feature',
16538
16721
  geometry: {
16539
16722
  type: 'Polygon',
16540
- coordinates: geometry
16723
+ coordinates: transformedGeometry
16541
16724
  },
16542
16725
  properties: {
16543
16726
  id,
@@ -16555,7 +16738,7 @@ class AirspaceManager extends manager_Manager {
16555
16738
  this.zones[id] = {
16556
16739
  id,
16557
16740
  name,
16558
- geometry,
16741
+ geometry: transformedGeometry,
16559
16742
  minAltitude,
16560
16743
  maxAltitude,
16561
16744
  color,
@@ -16604,11 +16787,13 @@ class AirspaceManager extends manager_Manager {
16604
16787
  if (!this.zones[id]) return;
16605
16788
  delete this.zones[id];
16606
16789
  delete this.originalProperties[id];
16790
+ delete this.originalGeometries[id];
16607
16791
  this.updateSource();
16608
16792
  }
16609
16793
  clearZones() {
16610
16794
  this.zones = {};
16611
16795
  this.originalProperties = {};
16796
+ this.originalGeometries = {};
16612
16797
  this.mapless?.setEmptyData(this.idHub?.sourceId);
16613
16798
  }
16614
16799
  updateZone(id, options) {
@@ -16664,7 +16849,8 @@ class AirspaceManager extends manager_Manager {
16664
16849
  });
16665
16850
  });
16666
16851
  if (coordinates.length > 0 && this.mapless?.map) {
16667
- const bounds = coordinates.reduce((bounds, coord)=>bounds.extend(coord), new mapbox_gl.LngLatBounds(coordinates[0], coordinates[0]));
16852
+ const originalCoordinates = coordinates.map((coord)=>this.mapless?.coordTrans('tileToData', coord));
16853
+ const bounds = originalCoordinates.reduce((bounds, coord)=>bounds.extend(coord), new mapbox_gl.LngLatBounds(originalCoordinates[0], originalCoordinates[0]));
16668
16854
  const currentPitch = this.mapless.map.getPitch();
16669
16855
  const currentBearing = this.mapless.map.getBearing();
16670
16856
  this.mapless.map.fitBounds(bounds, {
@@ -16674,10 +16860,26 @@ class AirspaceManager extends manager_Manager {
16674
16860
  });
16675
16861
  }
16676
16862
  }
16863
+ setFillExtrusionVisible(visible) {
16864
+ if (this.map && this.idHub?.fillLayerId) this.map.setLayoutProperty(this.idHub.fillLayerId, 'visibility', visible ? 'visible' : 'none');
16865
+ }
16866
+ isFillExtrusionVisible() {
16867
+ if (this.map && this.idHub?.fillLayerId) {
16868
+ const visibility = this.map.getLayoutProperty(this.idHub.fillLayerId, 'visibility');
16869
+ return 'none' !== visibility;
16870
+ }
16871
+ return true;
16872
+ }
16873
+ toggleFillExtrusion() {
16874
+ const currentState = this.isFillExtrusionVisible();
16875
+ this.setFillExtrusionVisible(!currentState);
16876
+ return !currentState;
16877
+ }
16677
16878
  destroy() {
16678
16879
  super.destroy();
16679
16880
  this.zones = {};
16680
16881
  this.originalProperties = {};
16882
+ this.originalGeometries = {};
16681
16883
  }
16682
16884
  }
16683
16885
  const attachAirspace = (mapless, name)=>mapless?.use(AirspaceManager, name);
@@ -16838,6 +17040,7 @@ class MapModelManager extends EmitManager {
16838
17040
  0
16839
17041
  ];
16840
17042
  themeColorModels = new Set();
17043
+ modelOptions = new Map();
16841
17044
  constructor(mapless, options){
16842
17045
  super(mapless, options, 'mapModel');
16843
17046
  this.map = mapless.map;
@@ -16848,6 +17051,14 @@ class MapModelManager extends EmitManager {
16848
17051
  this.onInitialized();
16849
17052
  this.setupGlobalClickHandler();
16850
17053
  }
17054
+ handleCoordSystemChange(_system) {
17055
+ if (this.modelOptions.size > 0) {
17056
+ this.clearModels();
17057
+ this.modelOptions.forEach((options)=>{
17058
+ this.addModel(options);
17059
+ });
17060
+ }
17061
+ }
16851
17062
  setupGlobalClickHandler() {
16852
17063
  if (!this.map) return;
16853
17064
  this.globalClickHandler = (e)=>{
@@ -16930,12 +17141,17 @@ class MapModelManager extends EmitManager {
16930
17141
  if (!this.map) throw new Error('Map not initialized');
16931
17142
  const sourceId = this.generateSourceId();
16932
17143
  const layerId = this.generateLayerId();
17144
+ const originalPosition = config.position || config.lngLat || [
17145
+ 0,
17146
+ 0
17147
+ ];
17148
+ const transformedPosition = this.mapless?.coordTrans('dataToTile', originalPosition);
16933
17149
  const sourceConfig = {
16934
17150
  type: 'model',
16935
17151
  models: {
16936
17152
  [modelId]: {
16937
17153
  uri: config.uri,
16938
- position: config.position || config.lngLat,
17154
+ position: transformedPosition,
16939
17155
  altitude: config.altitude || 0
16940
17156
  }
16941
17157
  }
@@ -17080,6 +17296,7 @@ class MapModelManager extends EmitManager {
17080
17296
  materialOverrides,
17081
17297
  nodeOverrides
17082
17298
  });
17299
+ this.modelOptions.set(id, options);
17083
17300
  if (!materialOverrides || 0 === Object.keys(materialOverrides).length) {
17084
17301
  this.themeColorModels.add(id);
17085
17302
  const themeColor = this.getDefaultThemeColor();
@@ -17095,9 +17312,10 @@ class MapModelManager extends EmitManager {
17095
17312
  const modelData = this.models.get(id);
17096
17313
  if (!modelData) return;
17097
17314
  if (!this.map) return;
17315
+ const transformedPosition = this.mapless?.coordTrans('dataToTile', lngLat);
17098
17316
  const source = this.map.getSource(modelData.sourceId);
17099
17317
  if (source?.models?.[id]) {
17100
- source.models[id].position = lngLat;
17318
+ source.models[id].position = transformedPosition;
17101
17319
  source.models[id].altitude = altitude;
17102
17320
  }
17103
17321
  if (this.map.getLayer(modelData.layerId)) this.map.setPaintProperty(modelData.layerId, 'model-translation', [
@@ -17105,6 +17323,11 @@ class MapModelManager extends EmitManager {
17105
17323
  0,
17106
17324
  altitude
17107
17325
  ]);
17326
+ const options = this.modelOptions.get(id);
17327
+ if (options) {
17328
+ options.lngLat = lngLat;
17329
+ if (void 0 !== altitude) options.altitude = altitude;
17330
+ }
17108
17331
  }
17109
17332
  updateModelRotation(id, rotation) {
17110
17333
  const modelData = this.models.get(id);
@@ -17133,6 +17356,7 @@ class MapModelManager extends EmitManager {
17133
17356
  if (this.map.getLayer(modelData.layerId)) this.map.removeLayer(modelData.layerId);
17134
17357
  if (this.map.getSource(modelData.sourceId)) this.map.removeSource(modelData.sourceId);
17135
17358
  this.models.delete(id);
17359
+ this.modelOptions.delete(id);
17136
17360
  this.themeColorModels.delete(id);
17137
17361
  if (this.selectedModelId === id) this.selectedModelId = null;
17138
17362
  }
@@ -17182,10 +17406,52 @@ class MapModelManager extends EmitManager {
17182
17406
  previousId
17183
17407
  });
17184
17408
  }
17409
+ hideLayer(id) {
17410
+ if (void 0 === id) return void this.models.forEach((modelData)=>{
17411
+ if (this.map?.getLayer(modelData.layerId)) this.map?.setLayoutProperty(modelData.layerId, 'visibility', 'none');
17412
+ });
17413
+ const modelData = this.models.get(id);
17414
+ if (!modelData) return;
17415
+ if (!this.map) return;
17416
+ if (this.map.getLayer(modelData.layerId)) this.map.setLayoutProperty(modelData.layerId, 'visibility', 'none');
17417
+ }
17418
+ showLayer(id) {
17419
+ if (void 0 === id) return void this.models.forEach((modelData)=>{
17420
+ if (this.map?.getLayer(modelData.layerId)) this.map?.setLayoutProperty(modelData.layerId, 'visibility', 'visible');
17421
+ });
17422
+ const modelData = this.models.get(id);
17423
+ if (!modelData) return;
17424
+ if (!this.map) return;
17425
+ if (this.map.getLayer(modelData.layerId)) this.map.setLayoutProperty(modelData.layerId, 'visibility', 'visible');
17426
+ }
17427
+ toggleLayer(id) {
17428
+ if (void 0 === id) {
17429
+ this.models.forEach((modelData)=>{
17430
+ const isVisible = this.isLayerVisible(modelData.id);
17431
+ if (isVisible) this.hideLayer(modelData.id);
17432
+ else this.showLayer(modelData.id);
17433
+ });
17434
+ return true;
17435
+ }
17436
+ const isVisible = this.isLayerVisible(id);
17437
+ if (isVisible) this.hideLayer(id);
17438
+ else this.showLayer(id);
17439
+ return !isVisible;
17440
+ }
17441
+ isLayerVisible(id) {
17442
+ const modelData = this.models.get(id);
17443
+ if (!modelData) return false;
17444
+ if (!this.map) return false;
17445
+ const layer = this.map.getLayer(modelData.layerId);
17446
+ if (!layer) return false;
17447
+ const visibility = layer.visibility;
17448
+ return 'none' !== visibility;
17449
+ }
17185
17450
  destroy() {
17186
17451
  if (this.map && this.globalClickHandler) this.map.off('click', this.globalClickHandler);
17187
17452
  this.selectedModelId = null;
17188
17453
  this.themeColorModels.clear();
17454
+ this.modelOptions.clear();
17189
17455
  this.clearModels();
17190
17456
  }
17191
17457
  }
@@ -17272,7 +17538,8 @@ class BasicThreeObjectManager extends manager_Manager {
17272
17538
  matrix: matrix.clone()
17273
17539
  });
17274
17540
  else {
17275
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
17541
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
17542
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
17276
17543
  const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * scale;
17277
17544
  mapThree.addRenderableObject(id, mesh, {
17278
17545
  translateX: modelAsMercator.x,
@@ -17289,7 +17556,13 @@ class BasicThreeObjectManager extends manager_Manager {
17289
17556
  type,
17290
17557
  mesh,
17291
17558
  geometry,
17292
- material
17559
+ material,
17560
+ originalOptions: {
17561
+ lngLat,
17562
+ altitude,
17563
+ rotation,
17564
+ scale
17565
+ }
17293
17566
  });
17294
17567
  console.log(`BasicThreeObject added: ${id}`, {
17295
17568
  type,
@@ -17309,7 +17582,8 @@ class BasicThreeObjectManager extends manager_Manager {
17309
17582
  if (!mapThree) return;
17310
17583
  const objData = this.objects.get(id);
17311
17584
  if (!objData) return void console.warn(`Object with id "${id}" not found`);
17312
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
17585
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
17586
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
17313
17587
  const renderableObj = mapThree.getRenderableObject(id);
17314
17588
  if (renderableObj) mapThree.updateRenderableObjectTransform(id, {
17315
17589
  ...renderableObj.transform,
@@ -17317,6 +17591,10 @@ class BasicThreeObjectManager extends manager_Manager {
17317
17591
  translateY: modelAsMercator.y,
17318
17592
  translateZ: modelAsMercator.z
17319
17593
  });
17594
+ if (objData.originalOptions) {
17595
+ objData.originalOptions.lngLat = lngLat;
17596
+ objData.originalOptions.altitude = altitude;
17597
+ }
17320
17598
  }
17321
17599
  updateObjectRotation(id, rotation) {
17322
17600
  const mapThree = this.getMapThree();
@@ -17350,7 +17628,8 @@ class BasicThreeObjectManager extends manager_Manager {
17350
17628
  if (!mapThree) return;
17351
17629
  const objData = this.objects.get(id);
17352
17630
  if (!objData) return void console.warn(`Object with id "${id}" not found`);
17353
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
17631
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
17632
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
17354
17633
  const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * scale;
17355
17634
  const renderableObj = mapThree.getRenderableObject(id);
17356
17635
  if (renderableObj) mapThree.updateRenderableObjectTransform(id, {
@@ -17421,6 +17700,27 @@ class BasicThreeObjectManager extends manager_Manager {
17421
17700
  getObjectIds() {
17422
17701
  return Array.from(this.objects.keys());
17423
17702
  }
17703
+ handleCoordSystemChange(_system) {
17704
+ const mapThree = this.getMapThree();
17705
+ if (!mapThree || 0 === this.objects.size) return;
17706
+ this.objects.forEach((objData, id)=>{
17707
+ if (!objData.originalOptions) return;
17708
+ const { lngLat, altitude, rotation, scale } = objData.originalOptions;
17709
+ mapThree.removeRenderableObject(id);
17710
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
17711
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
17712
+ const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * (scale || 1);
17713
+ mapThree.addRenderableObject(id, objData.mesh, {
17714
+ translateX: modelAsMercator.x,
17715
+ translateY: modelAsMercator.y,
17716
+ translateZ: modelAsMercator.z,
17717
+ rotateX: rotation?.[0] || 0,
17718
+ rotateY: rotation?.[1] || 0,
17719
+ rotateZ: rotation?.[2] || 0,
17720
+ scale: mercatorScale
17721
+ });
17722
+ });
17723
+ }
17424
17724
  destroy() {
17425
17725
  this.clearObjects();
17426
17726
  }
@@ -17470,10 +17770,11 @@ class Curve3DManager extends manager_Manager {
17470
17770
  }
17471
17771
  calculateTransform(points) {
17472
17772
  if (0 === points.length) throw new Error('Cannot calculate transform for empty points');
17473
- const firstPoint = mapbox_gl.MercatorCoordinate.fromLngLat([
17773
+ const transformedFirst = this.mapless?.coordTrans('dataToTile', [
17474
17774
  points[0].lng,
17475
17775
  points[0].lat
17476
- ], points[0].alt);
17776
+ ]);
17777
+ const firstPoint = mapbox_gl.MercatorCoordinate.fromLngLat(transformedFirst, points[0].alt);
17477
17778
  return {
17478
17779
  translateX: firstPoint.x,
17479
17780
  translateY: firstPoint.y,
@@ -17486,10 +17787,11 @@ class Curve3DManager extends manager_Manager {
17486
17787
  points.forEach((point, index)=>{
17487
17788
  if (0 === index) vector3Points.push(new Vector3(0, 0, 0));
17488
17789
  else {
17489
- const currentMercator = mapbox_gl.MercatorCoordinate.fromLngLat([
17790
+ const transformedPoint = this.mapless?.coordTrans('dataToTile', [
17490
17791
  point.lng,
17491
17792
  point.lat
17492
- ], point.alt);
17793
+ ]);
17794
+ const currentMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedPoint, point.alt);
17493
17795
  const dx = currentMercator.x - transform.translateX;
17494
17796
  const dy = currentMercator.y - transform.translateY;
17495
17797
  const dz = currentMercator.z - transform.translateZ;
@@ -17498,6 +17800,33 @@ class Curve3DManager extends manager_Manager {
17498
17800
  });
17499
17801
  return vector3Points;
17500
17802
  }
17803
+ handleCoordSystemChange(_system) {
17804
+ if (this.curves.size > 0 && this.getMapThree()) {
17805
+ const entries = Array.from(this.curves.entries());
17806
+ entries.forEach(([id, curveData])=>{
17807
+ const mapThree = this.getMapThree();
17808
+ if (mapThree) mapThree.removeRenderableObject(id);
17809
+ const transform = this.calculateTransform(curveData.originalPoints);
17810
+ const points = this.convertPoints(curveData.originalPoints, transform);
17811
+ const mesh = this.createMesh({
17812
+ ...curveData,
17813
+ points
17814
+ });
17815
+ if (mapThree) mapThree.addRenderableObject(id, mesh, {
17816
+ translateX: transform.translateX,
17817
+ translateY: transform.translateY,
17818
+ translateZ: transform.translateZ,
17819
+ scale: transform.scale
17820
+ });
17821
+ this.curves.set(id, {
17822
+ ...curveData,
17823
+ points,
17824
+ transform,
17825
+ mesh
17826
+ });
17827
+ });
17828
+ }
17829
+ }
17501
17830
  addCurve(id, config) {
17502
17831
  const mapThree = this.getMapThree();
17503
17832
  if (!mapThree) throw new Error('Three scene not initialized. Call useThree first.');
@@ -17517,7 +17846,8 @@ class Curve3DManager extends manager_Manager {
17517
17846
  points,
17518
17847
  mesh: null,
17519
17848
  transform,
17520
- config: curveConfig
17849
+ config: curveConfig,
17850
+ originalPoints: config.points
17521
17851
  };
17522
17852
  if (points.length >= 2) {
17523
17853
  const mesh = this.createMesh(curveData);
@@ -17550,6 +17880,7 @@ class Curve3DManager extends manager_Manager {
17550
17880
  mapThree.removeRenderableObject(id);
17551
17881
  curveData.transform = this.calculateTransform(config.points);
17552
17882
  curveData.points = this.convertPoints(config.points, curveData.transform);
17883
+ curveData.originalPoints = config.points;
17553
17884
  const mesh = this.createMesh(curveData);
17554
17885
  curveData.mesh = mesh;
17555
17886
  mapThree.addRenderableObject(id, mesh, {
@@ -17600,6 +17931,353 @@ const curve3d = Curve3DManager;
17600
17931
  const attachCurve3D = (mapless, name, options)=>mapless?.use(Curve3DManager, name, options);
17601
17932
  const getCurve3D = (mapless, name)=>mapless?.get(Curve3DManager, name);
17602
17933
  const detachCurve3D = (mapless, name)=>mapless?.unuse(Curve3DManager, name);
17934
+ class InstancedModelManager extends manager_Manager {
17935
+ scene = null;
17936
+ camera = null;
17937
+ renderer = null;
17938
+ customLayerId;
17939
+ isInitialized = false;
17940
+ instancedMeshes = new Map();
17941
+ instanceDataMap = new Map();
17942
+ rotationAngles = new Map();
17943
+ autoRotateEnabled = new Map();
17944
+ rotationSpeeds = new Map();
17945
+ clickCallback = null;
17946
+ lastProjectionMatrix = null;
17947
+ originalConfigs = new Map();
17948
+ constructor(mapless){
17949
+ super(mapless);
17950
+ this.map = mapless.map;
17951
+ this.customLayerId = `instanced-model-layer-${this.gmid}`;
17952
+ }
17953
+ initThree() {
17954
+ if (this.isInitialized || !this.map) return;
17955
+ const canvas = this.map.getCanvas();
17956
+ const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
17957
+ if (!gl) return void console.error('InstancedModelManager: WebGL context not available');
17958
+ this.scene = new Scene();
17959
+ this.camera = new PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 10000);
17960
+ this.renderer = new WebGLRenderer({
17961
+ canvas: canvas,
17962
+ context: gl,
17963
+ antialias: false
17964
+ });
17965
+ this.renderer.autoClear = false;
17966
+ this.renderer.setClearColor(0x000000, 0);
17967
+ this.renderer.setPixelRatio(window.devicePixelRatio);
17968
+ const ambientLight = new AmbientLight(0xffffff, 0.6);
17969
+ this.scene.add(ambientLight);
17970
+ const directionalLight = new DirectionalLight(0xffffff, 0.8);
17971
+ directionalLight.position.set(0, -70, 100);
17972
+ this.scene.add(directionalLight);
17973
+ const directionalLight2 = new DirectionalLight(0xffffff, 0.5);
17974
+ directionalLight2.position.set(0, 70, 100);
17975
+ this.scene.add(directionalLight2);
17976
+ this.setupCustomLayer();
17977
+ this.isInitialized = true;
17978
+ console.log('InstancedModelManager: Initialized', {
17979
+ canvas: `${canvas.width}x${canvas.height}`,
17980
+ customLayerId: this.customLayerId
17981
+ });
17982
+ }
17983
+ setupCustomLayer() {
17984
+ if (!this.map) return;
17985
+ const customLayer = {
17986
+ id: this.customLayerId,
17987
+ type: 'custom',
17988
+ renderingMode: '3d',
17989
+ onAdd: ()=>{
17990
+ console.log('InstancedModelManager: Custom layer added');
17991
+ this.setupClickHandler();
17992
+ },
17993
+ render: (_gl, matrix)=>{
17994
+ if (!this.camera || !this.renderer || !this.scene) return;
17995
+ this.updateAutoRotate();
17996
+ this.camera.projectionMatrix = new Matrix4().fromArray(matrix);
17997
+ this.lastProjectionMatrix = this.camera.projectionMatrix.clone();
17998
+ _gl.enable(_gl.DEPTH_TEST);
17999
+ this.renderer.resetState();
18000
+ this.renderer.render(this.scene, this.camera);
18001
+ if (this.map) this.map.triggerRepaint();
18002
+ }
18003
+ };
18004
+ this.map.addLayer(customLayer);
18005
+ }
18006
+ setupClickHandler() {
18007
+ if (!this.map) return;
18008
+ const canvas = this.map.getCanvas();
18009
+ const handleClick = (e)=>{
18010
+ if (!this.camera || !this.scene || !this.renderer || !this.lastProjectionMatrix) return;
18011
+ const rect = canvas.getBoundingClientRect();
18012
+ const ndcX = (e.clientX - rect.left) / rect.width * 2 - 1;
18013
+ const ndcY = 2 * -((e.clientY - rect.top) / rect.height) + 1;
18014
+ const meshes = Array.from(this.instancedMeshes.entries());
18015
+ let closestHit = null;
18016
+ let minDistance = 1 / 0;
18017
+ for (const [groupId, instancedMesh] of meshes){
18018
+ const inverseProj = this.lastProjectionMatrix.clone().invert();
18019
+ const nearPoint = new Vector4(ndcX, ndcY, -1, 1).applyMatrix4(inverseProj);
18020
+ nearPoint.divideScalar(nearPoint.w);
18021
+ const farPoint = new Vector4(ndcX, ndcY, 1, 1).applyMatrix4(inverseProj);
18022
+ farPoint.divideScalar(farPoint.w);
18023
+ const origin = new Vector3(0, 0, 0);
18024
+ const direction = new Vector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z).normalize();
18025
+ const raycaster = new Raycaster(origin, direction);
18026
+ const intersects = raycaster.intersectObject(instancedMesh, false);
18027
+ if (intersects.length > 0 && intersects[0].distance < minDistance) {
18028
+ const intersection = intersects[0];
18029
+ const instanceId = intersection.instanceId;
18030
+ if (void 0 !== instanceId) {
18031
+ minDistance = intersection.distance;
18032
+ closestHit = {
18033
+ groupId,
18034
+ instanceIndex: instanceId,
18035
+ point: intersection.point,
18036
+ distance: intersection.distance
18037
+ };
18038
+ }
18039
+ }
18040
+ }
18041
+ if (closestHit && this.clickCallback) {
18042
+ const instanceData = this.instanceDataMap.get(closestHit.groupId)?.[closestHit.instanceIndex];
18043
+ if (instanceData) this.clickCallback({
18044
+ id: closestHit.groupId,
18045
+ instanceIndex: closestHit.instanceIndex,
18046
+ point: closestHit.point,
18047
+ lngLat: instanceData.lngLat,
18048
+ altitude: instanceData.altitude
18049
+ });
18050
+ }
18051
+ };
18052
+ canvas.addEventListener('click', handleClick);
18053
+ }
18054
+ onClick(callback) {
18055
+ this.clickCallback = callback;
18056
+ }
18057
+ updateAutoRotate() {
18058
+ this.autoRotateEnabled.forEach((enabled, id)=>{
18059
+ if (!enabled) return;
18060
+ const instancedMesh = this.instancedMeshes.get(id);
18061
+ const angles = this.rotationAngles.get(id);
18062
+ const speed = this.rotationSpeeds.get(id) || 0.01;
18063
+ if (!instancedMesh || !angles) return;
18064
+ const dummy = new Object3D();
18065
+ const count = instancedMesh.count;
18066
+ for(let i = 0; i < count; i++){
18067
+ instancedMesh.getMatrixAt(i, dummy.matrix);
18068
+ dummy.matrix.decompose(dummy.position, dummy.quaternion, dummy.scale);
18069
+ angles[i] += speed;
18070
+ dummy.rotation.set(0, 0, angles[i]);
18071
+ dummy.updateMatrix();
18072
+ instancedMesh.setMatrixAt(i, dummy.matrix);
18073
+ }
18074
+ instancedMesh.instanceMatrix.needsUpdate = true;
18075
+ });
18076
+ }
18077
+ generateInstances(config) {
18078
+ const instances = [];
18079
+ for(let i = 0; i < config.count; i++){
18080
+ const lngOffset = (Math.random() - 0.5) * config.spread * 2;
18081
+ const latOffset = (Math.random() - 0.5) * config.spread * 2;
18082
+ const altitude = 500 * Math.random();
18083
+ const rotation = Math.random() * Math.PI * 2;
18084
+ const scaleVariation = 1 + 2 * Math.random();
18085
+ instances.push({
18086
+ lngLat: [
18087
+ config.center[0] + lngOffset,
18088
+ config.center[1] + latOffset
18089
+ ],
18090
+ altitude,
18091
+ rotation,
18092
+ scale: scaleVariation
18093
+ });
18094
+ }
18095
+ return instances;
18096
+ }
18097
+ handleCoordSystemChange(_system) {
18098
+ if (!this.scene || !this.map || 0 === this.originalConfigs.size) return;
18099
+ this.originalConfigs.forEach((config, id)=>{
18100
+ this.remove(id);
18101
+ this.load(id, config).catch((error)=>{
18102
+ console.error(`Failed to reload instanced model "${id}" after coord system change:`, error);
18103
+ });
18104
+ });
18105
+ }
18106
+ async load(id, config) {
18107
+ this.initThree();
18108
+ if (!this.scene || !this.map) throw new Error('Three.js scene not initialized');
18109
+ this.remove(id);
18110
+ const loader = new GLTFLoader();
18111
+ try {
18112
+ console.log('InstancedModel: Loading model', config.url);
18113
+ const gltf = await new Promise((resolve, reject)=>{
18114
+ loader.load(config.url, resolve, void 0, reject);
18115
+ });
18116
+ const gltfScene = gltf.scene;
18117
+ const meshes = [];
18118
+ gltfScene.traverse((object)=>{
18119
+ if (object instanceof Mesh) meshes.push(object);
18120
+ });
18121
+ if (0 === meshes.length) throw new Error('No mesh found in model');
18122
+ console.log('InstancedModel: Found meshes', {
18123
+ count: meshes.length,
18124
+ details: meshes.map((m, i)=>({
18125
+ index: i,
18126
+ vertices: m.geometry.attributes.position?.count,
18127
+ hasMaterial: !!m.material,
18128
+ materialArray: Array.isArray(m.material)
18129
+ }))
18130
+ });
18131
+ let meshToUse;
18132
+ if (1 === meshes.length) meshToUse = meshes[0];
18133
+ else {
18134
+ const geometries = meshes.map((mesh)=>{
18135
+ const geometry = mesh.geometry.clone();
18136
+ geometry.applyMatrix4(mesh.matrixWorld);
18137
+ return geometry;
18138
+ });
18139
+ const geometry = mergeGeometries(geometries, false);
18140
+ if (geometry) meshToUse = new Mesh(geometry, meshes[0].material);
18141
+ else {
18142
+ console.warn('Failed to merge geometries, falling back to first mesh');
18143
+ meshToUse = meshes[0];
18144
+ }
18145
+ }
18146
+ const mesh = meshToUse;
18147
+ const materialToUse = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material;
18148
+ const instancedMesh = new InstancedMesh(mesh.geometry.clone(), materialToUse.clone(), config.count);
18149
+ instancedMesh.castShadow = true;
18150
+ instancedMesh.receiveShadow = true;
18151
+ if ('side' in instancedMesh.material) instancedMesh.material.side = DoubleSide;
18152
+ const instances = this.generateInstances(config);
18153
+ const angles = new Float32Array(config.count);
18154
+ const transformedCenter = this.mapless?.coordTrans('dataToTile', config.center);
18155
+ const meterInMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedCenter, 0).meterInMercatorCoordinateUnits();
18156
+ console.log('InstancedModel: Creating instances', {
18157
+ instanceCount: config.count,
18158
+ center: config.center,
18159
+ scale: config.scale,
18160
+ meterInMercator,
18161
+ firstInstanceLngLat: instances[0].lngLat,
18162
+ firstInstanceAlt: instances[0].altitude
18163
+ });
18164
+ const dummy = new Object3D();
18165
+ instances.forEach((instance, i)=>{
18166
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', instance.lngLat);
18167
+ const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, instance.altitude);
18168
+ dummy.position.set(mercator.x, mercator.y, mercator.z);
18169
+ dummy.rotation.set(0, 0, instance.rotation);
18170
+ const scale = meterInMercator * config.scale * instance.scale;
18171
+ dummy.scale.set(scale, -scale, scale);
18172
+ dummy.updateMatrix();
18173
+ instancedMesh.setMatrixAt(i, dummy.matrix);
18174
+ angles[i] = instance.rotation;
18175
+ });
18176
+ instancedMesh.instanceMatrix.needsUpdate = true;
18177
+ this.scene.add(instancedMesh);
18178
+ this.instancedMeshes.set(id, instancedMesh);
18179
+ this.instanceDataMap.set(id, instances);
18180
+ this.rotationAngles.set(id, angles);
18181
+ this.autoRotateEnabled.set(id, config.autoRotate || false);
18182
+ this.rotationSpeeds.set(id, config.rotationSpeed || 0.01);
18183
+ this.originalConfigs.set(id, config);
18184
+ console.log(`InstancedModel "${id}" loaded with ${config.count} instances`);
18185
+ } catch (error) {
18186
+ console.error(`Failed to load instanced model "${id}":`, error);
18187
+ throw error;
18188
+ }
18189
+ }
18190
+ enableAutoRotate(id, speed = 0.01) {
18191
+ this.autoRotateEnabled.set(id, true);
18192
+ this.rotationSpeeds.set(id, speed);
18193
+ }
18194
+ disableAutoRotate(id) {
18195
+ this.autoRotateEnabled.set(id, false);
18196
+ }
18197
+ updateInstance(id, index, lngLat, altitude) {
18198
+ const instancedMesh = this.instancedMeshes.get(id);
18199
+ if (!instancedMesh) return;
18200
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
18201
+ const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18202
+ const dummy = new Object3D();
18203
+ instancedMesh.getMatrixAt(index, dummy.matrix);
18204
+ dummy.matrix.decompose(dummy.position, dummy.quaternion, dummy.scale);
18205
+ dummy.position.set(mercator.x, mercator.y, mercator.z);
18206
+ dummy.updateMatrix();
18207
+ instancedMesh.setMatrixAt(index, dummy.matrix);
18208
+ instancedMesh.instanceMatrix.needsUpdate = true;
18209
+ const instances = this.instanceDataMap.get(id);
18210
+ if (instances && instances[index]) {
18211
+ instances[index].lngLat = lngLat;
18212
+ instances[index].altitude = altitude;
18213
+ }
18214
+ }
18215
+ setInstanceVisible(id, visible) {
18216
+ const instancedMesh = this.instancedMeshes.get(id);
18217
+ if (instancedMesh) instancedMesh.visible = visible;
18218
+ }
18219
+ setVisible(visible) {
18220
+ this.IsVisible = visible;
18221
+ this.instancedMeshes.forEach((mesh)=>{
18222
+ mesh.visible = visible;
18223
+ });
18224
+ }
18225
+ getInstanceCount(id) {
18226
+ const instancedMesh = this.instancedMeshes.get(id);
18227
+ return instancedMesh?.count || 0;
18228
+ }
18229
+ getIds() {
18230
+ return Array.from(this.instancedMeshes.keys());
18231
+ }
18232
+ remove(id) {
18233
+ const instancedMesh = this.instancedMeshes.get(id);
18234
+ if (!instancedMesh) return;
18235
+ this.scene?.remove(instancedMesh);
18236
+ instancedMesh.geometry.dispose();
18237
+ if (Array.isArray(instancedMesh.material)) instancedMesh.material.forEach((m)=>{
18238
+ m.dispose();
18239
+ });
18240
+ else instancedMesh.material.dispose();
18241
+ this.instancedMeshes.delete(id);
18242
+ this.instanceDataMap.delete(id);
18243
+ this.rotationAngles.delete(id);
18244
+ this.autoRotateEnabled.delete(id);
18245
+ this.rotationSpeeds.delete(id);
18246
+ }
18247
+ clear() {
18248
+ const ids = this.getIds();
18249
+ ids.forEach((id)=>{
18250
+ this.remove(id);
18251
+ });
18252
+ }
18253
+ setColor(id, color) {
18254
+ const instancedMesh = this.instancedMeshes.get(id);
18255
+ if (!instancedMesh) return;
18256
+ const meshColor = 'string' == typeof color ? new Color(color) : color;
18257
+ if (Array.isArray(instancedMesh.material)) instancedMesh.material.forEach((m)=>{
18258
+ if ('color' in m) m.color.set(meshColor);
18259
+ });
18260
+ else if ('color' in instancedMesh.material) instancedMesh.material.color.set(meshColor);
18261
+ }
18262
+ destroy() {
18263
+ this.clear();
18264
+ if (this.map && this.customLayerId) try {
18265
+ this.map.removeLayer(this.customLayerId);
18266
+ } catch {}
18267
+ if (this.renderer) {
18268
+ this.renderer.dispose();
18269
+ this.renderer = null;
18270
+ }
18271
+ this.scene = null;
18272
+ this.camera = null;
18273
+ this.isInitialized = false;
18274
+ this.originalConfigs.clear();
18275
+ }
18276
+ }
18277
+ const instancedModel = InstancedModelManager;
18278
+ const attachInstancedModel = (mapless, name)=>mapless?.use(InstancedModelManager, name);
18279
+ const getInstancedModel = (mapless, name)=>mapless?.get(InstancedModelManager, name);
18280
+ const detachInstancedModel = (mapless, name)=>mapless?.unuse(InstancedModelManager, name);
17603
18281
  class Line2Manager extends manager_Manager {
17604
18282
  mapThree = null;
17605
18283
  lines = new Map();
@@ -17664,10 +18342,11 @@ class Line2Manager extends manager_Manager {
17664
18342
  }
17665
18343
  calculateTransform(points) {
17666
18344
  if (0 === points.length) throw new Error('Cannot calculate transform for empty points');
17667
- const firstPoint = mapbox_gl.MercatorCoordinate.fromLngLat([
18345
+ const transformedFirst = this.mapless?.coordTrans('dataToTile', [
17668
18346
  points[0].lng,
17669
18347
  points[0].lat
17670
- ], points[0].alt);
18348
+ ]);
18349
+ const firstPoint = mapbox_gl.MercatorCoordinate.fromLngLat(transformedFirst, points[0].alt);
17671
18350
  return {
17672
18351
  translateX: firstPoint.x,
17673
18352
  translateY: firstPoint.y,
@@ -17680,10 +18359,11 @@ class Line2Manager extends manager_Manager {
17680
18359
  points.forEach((point, index)=>{
17681
18360
  if (0 === index) positions.push(0, 0, 0);
17682
18361
  else {
17683
- const currentMercator = mapbox_gl.MercatorCoordinate.fromLngLat([
18362
+ const transformedPoint = this.mapless?.coordTrans('dataToTile', [
17684
18363
  point.lng,
17685
18364
  point.lat
17686
- ], point.alt);
18365
+ ]);
18366
+ const currentMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedPoint, point.alt);
17687
18367
  const dx = currentMercator.x - transform.translateX;
17688
18368
  const dy = currentMercator.y - transform.translateY;
17689
18369
  const dz = currentMercator.z - transform.translateZ;
@@ -17692,6 +18372,23 @@ class Line2Manager extends manager_Manager {
17692
18372
  });
17693
18373
  return positions;
17694
18374
  }
18375
+ handleCoordSystemChange(_system) {
18376
+ const mapThree = this.getMapThree();
18377
+ if (!mapThree || 0 === this.lines.size) return;
18378
+ this.lines.forEach((lineData, id)=>{
18379
+ mapThree.removeRenderableObject(id);
18380
+ lineData.transform = this.calculateTransform(lineData.points);
18381
+ const positions = this.convertPoints(lineData.points, lineData.transform);
18382
+ lineData.geometry.setPositions(positions);
18383
+ lineData.geometry.computeBoundingSphere();
18384
+ mapThree.addRenderableObject(id, lineData.line2, {
18385
+ translateX: lineData.transform.translateX,
18386
+ translateY: lineData.transform.translateY,
18387
+ translateZ: lineData.transform.translateZ,
18388
+ scale: lineData.transform.scale
18389
+ });
18390
+ });
18391
+ }
17695
18392
  createMaterial(config) {
17696
18393
  const colorNumber = 'string' == typeof config.color ? new Color(config.color).getHex() : 'number' == typeof config.color ? config.color : new Color(config.color).getHex();
17697
18394
  const material = new LineMaterial({
@@ -17976,6 +18673,7 @@ class ModelManager extends manager_Manager {
17976
18673
  prefabs = new Map();
17977
18674
  mixers = new Map();
17978
18675
  clock = new Clock();
18676
+ modelConfigs = new Map();
17979
18677
  constructor(mapless){
17980
18678
  super(mapless);
17981
18679
  this.map = mapless.map;
@@ -18037,7 +18735,8 @@ class ModelManager extends manager_Manager {
18037
18735
  });
18038
18736
  this.prefabs.set(modelId, model);
18039
18737
  }
18040
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
18738
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
18739
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18041
18740
  const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * scale;
18042
18741
  mapThree.addRenderableObject(modelId, model, {
18043
18742
  translateX: modelAsMercator.x,
@@ -18048,6 +18747,13 @@ class ModelManager extends manager_Manager {
18048
18747
  rotateZ: rotation[2],
18049
18748
  scale: mercatorScale
18050
18749
  });
18750
+ this.modelConfigs.set(modelId, {
18751
+ url,
18752
+ lngLat,
18753
+ altitude,
18754
+ rotation,
18755
+ scale
18756
+ });
18051
18757
  console.log('Model loaded:', {
18052
18758
  id: modelId,
18053
18759
  transform: {
@@ -18135,7 +18841,8 @@ class ModelManager extends manager_Manager {
18135
18841
  }
18136
18842
  });
18137
18843
  }
18138
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
18844
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
18845
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18139
18846
  const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * scale;
18140
18847
  if (groupId) {
18141
18848
  const group = mapThree.getGroup(groupId);
@@ -18150,6 +18857,7 @@ class ModelManager extends manager_Manager {
18150
18857
  rotateZ: rotation[2],
18151
18858
  scale: mercatorScale
18152
18859
  });
18860
+ this.modelConfigs.set(id, config);
18153
18861
  console.log('Model added:', {
18154
18862
  id,
18155
18863
  transform: {
@@ -18167,7 +18875,8 @@ class ModelManager extends manager_Manager {
18167
18875
  updateModelPosition(id, lngLat, altitude = 0) {
18168
18876
  const mapThree = this.getMapThree();
18169
18877
  if (!mapThree) return;
18170
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
18878
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
18879
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18171
18880
  const renderableObj = mapThree.getRenderableObject(id);
18172
18881
  if (renderableObj) mapThree.updateRenderableObjectTransform(id, {
18173
18882
  ...renderableObj.transform,
@@ -18175,6 +18884,11 @@ class ModelManager extends manager_Manager {
18175
18884
  translateY: modelAsMercator.y,
18176
18885
  translateZ: modelAsMercator.z
18177
18886
  });
18887
+ const config = this.modelConfigs.get(id);
18888
+ if (config) {
18889
+ config.lngLat = lngLat;
18890
+ config.altitude = altitude;
18891
+ }
18178
18892
  }
18179
18893
  updateModelRotation(id, rotation) {
18180
18894
  const mapThree = this.getMapThree();
@@ -18222,6 +18936,7 @@ class ModelManager extends manager_Manager {
18222
18936
  if (!mapThree) return;
18223
18937
  mapThree.removeRenderableObject(id);
18224
18938
  this.stopAnimation(id);
18939
+ this.modelConfigs.delete(id);
18225
18940
  }
18226
18941
  clearModels() {
18227
18942
  const mapThree = this.getMapThree();
@@ -18234,6 +18949,24 @@ class ModelManager extends manager_Manager {
18234
18949
  mixer.stopAllAction();
18235
18950
  });
18236
18951
  this.mixers.clear();
18952
+ this.modelConfigs.clear();
18953
+ }
18954
+ handleCoordSystemChange(_system) {
18955
+ const mapThree = this.getMapThree();
18956
+ if (!mapThree || 0 === this.modelConfigs.size) return;
18957
+ this.modelConfigs.forEach((config, id)=>{
18958
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', config.lngLat);
18959
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, config.altitude || 0);
18960
+ const mercatorScale = modelAsMercator.meterInMercatorCoordinateUnits() * (config.scale || 1);
18961
+ const renderableObj = mapThree.getRenderableObject(id);
18962
+ if (renderableObj) mapThree.updateRenderableObjectTransform(id, {
18963
+ ...renderableObj.transform,
18964
+ translateX: modelAsMercator.x,
18965
+ translateY: modelAsMercator.y,
18966
+ translateZ: modelAsMercator.z,
18967
+ scale: mercatorScale
18968
+ });
18969
+ });
18237
18970
  }
18238
18971
  getModel(id) {
18239
18972
  const mapThree = this.getMapThree();
@@ -18290,6 +19023,8 @@ class ThreeManager extends manager_Manager {
18290
19023
  };
18291
19024
  boxHelper = null;
18292
19025
  isSelected = false;
19026
+ clickCleanup = null;
19027
+ originalModelConfig = null;
18293
19028
  constructor(mapless){
18294
19029
  super(mapless);
18295
19030
  this.map = mapless.map;
@@ -18315,18 +19050,18 @@ class ThreeManager extends manager_Manager {
18315
19050
  0,
18316
19051
  0,
18317
19052
  0
18318
- ], scale = 1) {
19053
+ ], scale = 1, color) {
18319
19054
  const mapThree = this.getMapThree();
18320
19055
  if (!mapThree) throw new Error('MapThree not initialized. Call useThree first.');
18321
19056
  const loader = new GLTFLoader();
18322
19057
  return new Promise((resolve, reject)=>{
18323
19058
  loader.load(url, (gltf)=>{
18324
19059
  this.model = gltf.scene;
18325
- this.model.traverse((child)=>{
19060
+ if (color) this.model.traverse((child)=>{
18326
19061
  if (child instanceof Mesh) {
18327
19062
  const material = child.material;
18328
19063
  if (material.emissive) {
18329
- material.emissive = new Color(0x00ffff);
19064
+ material.emissive = new Color(color);
18330
19065
  material.emissiveIntensity = 0.5;
18331
19066
  }
18332
19067
  }
@@ -18335,7 +19070,8 @@ class ThreeManager extends manager_Manager {
18335
19070
  this.baseRotation = [
18336
19071
  ...rotation
18337
19072
  ];
18338
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
19073
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
19074
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18339
19075
  this.modelTransform = {
18340
19076
  translateX: modelAsMercator.x,
18341
19077
  translateY: modelAsMercator.y,
@@ -18357,6 +19093,14 @@ class ThreeManager extends manager_Manager {
18357
19093
  action.play();
18358
19094
  this.currentAction = action;
18359
19095
  }
19096
+ this.originalModelConfig = {
19097
+ url,
19098
+ lngLat,
19099
+ altitude,
19100
+ rotation,
19101
+ scale,
19102
+ color
19103
+ };
18360
19104
  const animationNames = this.animations.map((anim)=>anim.name);
18361
19105
  resolve({
18362
19106
  model: this.model,
@@ -18399,11 +19143,16 @@ class ThreeManager extends manager_Manager {
18399
19143
  updatePosition(lngLat, altitude = 0) {
18400
19144
  const mapThree = this.getMapThree();
18401
19145
  if (!mapThree || !this.model) return;
18402
- const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
19146
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
19147
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
18403
19148
  this.modelTransform.translateX = modelAsMercator.x;
18404
19149
  this.modelTransform.translateY = modelAsMercator.y;
18405
19150
  this.modelTransform.translateZ = modelAsMercator.z;
18406
19151
  this.modelTransform.scale = modelAsMercator.meterInMercatorCoordinateUnits() * this.userScale;
19152
+ if (this.originalModelConfig) {
19153
+ this.originalModelConfig.lngLat = lngLat;
19154
+ this.originalModelConfig.altitude = altitude;
19155
+ }
18407
19156
  this._buildFullTransformMatrix(this.currentOrientation.heading, this.currentOrientation.pitch, this.currentOrientation.roll);
18408
19157
  }
18409
19158
  _applyBaseRotation() {
@@ -18535,13 +19284,37 @@ class ThreeManager extends manager_Manager {
18535
19284
  if (!this.boxHelper || !this.model) return;
18536
19285
  this.boxHelper.update();
18537
19286
  }
19287
+ registerClick(onClick, tolerance = 30) {
19288
+ const mapThree = this.getMapThree();
19289
+ if (!mapThree || !this.modelId) {
19290
+ console.warn('ThreeManager: Cannot register click, MapThree or modelId not available');
19291
+ return null;
19292
+ }
19293
+ if (this.clickCleanup) {
19294
+ this.clickCleanup();
19295
+ this.clickCleanup = null;
19296
+ }
19297
+ const cleanup = mapThree.registerRenderableObjectClick(this.modelId, (_object, point)=>{
19298
+ if (onClick && this.model) onClick(this.model, point);
19299
+ }, tolerance);
19300
+ this.clickCleanup = cleanup;
19301
+ return cleanup;
19302
+ }
19303
+ unregisterClick() {
19304
+ if (this.clickCleanup) {
19305
+ this.clickCleanup();
19306
+ this.clickCleanup = null;
19307
+ }
19308
+ }
18538
19309
  dispose() {
19310
+ this.unregisterClick();
18539
19311
  this.deselect();
18540
19312
  const mapThree = this.getMapThree();
18541
19313
  if (mapThree && this.modelId) mapThree.removeRenderableObject(this.modelId);
18542
19314
  this.model = null;
18543
19315
  this.animations = [];
18544
19316
  this.currentAction = null;
19317
+ this.originalModelConfig = null;
18545
19318
  if (this.mixer) {
18546
19319
  this.mixer.stopAllAction();
18547
19320
  this.mixer = null;
@@ -18550,6 +19323,19 @@ class ThreeManager extends manager_Manager {
18550
19323
  this.updateAnimation();
18551
19324
  });
18552
19325
  }
19326
+ handleCoordSystemChange(_system) {
19327
+ if (!this.originalModelConfig) return;
19328
+ const mapThree = this.getMapThree();
19329
+ if (!mapThree || !this.model) return;
19330
+ const { lngLat, altitude } = this.originalModelConfig;
19331
+ const transformedLngLat = this.mapless?.coordTrans('dataToTile', lngLat);
19332
+ const modelAsMercator = mapbox_gl.MercatorCoordinate.fromLngLat(transformedLngLat, altitude);
19333
+ this.modelTransform.translateX = modelAsMercator.x;
19334
+ this.modelTransform.translateY = modelAsMercator.y;
19335
+ this.modelTransform.translateZ = modelAsMercator.z;
19336
+ this.modelTransform.scale = modelAsMercator.meterInMercatorCoordinateUnits() * this.userScale;
19337
+ this._buildFullTransformMatrix(this.currentOrientation.heading, this.currentOrientation.pitch, this.currentOrientation.roll);
19338
+ }
18553
19339
  destroy() {
18554
19340
  this.dispose();
18555
19341
  }
@@ -20482,4 +21268,4 @@ function detachPathTracker(mapless) {
20482
21268
  pathTrackerManagers.delete(mapless);
20483
21269
  }
20484
21270
  }
20485
- 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 };
21271
+ 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 };