isard 1.0.0 → 1.2.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.
- package/CHANGELOG.md +51 -0
- package/dist/{basemaps.d.ts → basemap/basemaps.d.ts} +3 -3
- package/dist/{basemaps.js → basemap/basemaps.js} +3 -3
- package/dist/basemap/basemaps.js.map +1 -0
- package/dist/{grid.d.ts → basemap/grid.d.ts} +6 -6
- package/dist/{grid.js → basemap/grid.js} +61 -67
- package/dist/basemap/grid.js.map +1 -0
- package/dist/{mvt.d.ts → basemap/mvt.d.ts} +1 -1
- package/dist/{mvt.js → basemap/mvt.js} +6 -6
- package/dist/basemap/mvt.js.map +1 -0
- package/dist/{pmtiles.d.ts → basemap/pmtiles.d.ts} +16 -10
- package/dist/{pmtiles.js → basemap/pmtiles.js} +41 -33
- package/dist/basemap/pmtiles.js.map +1 -0
- package/dist/{resample.d.ts → basemap/resample.d.ts} +11 -2
- package/dist/{resample.js → basemap/resample.js} +18 -16
- package/dist/basemap/resample.js.map +1 -0
- package/dist/{terrain.d.ts → basemap/terrain.d.ts} +3 -3
- package/dist/{terrain.js → basemap/terrain.js} +7 -7
- package/dist/basemap/terrain.js.map +1 -0
- package/dist/{vectorstyle.d.ts → basemap/vectorstyle.d.ts} +12 -10
- package/dist/{vectorstyle.js → basemap/vectorstyle.js} +129 -111
- package/dist/basemap/vectorstyle.js.map +1 -0
- package/dist/{vectortiles.d.ts → basemap/vectortiles.d.ts} +18 -18
- package/dist/{vectortiles.js → basemap/vectortiles.js} +157 -109
- package/dist/basemap/vectortiles.js.map +1 -0
- package/dist/{wmts.d.ts → basemap/wmts.d.ts} +3 -3
- package/dist/{wmts.js → basemap/wmts.js} +19 -14
- package/dist/basemap/wmts.js.map +1 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +14 -13
- package/dist/bind/layers.d.ts +46 -0
- package/dist/bind/layers.js +154 -0
- package/dist/bind/layers.js.map +1 -0
- package/dist/{crs.d.ts → data/crs.d.ts} +11 -11
- package/dist/{crs.js → data/crs.js} +38 -34
- package/dist/data/crs.js.map +1 -0
- package/dist/{gpx.d.ts → data/gpx.d.ts} +2 -2
- package/dist/{gpx.js → data/gpx.js} +20 -20
- package/dist/data/gpx.js.map +1 -0
- package/dist/{kml.d.ts → data/kml.d.ts} +2 -2
- package/dist/{kml.js → data/kml.js} +42 -39
- package/dist/data/kml.js.map +1 -0
- package/dist/{topojson.d.ts → data/topojson.d.ts} +2 -2
- package/dist/{topojson.js → data/topojson.js} +15 -10
- package/dist/data/topojson.js.map +1 -0
- package/dist/{xml.d.ts → data/xml.d.ts} +5 -5
- package/dist/{xml.js → data/xml.js} +19 -18
- package/dist/data/xml.js.map +1 -0
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +7 -7
- package/dist/{decoders.d.ts → engine/decoders.d.ts} +3 -3
- package/dist/{decoders.js → engine/decoders.js} +28 -25
- package/dist/engine/decoders.js.map +1 -0
- package/dist/{loader.d.ts → engine/loader.d.ts} +1 -1
- package/dist/{loader.js → engine/loader.js} +17 -14
- package/dist/engine/loader.js.map +1 -0
- package/dist/{protocol.d.ts → engine/protocol.d.ts} +1 -1
- package/dist/engine/protocol.js +3 -0
- package/dist/engine/protocol.js.map +1 -0
- package/dist/{requests.d.ts → engine/requests.d.ts} +1 -1
- package/dist/{requests.js → engine/requests.js} +19 -16
- package/dist/engine/requests.js.map +1 -0
- package/dist/engine-loader.d.ts +13 -9
- package/dist/engine-loader.js +30 -30
- package/dist/engine-loader.js.map +1 -1
- package/dist/formats.d.ts +3 -3
- package/dist/formats.js +3 -3
- package/dist/formats.js.map +1 -1
- package/dist/geoplateforme.d.ts +13 -13
- package/dist/geoplateforme.js +23 -21
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +30 -29
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_points_bg.wasm +0 -0
- package/dist/{extrusions.d.ts → layers/extrusions.d.ts} +1 -1
- package/dist/{extrusions.js → layers/extrusions.js} +10 -5
- package/dist/layers/extrusions.js.map +1 -0
- package/dist/{features.d.ts → layers/features.d.ts} +10 -10
- package/dist/{features.js → layers/features.js} +44 -45
- package/dist/layers/features.js.map +1 -0
- package/dist/{glyphs.d.ts → layers/glyphs.d.ts} +6 -6
- package/dist/{glyphs.js → layers/glyphs.js} +45 -41
- package/dist/layers/glyphs.js.map +1 -0
- package/dist/{icons.d.ts → layers/icons.d.ts} +10 -10
- package/dist/{icons.js → layers/icons.js} +84 -69
- package/dist/layers/icons.js.map +1 -0
- package/dist/{layers.d.ts → layers/layers.d.ts} +9 -4
- package/dist/{layers.js → layers/layers.js} +35 -31
- package/dist/layers/layers.js.map +1 -0
- package/dist/{panoramas.d.ts → layers/panoramas.d.ts} +3 -3
- package/dist/{panoramas.js → layers/panoramas.js} +54 -43
- package/dist/layers/panoramas.js.map +1 -0
- package/dist/{pointclouds.d.ts → layers/pointclouds.d.ts} +5 -5
- package/dist/{pointclouds.js → layers/pointclouds.js} +26 -34
- package/dist/layers/pointclouds.js.map +1 -0
- package/dist/{symbols.d.ts → layers/symbols.d.ts} +3 -3
- package/dist/{symbols.js → layers/symbols.js} +69 -72
- package/dist/layers/symbols.js.map +1 -0
- package/dist/map/basemap-layers.d.ts +26 -0
- package/dist/map/basemap-layers.js +61 -0
- package/dist/map/basemap-layers.js.map +1 -0
- package/dist/map/canvas.d.ts +17 -0
- package/dist/map/canvas.js +56 -0
- package/dist/map/canvas.js.map +1 -0
- package/dist/map/checks.d.ts +11 -0
- package/dist/map/checks.js +39 -0
- package/dist/map/checks.js.map +1 -0
- package/dist/map/credits.d.ts +17 -0
- package/dist/map/credits.js +34 -0
- package/dist/map/credits.js.map +1 -0
- package/dist/map/engine-settings.d.ts +15 -0
- package/dist/map/engine-settings.js +45 -0
- package/dist/map/engine-settings.js.map +1 -0
- package/dist/map/engines.d.ts +41 -0
- package/dist/map/engines.js +77 -0
- package/dist/map/engines.js.map +1 -0
- package/dist/map/events.d.ts +14 -0
- package/dist/map/events.js +46 -0
- package/dist/map/events.js.map +1 -0
- package/dist/map/frame-loop.d.ts +61 -0
- package/dist/map/frame-loop.js +139 -0
- package/dist/map/frame-loop.js.map +1 -0
- package/dist/map/hover-pick.d.ts +30 -0
- package/dist/map/hover-pick.js +56 -0
- package/dist/map/hover-pick.js.map +1 -0
- package/dist/map/layer-spec.d.ts +42 -0
- package/dist/map/layer-spec.js +34 -0
- package/dist/map/layer-spec.js.map +1 -0
- package/dist/map/layer-stack.d.ts +36 -0
- package/dist/map/layer-stack.js +101 -0
- package/dist/map/layer-stack.js.map +1 -0
- package/dist/map/overlay-host.d.ts +36 -0
- package/dist/map/overlay-host.js +101 -0
- package/dist/map/overlay-host.js.map +1 -0
- package/dist/map/panorama-host.d.ts +5 -0
- package/dist/map/panorama-host.js +32 -0
- package/dist/map/panorama-host.js.map +1 -0
- package/dist/map/raster-source.d.ts +11 -0
- package/dist/map/raster-source.js +26 -0
- package/dist/map/raster-source.js.map +1 -0
- package/dist/map/symbol-atlases.d.ts +26 -0
- package/dist/map/symbol-atlases.js +59 -0
- package/dist/map/symbol-atlases.js.map +1 -0
- package/dist/map/viewshed.d.ts +5 -0
- package/dist/map/viewshed.js +28 -0
- package/dist/map/viewshed.js.map +1 -0
- package/dist/map/workers.d.ts +46 -0
- package/dist/map/workers.js +73 -0
- package/dist/map/workers.js.map +1 -0
- package/dist/map.d.ts +46 -127
- package/dist/map.js +183 -698
- package/dist/map.js.map +1 -1
- package/dist/projections.d.ts +3 -3
- package/dist/projections.js +2 -2
- package/dist/projections.js.map +1 -1
- package/dist/react/Control.d.ts +11 -0
- package/dist/react/Control.js +18 -0
- package/dist/react/Control.js.map +1 -0
- package/dist/react/CustomLayer.d.ts +11 -0
- package/dist/react/CustomLayer.js +30 -0
- package/dist/react/CustomLayer.js.map +1 -0
- package/dist/react/IsardMap.d.ts +43 -0
- package/dist/react/IsardMap.js +146 -0
- package/dist/react/IsardMap.js.map +1 -0
- package/dist/react/Layer.d.ts +42 -0
- package/dist/react/Layer.js +74 -0
- package/dist/react/Layer.js.map +1 -0
- package/dist/react/Marker.d.ts +24 -0
- package/dist/react/Marker.js +53 -0
- package/dist/react/Marker.js.map +1 -0
- package/dist/react/Panel.d.ts +11 -0
- package/dist/react/Panel.js +37 -0
- package/dist/react/Panel.js.map +1 -0
- package/dist/react/Popup.d.ts +18 -0
- package/dist/react/Popup.js +60 -0
- package/dist/react/Popup.js.map +1 -0
- package/dist/react/Swipe.d.ts +9 -0
- package/dist/react/Swipe.js +41 -0
- package/dist/react/Swipe.js.map +1 -0
- package/dist/react/Viewshed.d.ts +5 -0
- package/dist/react/Viewshed.js +28 -0
- package/dist/react/Viewshed.js.map +1 -0
- package/dist/react/context.d.ts +32 -0
- package/dist/react/context.js +20 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +26 -0
- package/dist/react/index.js +22 -0
- package/dist/react/index.js.map +1 -0
- package/dist/settings.d.ts +6 -10
- package/dist/settings.js +19 -17
- package/dist/settings.js.map +1 -1
- package/dist/types.d.ts +8 -8
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/{controls.d.ts → ui/controls.d.ts} +1 -1
- package/dist/{controls.js → ui/controls.js} +6 -4
- package/dist/ui/controls.js.map +1 -0
- package/dist/{interaction.d.ts → ui/interaction.d.ts} +9 -5
- package/dist/{interaction.js → ui/interaction.js} +9 -8
- package/dist/ui/interaction.js.map +1 -0
- package/dist/{overlay.d.ts → ui/overlay.d.ts} +2 -2
- package/dist/{overlay.js → ui/overlay.js} +18 -20
- package/dist/ui/overlay.js.map +1 -0
- package/dist/{style.d.ts → ui/style.d.ts} +1 -1
- package/dist/{style.js → ui/style.js} +2 -2
- package/dist/ui/style.js.map +1 -0
- package/dist/{animation.d.ts → util/animation.d.ts} +9 -5
- package/dist/{animation.js → util/animation.js} +6 -6
- package/dist/util/animation.js.map +1 -0
- package/dist/{color.d.ts → util/color.d.ts} +1 -1
- package/dist/{color.js → util/color.js} +14 -16
- package/dist/util/color.js.map +1 -0
- package/dist/{geo.d.ts → util/geo.d.ts} +6 -6
- package/dist/{geo.js → util/geo.js} +12 -12
- package/dist/util/geo.js.map +1 -0
- package/dist/util/guards.d.ts +7 -0
- package/dist/util/guards.js +8 -0
- package/dist/util/guards.js.map +1 -0
- package/dist/util/lru.js.map +1 -0
- package/dist/wasm/isard.d.ts +168 -0
- package/dist/wasm/isard.js +146 -0
- package/dist/wasm/isard_core.d.ts +144 -0
- package/dist/wasm/isard_core.js +122 -0
- package/dist/{basemap.worker.d.ts → workers/basemap.worker.d.ts} +17 -7
- package/dist/workers/basemap.worker.js +658 -0
- package/dist/workers/basemap.worker.js.map +1 -0
- package/package.json +24 -1
- package/vite.js +1 -1
- package/dist/animation.js.map +0 -1
- package/dist/basemaps.js.map +0 -1
- package/dist/color.js.map +0 -1
- package/dist/controls.js.map +0 -1
- package/dist/crs.js.map +0 -1
- package/dist/decoders.js.map +0 -1
- package/dist/extrusions.js.map +0 -1
- package/dist/features.js.map +0 -1
- package/dist/geo.js.map +0 -1
- package/dist/glyphs.js.map +0 -1
- package/dist/gpx.js.map +0 -1
- package/dist/grid.js.map +0 -1
- package/dist/icons.js.map +0 -1
- package/dist/interaction.js.map +0 -1
- package/dist/kml.js.map +0 -1
- package/dist/layers.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/lru.js.map +0 -1
- package/dist/mvt.js.map +0 -1
- package/dist/overlay.js.map +0 -1
- package/dist/panoramas.js.map +0 -1
- package/dist/pmtiles.js.map +0 -1
- package/dist/pointclouds.js.map +0 -1
- package/dist/protocol.js +0 -2
- package/dist/protocol.js.map +0 -1
- package/dist/requests.js.map +0 -1
- package/dist/resample.js.map +0 -1
- package/dist/style.js.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/terrain.js.map +0 -1
- package/dist/topojson.js.map +0 -1
- package/dist/vectorstyle.js.map +0 -1
- package/dist/vectortiles.js.map +0 -1
- package/dist/wmts.js.map +0 -1
- package/dist/xml.js.map +0 -1
- /package/dist/{lru.d.ts → util/lru.d.ts} +0 -0
- /package/dist/{lru.js → util/lru.js} +0 -0
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* the map recreates its engine and every layer in order, with the same handle (its id is updated). Also the page's
|
|
4
4
|
* own 3D content: custom layers (its WebGL code called in every frame) and glTF models drawn at positions.
|
|
5
5
|
*/
|
|
6
|
+
import { rgb } from "../settings.js";
|
|
7
|
+
import { mercatorX, mercatorY, toMercator } from "../util/geo.js";
|
|
6
8
|
import { parseColor, rampTexels, stops } from "./features.js";
|
|
7
|
-
import { mercatorX, mercatorY, toMercator } from "./geo.js";
|
|
8
|
-
import { rgb } from "./settings.js";
|
|
9
9
|
export class Layer {
|
|
10
10
|
#id = -1;
|
|
11
11
|
/** @internal */
|
|
@@ -133,23 +133,23 @@ export class NetworkLayer extends Layer {
|
|
|
133
133
|
/** @internal */
|
|
134
134
|
create(engine) {
|
|
135
135
|
const { nodes, edges, lines } = this.geometry;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
else {
|
|
136
|
+
const mercator = (() => {
|
|
137
|
+
if (this.kept) {
|
|
138
|
+
const { origin, nodes: n, lines: l } = this.kept;
|
|
139
|
+
return { nodes: unpack(n, origin), lines: l && unpack(l, origin) };
|
|
140
|
+
}
|
|
142
141
|
// Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly
|
|
143
|
-
|
|
144
|
-
const origin = [
|
|
142
|
+
const projected = { nodes: mercatorPoints(nodes), lines: lines && mercatorPoints(lines.points) };
|
|
143
|
+
const origin = [projected.nodes[0] ?? 0, projected.nodes[1] ?? 0];
|
|
145
144
|
this.kept = {
|
|
146
145
|
origin,
|
|
147
|
-
nodes: pack(
|
|
148
|
-
lines:
|
|
146
|
+
nodes: pack(projected.nodes, origin),
|
|
147
|
+
lines: projected.lines && pack(projected.lines, origin),
|
|
149
148
|
};
|
|
150
149
|
// The degrees are not needed again: millions of points for a region
|
|
151
150
|
this.geometry = { nodes: EMPTY, edges, lines: lines && { start: lines.start, points: EMPTY } };
|
|
152
|
-
|
|
151
|
+
return projected;
|
|
152
|
+
})();
|
|
153
153
|
const id = engine.addNetwork(mercator.nodes, edges, lines?.start, mercator.lines, this.costs, networkStyle(this.style));
|
|
154
154
|
if (this.style.ramp)
|
|
155
155
|
engine.setNetworkRamp(id, rampTexels(this.style.ramp).rgba);
|
|
@@ -161,7 +161,7 @@ export class NetworkLayer extends Layer {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
/** The 25 numbers of a network style for the engine */
|
|
164
|
-
|
|
164
|
+
const networkStyle = (style) => {
|
|
165
165
|
const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;
|
|
166
166
|
return Float32Array.from([
|
|
167
167
|
...stops(width),
|
|
@@ -173,34 +173,34 @@ function networkStyle(style) {
|
|
|
173
173
|
...parseColor(unreachedColor),
|
|
174
174
|
fade,
|
|
175
175
|
]);
|
|
176
|
-
}
|
|
176
|
+
};
|
|
177
177
|
const EMPTY = new Float64Array(0);
|
|
178
178
|
/** Interleaved points as f32 offsets from an origin, and back */
|
|
179
|
-
|
|
179
|
+
const pack = (points, [ox, oy]) => {
|
|
180
180
|
const out = new Float32Array(points.length);
|
|
181
181
|
for (let i = 0; i < points.length; i += 2) {
|
|
182
182
|
out[i] = (points[i] ?? 0) - ox;
|
|
183
183
|
out[i + 1] = (points[i + 1] ?? 0) - oy;
|
|
184
184
|
}
|
|
185
185
|
return out;
|
|
186
|
-
}
|
|
187
|
-
|
|
186
|
+
};
|
|
187
|
+
const unpack = (points, [ox, oy]) => {
|
|
188
188
|
const out = new Float64Array(points.length);
|
|
189
189
|
for (let i = 0; i < points.length; i += 2) {
|
|
190
190
|
out[i] = (points[i] ?? 0) + ox;
|
|
191
191
|
out[i + 1] = (points[i + 1] ?? 0) + oy;
|
|
192
192
|
}
|
|
193
193
|
return out;
|
|
194
|
-
}
|
|
194
|
+
};
|
|
195
195
|
/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */
|
|
196
|
-
|
|
196
|
+
const mercatorPoints = (lonLat) => {
|
|
197
197
|
const out = new Float64Array(lonLat.length);
|
|
198
198
|
for (let i = 0; i < lonLat.length; i += 2) {
|
|
199
199
|
out[i] = mercatorX(lonLat[i] ?? 0);
|
|
200
200
|
out[i + 1] = mercatorY(lonLat[i + 1] ?? 0);
|
|
201
201
|
}
|
|
202
202
|
return out;
|
|
203
|
-
}
|
|
203
|
+
};
|
|
204
204
|
/** Textured meshes in 3D Tiles */
|
|
205
205
|
export class Tiles3dLayer extends Layer {
|
|
206
206
|
url;
|
|
@@ -263,10 +263,12 @@ export class GroundLayer extends Layer {
|
|
|
263
263
|
constructor(map, options) {
|
|
264
264
|
super(map);
|
|
265
265
|
this.options = options;
|
|
266
|
-
|
|
266
|
+
Object.entries(options.textures ?? {}).forEach(([name, texture]) => {
|
|
267
267
|
this.textures.set(name, texture);
|
|
268
|
-
|
|
268
|
+
});
|
|
269
|
+
Object.entries(options.uniforms ?? {}).forEach(([name, value]) => {
|
|
269
270
|
this.uniforms.set(name, [value].flat());
|
|
271
|
+
});
|
|
270
272
|
}
|
|
271
273
|
/** Creates or replaces a texture of the code's sampler `name` */
|
|
272
274
|
setTexture(name, texture) {
|
|
@@ -308,30 +310,32 @@ export class GroundLayer extends Layer {
|
|
|
308
310
|
create(engine) {
|
|
309
311
|
const [ax, ay] = toMercator(this.options.anchor);
|
|
310
312
|
const id = engine.addGround(this.options.code, ax, ay, ...mercatorBox(this.options.bounds ?? [-180, -85.06, 180, 85.06]));
|
|
311
|
-
|
|
313
|
+
this.textures.forEach((texture, name) => {
|
|
312
314
|
this.sendTexture(engine, id, name, texture);
|
|
313
|
-
|
|
315
|
+
});
|
|
316
|
+
this.uniforms.forEach((values, name) => {
|
|
314
317
|
engine.setGroundUniform(id, name, Float64Array.from(values));
|
|
318
|
+
});
|
|
315
319
|
engine.setGroundVisible(id, this.visible);
|
|
316
320
|
return id;
|
|
317
321
|
}
|
|
318
322
|
}
|
|
319
323
|
/** A lon/lat box to Mercator min x, min y, max x, max y (y towards the south) */
|
|
320
|
-
|
|
324
|
+
const mercatorBox = ([west, south, east, north]) => {
|
|
321
325
|
const [x0, y1] = toMercator([west, south]);
|
|
322
326
|
const [x1, y0] = toMercator([east, north]);
|
|
323
327
|
return [x0, y0, x1, y1];
|
|
324
|
-
}
|
|
328
|
+
};
|
|
325
329
|
// ── The page's own 3D content: custom layers, glTF models ──
|
|
326
330
|
/** Reports an error of the page without throwing it here: the console shows it, as an uncaught one */
|
|
327
|
-
|
|
331
|
+
const report = (error) => {
|
|
328
332
|
if (typeof reportError === 'function')
|
|
329
333
|
reportError(error);
|
|
330
334
|
else
|
|
331
335
|
queueMicrotask(() => {
|
|
332
336
|
throw error;
|
|
333
337
|
});
|
|
334
|
-
}
|
|
338
|
+
};
|
|
335
339
|
/** A layer drawn by the page's WebGL code (see `CustomLayerInterface`) */
|
|
336
340
|
export class CustomLayer extends Layer {
|
|
337
341
|
implementation;
|
|
@@ -410,13 +414,13 @@ export class CustomLayer extends Layer {
|
|
|
410
414
|
}
|
|
411
415
|
}
|
|
412
416
|
/** The numbers of instances for the engine: longitude, latitude, altitude, heading, pitch, roll, scale */
|
|
413
|
-
export
|
|
417
|
+
export const instanceNumbers = (instances) => {
|
|
414
418
|
const out = new Float64Array(instances.length * 7);
|
|
415
419
|
instances.forEach(({ lonLat, altitude = 0, heading = 0, pitch = 0, roll = 0, scale = 1 }, i) => {
|
|
416
420
|
out.set([lonLat[0], lonLat[1], altitude, heading, pitch, roll, scale], i * 7);
|
|
417
421
|
});
|
|
418
422
|
return out;
|
|
419
|
-
}
|
|
423
|
+
};
|
|
420
424
|
/** A glTF model drawn at positions, in one instanced draw; `pickFeature` gives the instance's index */
|
|
421
425
|
export class ModelLayer extends Layer {
|
|
422
426
|
url;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/layers/layers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Handles of the layers added to a map. Each one keeps what it needs to be created again: after a WebGL context loss,\n * the map recreates its engine and every layer in order, with the same handle (its id is updated). Also the page's\n * own 3D content: custom layers (its WebGL code called in every frame) and glTF models drawn at positions.\n */\n\nimport type { GeoMap } from '../map.ts';\nimport { rgb } from '../settings.ts';\nimport type {\n LayerHost,\n LonLat,\n NetworkOptions,\n NetworkStyle,\n RasterOptions,\n RasterStyle,\n Tiles3dStyle,\n} from '../types.ts';\nimport { mercatorX, mercatorY, toMercator } from '../util/geo.ts';\nimport type { Camera, Engine, NetworkStats, Tiles3dStats } from '../wasm/isard.js';\nimport { type Feature, parseColor, rampTexels, stops } from './features.ts';\n\nexport abstract class Layer {\n #id = -1;\n\n /** @internal */\n protected readonly map: LayerHost;\n\n /** @internal */\n constructor(map: LayerHost) {\n this.map = map;\n }\n\n /** Id of the layer in the engine */\n get id(): number {\n return this.#id;\n }\n\n #ready: Promise<void> | undefined;\n\n /** Resolves once the map has drawn the layer, what it shows in view loaded (the map idle after it was added; a\n * layer waiting for the engine with 3D Tiles, once that one has drawn it) */\n get ready(): Promise<void> {\n this.#ready ??= (async () => {\n do await this.map.whenIdle();\n while (this.#id < 0 && this.needsFullEngine);\n })();\n\n return this.#ready;\n }\n\n /** @internal Creates the layer in an engine (again after a context loss); its id is -1 if that fails */\n attach(engine: Engine): void {\n this.#id = -1;\n this.#id = this.create(engine);\n }\n\n /** @internal Forgets its id in an engine that is gone (before the layers are created in a new one) */\n forgetEngine(): void {\n this.#id = -1;\n }\n\n /** @internal Sends what refers to other layers, once every layer of a new engine has its id */\n relink(_engine: Engine): void {}\n\n /** @internal Drawn by the engine with 3D Tiles only (3D Tiles, models): on the core engine, it waits for that one */\n get needsFullEngine(): boolean {\n return false;\n }\n\n /** @internal The layer is removed or its map destroyed: frees what it holds outside the engine */\n dispose(): void {}\n\n /** @internal */\n protected abstract create(engine: Engine): number;\n\n remove(): void {\n // Not created yet: a 3D Tiles layer or a model waiting for the engine with 3D Tiles\n if (this.#id >= 0) this.map.engine.removeLayer(this.#id);\n this.#id = -1;\n this.map.detach(this);\n this.map.requestRender();\n }\n\n /** Moves the layer under `other`, or on top of every layer (above the labels of a vector basemap too) */\n moveBefore(other: Layer | undefined): void {\n this.map.moveLayer(this, other);\n }\n}\n\n/** Raster tiles (basemaps, overlays) */\nexport class RasterLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: Required<Omit<RasterOptions, 'size' | 'loader' | 'grid' | 'attribution'>> & {\n size: number | undefined;\n loader: RasterOptions['loader'] | undefined;\n },\n ) {\n super(map);\n }\n\n /** Changes the opacity or saturation, the other kept */\n setStyle(style: Partial<RasterStyle>): void {\n this.options.opacity = style.opacity ?? this.options.opacity;\n this.options.saturation = style.saturation ?? this.options.saturation;\n this.map.engine.setRasterStyle(this.id, this.options.opacity, this.options.saturation);\n this.map.requestRender();\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { url, minZoom, maxZoom, opacity, saturation, size, loader } = this.options;\n\n return engine.addRaster(url, minZoom, maxZoom, opacity, saturation, size, loader);\n }\n}\n\n/** Line network colored by a value per node (travel time, water depth…) */\nexport class NetworkLayer extends Layer {\n private values: Float32Array | undefined;\n /** Node and line positions in Mercator, kept for a context loss: f32 offsets from an origin (exact to the centimetre\n * across a region, half the memory of f64) */\n private kept: { origin: [number, number]; nodes: Float32Array; lines: Float32Array | undefined } | undefined;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private geometry: { nodes: Float64Array; edges: Uint32Array; lines: NetworkOptions['lines'] | undefined },\n private costs: Float32Array | undefined,\n private style: NetworkStyle,\n private edgeWidths: Float32Array | undefined,\n ) {\n super(map);\n }\n\n /** One value per node, in node order; negative (or 1e30 and above) = unreached. Costs one texture upload, drawn\n * next frame. */\n setValues(values: Float32Array): void {\n this.values = values;\n this.map.engine.setNetworkValues(this.id, values);\n this.map.requestRender();\n }\n\n /** Costs of the edges, A → B then B → A (see `NetworkOptions.costs`), when the way the network is travelled\n * changes; undefined: values interpolated along the edges. The geometry stays on the graphics card. */\n setCosts(costs: Float32Array | undefined): void {\n this.costs = costs;\n this.map.engine.setNetworkCosts(this.id, costs);\n this.map.requestRender();\n }\n\n setStyle(style: Partial<NetworkStyle>): void {\n const ramp = this.style.ramp;\n\n this.style = { ...this.style, ...style };\n this.map.engine.setNetworkStyle(this.id, networkStyle(this.style));\n if (this.style.ramp !== ramp)\n this.map.engine.setNetworkRamp(this.id, this.style.ramp && rampTexels(this.style.ramp).rgba);\n this.map.requestRender();\n }\n\n /** Width factor of each edge (undefined: 1 for all) */\n setEdgeWidths(widths: Float32Array | undefined): void {\n this.edgeWidths = widths;\n this.map.engine.setNetworkScales(this.id, widths);\n this.map.requestRender();\n }\n\n /** Pieces in all and drawn in the last frame */\n stats(): NetworkStats | undefined {\n return this.map.engine.networkStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { nodes, edges, lines } = this.geometry;\n const mercator = ((): { nodes: Float64Array; lines: Float64Array | undefined } => {\n if (this.kept) {\n const { origin, nodes: n, lines: l } = this.kept;\n\n return { nodes: unpack(n, origin), lines: l && unpack(l, origin) };\n }\n\n // Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly\n const projected = { nodes: mercatorPoints(nodes), lines: lines && mercatorPoints(lines.points) };\n const origin: [number, number] = [projected.nodes[0] ?? 0, projected.nodes[1] ?? 0];\n\n this.kept = {\n origin,\n nodes: pack(projected.nodes, origin),\n lines: projected.lines && pack(projected.lines, origin),\n };\n // The degrees are not needed again: millions of points for a region\n this.geometry = { nodes: EMPTY, edges, lines: lines && { start: lines.start, points: EMPTY } };\n\n return projected;\n })();\n const id = engine.addNetwork(\n mercator.nodes,\n edges,\n lines?.start,\n mercator.lines,\n this.costs,\n networkStyle(this.style),\n );\n\n if (this.style.ramp) engine.setNetworkRamp(id, rampTexels(this.style.ramp).rgba);\n if (this.edgeWidths) engine.setNetworkScales(id, this.edgeWidths);\n if (this.values) engine.setNetworkValues(id, this.values);\n\n return id;\n }\n}\n\n/** The 25 numbers of a network style for the engine */\nconst networkStyle = (style: NetworkStyle): Float32Array => {\n const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;\n\n return Float32Array.from([\n ...stops(width),\n ...stops(halo),\n max,\n contour,\n opacity,\n haloOpacity,\n ...parseColor(unreachedColor),\n fade,\n ]);\n};\n\nconst EMPTY = new Float64Array(0);\n\n/** Interleaved points as f32 offsets from an origin, and back */\nconst pack = (points: Float64Array, [ox, oy]: [number, number]): Float32Array => {\n const out = new Float32Array(points.length);\n\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) - ox;\n out[i + 1] = (points[i + 1] ?? 0) - oy;\n }\n\n return out;\n};\n\nconst unpack = (points: Float32Array, [ox, oy]: [number, number]): Float64Array => {\n const out = new Float64Array(points.length);\n\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) + ox;\n out[i + 1] = (points[i + 1] ?? 0) + oy;\n }\n\n return out;\n};\n\n/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */\nconst mercatorPoints = (lonLat: Float64Array): Float64Array => {\n const out = new Float64Array(lonLat.length);\n\n for (let i = 0; i < lonLat.length; i += 2) {\n out[i] = mercatorX(lonLat[i] ?? 0);\n out[i + 1] = mercatorY(lonLat[i + 1] ?? 0);\n }\n\n return out;\n};\n\n/** Textured meshes in 3D Tiles */\nexport class Tiles3dLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly url: string,\n private readonly geoid: boolean,\n private style: Tiles3dStyle,\n ) {\n super(map);\n }\n\n setStyle(style: Partial<Tiles3dStyle>): void {\n this.style = { ...this.style, ...style };\n // Kept for its creation while the engine with 3D Tiles loads\n if (this.id < 0) return;\n this.applyStyle(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n /** @internal */\n override get needsFullEngine(): boolean {\n return true;\n }\n\n /** @internal The feature picked (`pickFeature`, 'hoverfeature'): the properties of its feature in the tile\n * (`EXT_structural_metadata`, a b3dm batch table), none for a mesh without features; its index in the tile as id */\n featureAt(index: number): Feature<Record<string, unknown>> | undefined {\n if (this.id < 0) return undefined;\n\n const hit = this.map.engine.tiles3dFeature(this.id, index);\n\n if (!hit) return undefined;\n\n const [properties, feature] = hit;\n\n return { type: 'Feature', id: feature, properties: properties ?? {}, geometry: null };\n }\n\n /** Loading counters; undefined once the layer is removed, and while the engine with 3D Tiles loads (see\n * `GeoMapOptions.tiles3d`) */\n stats(): Tiles3dStats | undefined {\n return this.id < 0 ? undefined : this.map.engine.tiles3dStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addTiles3d(this.url, this.style.maxScreenSpaceError, this.geoid);\n\n this.applyStyle(engine, id);\n\n return id;\n }\n\n private applyStyle(engine: Engine, id: number): void {\n const { maxScreenSpaceError, opacity, pointSize, color } = this.style;\n\n engine.setTiles3dStyle(id, maxScreenSpaceError, opacity, pointSize, new Float32Array(color ? rgb(color) : []));\n }\n}\n\n/** A texture of a ground layer (see `GroundLayer`) */\nexport interface GroundTexture {\n /** `r8`, `r8ui`, `r16ui`, `r16i`, `r32ui`, `r32f`, `rg16ui`, `rg32f`, `rgba8`, `rgba8ui`, `rgba16ui`, `rgba32f`:\n * integer formats are read with `usampler2D` / `isampler2D` and `texelFetch` */\n format: string;\n width: number;\n height: number;\n /** Layers of a 2D array (`sampler2DArray`, `usampler2DArray`…); 0 or undefined: a 2D texture */\n depth?: number;\n /** Linear filtering (non-integer formats); default nearest */\n linear?: boolean;\n /** Texels row after row (layer after layer), any typed array; undefined: left empty */\n data?: ArrayBufferView;\n}\n\nexport interface GroundOptions {\n /**\n * GLSL ES 3.0 defining `vec4 ground(vec2 offset)`: the color of the ground (premultiplied alpha, 0 for nothing) at\n * `offset`, the Mercator offset of the pixel from `anchor` (times `ISARD_CIRCUMFERENCE`: metres of EPSG:3857), exact to\n * the millimetre at any zoom. The code declares its own uniforms and samplers; also there: `u_zoom`,\n * `u_pixel_ratio`\n */\n code: string;\n /** Where the offsets are taken from */\n anchor: LonLat;\n /** Box it shows in, `[west, south, east, north]` (default the world): only the ground there is drawn again */\n bounds?: [west: number, south: number, east: number, north: number];\n textures?: Record<string, GroundTexture>;\n uniforms?: Record<string, number | readonly number[]>;\n}\n\nconst bytesOf = (data: ArrayBufferView) => new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\n/** The application's fragment shader run over the ground, draped on the relief (water depth, heat maps…) */\nexport class GroundLayer extends Layer {\n private readonly textures = new Map<string, GroundTexture>();\n private readonly uniforms = new Map<string, number[]>();\n private visible = true;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: GroundOptions,\n ) {\n super(map);\n Object.entries(options.textures ?? {}).forEach(([name, texture]) => {\n this.textures.set(name, texture);\n });\n Object.entries(options.uniforms ?? {}).forEach(([name, value]) => {\n this.uniforms.set(name, [value].flat());\n });\n }\n\n /** Creates or replaces a texture of the code's sampler `name` */\n setTexture(name: string, texture: GroundTexture): void {\n this.textures.set(name, texture);\n this.sendTexture(this.map.engine, this.id, name, texture);\n this.map.requestRender();\n }\n\n /**\n * Replaces a region of a texture: `data` holds `width` × `height` texels for (`x`, `y`) of `layer` (2D arrays).\n * Keep the texture's own `data` up to date too if it must survive a WebGL context loss.\n */\n updateTexture(\n name: string,\n data: ArrayBufferView,\n region: { x?: number; y?: number; layer?: number; width: number; height: number },\n ): void {\n const { x = 0, y = 0, layer = 0, width, height } = region;\n\n this.map.engine.updateGroundTexture(this.id, name, x, y, layer, width, height, bytesOf(data));\n this.map.requestRender();\n }\n\n /** A uniform of the code: a number, or numbers for vectors, arrays and matrices (column major) */\n setUniform(name: string, value: number | readonly number[]): void {\n const values = [value].flat();\n\n this.uniforms.set(name, values);\n this.map.engine.setGroundUniform(this.id, name, Float64Array.from(values));\n this.map.requestRender();\n }\n\n setBounds(bounds: [west: number, south: number, east: number, north: number]): void {\n this.options.bounds = bounds;\n this.map.engine.setGroundBounds(this.id, ...mercatorBox(bounds));\n this.map.requestRender();\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n this.map.engine.setGroundVisible(this.id, visible);\n this.map.requestRender();\n }\n\n private sendTexture(engine: Engine, id: number, name: string, t: GroundTexture): void {\n const data = t.data && bytesOf(t.data);\n\n engine.setGroundTexture(id, name, t.format, t.width, t.height, t.depth ?? 0, t.linear ?? false, data);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const [ax, ay] = toMercator(this.options.anchor);\n const id = engine.addGround(\n this.options.code,\n ax,\n ay,\n ...mercatorBox(this.options.bounds ?? [-180, -85.06, 180, 85.06]),\n );\n\n this.textures.forEach((texture, name) => {\n this.sendTexture(engine, id, name, texture);\n });\n this.uniforms.forEach((values, name) => {\n engine.setGroundUniform(id, name, Float64Array.from(values));\n });\n engine.setGroundVisible(id, this.visible);\n\n return id;\n }\n}\n\n/** A lon/lat box to Mercator min x, min y, max x, max y (y towards the south) */\nconst mercatorBox = ([west, south, east, north]: [number, number, number, number]): [\n number,\n number,\n number,\n number,\n] => {\n const [x0, y1] = toMercator([west, south]);\n const [x1, y0] = toMercator([east, north]);\n\n return [x0, y0, x1, y1];\n};\n\n// ── The page's own 3D content: custom layers, glTF models ──\n\n/** Reports an error of the page without throwing it here: the console shows it, as an uncaught one */\nconst report = (error: unknown): void => {\n if (typeof reportError === 'function') reportError(error);\n else\n queueMicrotask(() => {\n throw error;\n });\n};\n\n/** What a custom layer gets to draw a frame (`CustomLayerInterface.render`) */\nexport interface CustomFrame {\n /**\n * The model-view-projection matrix of a local frame at a position and altitude (metres above the ellipsoid, as the\n * relief is drawn: times its exaggeration), column-major for `uniformMatrix4fv` or a three.js camera: x east, y\n * north, z up, in metres. Made in double precision relative to the camera, so that what is drawn stays exact at\n * any zoom; draw within a few kilometres of the position (or take one matrix per object far apart). Only during\n * `render`.\n */\n matrixAt(lonLat: LonLat, altitude?: number): Float32Array;\n /** The camera of the frame */\n readonly camera: Camera;\n}\n\n/**\n * A layer drawn by the page with its own WebGL code, as MapLibre's `CustomLayerInterface`: `render` is called at the\n * layer's place in every frame drawn. It starts with the canvas bound, its viewport set, blending on (`SRC_ALPHA`,\n * `ONE_MINUS_SRC_ALPHA`), no culling, and in `'3d'` mode the depth test on (`LEQUAL`, depth written): the relief, the\n * buildings and the 3D Tiles hide what it draws and what it draws hides them. Whatever WebGL state it changes is set\n * back afterwards; a library that caches the WebGL state (three.js) must forget it first (`renderer.resetState()`).\n *\n * The map is busy drawing meanwhile: `render` reads the frame, not the map (`getCamera` excepted); it may call\n * `requestRender` for an animation.\n */\nexport interface CustomLayerInterface {\n /** A name for the application (the map numbers its layers) */\n id?: string;\n /** `'2d'` (the default): drawn over what is under it; `'3d'`: with the depth buffer of the 3D layers */\n renderingMode?: '2d' | '3d';\n /** Creates the WebGL objects: once added, and again after the WebGL context was lost and restored */\n onAdd?(gl: WebGL2RenderingContext, map: GeoMap): void;\n render(gl: WebGL2RenderingContext, frame: CustomFrame): void;\n /** Frees the WebGL objects: the layer is removed, or the map destroyed */\n onRemove?(gl: WebGL2RenderingContext, map: GeoMap): void;\n}\n\n/** The model-view-projection of a local frame in the engine running the map (`Engine.customMatrix`) */\n/** @internal */\nexport type CustomMatrix = (lon: number, lat: number, altitude: number) => Float32Array | undefined;\n\n/** A layer drawn by the page's WebGL code (see `CustomLayerInterface`) */\nexport class CustomLayer extends Layer {\n /** The map's WebGL context, and whether `onAdd` made the layer's objects there (until `onRemove`) */\n private readonly gl: WebGL2RenderingContext;\n private added = false;\n /** The context was lost since `onAdd`: its objects are gone */\n private stale = false;\n private readonly lost = () => {\n this.stale = true;\n };\n private readonly frame: CustomFrame;\n\n /** @internal */\n constructor(\n map: LayerHost,\n /** The application's object */\n readonly implementation: CustomLayerInterface,\n private readonly canvas: HTMLCanvasElement,\n private readonly owner: GeoMap,\n matrix: CustomMatrix,\n camera: () => Camera,\n ) {\n super(map);\n // The context the engine made on the canvas\n this.gl = canvas.getContext('webgl2') as WebGL2RenderingContext;\n this.frame = {\n matrixAt: ([lon, lat], altitude = 0) => {\n const m = matrix(lon, lat, altitude);\n\n if (!m) throw new Error('isard: frame.matrixAt is only available during render');\n\n return m;\n },\n get camera() {\n return camera();\n },\n };\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n // Once, and again on a context restored (not when the map moves onto another engine: the same context)\n if (!this.added || this.stale) {\n if (!this.added) this.canvas.addEventListener('webglcontextlost', this.lost);\n this.added = true;\n this.stale = false;\n this.implementation.onAdd?.(this.gl, this.owner);\n }\n\n return engine.addCustomLayer(this.draw, this.implementation.renderingMode === '3d');\n }\n\n /** Called by the engine at the layer's place in the frame; the page's errors are reported, the frame goes on */\n private readonly draw = (): void => {\n try {\n this.implementation.render(this.gl, this.frame);\n } catch (error) {\n report(error);\n }\n };\n\n override remove(): void {\n super.remove();\n this.dispose();\n }\n\n /** @internal The layer is removed or the map destroyed: `onRemove`, unless the context is lost */\n override dispose(): void {\n if (!this.added) return;\n this.added = false;\n this.canvas.removeEventListener('webglcontextlost', this.lost);\n if (this.stale) return;\n try {\n this.implementation.onRemove?.(this.gl, this.owner);\n } catch (error) {\n report(error);\n }\n }\n}\n\n/** Where and how a model stands */\nexport interface ModelInstance {\n lonLat: LonLat;\n /** Metres above the ground (or above the ellipsoid, `altitudeReference: 'sea'`); 0 by default */\n altitude?: number;\n /** Degrees clockwise from the north of the model's front (glTF +Z); 0 by default */\n heading?: number;\n /** Degrees, nose up */\n pitch?: number;\n /** Degrees, right side down */\n roll?: number;\n /** 1 by default: the model's metres */\n scale?: number;\n}\n\nexport interface ModelOptions {\n /** URL of a glTF binary (`.glb`): meshes, textures, Draco, meshopt, KTX2, as in 3D Tiles; or its bytes (`data`) */\n url?: string;\n data?: ArrayBuffer | ArrayBufferView<ArrayBuffer>;\n instances: readonly ModelInstance[];\n /** What the altitudes are above: `'ground'` (the relief, the default) or `'sea'` (the ellipsoid) */\n altitudeReference?: 'ground' | 'sea';\n}\n\n/** The numbers of instances for the engine: longitude, latitude, altitude, heading, pitch, roll, scale */\nexport const instanceNumbers = (instances: readonly ModelInstance[]): Float64Array => {\n const out = new Float64Array(instances.length * 7);\n\n instances.forEach(({ lonLat, altitude = 0, heading = 0, pitch = 0, roll = 0, scale = 1 }, i) => {\n out.set([lonLat[0], lonLat[1], altitude, heading, pitch, roll, scale], i * 7);\n });\n\n return out;\n};\n\n/** A glTF model drawn at positions, in one instanced draw; `pickFeature` gives the instance's index */\nexport class ModelLayer extends Layer {\n private readonly url: string;\n /** The `blob:` URL of the page's bytes, revoked once the layer is gone */\n private readonly blob: string | undefined;\n private instances: Float64Array;\n private ground: boolean;\n\n /** @internal */\n constructor(map: LayerHost, options: ModelOptions) {\n super(map);\n\n const { url, data } = options;\n\n if (data) {\n this.blob = URL.createObjectURL(new Blob([data], { type: 'model/gltf-binary' }));\n this.url = this.blob;\n } else if (url) {\n // Against the page: the decoding workers fetch it, and a relative URL would be theirs\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n this.url = base ? new URL(url, base).href : url;\n } else {\n throw new Error('isard: a model needs a url or data');\n }\n this.instances = instanceNumbers(options.instances);\n this.ground = options.altitudeReference !== 'sea';\n }\n\n /** @internal The engine with 3D Tiles decodes and draws the models */\n override get needsFullEngine(): boolean {\n return true;\n }\n\n /** Replaces the instances (and what their altitudes are above, kept if not given) */\n setInstances(instances: readonly ModelInstance[], altitudeReference?: 'ground' | 'sea'): void {\n this.instances = instanceNumbers(instances);\n if (altitudeReference) this.ground = altitudeReference === 'ground';\n // Kept for its creation while the engine with 3D Tiles loads\n if (this.id < 0) return;\n this.map.engine.setModelInstances(this.id, this.instances, this.ground);\n this.map.requestRender();\n }\n\n override remove(): void {\n super.remove();\n this.dispose();\n }\n\n /** @internal */\n override dispose(): void {\n if (this.blob) URL.revokeObjectURL(this.blob);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n return engine.addModels(this.url, this.instances, this.ground);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FirstPersonView, LonLat } from '
|
|
1
|
+
import type { FirstPersonView, LonLat } from '../types.ts';
|
|
2
2
|
export interface PanoramaOptions {
|
|
3
3
|
/** URL of an image: `{cameraId}` and `{panoId}` replaced by a camera's id and a panorama's */
|
|
4
4
|
url: string;
|
|
@@ -50,7 +50,7 @@ interface Attitude {
|
|
|
50
50
|
* `quaternionFromRollPitchHeading`: Ry(-roll) · Rx(-pitch) · Rz(-heading)), turned by the meridian convergence of the
|
|
51
51
|
* projection (Lambert-93: sin(46.5°) · (3° - longitude))
|
|
52
52
|
*/
|
|
53
|
-
export declare
|
|
53
|
+
export declare const panoramaRotation: (attitude: Attitude, lon: number, lambert93: boolean) => number[];
|
|
54
54
|
/** The panoramas of a set, one shown at a time */
|
|
55
55
|
export declare class Panoramas {
|
|
56
56
|
private readonly host;
|
|
@@ -90,5 +90,5 @@ export declare class Panoramas {
|
|
|
90
90
|
exit(): void;
|
|
91
91
|
}
|
|
92
92
|
/** Loads a set of panoramas: their positions and attitudes, the calibration of their cameras */
|
|
93
|
-
export declare
|
|
93
|
+
export declare const loadPanoramas: (host: PanoramaHost, options: PanoramaOptions) => Promise<Panoramas>;
|
|
94
94
|
export {};
|
|
@@ -10,22 +10,35 @@
|
|
|
10
10
|
* await panoramas.show(panoramas.nearest([2.3345, 48.8505]).index);
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
|
-
import { getCrs } from "
|
|
14
|
-
import { withHeaders } from "
|
|
13
|
+
import { getCrs } from "../data/crs.js";
|
|
14
|
+
import { withHeaders } from "../engine/requests.js";
|
|
15
|
+
import { isNumbers, isRecord } from "../util/guards.js";
|
|
16
|
+
const isOrientation = (value) => isRecord(value) && isRecord(value.geometry) && isNumbers(value.geometry.coordinates) && isRecord(value.properties);
|
|
17
|
+
const isCrs = (value) => isRecord(value) &&
|
|
18
|
+
(value.properties === undefined ||
|
|
19
|
+
(isRecord(value.properties) && (value.properties.name === undefined || typeof value.properties.name === 'string')));
|
|
20
|
+
const isOrientations = (value) => isRecord(value) &&
|
|
21
|
+
(value.crs === undefined || isCrs(value.crs)) &&
|
|
22
|
+
Array.isArray(value.features) &&
|
|
23
|
+
value.features.every(isOrientation);
|
|
24
|
+
const isCalibration = (value) => isRecord(value) &&
|
|
25
|
+
(typeof value.id === 'number' || typeof value.id === 'string') &&
|
|
26
|
+
isNumbers(value.rotation) &&
|
|
27
|
+
isNumbers(value.position) &&
|
|
28
|
+
isNumbers(value.projection) &&
|
|
29
|
+
isNumbers(value.size) &&
|
|
30
|
+
(value.distortion === undefined ||
|
|
31
|
+
(isRecord(value.distortion) &&
|
|
32
|
+
isNumbers(value.distortion.pps) &&
|
|
33
|
+
isNumbers(value.distortion.poly357) &&
|
|
34
|
+
(value.distortion.limit === undefined || typeof value.distortion.limit === 'number')));
|
|
35
|
+
const isCalibrations = (value) => Array.isArray(value) && value.every(isCalibration);
|
|
15
36
|
const RAD = Math.PI / 180;
|
|
16
37
|
/** 3 × 3 product, row-major */
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let sum = 0;
|
|
22
|
-
for (let k = 0; k < 3; k++)
|
|
23
|
-
sum += (a[r * 3 + k] ?? 0) * (b[k * 3 + c] ?? 0);
|
|
24
|
-
out.push(sum);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
38
|
+
const times = (a, b) => Array.from({ length: 9 }, (_, i) => {
|
|
39
|
+
const [r, c] = [Math.floor(i / 3), i % 3];
|
|
40
|
+
return [0, 1, 2].reduce((sum, k) => sum + (a[r * 3 + k] ?? 0) * (b[k * 3 + c] ?? 0), 0);
|
|
41
|
+
});
|
|
29
42
|
const rotX = (t) => [1, 0, 0, 0, Math.cos(t), -Math.sin(t), 0, Math.sin(t), Math.cos(t)];
|
|
30
43
|
const rotY = (t) => [Math.cos(t), 0, Math.sin(t), 0, 1, 0, -Math.sin(t), 0, Math.cos(t)];
|
|
31
44
|
const rotZ = (t) => [Math.cos(t), -Math.sin(t), 0, Math.sin(t), Math.cos(t), 0, 0, 0, 1];
|
|
@@ -34,13 +47,13 @@ const rotZ = (t) => [Math.cos(t), -Math.sin(t), 0, Math.sin(t), Math.cos(t), 0,
|
|
|
34
47
|
* `quaternionFromRollPitchHeading`: Ry(-roll) · Rx(-pitch) · Rz(-heading)), turned by the meridian convergence of the
|
|
35
48
|
* projection (Lambert-93: sin(46.5°) · (3° - longitude))
|
|
36
49
|
*/
|
|
37
|
-
export
|
|
50
|
+
export const panoramaRotation = (attitude, lon, lambert93) => {
|
|
38
51
|
const vehicle = times(times(rotY(-attitude.roll * RAD), rotX(-attitude.pitch * RAD)), rotZ(-attitude.heading * RAD));
|
|
39
52
|
const convergence = lambert93 ? Math.sin(46.5 * RAD) * (3 - lon) * RAD : 0;
|
|
40
53
|
return times(rotZ(convergence), vehicle);
|
|
41
|
-
}
|
|
54
|
+
};
|
|
42
55
|
/** The 25 numbers of a camera for `setPanorama` */
|
|
43
|
-
|
|
56
|
+
const cameraNumbers = (c) => {
|
|
44
57
|
const p = c.projection;
|
|
45
58
|
const d = c.distortion;
|
|
46
59
|
return [
|
|
@@ -60,7 +73,7 @@ function cameraNumbers(c) {
|
|
|
60
73
|
d?.poly357[2] ?? 0,
|
|
61
74
|
d?.limit ?? 0,
|
|
62
75
|
];
|
|
63
|
-
}
|
|
76
|
+
};
|
|
64
77
|
/** The panoramas of a set, one shown at a time */
|
|
65
78
|
export class Panoramas {
|
|
66
79
|
host;
|
|
@@ -84,14 +97,10 @@ export class Panoramas {
|
|
|
84
97
|
/** The panorama nearest to a position */
|
|
85
98
|
nearest(lonLat) {
|
|
86
99
|
const cos = Math.cos(lonLat[1] * RAD);
|
|
87
|
-
|
|
88
|
-
let distance = Number.POSITIVE_INFINITY;
|
|
89
|
-
for (const p of this.list) {
|
|
100
|
+
return this.list.reduce((nearest, p) => {
|
|
90
101
|
const d = ((p.lonLat[0] - lonLat[0]) * cos) ** 2 + (p.lonLat[1] - lonLat[1]) ** 2;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
return best;
|
|
102
|
+
return d < nearest.distance ? { best: p, distance: d } : nearest;
|
|
103
|
+
}, { distance: Number.POSITIVE_INFINITY }).best;
|
|
95
104
|
}
|
|
96
105
|
/** Shows a panorama (its index in `list`): projected as soon as its first image arrives, the others after */
|
|
97
106
|
async show(index) {
|
|
@@ -167,18 +176,14 @@ export class Panoramas {
|
|
|
167
176
|
return undefined;
|
|
168
177
|
const cos = Math.cos(here.lonLat[1] * RAD);
|
|
169
178
|
const look = (eye.bearing + (forward ? 0 : 180)) * RAD;
|
|
170
|
-
|
|
171
|
-
let distance = Number.POSITIVE_INFINITY;
|
|
172
|
-
for (const p of this.list) {
|
|
179
|
+
return this.list.reduce((nearest, p) => {
|
|
173
180
|
if (p === here)
|
|
174
|
-
|
|
181
|
+
return nearest;
|
|
175
182
|
const [east, north] = [(p.lonLat[0] - here.lonLat[0]) * cos, p.lonLat[1] - here.lonLat[1]];
|
|
176
183
|
const d = Math.hypot(east, north);
|
|
177
184
|
const off = Math.acos(Math.max(-1, Math.min(1, (east * Math.sin(look) + north * Math.cos(look)) / (d || 1))));
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
return best;
|
|
185
|
+
return off < 60 * RAD && d < nearest.distance ? { best: p, distance: d } : nearest;
|
|
186
|
+
}, { distance: Number.POSITIVE_INFINITY }).best;
|
|
182
187
|
}
|
|
183
188
|
/** Goes to a panorama during the walk, the eye looking the same way (or `bearing`) */
|
|
184
189
|
async go(index, bearing) {
|
|
@@ -205,16 +210,19 @@ export class Panoramas {
|
|
|
205
210
|
}
|
|
206
211
|
}
|
|
207
212
|
/** Loads a set of panoramas: their positions and attitudes, the calibration of their cameras */
|
|
208
|
-
export async
|
|
209
|
-
const json = async (src) => {
|
|
213
|
+
export const loadPanoramas = async (host, options) => {
|
|
214
|
+
const json = async (src, is) => {
|
|
210
215
|
const response = await fetch(src, withHeaders(src));
|
|
211
216
|
if (!response.ok)
|
|
212
217
|
throw new Error(`isard: ${src}: ${response.status}`);
|
|
213
|
-
|
|
218
|
+
const value = await response.json();
|
|
219
|
+
if (!is(value))
|
|
220
|
+
throw new Error(`isard: ${src}: unexpected content`);
|
|
221
|
+
return value;
|
|
214
222
|
};
|
|
215
223
|
const [orientations, cameras] = await Promise.all([
|
|
216
|
-
json(options.orientationsUrl),
|
|
217
|
-
json(options.calibrationUrl),
|
|
224
|
+
json(options.orientationsUrl, isOrientations),
|
|
225
|
+
json(options.calibrationUrl, isCalibrations),
|
|
218
226
|
]);
|
|
219
227
|
const crsName = options.crs ?? orientations.crs?.properties?.name ?? 'EPSG:2154';
|
|
220
228
|
const lambert93 = /2154/.test(crsName);
|
|
@@ -222,24 +230,27 @@ export async function loadPanoramas(host, options) {
|
|
|
222
230
|
const geoid = options.geoid ?? lambert93;
|
|
223
231
|
const list = [];
|
|
224
232
|
const attitudes = [];
|
|
225
|
-
|
|
233
|
+
orientations.features.forEach((feature) => {
|
|
226
234
|
const [x = 0, y = 0, z = 0] = feature.geometry.coordinates;
|
|
227
235
|
const [lon = 0, lat = 0] = crs.inverse([x, y]);
|
|
228
236
|
const p = feature.properties;
|
|
229
|
-
const number = (key) =>
|
|
237
|
+
const number = (key) => {
|
|
238
|
+
const value = p[key];
|
|
239
|
+
return typeof value === 'number' ? value : 0;
|
|
240
|
+
};
|
|
230
241
|
attitudes.push({ heading: number('heading'), pitch: number('pitch'), roll: number('roll') });
|
|
231
242
|
list.push({
|
|
232
243
|
index: list.length,
|
|
233
|
-
id: p.id
|
|
244
|
+
id: typeof p.id === 'number' || typeof p.id === 'string' ? p.id : list.length,
|
|
234
245
|
lonLat: [lon, lat],
|
|
235
246
|
height: z + (geoid ? host.geoidHeight(lon, lat) : 0),
|
|
236
247
|
heading: number('heading'),
|
|
237
248
|
});
|
|
238
|
-
}
|
|
249
|
+
});
|
|
239
250
|
return new Panoramas(host, {
|
|
240
251
|
url: options.url,
|
|
241
252
|
backgroundDistance: options.backgroundDistance ?? 1000,
|
|
242
253
|
opacity: options.opacity ?? 1,
|
|
243
254
|
}, list, attitudes, cameras, lambert93);
|
|
244
|
-
}
|
|
255
|
+
};
|
|
245
256
|
//# sourceMappingURL=panoramas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panoramas.js","sourceRoot":"","sources":["../../src/layers/panoramas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Street-level panoramas: the oriented images of a vehicle's cameras around each of its positions (Stereopolis, the\n * iTowns immersive examples), projected onto the scene around the panorama shown. Their positions and attitudes come\n * as GeoJSON points (Lambert-93 by default, altitudes NGF-IGN69 raised by the RAF20 geoid onto the IGN relief), the\n * calibration of the cameras as JSON (rotation and position in the panorama frame, intrinsics, MicMac's radial\n * distortion), the images from a URL template with `{cameraId}` and `{panoId}`.\n *\n * ```ts\n * const panoramas = await map.addPanoramas({ url, orientationsUrl, calibrationUrl });\n * await panoramas.show(panoramas.nearest([2.3345, 48.8505]).index);\n * ```\n */\nimport { getCrs } from '../data/crs.ts';\nimport { withHeaders } from '../engine/requests.ts';\nimport type { FirstPersonView, LonLat } from '../types.ts';\nimport { isNumbers, isRecord } from '../util/guards.ts';\n\nexport interface PanoramaOptions {\n /** URL of an image: `{cameraId}` and `{panoId}` replaced by a camera's id and a panorama's */\n url: string;\n /** GeoJSON points: each panorama's position, and its `id`, `heading`, `pitch`, `roll` (degrees) in properties */\n orientationsUrl: string;\n /** JSON array of the cameras: `id`, `rotation` (row-major), `position`, `projection`, `size`, `distortion` */\n calibrationUrl: string;\n /** CRS of the positions (default the GeoJSON's `crs` member, else `EPSG:2154`) */\n crs?: string;\n /** Altitudes above the geoid (NGF-IGN69), raised by the RAF20 geoid onto the IGN relief (default true in\n * Lambert-93) */\n geoid?: boolean;\n /** Radius of the sphere around the panorama its images are a backdrop on, metres (default 1000) */\n backgroundDistance?: number;\n /** 0-1 (default 1) */\n opacity?: number;\n}\n\n/** A panorama: where it is and which way the vehicle faced */\nexport interface Panorama {\n index: number;\n id: number | string;\n lonLat: LonLat;\n /** Metres above the ellipsoid */\n height: number;\n /** Degrees clockwise from north */\n heading: number;\n}\n\n/** What the map gives the panoramas */\nexport interface PanoramaHost {\n setPanorama(\n lon: number,\n lat: number,\n height: number,\n rotation: Float64Array,\n cameras: Float64Array,\n radius: number,\n opacity: number,\n ): void;\n setPanoramaImage(index: number, image: ImageBitmap): void;\n clearPanorama(): void;\n geoidHeight(lon: number, lat: number): number;\n /** The street-level eye, and setting it (undefined: back to the camera turning around a point) */\n firstPerson(): Readonly<Required<FirstPersonView>> | undefined;\n setFirstPerson(view: FirstPersonView | undefined): void;\n elevationAt(lonLat: LonLat): number | undefined;\n /** Follows the clicks on the map (with the ground clicked), the keys typed on it and its wheel (taken from the\n * map's own); returns what stops */\n listen(\n click: (lonLat: LonLat | undefined) => void,\n key: (e: KeyboardEvent) => void,\n wheel: (e: WheelEvent) => void,\n ): () => void;\n}\n\ninterface Calibration {\n id: number | string;\n rotation: number[];\n position: number[];\n projection: number[];\n size: number[];\n distortion?: { pps: number[]; poly357: number[]; limit?: number };\n}\n\ninterface Orientations {\n crs?: { properties?: { name?: string } };\n features: { geometry: { coordinates: number[] }; properties: Record<string, unknown> }[];\n}\n\nconst isOrientation = (value: unknown): value is Orientations['features'][number] =>\n isRecord(value) && isRecord(value.geometry) && isNumbers(value.geometry.coordinates) && isRecord(value.properties);\n\nconst isCrs = (value: unknown): value is Orientations['crs'] =>\n isRecord(value) &&\n (value.properties === undefined ||\n (isRecord(value.properties) && (value.properties.name === undefined || typeof value.properties.name === 'string')));\n\nconst isOrientations = (value: unknown): value is Orientations =>\n isRecord(value) &&\n (value.crs === undefined || isCrs(value.crs)) &&\n Array.isArray(value.features) &&\n value.features.every(isOrientation);\n\nconst isCalibration = (value: unknown): value is Calibration =>\n isRecord(value) &&\n (typeof value.id === 'number' || typeof value.id === 'string') &&\n isNumbers(value.rotation) &&\n isNumbers(value.position) &&\n isNumbers(value.projection) &&\n isNumbers(value.size) &&\n (value.distortion === undefined ||\n (isRecord(value.distortion) &&\n isNumbers(value.distortion.pps) &&\n isNumbers(value.distortion.poly357) &&\n (value.distortion.limit === undefined || typeof value.distortion.limit === 'number')));\n\nconst isCalibrations = (value: unknown): value is Calibration[] => Array.isArray(value) && value.every(isCalibration);\n\ninterface Attitude {\n heading: number;\n pitch: number;\n roll: number;\n}\n\nconst RAD = Math.PI / 180;\n\n/** 3 × 3 product, row-major */\nconst times = (a: number[], b: number[]): number[] =>\n Array.from({ length: 9 }, (_, i) => {\n const [r, c] = [Math.floor(i / 3), i % 3];\n\n return [0, 1, 2].reduce((sum, k) => sum + (a[r * 3 + k] ?? 0) * (b[k * 3 + c] ?? 0), 0);\n });\n\nconst rotX = (t: number) => [1, 0, 0, 0, Math.cos(t), -Math.sin(t), 0, Math.sin(t), Math.cos(t)];\nconst rotY = (t: number) => [Math.cos(t), 0, Math.sin(t), 0, 1, 0, -Math.sin(t), 0, Math.cos(t)];\nconst rotZ = (t: number) => [Math.cos(t), -Math.sin(t), 0, Math.sin(t), Math.cos(t), 0, 0, 0, 1];\n\n/**\n * The panorama frame to east, north, up (row-major): the vehicle's attitude in the CRS's grid (iTowns'\n * `quaternionFromRollPitchHeading`: Ry(-roll) · Rx(-pitch) · Rz(-heading)), turned by the meridian convergence of the\n * projection (Lambert-93: sin(46.5°) · (3° - longitude))\n */\nexport const panoramaRotation = (attitude: Attitude, lon: number, lambert93: boolean): number[] => {\n const vehicle = times(times(rotY(-attitude.roll * RAD), rotX(-attitude.pitch * RAD)), rotZ(-attitude.heading * RAD));\n const convergence = lambert93 ? Math.sin(46.5 * RAD) * (3 - lon) * RAD : 0;\n\n return times(rotZ(convergence), vehicle);\n};\n\n/** The 25 numbers of a camera for `setPanorama` */\nconst cameraNumbers = (c: Calibration): number[] => {\n const p = c.projection;\n const d = c.distortion;\n\n return [\n ...c.rotation.slice(0, 9),\n ...c.position.slice(0, 3),\n p[0] ?? 1,\n p[4] ?? 1,\n p[2] ?? 0,\n p[5] ?? 0,\n p[1] ?? 0,\n c.size[0] ?? 1,\n c.size[1] ?? 1,\n d?.pps[0] ?? 0,\n d?.pps[1] ?? 0,\n d?.poly357[0] ?? 0,\n d?.poly357[1] ?? 0,\n d?.poly357[2] ?? 0,\n d?.limit ?? 0,\n ];\n};\n\n/** The panoramas of a set, one shown at a time */\nexport class Panoramas {\n /** The panorama shown, if any */\n current: Panorama | undefined;\n private shown = 0;\n\n /** @internal */\n constructor(\n private readonly host: PanoramaHost,\n private readonly options: Required<Pick<PanoramaOptions, 'url' | 'backgroundDistance' | 'opacity'>>,\n readonly list: readonly Panorama[],\n private readonly attitudes: readonly Attitude[],\n private readonly cameras: readonly Calibration[],\n private readonly lambert93: boolean,\n ) {}\n\n /** The panorama nearest to a position */\n nearest(lonLat: LonLat): Panorama | undefined {\n const cos = Math.cos(lonLat[1] * RAD);\n\n return this.list.reduce<{ best?: Panorama; distance: number }>(\n (nearest, p) => {\n const d = ((p.lonLat[0] - lonLat[0]) * cos) ** 2 + (p.lonLat[1] - lonLat[1]) ** 2;\n\n return d < nearest.distance ? { best: p, distance: d } : nearest;\n },\n { distance: Number.POSITIVE_INFINITY },\n ).best;\n }\n\n /** Shows a panorama (its index in `list`): projected as soon as its first image arrives, the others after */\n async show(index: number): Promise<void> {\n const pano = this.list[index];\n const attitude = this.attitudes[index];\n\n if (!pano || !attitude) return;\n\n const shown = ++this.shown;\n\n this.current = pano;\n\n const rotation = panoramaRotation(attitude, pano.lonLat[0], this.lambert93);\n const { url, backgroundDistance, opacity } = this.options;\n\n this.host.setPanorama(\n pano.lonLat[0],\n pano.lonLat[1],\n pano.height,\n Float64Array.from(rotation),\n Float64Array.from(this.cameras.flatMap(cameraNumbers)),\n backgroundDistance,\n opacity,\n );\n await Promise.all(\n this.cameras.map(async (camera, k) => {\n const src = url.replaceAll('{cameraId}', String(camera.id)).replaceAll('{panoId}', String(pano.id));\n const response = await fetch(src, withHeaders(src));\n\n if (!response.ok) throw new Error(`isard: panorama image ${src}: ${response.status}`);\n\n const image = await createImageBitmap(await response.blob(), { premultiplyAlpha: 'none' });\n\n // Another panorama shown since: this image is not its\n if (shown === this.shown) this.host.setPanoramaImage(k, image);\n image.close();\n }),\n );\n }\n\n /** Hides the panorama shown */\n hide(): void {\n this.shown++;\n this.current = undefined;\n this.host.clearPanorama();\n }\n\n /** Stops the walk (`enter`) */\n private stopWalking: (() => void) | undefined;\n\n /**\n * Street-level walk from panorama to panorama (the iTowns immersive view): the eye on a panorama, the drag\n * turning it; a click goes to the panorama nearest to the clicked point, the wheel to the nearest one ahead (or\n * behind), Z and S (or Page Up and Page Down) to the next and the previous ones. Starts on the panorama `index`,\n * else the one nearest to `near`\n */\n async enter(start: { index?: number; near?: LonLat } = {}): Promise<void> {\n const first = start.index ?? (start.near && this.nearest(start.near)?.index) ?? 0;\n\n this.stopWalking?.();\n this.stopWalking = this.host.listen(\n (lonLat) => {\n const target = lonLat && this.nearest(lonLat);\n\n if (target && target !== this.current) void this.go(target.index);\n },\n (e) => {\n const step = { z: 1, Z: 1, PageUp: 1, s: -1, S: -1, PageDown: -1 }[e.key];\n\n if (!step || !this.current) return;\n e.preventDefault();\n void this.go((this.current.index + step + this.list.length) % this.list.length);\n },\n (e) => {\n // One step per notch, the next ones once it is shown\n if (this.moving || e.deltaY === 0) return;\n\n const target = this.ahead(e.deltaY < 0);\n\n if (target) {\n this.moving = true;\n void this.go(target.index).finally(() => {\n this.moving = false;\n });\n }\n },\n );\n await this.go(first, this.list[first]?.heading);\n }\n\n /** A step of the wheel under way */\n private moving = false;\n\n /** The nearest panorama ahead of the eye (within 60° of where it looks), or behind it */\n ahead(forward = true): Panorama | undefined {\n const eye = this.host.firstPerson();\n const here = this.current;\n\n if (!eye || !here) return undefined;\n\n const cos = Math.cos(here.lonLat[1] * RAD);\n const look = (eye.bearing + (forward ? 0 : 180)) * RAD;\n\n return this.list.reduce<{ best?: Panorama; distance: number }>(\n (nearest, p) => {\n if (p === here) return nearest;\n\n const [east, north] = [(p.lonLat[0] - here.lonLat[0]) * cos, p.lonLat[1] - here.lonLat[1]];\n const d = Math.hypot(east, north);\n const off = Math.acos(Math.max(-1, Math.min(1, (east * Math.sin(look) + north * Math.cos(look)) / (d || 1))));\n\n return off < 60 * RAD && d < nearest.distance ? { best: p, distance: d } : nearest;\n },\n { distance: Number.POSITIVE_INFINITY },\n ).best;\n }\n\n /** Goes to a panorama during the walk, the eye looking the same way (or `bearing`) */\n async go(index: number, bearing?: number): Promise<void> {\n const pano = this.list[index];\n\n if (!pano) return;\n\n const eye = this.host.firstPerson();\n // The eye at the panorama's cameras, above the ground there\n const ground = this.host.elevationAt(pano.lonLat);\n\n this.host.setFirstPerson({\n lonLat: pano.lonLat,\n height: ground === undefined ? 2.5 : Math.max(0.5, pano.height - ground),\n bearing: bearing ?? eye?.bearing ?? pano.heading,\n ...(eye ? { pitch: eye.pitch, fov: eye.fov } : {}),\n });\n await this.show(index);\n }\n\n /** Ends the walk: the panorama hidden, the camera turning around a point again, above where the eye stood */\n exit(): void {\n this.stopWalking?.();\n this.stopWalking = undefined;\n this.hide();\n this.host.setFirstPerson(undefined);\n }\n}\n\n/** Loads a set of panoramas: their positions and attitudes, the calibration of their cameras */\nexport const loadPanoramas = async (host: PanoramaHost, options: PanoramaOptions): Promise<Panoramas> => {\n const json = async <T>(src: string, is: (value: unknown) => value is T): Promise<T> => {\n const response = await fetch(src, withHeaders(src));\n\n if (!response.ok) throw new Error(`isard: ${src}: ${response.status}`);\n\n const value: unknown = await response.json();\n\n if (!is(value)) throw new Error(`isard: ${src}: unexpected content`);\n\n return value;\n };\n const [orientations, cameras] = await Promise.all([\n json(options.orientationsUrl, isOrientations),\n json(options.calibrationUrl, isCalibrations),\n ]);\n const crsName = options.crs ?? orientations.crs?.properties?.name ?? 'EPSG:2154';\n const lambert93 = /2154/.test(crsName);\n const crs = getCrs(crsName);\n const geoid = options.geoid ?? lambert93;\n const list: Panorama[] = [];\n const attitudes: Attitude[] = [];\n\n orientations.features.forEach((feature) => {\n const [x = 0, y = 0, z = 0] = feature.geometry.coordinates;\n const [lon = 0, lat = 0] = crs.inverse([x, y]);\n const p = feature.properties;\n const number = (key: string) => {\n const value = p[key];\n\n return typeof value === 'number' ? value : 0;\n };\n\n attitudes.push({ heading: number('heading'), pitch: number('pitch'), roll: number('roll') });\n list.push({\n index: list.length,\n id: typeof p.id === 'number' || typeof p.id === 'string' ? p.id : list.length,\n lonLat: [lon, lat],\n height: z + (geoid ? host.geoidHeight(lon, lat) : 0),\n heading: number('heading'),\n });\n });\n\n return new Panoramas(\n host,\n {\n url: options.url,\n backgroundDistance: options.backgroundDistance ?? 1000,\n opacity: options.opacity ?? 1,\n },\n list,\n attitudes,\n cameras,\n lambert93,\n );\n};\n"]}
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* in NGF-IGN69 (Lambert-93, the CC zones) are raised by the RAF20 geoid height onto the ellipsoid of the relief and
|
|
6
6
|
* the 3D Tiles.
|
|
7
7
|
*/
|
|
8
|
-
import { type CrsLike } from '
|
|
8
|
+
import { type CrsLike } from '../data/crs.ts';
|
|
9
|
+
import type { PointCloudCrs, PointCloudInfo, PointCloudStats, Tiles3dStats } from '../wasm/isard.js';
|
|
9
10
|
import { type Ramp } from './features.ts';
|
|
10
11
|
import { Layer } from './layers.ts';
|
|
11
|
-
import type { PointCloudCrs, PointCloudInfo, PointCloudStats, Tiles3dStats } from './wasm/isard.js';
|
|
12
12
|
/** What the points are colored by */
|
|
13
13
|
export type PointColor = 'rgb' | 'classification' | 'elevation' | 'intensity';
|
|
14
14
|
/** The look of a class of points */
|
|
@@ -73,14 +73,14 @@ export declare const CLASSIFICATIONS: Readonly<Record<number, Readonly<Required<
|
|
|
73
73
|
/** The default ramp of the altitudes, low to high */
|
|
74
74
|
export declare const ELEVATION_RAMP: Ramp;
|
|
75
75
|
/** The colors of the 256 classes (RGBA, alpha 0 hides one) */
|
|
76
|
-
export declare
|
|
76
|
+
export declare const classPalette: (overrides?: Record<number, ClassStyle>) => Uint8Array;
|
|
77
77
|
/** What a WKT says of a CRS: its EPSG code (projected first), the metres of a unit of z */
|
|
78
|
-
export declare
|
|
78
|
+
export declare const wktCrs: (wkt: string) => {
|
|
79
79
|
code: number | undefined;
|
|
80
80
|
verticalScale: number | undefined;
|
|
81
81
|
};
|
|
82
82
|
/** The CRS of a COPC file for the engine, from its WKT and the options */
|
|
83
|
-
export declare
|
|
83
|
+
export declare const pointCloudCrs: (wkt: string | undefined, options: Pick<PointCloudOptions, "crs" | "geoid" | "verticalScale">) => PointCloudCrs;
|
|
84
84
|
/** A point cloud (`GeoMap.addPointCloud`): COPC or 3D Tiles points; `pickFeature` gives a COPC point's attributes */
|
|
85
85
|
export declare class PointCloudLayer extends Layer {
|
|
86
86
|
readonly url: string;
|