isard 1.8.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/CHANGELOG.md +82 -1
  2. package/README.md +9 -4
  3. package/dist/basemap/grid.js +2 -5
  4. package/dist/basemap/grid.js.map +1 -1
  5. package/dist/basemap/models/furniture.d.ts +12 -0
  6. package/dist/basemap/{furniture.js → models/furniture.js} +6 -8
  7. package/dist/basemap/models/furniture.js.map +1 -0
  8. package/dist/basemap/{meshes.js → models/meshes.js} +1 -1
  9. package/dist/basemap/models/meshes.js.map +1 -0
  10. package/dist/basemap/models/trees.d.ts +21 -0
  11. package/dist/basemap/{trees.js → models/trees.js} +4 -36
  12. package/dist/basemap/models/trees.js.map +1 -0
  13. package/dist/basemap/placed.d.ts +2 -0
  14. package/dist/basemap/placed.js +2 -0
  15. package/dist/basemap/placed.js.map +1 -1
  16. package/dist/basemap/pmtiles.js +4 -3
  17. package/dist/basemap/pmtiles.js.map +1 -1
  18. package/dist/basemap/pmtileslayer.d.ts +4 -4
  19. package/dist/basemap/pmtileslayer.js +2 -1
  20. package/dist/basemap/pmtileslayer.js.map +1 -1
  21. package/dist/basemap/resample.js +3 -2
  22. package/dist/basemap/resample.js.map +1 -1
  23. package/dist/basemap/terrain.d.ts +5 -0
  24. package/dist/basemap/terrain.js +6 -4
  25. package/dist/basemap/terrain.js.map +1 -1
  26. package/dist/basemap/vectortiles/context.d.ts +3 -2
  27. package/dist/basemap/vectortiles/context.js.map +1 -1
  28. package/dist/basemap/vectortiles/extrusions.js.map +1 -1
  29. package/dist/basemap/vectortiles/furniture.d.ts +3 -3
  30. package/dist/basemap/vectortiles/furniture.js +2 -1
  31. package/dist/basemap/vectortiles/furniture.js.map +1 -1
  32. package/dist/basemap/vectortiles/labels.js +2 -1
  33. package/dist/basemap/vectortiles/labels.js.map +1 -1
  34. package/dist/basemap/vectortiles/lamps.d.ts +3 -3
  35. package/dist/basemap/vectortiles/lamps.js +1 -1
  36. package/dist/basemap/vectortiles/lamps.js.map +1 -1
  37. package/dist/basemap/vectortiles/placed.d.ts +3 -2
  38. package/dist/basemap/vectortiles/placed.js +5 -10
  39. package/dist/basemap/vectortiles/placed.js.map +1 -1
  40. package/dist/basemap/vectortiles/requests.d.ts +8 -1
  41. package/dist/basemap/vectortiles/requests.js +32 -4
  42. package/dist/basemap/vectortiles/requests.js.map +1 -1
  43. package/dist/basemap/vectortiles/street-wind.js +2 -2
  44. package/dist/basemap/vectortiles/street-wind.js.map +1 -1
  45. package/dist/basemap/vectortiles/style.js +7 -8
  46. package/dist/basemap/vectortiles/style.js.map +1 -1
  47. package/dist/basemap/vectortiles/tiles.d.ts +1 -3
  48. package/dist/basemap/vectortiles/tiles.js +1 -1
  49. package/dist/basemap/vectortiles/tiles.js.map +1 -1
  50. package/dist/basemap/vectortiles/trees.d.ts +4 -4
  51. package/dist/basemap/vectortiles/trees.js +2 -1
  52. package/dist/basemap/vectortiles/trees.js.map +1 -1
  53. package/dist/basemap/vectortiles/vectors.d.ts +9 -3
  54. package/dist/basemap/vectortiles/vectors.js +26 -2
  55. package/dist/basemap/vectortiles/vectors.js.map +1 -1
  56. package/dist/basemap/vectortiles.d.ts +8 -6
  57. package/dist/basemap/vectortiles.js +7 -4
  58. package/dist/basemap/vectortiles.js.map +1 -1
  59. package/dist/basemap/wmts.js +3 -4
  60. package/dist/basemap/wmts.js.map +1 -1
  61. package/dist/basemap/{trees.d.ts → woods.d.ts} +2 -19
  62. package/dist/basemap/woods.js +38 -0
  63. package/dist/basemap/woods.js.map +1 -0
  64. package/dist/basemap/workerpool.d.ts +1 -1
  65. package/dist/basemap/workerpool.js +3 -3
  66. package/dist/basemap/workerpool.js.map +1 -1
  67. package/dist/basemap.worker.js +2 -2
  68. package/dist/basemap.worker.js.map +23 -22
  69. package/dist/bind/layers.js +3 -0
  70. package/dist/bind/layers.js.map +1 -1
  71. package/dist/data/collada.js +4 -4
  72. package/dist/data/collada.js.map +1 -1
  73. package/dist/data/ifc.js +6 -11
  74. package/dist/data/ifc.js.map +1 -1
  75. package/dist/data/tileset.d.ts +21 -0
  76. package/dist/data/tileset.js +101 -0
  77. package/dist/data/tileset.js.map +1 -0
  78. package/dist/decoder.worker.js +5 -5
  79. package/dist/decoder.worker.js.map +7 -6
  80. package/dist/decoding/decoders.js.map +1 -0
  81. package/dist/{engine → decoding}/loader.js +2 -2
  82. package/dist/decoding/loader.js.map +1 -0
  83. package/dist/{engine → decoding}/protocol.d.ts +1 -1
  84. package/dist/decoding/protocol.js.map +1 -0
  85. package/dist/engine-loader.d.ts +3 -3
  86. package/dist/engine-loader.js +12 -5
  87. package/dist/engine-loader.js.map +1 -1
  88. package/dist/geoplateforme.d.ts +2 -1
  89. package/dist/geoplateforme.js +6 -8
  90. package/dist/geoplateforme.js.map +1 -1
  91. package/dist/index.d.ts +15 -7
  92. package/dist/index.js +9 -3
  93. package/dist/index.js.map +1 -1
  94. package/dist/isard_bg.wasm +0 -0
  95. package/dist/isard_core_bg.wasm +0 -0
  96. package/dist/isard_tess_bg.wasm +0 -0
  97. package/dist/layers/custom.d.ts +56 -0
  98. package/dist/layers/custom.js +93 -0
  99. package/dist/layers/custom.js.map +1 -0
  100. package/dist/layers/extrusions.d.ts +4 -2
  101. package/dist/layers/extrusions.js +2 -1
  102. package/dist/layers/extrusions.js.map +1 -1
  103. package/dist/layers/features.d.ts +3 -14
  104. package/dist/layers/features.js +4 -25
  105. package/dist/layers/features.js.map +1 -1
  106. package/dist/layers/flow.d.ts +3 -3
  107. package/dist/layers/flow.js +3 -4
  108. package/dist/layers/flow.js.map +1 -1
  109. package/dist/layers/glyphs.js +5 -3
  110. package/dist/layers/glyphs.js.map +1 -1
  111. package/dist/layers/ground.d.ts +57 -0
  112. package/dist/layers/ground.js +78 -0
  113. package/dist/layers/ground.js.map +1 -0
  114. package/dist/layers/icons.js +8 -6
  115. package/dist/layers/icons.js.map +1 -1
  116. package/dist/layers/layers.d.ts +2 -199
  117. package/dist/layers/layers.js +2 -469
  118. package/dist/layers/layers.js.map +1 -1
  119. package/dist/layers/models.d.ts +48 -0
  120. package/dist/layers/models.js +111 -0
  121. package/dist/layers/models.js.map +1 -0
  122. package/dist/layers/network.d.ts +26 -0
  123. package/dist/layers/network.js +127 -0
  124. package/dist/layers/network.js.map +1 -0
  125. package/dist/layers/panoramas.d.ts +2 -11
  126. package/dist/layers/panoramas.js +19 -9
  127. package/dist/layers/panoramas.js.map +1 -1
  128. package/dist/layers/photos.d.ts +4 -7
  129. package/dist/layers/photos.js +3 -4
  130. package/dist/layers/photos.js.map +1 -1
  131. package/dist/layers/pointclouds.d.ts +3 -2
  132. package/dist/layers/pointclouds.js +3 -3
  133. package/dist/layers/pointclouds.js.map +1 -1
  134. package/dist/layers/raster.d.ts +9 -0
  135. package/dist/layers/raster.js +24 -0
  136. package/dist/layers/raster.js.map +1 -0
  137. package/dist/layers/symbols.d.ts +2 -2
  138. package/dist/layers/symbols.js +2 -1
  139. package/dist/layers/symbols.js.map +1 -1
  140. package/dist/layers/tiles3d.d.ts +20 -0
  141. package/dist/layers/tiles3d.js +69 -0
  142. package/dist/layers/tiles3d.js.map +1 -0
  143. package/dist/layers/trees.d.ts +5 -7
  144. package/dist/layers/trees.js +2 -1
  145. package/dist/layers/trees.js.map +1 -1
  146. package/dist/layers/vectors.d.ts +3 -0
  147. package/dist/layers/vectors.js +4 -0
  148. package/dist/layers/vectors.js.map +1 -1
  149. package/dist/map/basemap-layers.js +1 -1
  150. package/dist/map/basemap-layers.js.map +1 -1
  151. package/dist/map/engine-settings.d.ts +1 -1
  152. package/dist/map/engine-settings.js +1 -1
  153. package/dist/map/engine-settings.js.map +1 -1
  154. package/dist/map/engines.js.map +1 -1
  155. package/dist/map/layer-spec.d.ts +7 -13
  156. package/dist/map/layer-spec.js.map +1 -1
  157. package/dist/map/workers.js +3 -4
  158. package/dist/map/workers.js.map +1 -1
  159. package/dist/map.d.ts +25 -58
  160. package/dist/map.js +61 -53
  161. package/dist/map.js.map +1 -1
  162. package/dist/panoramax.js +6 -8
  163. package/dist/panoramax.js.map +1 -1
  164. package/dist/react/CustomLayer.d.ts +1 -1
  165. package/dist/react/CustomLayer.js.map +1 -1
  166. package/dist/react/Layer.d.ts +5 -1
  167. package/dist/react/Layer.js.map +1 -1
  168. package/dist/react/VectorGeometry.d.ts +4 -0
  169. package/dist/react/VectorGeometry.js +6 -3
  170. package/dist/react/VectorGeometry.js.map +1 -1
  171. package/dist/react/VectorTiles.d.ts +2 -2
  172. package/dist/react/VectorTiles.js +1 -1
  173. package/dist/react/VectorTiles.js.map +1 -1
  174. package/dist/types.d.ts +16 -4
  175. package/dist/types.js.map +1 -1
  176. package/dist/ui/controls.js +2 -1
  177. package/dist/ui/controls.js.map +1 -1
  178. package/dist/ui/interaction.d.ts +4 -0
  179. package/dist/ui/interaction.js +59 -7
  180. package/dist/ui/interaction.js.map +1 -1
  181. package/dist/ui/minimap.js +1 -1
  182. package/dist/ui/minimap.js.map +1 -1
  183. package/dist/ui/overlay.js +3 -3
  184. package/dist/ui/overlay.js.map +1 -1
  185. package/dist/ui/search.js +1 -1
  186. package/dist/ui/search.js.map +1 -1
  187. package/dist/util/animation.js +3 -2
  188. package/dist/util/animation.js.map +1 -1
  189. package/dist/util/color.d.ts +10 -0
  190. package/dist/util/color.js +29 -9
  191. package/dist/util/color.js.map +1 -1
  192. package/dist/util/fetch.d.ts +5 -0
  193. package/dist/util/fetch.js +11 -0
  194. package/dist/util/fetch.js.map +1 -0
  195. package/dist/util/geo.d.ts +5 -0
  196. package/dist/util/geo.js +8 -2
  197. package/dist/util/geo.js.map +1 -1
  198. package/dist/util/math.d.ts +3 -0
  199. package/dist/util/math.js +4 -0
  200. package/dist/util/math.js.map +1 -0
  201. package/dist/util/requests.js.map +1 -0
  202. package/dist/util/roofs.d.ts +0 -2
  203. package/dist/util/roofs.js +0 -3
  204. package/dist/util/roofs.js.map +1 -1
  205. package/dist/wasm/isard.d.ts +18 -1
  206. package/dist/wasm/isard.js +28 -2
  207. package/dist/wasm/isard_core.d.ts +13 -1
  208. package/dist/wasm/isard_core.js +20 -2
  209. package/dist/workers/basemap/geometry.d.ts +9 -19
  210. package/dist/workers/{basemap.worker.d.ts → basemap/protocol.d.ts} +32 -23
  211. package/dist/workers/basemap/street.d.ts +4 -2
  212. package/dist/workers/basemap/tiles.d.ts +1 -3
  213. package/dist/workers/basemap/trees.d.ts +2 -2
  214. package/package.json +1 -1
  215. package/dist/basemap/furniture.d.ts +0 -26
  216. package/dist/basemap/furniture.js.map +0 -1
  217. package/dist/basemap/meshes.js.map +0 -1
  218. package/dist/basemap/trees.js.map +0 -1
  219. package/dist/engine/decoders.js.map +0 -1
  220. package/dist/engine/loader.js.map +0 -1
  221. package/dist/engine/protocol.js.map +0 -1
  222. package/dist/engine/requests.js.map +0 -1
  223. package/dist/workers/basemap/furniture.d.ts +0 -13
  224. package/dist/workers/basemap/labels.d.ts +0 -24
  225. package/dist/workers/basemap/lamps.d.ts +0 -10
  226. package/dist/workers/basemap/raster.d.ts +0 -10
  227. package/dist/workers/basemap.worker.js +0 -221
  228. package/dist/workers/basemap.worker.js.map +0 -1
  229. /package/dist/basemap/{meshes.d.ts → models/meshes.d.ts} +0 -0
  230. /package/dist/{engine → decoding}/decoders.d.ts +0 -0
  231. /package/dist/{engine → decoding}/decoders.js +0 -0
  232. /package/dist/{engine → decoding}/loader.d.ts +0 -0
  233. /package/dist/{engine → decoding}/protocol.js +0 -0
  234. /package/dist/{engine → util}/requests.d.ts +0 -0
  235. /package/dist/{engine → util}/requests.js +0 -0
