isard 0.8.0 → 1.0.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 +29 -0
- package/dist/basemaps.d.ts +3 -3
- package/dist/basemaps.js +2 -14
- package/dist/basemaps.js.map +1 -1
- package/dist/controls.d.ts +4 -3
- package/dist/controls.js +0 -8
- package/dist/controls.js.map +1 -1
- package/dist/engine-loader.d.ts +11 -4
- package/dist/engine-loader.js +36 -5
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +51 -1
- package/dist/geoplateforme.js +34 -0
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/layers.d.ts +3 -2
- package/dist/layers.js +15 -4
- package/dist/layers.js.map +1 -1
- package/dist/map.d.ts +78 -3
- package/dist/map.js +93 -12
- package/dist/map.js.map +1 -1
- package/dist/types.d.ts +11 -7
- package/dist/types.js.map +1 -1
- package/dist/vectortiles.d.ts +2 -2
- package/dist/vectortiles.js +4 -3
- package/dist/vectortiles.js.map +1 -1
- package/package.json +8 -2
- package/vite.d.ts +17 -0
- package/vite.js +64 -0
package/dist/index.js
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
export { OPENFREEMAP_ATTRIBUTION, TERRAIN_TILES_ATTRIBUTION } from "./basemaps.js";
|
|
15
|
-
export { AttributionControl,
|
|
15
|
+
export { AttributionControl, NavigationControl, } from "./controls.js";
|
|
16
16
|
export { getCrs, lambertConformalConic, registerCrs, reproject, transverseMercator, } from "./crs.js";
|
|
17
17
|
export { ExtrusionLayer } from "./extrusions.js";
|
|
18
18
|
export { CircleLayer, FeatureLayer, FillLayer, interpolate, LineLayer, parseColor } from "./features.js";
|
|
19
|
-
export { geoplateformeWfs, geoplateformeWms, geoplateformeWmts, IGN_ATTRIBUTION } from "./geoplateforme.js";
|
|
19
|
+
export { BATIMENTS_3D_URL, batiments3d, bdtopoBuildings, geoplateformeWfs, geoplateformeWms, geoplateformeWmts, IGN_ATTRIBUTION, IGN_PRESETS, } from "./geoplateforme.js";
|
|
20
20
|
export { DEFAULT_FONT, GLYPHS_URL } from "./glyphs.js";
|
|
21
21
|
export { parseGpx } from "./gpx.js";
|
|
22
22
|
export { parseKml } from "./kml.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EACL,kBAAkB,EAIlB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EACL,kBAAkB,EAIlB,iBAAiB,GAElB,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,MAAM,EACN,qBAAqB,EACrB,WAAW,EACX,SAAS,EACT,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAqBjD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EACL,gBAAgB,EAEhB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,WAAW,GAEZ,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AASpC,OAAO,EACL,WAAW,EACX,WAAW,EACX,KAAK,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAkB,MAAM,UAAU,CAAC;AAClD,OAAO,EAEL,MAAM,EAIN,KAAK,EAEL,KAAK,GAGN,MAAM,cAAc,CAAC;AACtB,OAAO,EAAuC,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,OAAO,EAIP,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAoC,MAAM,eAAe,CAAC;AA0ChF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAY5F,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC","sourcesContent":["/**\n * isard: a WebGL2 map engine for large, interactive data layers, labels and 3D Tiles.\n *\n * ```ts\n * import { GeoMap } from 'isard';\n * const map = await GeoMap.create(container, { center: [2.4246, 48.8457], zoom: 13 });\n * const network = map.addNetwork({ nodes, edges, max: 1800, contour: 300 });\n * map.on('hover', ({ lonLat }) => lonLat && network.setValues(travelTimes(lonLat)));\n * map.addTiles3d({ url: 'https://…/tileset.json' });\n * map.addControl(new NavigationControl());\n * new Marker().setLonLat([2.4246, 48.8457]).setPopup(new Popup({ offset: [0, -34] }).setText('Here')).addTo(map);\n * ```\n */\nexport { OPENFREEMAP_ATTRIBUTION, TERRAIN_TILES_ATTRIBUTION } from './basemaps.ts';\nexport {\n AttributionControl,\n type AttributionOptions,\n type Control,\n type ControlPosition,\n NavigationControl,\n type NavigationOptions,\n} from './controls.ts';\nexport {\n type Crs,\n type CrsLike,\n getCrs,\n lambertConformalConic,\n registerCrs,\n reproject,\n transverseMercator,\n} from './crs.ts';\nexport type { DecoderUrls } from './decoders.ts';\nexport type { ExtrusionOptions, ExtrusionStyle, PolygonArrays, TileKey } from './extrusions.ts';\nexport { ExtrusionLayer } from './extrusions.ts';\nexport type {\n CircleOptions,\n CircleStyle,\n Feature,\n FeatureCollection,\n FeatureData,\n FeatureLayerStyle,\n FillOptions,\n FillStyle,\n Geometry,\n LineOptions,\n LineStyle,\n Placement,\n Position,\n Properties,\n Ramp,\n Size,\n Stops,\n Styled,\n} from './features.ts';\nexport { CircleLayer, FeatureLayer, FillLayer, interpolate, LineLayer, parseColor } from './features.ts';\nexport {\n BATIMENTS_3D_URL,\n type BdTopoBuilding,\n batiments3d,\n bdtopoBuildings,\n geoplateformeWfs,\n geoplateformeWms,\n geoplateformeWmts,\n IGN_ATTRIBUTION,\n IGN_PRESETS,\n type IgnPreset,\n} from './geoplateforme.ts';\nexport type { TextPart } from './glyphs.ts';\nexport { DEFAULT_FONT, GLYPHS_URL } from './glyphs.ts';\nexport { parseGpx } from './gpx.ts';\nexport type { TileGrid, TileMatrix } from './grid.ts';\nexport type { ImageOptions, Pixels, SpriteIcon } from './icons.ts';\nexport { parseKml } from './kml.ts';\nexport type {\n CustomFrame,\n CustomLayerInterface,\n GroundOptions,\n GroundTexture,\n ModelInstance,\n ModelOptions,\n} from './layers.ts';\nexport {\n CustomLayer,\n GroundLayer,\n Layer,\n ModelLayer,\n NetworkLayer,\n RasterLayer,\n Tiles3dLayer,\n} from './layers.ts';\nexport { GeoMap, type LayerSpec } from './map.ts';\nexport {\n type Anchor,\n Marker,\n type MarkerEvent,\n type MarkerEvents,\n type MarkerOptions,\n Panel,\n type PanelOptions,\n Popup,\n type PopupEvents,\n type PopupOptions,\n} from './overlay.ts';\nexport { type Panorama, type PanoramaOptions, Panoramas } from './panoramas.ts';\nexport {\n PMTiles,\n type PmtilesEntry,\n type PmtilesHeader,\n type PmtilesTileType,\n tileIdToZxy,\n zxyToTileId,\n} from './pmtiles.ts';\nexport type { ClassStyle, PointCloudOptions, PointCloudStyle, PointColor } from './pointclouds.ts';\nexport { CLASSIFICATIONS, ELEVATION_RAMP, PointCloudLayer } from './pointclouds.ts';\nexport { setRequestHeaders } from './requests.ts';\nexport type { Overlap, SymbolOptions, SymbolStyle } from './symbols.ts';\nexport { SymbolLayer } from './symbols.ts';\nexport { parseTopoJson, type TopoGeometry, type Topology } from './topojson.ts';\nexport type {\n AnimationOptions,\n AtmosphereOptions,\n Basemap,\n BasemapName,\n BodyOptions,\n CelestialBody,\n FeatureHit,\n FirstPersonView,\n FlyToOptions,\n GeoMapOptions,\n LoadingMode,\n LonLat,\n MapEvents,\n MapHoverFeatureEvent,\n MapPointerEvent,\n NetworkOptions,\n NetworkStyle,\n Point,\n Projection,\n RasterGrid,\n RasterOptions,\n RasterStyle,\n SwipeOptions,\n TerrainEncoding,\n TerrainModel,\n TerrainOptions,\n Tiles3dOptions,\n Tiles3dStyle,\n ViewshedOptions,\n} from './types.ts';\nexport type {\n CandidateIcon,\n CandidateOverlap,\n Json,\n LabelCandidate,\n RasterSource,\n Style,\n StyleLayer,\n} from './vectorstyle.ts';\nexport type { PmtilesOptions, VectorTilesOptions } from './vectortiles.ts';\nexport { basicStyle, OPENFREEMAP_STYLES, PLAN_STYLES, VectorTiles } from './vectortiles.ts';\nexport type {\n Camera,\n NetworkStats,\n PickHit,\n PickResult,\n PointCloudInfo,\n PointCloudPoint,\n PointCloudStats,\n RasterLayerStats,\n Tiles3dStats,\n} from './wasm/isard.js';\nexport { parseWmtsGrid, wmtsGrid } from './wmts.ts';\n"]}
|
package/dist/isard_bg.wasm
CHANGED
|
Binary file
|
package/dist/isard_core_bg.wasm
CHANGED
|
Binary file
|
package/dist/layers.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ export declare abstract class Layer {
|
|
|
5
5
|
#private;
|
|
6
6
|
/** Id of the layer in the engine */
|
|
7
7
|
get id(): number;
|
|
8
|
+
/** Resolves once the map has drawn the layer, what it shows in view loaded (the map idle after it was added; a
|
|
9
|
+
* layer waiting for the engine with 3D Tiles, once that one has drawn it) */
|
|
10
|
+
get ready(): Promise<void>;
|
|
8
11
|
remove(): void;
|
|
9
12
|
/** Moves the layer under `other`, or on top of every layer (above the labels of a vector basemap too) */
|
|
10
13
|
moveBefore(other: Layer | undefined): void;
|
|
@@ -14,8 +17,6 @@ export declare class RasterLayer extends Layer {
|
|
|
14
17
|
private readonly options;
|
|
15
18
|
/** Changes the opacity or saturation, the other kept */
|
|
16
19
|
setStyle(style: Partial<RasterStyle>): void;
|
|
17
|
-
/** @deprecated Positional form (saturation back to 1 when not given): `setStyle({ opacity, saturation })` */
|
|
18
|
-
setStyle(opacity: number, saturation?: number): void;
|
|
19
20
|
}
|
|
20
21
|
/** Line network colored by a value per node (travel time, water depth…) */
|
|
21
22
|
export declare class NetworkLayer extends Layer {
|
package/dist/layers.js
CHANGED
|
@@ -18,6 +18,17 @@ export class Layer {
|
|
|
18
18
|
get id() {
|
|
19
19
|
return this.#id;
|
|
20
20
|
}
|
|
21
|
+
#ready;
|
|
22
|
+
/** Resolves once the map has drawn the layer, what it shows in view loaded (the map idle after it was added; a
|
|
23
|
+
* layer waiting for the engine with 3D Tiles, once that one has drawn it) */
|
|
24
|
+
get ready() {
|
|
25
|
+
this.#ready ??= (async () => {
|
|
26
|
+
do
|
|
27
|
+
await this.map.whenIdle();
|
|
28
|
+
while (this.#id < 0 && this.needsFullEngine);
|
|
29
|
+
})();
|
|
30
|
+
return this.#ready;
|
|
31
|
+
}
|
|
21
32
|
/** @internal Creates the layer in an engine (again after a context loss); its id is -1 if that fails */
|
|
22
33
|
attach(engine) {
|
|
23
34
|
this.#id = -1;
|
|
@@ -56,10 +67,10 @@ export class RasterLayer extends Layer {
|
|
|
56
67
|
super(map);
|
|
57
68
|
this.options = options;
|
|
58
69
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.options.opacity =
|
|
62
|
-
this.options.saturation =
|
|
70
|
+
/** Changes the opacity or saturation, the other kept */
|
|
71
|
+
setStyle(style) {
|
|
72
|
+
this.options.opacity = style.opacity ?? this.options.opacity;
|
|
73
|
+
this.options.saturation = style.saturation ?? this.options.saturation;
|
|
63
74
|
this.map.engine.setRasterStyle(this.id, this.options.opacity, this.options.saturation);
|
|
64
75
|
this.map.requestRender();
|
|
65
76
|
}
|
package/dist/layers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/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 */\nimport { type Feature, parseColor, rampTexels, stops } from './features.ts';\nimport { mercatorX, mercatorY, toMercator } from './geo.ts';\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 type { Camera, Engine, NetworkStats, Tiles3dStats } from './wasm/isard.js';\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 /** @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 /** @deprecated Positional form (saturation back to 1 when not given): `setStyle({ opacity, saturation })` */\n setStyle(opacity: number, saturation?: number): void;\n setStyle(style: Partial<RasterStyle> | number, saturation = 1): void {\n const changed = typeof style === 'number' ? { opacity: style, saturation } : style;\n this.options.opacity = changed.opacity ?? this.options.opacity;\n this.options.saturation = changed.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 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 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 let mercator: { nodes: Float64Array; lines: Float64Array | undefined };\n if (this.kept) {\n const { origin, nodes: n, lines: l } = this.kept;\n mercator = { nodes: unpack(n, origin), lines: l && unpack(l, origin) };\n } else {\n // Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly\n mercator = { nodes: mercatorPoints(nodes), lines: lines && mercatorPoints(lines.points) };\n const origin: [number, number] = [mercator.nodes[0] ?? 0, mercator.nodes[1] ?? 0];\n this.kept = {\n origin,\n nodes: pack(mercator.nodes, origin),\n lines: mercator.lines && pack(mercator.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 const id = engine.addNetwork(\n mercator.nodes,\n edges,\n lines?.start,\n mercator.lines,\n this.costs,\n networkStyle(this.style),\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 return id;\n }\n}\n\n/** The 25 numbers of a network style for the engine */\nfunction networkStyle(style: NetworkStyle): Float32Array {\n const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;\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 */\nfunction pack(points: Float64Array, [ox, oy]: [number, number]): Float32Array {\n const out = new Float32Array(points.length);\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 return out;\n}\n\nfunction unpack(points: Float32Array, [ox, oy]: [number, number]): Float64Array {\n const out = new Float64Array(points.length);\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 return out;\n}\n\n/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */\nfunction mercatorPoints(lonLat: Float64Array): Float64Array {\n const out = new Float64Array(lonLat.length);\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 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 const hit = this.map.engine.tiles3dFeature(this.id, index);\n if (!hit) return undefined;\n const [properties, feature] = hit;\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 this.applyStyle(engine, id);\n return id;\n }\n\n private applyStyle(engine: Engine, id: number): void {\n const { maxScreenSpaceError, opacity, pointSize, color } = this.style;\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 for (const [name, texture] of Object.entries(options.textures ?? {})) this.textures.set(name, texture);\n for (const [name, value] of Object.entries(options.uniforms ?? {})) this.uniforms.set(name, [value].flat());\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 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 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 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 for (const [name, texture] of this.textures) this.sendTexture(engine, id, name, texture);\n for (const [name, values] of this.uniforms) engine.setGroundUniform(id, name, Float64Array.from(values));\n engine.setGroundVisible(id, this.visible);\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) */\nfunction mercatorBox([west, south, east, north]: [number, number, number, number]): [number, number, number, number] {\n const [x0, y1] = toMercator([west, south]);\n const [x1, y0] = toMercator([east, north]);\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 */\nfunction 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 if (!m) throw new Error('isard: frame.matrixAt is only available during render');\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 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 function instanceNumbers(instances: readonly ModelInstance[]): Float64Array {\n const out = new Float64Array(instances.length * 7);\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 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 const { url, data } = options;\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 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
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/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 */\nimport { type Feature, parseColor, rampTexels, stops } from './features.ts';\nimport { mercatorX, mercatorY, toMercator } from './geo.ts';\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 type { Camera, Engine, NetworkStats, Tiles3dStats } from './wasm/isard.js';\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 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 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 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 let mercator: { nodes: Float64Array; lines: Float64Array | undefined };\n if (this.kept) {\n const { origin, nodes: n, lines: l } = this.kept;\n mercator = { nodes: unpack(n, origin), lines: l && unpack(l, origin) };\n } else {\n // Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly\n mercator = { nodes: mercatorPoints(nodes), lines: lines && mercatorPoints(lines.points) };\n const origin: [number, number] = [mercator.nodes[0] ?? 0, mercator.nodes[1] ?? 0];\n this.kept = {\n origin,\n nodes: pack(mercator.nodes, origin),\n lines: mercator.lines && pack(mercator.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 const id = engine.addNetwork(\n mercator.nodes,\n edges,\n lines?.start,\n mercator.lines,\n this.costs,\n networkStyle(this.style),\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 return id;\n }\n}\n\n/** The 25 numbers of a network style for the engine */\nfunction networkStyle(style: NetworkStyle): Float32Array {\n const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;\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 */\nfunction pack(points: Float64Array, [ox, oy]: [number, number]): Float32Array {\n const out = new Float32Array(points.length);\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 return out;\n}\n\nfunction unpack(points: Float32Array, [ox, oy]: [number, number]): Float64Array {\n const out = new Float64Array(points.length);\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 return out;\n}\n\n/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */\nfunction mercatorPoints(lonLat: Float64Array): Float64Array {\n const out = new Float64Array(lonLat.length);\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 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 const hit = this.map.engine.tiles3dFeature(this.id, index);\n if (!hit) return undefined;\n const [properties, feature] = hit;\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 this.applyStyle(engine, id);\n return id;\n }\n\n private applyStyle(engine: Engine, id: number): void {\n const { maxScreenSpaceError, opacity, pointSize, color } = this.style;\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 for (const [name, texture] of Object.entries(options.textures ?? {})) this.textures.set(name, texture);\n for (const [name, value] of Object.entries(options.uniforms ?? {})) this.uniforms.set(name, [value].flat());\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 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 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 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 for (const [name, texture] of this.textures) this.sendTexture(engine, id, name, texture);\n for (const [name, values] of this.uniforms) engine.setGroundUniform(id, name, Float64Array.from(values));\n engine.setGroundVisible(id, this.visible);\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) */\nfunction mercatorBox([west, south, east, north]: [number, number, number, number]): [number, number, number, number] {\n const [x0, y1] = toMercator([west, south]);\n const [x1, y0] = toMercator([east, north]);\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 */\nfunction 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 if (!m) throw new Error('isard: frame.matrixAt is only available during render');\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 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 function instanceNumbers(instances: readonly ModelInstance[]): Float64Array {\n const out = new Float64Array(instances.length * 7);\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 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 const { url, data } = options;\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 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"]}
|
package/dist/map.d.ts
CHANGED
|
@@ -91,7 +91,7 @@ export declare class GeoMap {
|
|
|
91
91
|
* tiles when only the exaggeration changes) */
|
|
92
92
|
private readonly terrainLoaders;
|
|
93
93
|
/** Loads the engine (once per page) and creates a map filling `container` */
|
|
94
|
-
static create(container: HTMLElement,
|
|
94
|
+
static create(container: HTMLElement, given?: GeoMapOptions): Promise<GeoMap>;
|
|
95
95
|
private constructor();
|
|
96
96
|
/** The element the map was created in */
|
|
97
97
|
getContainer(): HTMLElement;
|
|
@@ -126,13 +126,50 @@ export declare class GeoMap {
|
|
|
126
126
|
private applySwipe;
|
|
127
127
|
/** Takes a layer out of the drawing order (to put it back elsewhere, or for good) */
|
|
128
128
|
private unlist;
|
|
129
|
-
private
|
|
129
|
+
private addLayer;
|
|
130
130
|
/** Index in the engine of the layer at `index`: the layers waiting for the engine with 3D Tiles are not in it yet */
|
|
131
131
|
private engineIndex;
|
|
132
132
|
/** Moves a layer under all the others */
|
|
133
133
|
private toBottom;
|
|
134
134
|
/** Listens to an event; returns the function that stops listening */
|
|
135
135
|
on<K extends keyof MapEvents>(type: K, listener: (event: MapEvents[K]) => void): () => void;
|
|
136
|
+
/**
|
|
137
|
+
* The camera's methods together: `get`, `set`, `easeTo`, `flyTo`, `bounds`, `firstPerson` and `setFirstPerson`
|
|
138
|
+
* (street level), `project`, `unproject`; the same as the map's own (`getCamera`, `setCamera`…)
|
|
139
|
+
*/
|
|
140
|
+
readonly camera: {
|
|
141
|
+
readonly get: () => Camera;
|
|
142
|
+
readonly set: (camera: Partial<Camera>) => void;
|
|
143
|
+
readonly easeTo: (camera: Partial<Camera>, options?: number | AnimationOptions) => void;
|
|
144
|
+
readonly flyTo: (camera: Partial<Camera>, options?: FlyToOptions) => void;
|
|
145
|
+
readonly bounds: () => [west: number, south: number, east: number, north: number];
|
|
146
|
+
readonly firstPerson: () => Readonly<Required<FirstPersonView>> | undefined;
|
|
147
|
+
readonly setFirstPerson: (view: FirstPersonView | undefined) => void;
|
|
148
|
+
readonly project: (lonLat: LonLat, height?: number) => Point | undefined;
|
|
149
|
+
readonly unproject: (point: Point) => LonLat | undefined;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* What lies under a point or at a position, together: `feature` (`pickFeature`), `surface` (`pickSurface`),
|
|
153
|
+
* `surfaceAt`, `elevationAt`, `metersPerPixel`
|
|
154
|
+
*/
|
|
155
|
+
readonly query: {
|
|
156
|
+
readonly feature: (point: Point, options?: {
|
|
157
|
+
radius?: number;
|
|
158
|
+
layers?: readonly Layer[];
|
|
159
|
+
}) => FeatureHit | undefined;
|
|
160
|
+
readonly surface: (point: Point) => {
|
|
161
|
+
lonLat: LonLat;
|
|
162
|
+
height: number;
|
|
163
|
+
} | undefined;
|
|
164
|
+
readonly surfaceAt: (lonLat: LonLat) => number | undefined;
|
|
165
|
+
readonly elevationAt: (lonLat: LonLat) => number | undefined;
|
|
166
|
+
readonly metersPerPixel: (point?: Point) => number | undefined;
|
|
167
|
+
};
|
|
168
|
+
/** What is drawn over the scene, together: `viewshed` (`setViewshed`), `swipe` (`setSwipe`) */
|
|
169
|
+
readonly effects: {
|
|
170
|
+
readonly viewshed: (options: ViewshedOptions | readonly ViewshedOptions[] | undefined) => void;
|
|
171
|
+
readonly swipe: (options: SwipeOptions | undefined) => void;
|
|
172
|
+
};
|
|
136
173
|
getCamera(): Camera;
|
|
137
174
|
setCamera(camera: Partial<Camera>): void;
|
|
138
175
|
/** Animated move to a camera: over `duration` milliseconds (or the options), ease-out by default */
|
|
@@ -228,7 +265,7 @@ export declare class GeoMap {
|
|
|
228
265
|
addControl(control: Control, position?: ControlPosition): this;
|
|
229
266
|
removeControl(control: Control): this;
|
|
230
267
|
/** Replaces the basemap and the IGN hillshade, under the other layers (hillshade by default: 0, none). The former
|
|
231
|
-
* names of the Géoplateforme basemaps
|
|
268
|
+
* names of the Géoplateforme basemaps throw, naming the new ones */
|
|
232
269
|
setBasemap(basemap: Basemap, hillshade?: number): void;
|
|
233
270
|
/** Raster tiles ({z}, {x}, {y} URL; Web Mercator, or reprojected from another `grid`: longitudes and latitudes,
|
|
234
271
|
* Lambert-93, UTM…), over the layers already added */
|
|
@@ -244,6 +281,12 @@ export declare class GeoMap {
|
|
|
244
281
|
addPmtiles(url: string, options?: PmtilesOptions): Promise<RasterLayer | VectorTiles>;
|
|
245
282
|
/** Line network colored by a value per node; `layer.setValues` recolors it in one texture upload */
|
|
246
283
|
addNetwork(options: NetworkOptions): NetworkLayer;
|
|
284
|
+
/**
|
|
285
|
+
* A layer from its description, as an application's configuration gives it: `{ type, ...options }`, the options of
|
|
286
|
+
* the `add…` method of that type (`'lines'` for `addLines`, `'tiles3d'` for `addTiles3d`…); `before` to go under
|
|
287
|
+
* another layer. The layer's `ready` resolves once the map has drawn it
|
|
288
|
+
*/
|
|
289
|
+
add<P = Record<string, unknown>>(spec: LayerSpec<P>): Layer;
|
|
247
290
|
/** Lines from GeoJSON (line strings, and polygon outlines), styled per feature */
|
|
248
291
|
addLines<P = Record<string, unknown>>(options: LineOptions<P>): LineLayer<P>;
|
|
249
292
|
/** Discs from GeoJSON points, styled per feature */
|
|
@@ -316,3 +359,35 @@ export declare class GeoMap {
|
|
|
316
359
|
private resize;
|
|
317
360
|
destroy(): void;
|
|
318
361
|
}
|
|
362
|
+
/** A layer by its type and the options of its `add…` method (`GeoMap.add`) */
|
|
363
|
+
export type LayerSpec<P = Record<string, unknown>> = ({
|
|
364
|
+
type: 'lines';
|
|
365
|
+
} & LineOptions<P>) | ({
|
|
366
|
+
type: 'circles';
|
|
367
|
+
} & CircleOptions<P>) | ({
|
|
368
|
+
type: 'fills';
|
|
369
|
+
} & FillOptions<P>) | ({
|
|
370
|
+
type: 'symbols';
|
|
371
|
+
} & SymbolOptions<P>) | ({
|
|
372
|
+
type: 'extrusions';
|
|
373
|
+
} & ExtrusionOptions<P>) | ({
|
|
374
|
+
type: 'raster';
|
|
375
|
+
} & RasterOptions & {
|
|
376
|
+
before?: Layer;
|
|
377
|
+
}) | ({
|
|
378
|
+
type: 'ground';
|
|
379
|
+
} & GroundOptions & {
|
|
380
|
+
before?: Layer;
|
|
381
|
+
}) | ({
|
|
382
|
+
type: 'network';
|
|
383
|
+
} & NetworkOptions) | ({
|
|
384
|
+
type: 'tiles3d';
|
|
385
|
+
} & Tiles3dOptions) | ({
|
|
386
|
+
type: 'pointcloud';
|
|
387
|
+
} & PointCloudOptions & {
|
|
388
|
+
before?: Layer;
|
|
389
|
+
}) | ({
|
|
390
|
+
type: 'models';
|
|
391
|
+
} & ModelOptions & {
|
|
392
|
+
before?: Layer;
|
|
393
|
+
});
|
package/dist/map.js
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* the camera animations in animation.ts.
|
|
6
6
|
*/
|
|
7
7
|
import { easeTo, flyTo } from "./animation.js";
|
|
8
|
-
import { BASEMAPS,
|
|
8
|
+
import { BASEMAPS, HILLSHADE, RENAMED_BASEMAPS, SEA } from "./basemaps.js";
|
|
9
9
|
import { AttributionControl } from "./controls.js";
|
|
10
10
|
import { destroyedEngine, engineUrl, loadEngine, loadFullEngineLater, preloadFullEngine, startTileLoader, } from "./engine-loader.js";
|
|
11
11
|
import { ExtrusionLayer, extrusionStyle } from "./extrusions.js";
|
|
12
12
|
import { CircleLayer, circleStyle, FillLayer, fillStyle, LineLayer, lineStyle, } from "./features.js";
|
|
13
|
+
import { IGN_PRESETS } from "./geoplateforme.js";
|
|
13
14
|
import { Glyphs } from "./glyphs.js";
|
|
14
15
|
import { equirectangularGrid, gridLoader, gridZooms, resolveGrid } from "./grid.js";
|
|
15
16
|
import { Icons, readPixels } from "./icons.js";
|
|
@@ -50,11 +51,13 @@ const CORNERS = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
|
50
51
|
const MAX_POLLS = 30;
|
|
51
52
|
/** The name of a basemap, checked: an unknown one throws */
|
|
52
53
|
function checkBasemap(basemap) {
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
54
|
+
const renamed = RENAMED_BASEMAPS[basemap];
|
|
55
|
+
if (renamed)
|
|
56
|
+
throw new Error(`isard: the basemap '${basemap}' is now named '${renamed}'`);
|
|
57
|
+
if (basemap !== 'none' && !(basemap in VECTOR_BASEMAPS) && !(basemap in BASEMAPS)) {
|
|
55
58
|
throw new Error(`isard: unknown basemap '${basemap}'`);
|
|
56
59
|
}
|
|
57
|
-
return
|
|
60
|
+
return basemap;
|
|
58
61
|
}
|
|
59
62
|
/** A map (see `GeoMap.create`); layers take it as their host */
|
|
60
63
|
export class GeoMap {
|
|
@@ -148,7 +151,9 @@ export class GeoMap {
|
|
|
148
151
|
* tiles when only the exaggeration changes) */
|
|
149
152
|
terrainLoaders = new Map();
|
|
150
153
|
/** Loads the engine (once per page) and creates a map filling `container` */
|
|
151
|
-
static async create(container,
|
|
154
|
+
static async create(container, given = {}) {
|
|
155
|
+
// A preset under the options given
|
|
156
|
+
const options = given.preset ? { ...IGN_PRESETS[given.preset], ...given } : given;
|
|
152
157
|
// With 3D Tiles from the start when asked, or when only that engine's URL is given (as before the core engine)
|
|
153
158
|
const full = options.tiles3d === true || (options.wasmUrl !== undefined && options.coreWasmUrl === undefined);
|
|
154
159
|
// Before anything is created
|
|
@@ -166,7 +171,7 @@ export class GeoMap {
|
|
|
166
171
|
this.tiles3dModule = tiles3dModule;
|
|
167
172
|
this.tiles3dOptions = { ...options };
|
|
168
173
|
this.glyphsUrl = options.glyphs;
|
|
169
|
-
this.basemapWorkerUrl = options.basemapWorkerUrl;
|
|
174
|
+
this.basemapWorkerUrl = options.basemapWorkerUrl ?? defaultWorkerUrl(options.assetsUrl);
|
|
170
175
|
this.basemapTileSize = options.basemapTileSize;
|
|
171
176
|
this.container = container;
|
|
172
177
|
this.canvas = document.createElement('canvas');
|
|
@@ -435,7 +440,7 @@ export class GeoMap {
|
|
|
435
440
|
if (index >= 0)
|
|
436
441
|
this.layers.splice(index, 1);
|
|
437
442
|
}
|
|
438
|
-
|
|
443
|
+
addLayer(layer) {
|
|
439
444
|
// On the core engine, a 3D Tiles layer or a model waits for the engine with 3D Tiles: it is created with the
|
|
440
445
|
// others on it
|
|
441
446
|
if (layer.needsFullEngine && !this.tiles3dModule)
|
|
@@ -506,6 +511,37 @@ export class GeoMap {
|
|
|
506
511
|
}
|
|
507
512
|
}
|
|
508
513
|
// ── Camera ──
|
|
514
|
+
/**
|
|
515
|
+
* The camera's methods together: `get`, `set`, `easeTo`, `flyTo`, `bounds`, `firstPerson` and `setFirstPerson`
|
|
516
|
+
* (street level), `project`, `unproject`; the same as the map's own (`getCamera`, `setCamera`…)
|
|
517
|
+
*/
|
|
518
|
+
camera = {
|
|
519
|
+
get: () => this.getCamera(),
|
|
520
|
+
set: (camera) => this.setCamera(camera),
|
|
521
|
+
easeTo: (camera, options) => this.easeTo(camera, options),
|
|
522
|
+
flyTo: (camera, options) => this.flyTo(camera, options),
|
|
523
|
+
bounds: () => this.getBounds(),
|
|
524
|
+
firstPerson: () => this.firstPerson,
|
|
525
|
+
setFirstPerson: (view) => this.setFirstPerson(view),
|
|
526
|
+
project: (lonLat, height) => this.project(lonLat, height),
|
|
527
|
+
unproject: (point) => this.unproject(point),
|
|
528
|
+
};
|
|
529
|
+
/**
|
|
530
|
+
* What lies under a point or at a position, together: `feature` (`pickFeature`), `surface` (`pickSurface`),
|
|
531
|
+
* `surfaceAt`, `elevationAt`, `metersPerPixel`
|
|
532
|
+
*/
|
|
533
|
+
query = {
|
|
534
|
+
feature: (point, options) => this.pickFeature(point, options),
|
|
535
|
+
surface: (point) => this.pickSurface(point),
|
|
536
|
+
surfaceAt: (lonLat) => this.surfaceAt(lonLat),
|
|
537
|
+
elevationAt: (lonLat) => this.elevationAt(lonLat),
|
|
538
|
+
metersPerPixel: (point) => this.metersPerPixel(point),
|
|
539
|
+
};
|
|
540
|
+
/** What is drawn over the scene, together: `viewshed` (`setViewshed`), `swipe` (`setSwipe`) */
|
|
541
|
+
effects = {
|
|
542
|
+
viewshed: (options) => this.setViewshed(options),
|
|
543
|
+
swipe: (options) => this.setSwipe(options),
|
|
544
|
+
};
|
|
509
545
|
getCamera() {
|
|
510
546
|
return this.frameCamera ?? this.engine.camera();
|
|
511
547
|
}
|
|
@@ -839,7 +875,7 @@ export class GeoMap {
|
|
|
839
875
|
}
|
|
840
876
|
// ── Layers ──
|
|
841
877
|
/** Replaces the basemap and the IGN hillshade, under the other layers (hillshade by default: 0, none). The former
|
|
842
|
-
* names of the Géoplateforme basemaps
|
|
878
|
+
* names of the Géoplateforme basemaps throw, naming the new ones */
|
|
843
879
|
setBasemap(basemap, hillshade = 0) {
|
|
844
880
|
const name = checkBasemap(basemap);
|
|
845
881
|
if (this.basemap && this.hasLayer(this.basemap))
|
|
@@ -917,7 +953,52 @@ export class GeoMap {
|
|
|
917
953
|
const { halo = 0, haloOpacity = 0.11, ramp, unreachedColor = 'rgba(140, 140, 140, 0.25)', fade = 0 } = options;
|
|
918
954
|
const style = { width, max, contour, opacity, halo, haloOpacity, ramp, unreachedColor, fade };
|
|
919
955
|
validateNetwork(nodes, edges);
|
|
920
|
-
return this.
|
|
956
|
+
return this.addLayer(new NetworkLayer(this, { nodes, edges, lines }, costs, style, edgeWidths));
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* A layer from its description, as an application's configuration gives it: `{ type, ...options }`, the options of
|
|
960
|
+
* the `add…` method of that type (`'lines'` for `addLines`, `'tiles3d'` for `addTiles3d`…); `before` to go under
|
|
961
|
+
* another layer. The layer's `ready` resolves once the map has drawn it
|
|
962
|
+
*/
|
|
963
|
+
add(spec) {
|
|
964
|
+
switch (spec.type) {
|
|
965
|
+
case 'lines':
|
|
966
|
+
return this.addLines(spec);
|
|
967
|
+
case 'circles':
|
|
968
|
+
return this.addCircles(spec);
|
|
969
|
+
case 'fills':
|
|
970
|
+
return this.addFills(spec);
|
|
971
|
+
case 'symbols':
|
|
972
|
+
return this.addSymbols(spec);
|
|
973
|
+
case 'extrusions':
|
|
974
|
+
return this.addExtrusions(spec);
|
|
975
|
+
case 'raster':
|
|
976
|
+
return this.addRaster(spec);
|
|
977
|
+
case 'ground':
|
|
978
|
+
return this.addGround(spec);
|
|
979
|
+
case 'network':
|
|
980
|
+
return this.addNetwork(spec);
|
|
981
|
+
case 'tiles3d':
|
|
982
|
+
return this.addTiles3d(spec);
|
|
983
|
+
case 'pointcloud':
|
|
984
|
+
return this.addPointCloud(spec);
|
|
985
|
+
case 'models':
|
|
986
|
+
return this.addModels(spec);
|
|
987
|
+
default:
|
|
988
|
+
throw new Error(`isard: no layer of type ${String(spec.type)}`);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
/** @internal Resolves once the map is idle (everything in view loaded and drawn) */
|
|
992
|
+
whenIdle() {
|
|
993
|
+
if (this.gone)
|
|
994
|
+
return Promise.resolve();
|
|
995
|
+
return new Promise((resolve) => {
|
|
996
|
+
const off = this.on('idle', () => {
|
|
997
|
+
off();
|
|
998
|
+
resolve();
|
|
999
|
+
});
|
|
1000
|
+
this.requestRender();
|
|
1001
|
+
});
|
|
921
1002
|
}
|
|
922
1003
|
/** Lines from GeoJSON (line strings, and polygon outlines), styled per feature */
|
|
923
1004
|
addLines(options) {
|
|
@@ -1005,7 +1086,7 @@ export class GeoMap {
|
|
|
1005
1086
|
* when it asks for another count or URL
|
|
1006
1087
|
*/
|
|
1007
1088
|
basemapWorkers(count, url) {
|
|
1008
|
-
const sharedUrl = this.basemapWorkerUrl
|
|
1089
|
+
const sharedUrl = this.basemapWorkerUrl;
|
|
1009
1090
|
const shared = defaultWorkerCount();
|
|
1010
1091
|
const workers = Math.max(1, count ?? shared);
|
|
1011
1092
|
const workerUrl = url ?? sharedUrl;
|
|
@@ -1041,7 +1122,7 @@ export class GeoMap {
|
|
|
1041
1122
|
};
|
|
1042
1123
|
/** Adds a layer, under `before` if given */
|
|
1043
1124
|
place(layer, before) {
|
|
1044
|
-
this.
|
|
1125
|
+
this.addLayer(layer);
|
|
1045
1126
|
if (before)
|
|
1046
1127
|
this.moveLayer(layer, before);
|
|
1047
1128
|
return layer;
|
|
@@ -1049,7 +1130,7 @@ export class GeoMap {
|
|
|
1049
1130
|
/** Textured meshes in 3D Tiles (photogrammetry, buildings), drawn with depth over the basemap */
|
|
1050
1131
|
addTiles3d(options) {
|
|
1051
1132
|
const { url, maxScreenSpaceError = 16, opacity = 1, pointSize, color, geoid = false } = options;
|
|
1052
|
-
return this.
|
|
1133
|
+
return this.addLayer(new Tiles3dLayer(this, url, geoid, {
|
|
1053
1134
|
maxScreenSpaceError,
|
|
1054
1135
|
opacity,
|
|
1055
1136
|
...(pointSize !== undefined ? { pointSize } : {}),
|