package/dist/map.js CHANGED
@@ -9,17 +9,21 @@ import { SEA } from "./basemap/basemaps.js";
9
9
  import { pmtilesLayer } from "./basemap/pmtileslayer.js";
10
10
  import { VectorTiles } from "./basemap/vectortiles.js";
11
11
  import { defaultWorkerUrl } from "./basemap/workerpool.js";
12
- import { onHeaderRules } from "./engine/requests.js";
13
12
  import { destroyedEngine, engineUrl, gridUrl, loadEngine, tessUrl } from "./engine-loader.js";
14
13
  import { IGN_PRESETS } from "./geoplateforme.js";
14
+ import { CustomLayer } from "./layers/custom.js";
15
15
  import { ExtrusionLayer, extrusionStyle } from "./layers/extrusions.js";
16
16
  import { CircleLayer, circleStyle, FillLayer, fillStyle, LineLayer, lineStyle, } from "./layers/features.js";
17
17
  import { FlowLayer } from "./layers/flow.js";
18
- import { CustomLayer, GroundLayer, ModelLayer, NetworkLayer, RasterLayer, Tiles3dLayer, } from "./layers/layers.js";
18
+ import { GroundLayer } from "./layers/ground.js";
19
+ import { ModelLayer } from "./layers/models.js";
20
+ import { NetworkLayer } from "./layers/network.js";
19
21
  import { loadPanoramas } from "./layers/panoramas.js";
20
22
  import { addPhoto } from "./layers/photos.js";
21
23
  import { PointCloudLayer } from "./layers/pointclouds.js";
24
+ import { RasterLayer } from "./layers/raster.js";
22
25
  import { SymbolLayer, symbolStyle } from "./layers/symbols.js";
26
+ import { Tiles3dLayer } from "./layers/tiles3d.js";
23
27
  import { addTrees } from "./layers/trees.js";
24
28
  import { VectorLayer } from "./layers/vectors.js";
25
29
  import { BasemapLayers } from "./map/basemap-layers.js";
@@ -43,7 +47,22 @@ import { atmosphereSettings, rgb, terrainSettings } from "./settings.js";
43
47
  import { AttributionControl } from "./ui/controls.js";
44
48
  import { Interaction } from "./ui/interaction.js";
45
49
  import { easeTo, flyTo } from "./util/animation.js";
50
+ import { RAD } from "./util/geo.js";
51
+ import { clamp } from "./util/math.js";
52
+ import { onHeaderRules } from "./util/requests.js";
46
53
  import { sunPosition } from "./util/sun.js";
54
+ /** Where a map of the Earth opens without a camera given: Saint-Mandé, the IGN's home, its streets in view; of another
55
+ * body, all of it */
56
+ const EARTH_START = { center: [2.4246, 48.8457], zoom: 13, pitch: 0, bearing: 0 };
57
+ const BODY_START = { center: [0, 0], zoom: 2, pitch: 0, bearing: 0 };
58
+ /** The eye's pitch at street level (degrees from straight down): off the vertical, where its heading means nothing */
59
+ const FIRST_PERSON_PITCH = [1, 179];
60
+ /** The eye's field of view at street level (degrees): from a telephoto to a wide angle, the projection still sane */
61
+ const FIRST_PERSON_FOV = [10, 140];
62
+ /** A network's defaults: the values past which it is unreached (half an hour of travel, in seconds), its halo's
63
+ * opacity at the middle of a line (a glow, not a second line) */
64
+ const NETWORK_MAX = 1800;
65
+ const NETWORK_HALO_OPACITY = 0.11;
47
66
  /** A layer whose picked features come back with their properties (lines, circles, fills, extrusions, 3D Tiles…) */
48
67
  const hasFeatures = (layer) => 'featureAt' in layer && typeof layer.featureAt === 'function';
49
68
  /** A map (see `GeoMap.create`); layers take it as their host */
@@ -153,10 +172,9 @@ export class GeoMap {
153
172
  this.unwatchContext = watchContext(this.canvas, () => {
154
173
  this.lost = true;
155
174
  this.frames.cancel();
175
+ this.dropLostEngine();
156
176
  }, () => this.restore());
157
- const start = this.earth
158
- ? { center: [2.4246, 48.8457], zoom: 13, pitch: 0, bearing: 0 }
159
- : { center: [0, 0], zoom: 2, pitch: 0, bearing: 0 };
177
+ const start = this.earth ? EARTH_START : BODY_START;
160
178
  this.setCamera({ ...start, ...options });
161
179
  this.setBasemap(options.basemap ?? (this.earth ? 'osm-positron' : 'none'), options.hillshade ?? 0);
162
180
  if (options.sun)
@@ -221,6 +239,20 @@ export class GeoMap {
221
239
  });
222
240
  }
223
241
  }
242
+ /**
243
+ * The context is lost: its engine freed at once, the map's calls going to one that does nothing until `restore`
244
+ * builds the next. The old engine's GPU objects went with the context: deleted now, it is silent (on the context
245
+ * restored, each one warns); its 3D Tiles downloads stop. Its layers' updates meanwhile (a tile uploaded, labels)
246
+ * would fail on the lost context, whose limits read 0
247
+ */
248
+ dropLostEngine() {
249
+ this.hoverPick.cancel();
250
+ const camera = this.getCamera();
251
+ this.#engine.free();
252
+ this.#engine = destroyedEngine(camera);
253
+ // Glyph ranges and icons arriving meanwhile upload to it, not to the freed engine
254
+ this.atlases.attach(this.#engine);
255
+ }
224
256
  /** After a context loss: a new engine with the same camera, settings and layers (same handles, same order) */
225
257
  restore() {
226
258
  if (this.gone)
@@ -270,8 +302,8 @@ export class GeoMap {
270
302
  }
271
303
  const lonLat = [view.lonLat[0], view.lonLat[1]];
272
304
  const eye = { height: 1.7, pitch: 90, fov: 75, ...view, lonLat };
273
- eye.pitch = Math.max(1, Math.min(179, eye.pitch));
274
- eye.fov = Math.max(10, Math.min(140, eye.fov));
305
+ eye.pitch = clamp(eye.pitch, ...FIRST_PERSON_PITCH);
306
+ eye.fov = clamp(eye.fov, ...FIRST_PERSON_FOV);
275
307
  eye.bearing = ((eye.bearing % 360) + 360) % 360;
276
308
  this.#firstPerson = eye;
277
309
  this.engine.setFirstPerson(eye.lonLat[0], eye.lonLat[1], eye.height, eye.bearing, eye.pitch, eye.fov);
@@ -343,38 +375,6 @@ export class GeoMap {
343
375
  this.listeners.emit(type, event);
344
376
  }
345
377
  // ── Camera ──
346
- /**
347
- * The camera's methods together: `get`, `set`, `easeTo`, `flyTo`, `bounds`, `firstPerson` and `setFirstPerson`
348
- * (street level), `project`, `unproject`; the same as the map's own (`getCamera`, `setCamera`…)
349
- */
350
- camera = {
351
- get: () => this.getCamera(),
352
- set: (camera) => this.setCamera(camera),
353
- easeTo: (camera, options) => this.easeTo(camera, options),
354
- flyTo: (camera, options) => this.flyTo(camera, options),
355
- bounds: () => this.getBounds(),
356
- firstPerson: () => this.firstPerson,
357
- setFirstPerson: (view) => this.setFirstPerson(view),
358
- project: (lonLat, height) => this.project(lonLat, height),
359
- unproject: (point) => this.unproject(point),
360
- };
361
- /**
362
- * What lies under a point or at a position, together: `feature` (`pickFeature`), `surface` (`pickSurface`),
363
- * `surfaceAt`, `elevationAt`, `metersPerPixel`
364
- */
365
- query = {
366
- feature: (point, options) => this.pickFeature(point, options),
367
- surface: (point) => this.pickSurface(point),
368
- surfaceAt: (lonLat) => this.surfaceAt(lonLat),
369
- elevationAt: (lonLat) => this.elevationAt(lonLat),
370
- metersPerPixel: (point) => this.metersPerPixel(point),
371
- };
372
- /** What is drawn over the scene, together: `viewshed` (`setViewshed`), `sun` (`setSun`), `swipe` (`setSwipe`) */
373
- effects = {
374
- viewshed: (options) => this.setViewshed(options),
375
- sun: (options) => this.setSun(options),
376
- swipe: (options) => this.setSwipe(options),
377
- };
378
378
  getCamera() {
379
379
  return this.frames.camera ?? this.engine.camera();
380
380
  }
@@ -524,7 +524,7 @@ export class GeoMap {
524
524
  * offscreen picking pass, whatever the number of features, but waits for the GPU to finish the frame (a stall): for
525
525
  * clicks and one-off queries. On hover, listen to 'hoverfeature' instead, which picks without waiting.
526
526
  */
527
- pick(point, radius = 0, layers) {
527
+ pick(point, { radius = 0, layers } = {}) {
528
528
  const only = layers && Uint32Array.from(layers.map((l) => l.id));
529
529
  return this.engine.pick(point[0], point[1], radius, only);
530
530
  }
@@ -534,7 +534,7 @@ export class GeoMap {
534
534
  * search to some layers (the others hide nothing).
535
535
  */
536
536
  pickFeature(point, options = {}) {
537
- const hit = this.pick(point, options.radius ?? 0, options.layers);
537
+ const hit = this.pick(point, options);
538
538
  return hit && this.featureHit(hit);
539
539
  }
540
540
  /** A hit with its layer handle and feature; undefined if the layer is gone */
@@ -569,6 +569,9 @@ export class GeoMap {
569
569
  const host = panoramaHost(this, (lon, lat) => this.engines.geoidHeight(lon, lat));
570
570
  const panoramas = await loadPanoramas(host, options);
571
571
  this.panoramaSets.add(panoramas);
572
+ panoramas.whenRemoved.push(() => {
573
+ this.panoramaSets.delete(panoramas);
574
+ });
572
575
  return panoramas;
573
576
  }
574
577
  /** The panorama sets, their panorama shown again in a new engine */
@@ -587,9 +590,8 @@ export class GeoMap {
587
590
  if (!a || !b)
588
591
  return undefined;
589
592
  // Haversine, on the mean radius of the body
590
- const rad = Math.PI / 180;
591
- const [dLat, dLon] = [(b[1] - a[1]) * rad, (b[0] - a[0]) * rad];
592
- const h = Math.sin(dLat / 2) ** 2 + Math.cos(a[1] * rad) * Math.cos(b[1] * rad) * Math.sin(dLon / 2) ** 2;
593
+ const [dLat, dLon] = [(b[1] - a[1]) * RAD, (b[0] - a[0]) * RAD];
594
+ const h = Math.sin(dLat / 2) ** 2 + Math.cos(a[1] * RAD) * Math.cos(b[1] * RAD) * Math.sin(dLon / 2) ** 2;
593
595
  return 2 * this.settings.body.radius * Math.asin(Math.min(1, Math.sqrt(h)));
594
596
  }
595
597
  /** Whether a double click zooms in (Shift: out), on by default: off while a drawing takes double clicks */
@@ -597,6 +599,12 @@ export class GeoMap {
597
599
  if (this.interaction)
598
600
  this.interaction.doubleClickZoom = enabled;
599
601
  }
602
+ /** Whether a drag that turns and tilts the map (right button, Ctrl or Shift) goes around what is under the pointer
603
+ * where it starts, a roof or a mesh as the relief (on by default), or around the screen center */
604
+ setRotateAroundPointer(enabled) {
605
+ if (this.interaction)
606
+ this.interaction.rotateAroundPointer = enabled;
607
+ }
600
608
  /** What is drawn under a screen point (CSS pixels), on the relief or standing on it (a roof, a wall, a mesh): its
601
609
  * position and its height above the relief, in metres; undefined where nothing was drawn. The last frame's scene is
602
610
  * drawn again and read back, waiting for the GPU (a stall): for clicks and drags */
@@ -662,16 +670,16 @@ export class GeoMap {
662
670
  * `url` with or without `pmtiles://`, relative to the page, or a `blob:` URL. `addRaster({ url: 'pmtiles://…' })` and
663
671
  * a style source `pmtiles://…` in `vectorTiles` read archives too
664
672
  */
665
- addPmtiles(url, options = {}) {
666
- return pmtilesLayer(this, url, options);
673
+ addPmtiles(options) {
674
+ return pmtilesLayer(this, options);
667
675
  }
668
676
  /** Line network colored by a value per node; `layer.setValues` recolors it in one texture upload */
669
677
  addNetwork(options) {
670
- const { nodes, edges, lines, costs, edgeWidths, width = 2, max = 1800, contour = 0, opacity = 1 } = options;
671
- const { halo = 0, haloOpacity = 0.11, ramp, unreachedColor = 'rgba(140, 140, 140, 0.25)', fade = 0 } = options;
678
+ const { nodes, edges, lines, costs, edgeWidths, width = 2, max = NETWORK_MAX, contour = 0, opacity = 1 } = options;
679
+ const { halo = 0, haloOpacity = NETWORK_HALO_OPACITY, ramp, unreachedColor = 'rgba(140, 140, 140, 0.25)', fade = 0, } = options;
672
680
  const style = { width, max, contour, opacity, halo, haloOpacity, ramp, unreachedColor, fade };
673
681
  validateNetwork(nodes, edges);
674
- return this.addLayer(new NetworkLayer(this, { nodes, edges, lines }, costs, style, edgeWidths));
682
+ return this.place(new NetworkLayer(this, { nodes, edges, lines }, costs, style, edgeWidths), options.before);
675
683
  }
676
684
  /**
677
685
  * A layer from its description, as an application's configuration gives it: `{ type, ...options }`, the options of
@@ -803,13 +811,13 @@ export class GeoMap {
803
811
  }
804
812
  /** Textured meshes in 3D Tiles (photogrammetry, buildings), drawn with depth over the basemap */
805
813
  addTiles3d(options) {
806
- const { url, maxScreenSpaceError = 16, opacity = 1, pointSize, color, geoid = false } = options;
807
- return this.addLayer(new Tiles3dLayer(this, url, geoid, {
814
+ const { url, maxScreenSpaceError = 16, opacity = 1, pointSize, color, geoid = false, facades = false } = options;
815
+ return this.place(new Tiles3dLayer(this, url, geoid, {
808
816
  maxScreenSpaceError,
809
817
  opacity,
810
818
  ...(pointSize !== undefined ? { pointSize } : {}),
811
819
  ...(color !== undefined ? { color } : {}),
812
- }));
820
+ }, facades), options.before);
813
821
  }
814
822
  /**
815
823
  * A point cloud (see `PointCloudOptions`): a COPC file read by range requests (IGN's LiDAR HD…), or 3D Tiles
@@ -900,7 +908,7 @@ export class GeoMap {
900
908
  this.hoverPick.cancel();
901
909
  this.basemaps.destroy();
902
910
  [...this.vectorSets].forEach((tiles) => {
903
- tiles.destroy();
911
+ tiles.remove();
904
912
  });
905
913
  this.vectorSets.clear();
906
914
  this.workers.terminate();