isard 0.2.0 → 0.3.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 +134 -14
- package/README.md +2 -2
- package/dist/animation.d.ts +18 -0
- package/dist/animation.js +84 -0
- package/dist/animation.js.map +1 -0
- package/dist/basemap.worker.d.ts +26 -1
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +8 -4
- package/dist/basemaps.d.ts +5 -3
- package/dist/basemaps.js +5 -3
- package/dist/basemaps.js.map +1 -1
- package/dist/crs.d.ts +72 -0
- package/dist/crs.js +243 -0
- package/dist/crs.js.map +1 -0
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +4 -4
- package/dist/engine-loader.d.ts +27 -0
- package/dist/engine-loader.js +112 -0
- package/dist/engine-loader.js.map +1 -0
- package/dist/extrusions.js +11 -2
- package/dist/extrusions.js.map +1 -1
- package/dist/features.d.ts +8 -0
- package/dist/features.js +17 -10
- package/dist/features.js.map +1 -1
- package/dist/geo.d.ts +16 -0
- package/dist/geo.js +32 -0
- package/dist/geo.js.map +1 -0
- package/dist/geoplateforme.d.ts +21 -5
- package/dist/geoplateforme.js +47 -12
- package/dist/geoplateforme.js.map +1 -1
- package/dist/glyphs.d.ts +10 -3
- package/dist/glyphs.js +14 -2
- package/dist/glyphs.js.map +1 -1
- package/dist/gpx.d.ts +11 -0
- package/dist/gpx.js +74 -0
- package/dist/gpx.js.map +1 -0
- package/dist/grid.d.ts +81 -0
- package/dist/grid.js +270 -0
- package/dist/grid.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +3 -4
- package/dist/interaction.js +27 -7
- package/dist/interaction.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/kml.d.ts +12 -0
- package/dist/kml.js +159 -0
- package/dist/kml.js.map +1 -0
- package/dist/layers.d.ts +5 -2
- package/dist/layers.js +22 -18
- package/dist/layers.js.map +1 -1
- package/dist/lru.d.ts +22 -0
- package/dist/lru.js +52 -0
- package/dist/lru.js.map +1 -0
- package/dist/map.d.ts +26 -6
- package/dist/map.js +196 -287
- package/dist/map.js.map +1 -1
- package/dist/resample.d.ts +41 -0
- package/dist/resample.js +164 -0
- package/dist/resample.js.map +1 -0
- package/dist/settings.d.ts +39 -0
- package/dist/settings.js +104 -0
- package/dist/settings.js.map +1 -0
- package/dist/symbols.d.ts +12 -1
- package/dist/symbols.js +124 -26
- package/dist/symbols.js.map +1 -1
- package/dist/terrain.d.ts +19 -7
- package/dist/terrain.js +50 -26
- package/dist/terrain.js.map +1 -1
- package/dist/topojson.d.ts +29 -0
- package/dist/topojson.js +66 -0
- package/dist/topojson.js.map +1 -0
- package/dist/types.d.ts +23 -7
- package/dist/types.js.map +1 -1
- package/dist/vectortiles.d.ts +13 -3
- package/dist/vectortiles.js +85 -46
- package/dist/vectortiles.js.map +1 -1
- package/dist/wasm/isard.d.ts +14 -7
- package/dist/wasm/isard.js +33 -10
- package/dist/wasm/isard_core.d.ts +6 -5
- package/dist/wasm/isard_core.js +41 -10
- package/dist/wmts.d.ts +14 -0
- package/dist/wmts.js +76 -0
- package/dist/wmts.js.map +1 -0
- package/dist/xml.d.ts +26 -0
- package/dist/xml.js +109 -0
- package/dist/xml.js.map +1 -0
- package/package.json +1 -1
- package/dist/equirectangular.d.ts +0 -35
- package/dist/equirectangular.js +0 -113
- package/dist/equirectangular.js.map +0 -1
package/dist/grid.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rasters in another tile grid, the planning half: a WMTS-like tile matrix set in any CRS (Lambert-93, UTM, longitudes
|
|
3
|
+
* and latitudes…), or a WMS asked for a box in that CRS, reprojected into the Web Mercator tiles the engine draws. For
|
|
4
|
+
* each Mercator tile the page projects a mesh of 17 × 17 points of the tile into the source CRS (the only projection
|
|
5
|
+
* work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source
|
|
6
|
+
* images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.
|
|
7
|
+
*/
|
|
8
|
+
import { type Crs, type CrsLike } from './crs.ts';
|
|
9
|
+
import { type Job } from './resample.ts';
|
|
10
|
+
/** One level of a tile grid, as a `TileMatrix` of WMTS */
|
|
11
|
+
export interface TileMatrix {
|
|
12
|
+
/** What replaces {z} in the URL (the `TILEMATRIX` of a WMTS; default the index of the matrix in the grid) */
|
|
13
|
+
id?: string | number;
|
|
14
|
+
/** Size of a pixel, CRS units (WMTS: its `ScaleDenominator` × 0.00028 m, in CRS units) */
|
|
15
|
+
resolution: number;
|
|
16
|
+
/** Top-left corner of the tile (0, 0), CRS units (x east, y north) */
|
|
17
|
+
origin: [x: number, y: number];
|
|
18
|
+
/** Size of a tile, pixels (default 256) */
|
|
19
|
+
tileWidth?: number;
|
|
20
|
+
tileHeight?: number;
|
|
21
|
+
/** Tiles across and down (default unbounded) */
|
|
22
|
+
matrixWidth?: number;
|
|
23
|
+
matrixHeight?: number;
|
|
24
|
+
/** The tiles the source has (a WMTS's `TileMatrixLimits`), inclusive: none is asked for outside */
|
|
25
|
+
limits?: [minCol: number, minRow: number, maxCol: number, maxRow: number];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A raster's tile grid in a CRS of its own, reprojected into Web Mercator by the map: `matrices` for tiles ({z}, {x},
|
|
29
|
+
* {y} in the URL: matrix, column, row, rows from the north), none for a WMS whose URL has `{bbox}` (the box of each
|
|
30
|
+
* Mercator tile in that CRS: minimum x, minimum y, maximum x, maximum y, asked for at the tile's size)
|
|
31
|
+
*/
|
|
32
|
+
export interface TileGrid {
|
|
33
|
+
/** `'EPSG:2154'`, another built-in or registered name, or an object with `forward` and `inverse` (proj4's) */
|
|
34
|
+
crs: CrsLike;
|
|
35
|
+
/** The levels of the grid, in any order */
|
|
36
|
+
matrices?: TileMatrix[];
|
|
37
|
+
/** Longitudes and latitudes the source covers (west, south, east, north): nothing is asked for outside */
|
|
38
|
+
bounds?: [west: number, south: number, east: number, north: number];
|
|
39
|
+
/** Identifier of the tile matrix set (a WMTS's `TILEMATRIXSET`), for the helpers that write the URL */
|
|
40
|
+
name?: string;
|
|
41
|
+
}
|
|
42
|
+
interface Matrix extends Required<Omit<TileMatrix, 'limits' | 'id'>> {
|
|
43
|
+
id: string | number;
|
|
44
|
+
limits: [number, number, number, number] | undefined;
|
|
45
|
+
}
|
|
46
|
+
interface Resolved {
|
|
47
|
+
crs: Crs;
|
|
48
|
+
/** Coarsest first */
|
|
49
|
+
matrices: Matrix[];
|
|
50
|
+
bounds: [number, number, number, number] | undefined;
|
|
51
|
+
/** The bounds in the CRS: minimum x, minimum y, maximum x, maximum y */
|
|
52
|
+
extent: [number, number, number, number] | undefined;
|
|
53
|
+
}
|
|
54
|
+
/** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */
|
|
55
|
+
export declare function resolveGrid(grid: TileGrid): Resolved;
|
|
56
|
+
/** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows
|
|
57
|
+
* from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */
|
|
58
|
+
export declare function equirectangularGrid(minLevel: number, maxLevel: number): TileGrid;
|
|
59
|
+
/**
|
|
60
|
+
* The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null
|
|
61
|
+
* where the source has nothing
|
|
62
|
+
*/
|
|
63
|
+
export declare function planTile(g: Resolved, url: string, z: number, x: number, y: number, size: number): Job | null;
|
|
64
|
+
/**
|
|
65
|
+
* The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where
|
|
66
|
+
* the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix
|
|
67
|
+
*/
|
|
68
|
+
export declare function gridZooms(g: Resolved): {
|
|
69
|
+
minZoom: number;
|
|
70
|
+
maxZoom: number;
|
|
71
|
+
};
|
|
72
|
+
/** Draws a Mercator tile `z`/`x`/`y`: its image, null where the source has nothing; rejects on errors */
|
|
73
|
+
type Draw = (z: number, x: number, y: number, signal: AbortSignal) => Promise<ImageBitmap | null>;
|
|
74
|
+
/** A planned tile drawn in a worker; undefined when the map has no workers (drawn in the page) */
|
|
75
|
+
export type RemoteReprojection = (job: Job, tile: [z: number, x: number, y: number], signal: AbortSignal) => Promise<ImageBitmap | null> | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:
|
|
78
|
+
* planned here, drawn in a worker of the map through `remote` when it can, else in the page
|
|
79
|
+
*/
|
|
80
|
+
export declare function gridLoader(url: string, grid: Resolved, size: number, remote?: RemoteReprojection): Draw;
|
|
81
|
+
export {};
|
package/dist/grid.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rasters in another tile grid, the planning half: a WMTS-like tile matrix set in any CRS (Lambert-93, UTM, longitudes
|
|
3
|
+
* and latitudes…), or a WMS asked for a box in that CRS, reprojected into the Web Mercator tiles the engine draws. For
|
|
4
|
+
* each Mercator tile the page projects a mesh of 17 × 17 points of the tile into the source CRS (the only projection
|
|
5
|
+
* work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source
|
|
6
|
+
* images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.
|
|
7
|
+
*/
|
|
8
|
+
import { getCrs } from "./crs.js";
|
|
9
|
+
import { latitude, longitude, mercatorX, mercatorY } from "./geo.js";
|
|
10
|
+
import { resampler } from "./resample.js";
|
|
11
|
+
/** Cells of the mesh along each side of a tile */
|
|
12
|
+
const N = 16;
|
|
13
|
+
/** Source levels finer at most than the pixel size across, where the grid stretches one axis (towards the poles in
|
|
14
|
+
* longitudes and latitudes) */
|
|
15
|
+
const MAX_BOOST = 3;
|
|
16
|
+
/** Pixels of a mosaic at most: coarser levels beyond, nothing if even the coarsest is larger */
|
|
17
|
+
const MAX_MOSAIC = 2048 * 2048;
|
|
18
|
+
/** A box of the CRS around points of it (x, y, x, y…), NaN ignored; undefined without any */
|
|
19
|
+
function box(points) {
|
|
20
|
+
let [x0, y0, x1, y1] = [Infinity, Infinity, -Infinity, -Infinity];
|
|
21
|
+
for (let k = 0; k + 1 < points.length; k += 2) {
|
|
22
|
+
const [x, y] = [points[k], points[k + 1]];
|
|
23
|
+
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
24
|
+
continue;
|
|
25
|
+
x0 = Math.min(x0, x);
|
|
26
|
+
y0 = Math.min(y0, y);
|
|
27
|
+
x1 = Math.max(x1, x);
|
|
28
|
+
y1 = Math.max(y1, y);
|
|
29
|
+
}
|
|
30
|
+
return x0 <= x1 ? [x0, y0, x1, y1] : undefined;
|
|
31
|
+
}
|
|
32
|
+
/** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */
|
|
33
|
+
export function resolveGrid(grid) {
|
|
34
|
+
const crs = getCrs(grid.crs);
|
|
35
|
+
const matrices = (grid.matrices ?? [])
|
|
36
|
+
.map((m, i) => ({
|
|
37
|
+
id: m.id ?? i,
|
|
38
|
+
resolution: m.resolution,
|
|
39
|
+
origin: m.origin,
|
|
40
|
+
tileWidth: m.tileWidth ?? 256,
|
|
41
|
+
tileHeight: m.tileHeight ?? 256,
|
|
42
|
+
matrixWidth: m.matrixWidth ?? Infinity,
|
|
43
|
+
matrixHeight: m.matrixHeight ?? Infinity,
|
|
44
|
+
limits: m.limits,
|
|
45
|
+
}))
|
|
46
|
+
.sort((a, b) => b.resolution - a.resolution);
|
|
47
|
+
let extent;
|
|
48
|
+
if (grid.bounds) {
|
|
49
|
+
// Its outline and inside, projected: the box of the CRS around them, a little larger (curved edges)
|
|
50
|
+
const [w, s, e, n] = grid.bounds;
|
|
51
|
+
const points = [];
|
|
52
|
+
for (let i = 0; i <= 8; i += 1) {
|
|
53
|
+
for (let j = 0; j <= 8; j += 1)
|
|
54
|
+
points.push(...crs.forward([w + ((e - w) * i) / 8, s + ((n - s) * j) / 8]));
|
|
55
|
+
}
|
|
56
|
+
const b = box(points);
|
|
57
|
+
if (b) {
|
|
58
|
+
const margin = 0.01 * Math.max(b[2] - b[0], b[3] - b[1]);
|
|
59
|
+
extent = [b[0] - margin, b[1] - margin, b[2] + margin, b[3] + margin];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { crs, matrices, bounds: grid.bounds, extent };
|
|
63
|
+
}
|
|
64
|
+
/** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows
|
|
65
|
+
* from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */
|
|
66
|
+
export function equirectangularGrid(minLevel, maxLevel) {
|
|
67
|
+
const matrices = [];
|
|
68
|
+
for (let level = minLevel; level <= maxLevel; level += 1) {
|
|
69
|
+
const n = 2 ** level;
|
|
70
|
+
matrices.push({ id: level, resolution: 180 / 256 / n, origin: [-180, 90], matrixWidth: 2 * n, matrixHeight: n });
|
|
71
|
+
}
|
|
72
|
+
return { crs: 'EPSG:4326', matrices };
|
|
73
|
+
}
|
|
74
|
+
/** A URL of the source: {z}, {x}, {y}, {bbox}, {width} and {height} replaced */
|
|
75
|
+
function sourceUrl(template, z, x, y, bbox, w, h) {
|
|
76
|
+
return template
|
|
77
|
+
.replaceAll('{z}', String(z))
|
|
78
|
+
.replaceAll('{x}', String(x))
|
|
79
|
+
.replaceAll('{y}', String(y))
|
|
80
|
+
.replaceAll('{bbox}', bbox.join(','))
|
|
81
|
+
.replaceAll('{width}', String(w))
|
|
82
|
+
.replaceAll('{height}', String(h));
|
|
83
|
+
}
|
|
84
|
+
/** CRS units per pixel along the mesh's x and y around its middle (NaN where the CRS has nothing there) */
|
|
85
|
+
function pixelSize(points, size) {
|
|
86
|
+
const c = N / 2;
|
|
87
|
+
const at = (i, j) => 2 * (j * (N + 1) + i);
|
|
88
|
+
const d = (p, q) => Math.hypot(points[q] - points[p], points[q + 1] - points[p + 1]);
|
|
89
|
+
const step = (2 * size) / N;
|
|
90
|
+
return [d(at(c - 1, c), at(c + 1, c)) / step, d(at(c, c - 1), at(c, c + 1)) / step];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The box (CRS) of the points a tile samples: the centers of its edge pixels, interpolated in the mesh as `resample`
|
|
94
|
+
* does, and the inner points of the mesh (should the projection bend); within `clip`. Undefined if none is
|
|
95
|
+
*/
|
|
96
|
+
function sampled(points, size, clip) {
|
|
97
|
+
const at = (i, j, k) => points[2 * (j * (N + 1) + i) + k];
|
|
98
|
+
const centers = [];
|
|
99
|
+
for (let j = 1; j < N; j += 1)
|
|
100
|
+
for (let i = 1; i < N; i += 1)
|
|
101
|
+
centers.push(at(i, j, 0), at(i, j, 1));
|
|
102
|
+
const cell = size / N;
|
|
103
|
+
const add = (px, py) => {
|
|
104
|
+
const [fx, fy] = [px / cell, py / cell];
|
|
105
|
+
const [i, j] = [Math.min(N - 1, Math.floor(fx)), Math.min(N - 1, Math.floor(fy))];
|
|
106
|
+
const [tx, ty] = [fx - i, fy - j];
|
|
107
|
+
for (const k of [0, 1]) {
|
|
108
|
+
const top = at(i, j, k) + (at(i + 1, j, k) - at(i, j, k)) * tx;
|
|
109
|
+
const bottom = at(i, j + 1, k) + (at(i + 1, j + 1, k) - at(i, j + 1, k)) * tx;
|
|
110
|
+
centers.push(top + (bottom - top) * ty);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
for (let p = 0.5; p < size; p += 1) {
|
|
114
|
+
add(p, 0.5);
|
|
115
|
+
add(p, size - 0.5);
|
|
116
|
+
add(0.5, p);
|
|
117
|
+
add(size - 0.5, p);
|
|
118
|
+
}
|
|
119
|
+
const b = box(centers);
|
|
120
|
+
if (!b)
|
|
121
|
+
return undefined;
|
|
122
|
+
const out = [
|
|
123
|
+
Math.max(b[0], clip[0]),
|
|
124
|
+
Math.max(b[1], clip[1]),
|
|
125
|
+
Math.min(b[2], clip[2]),
|
|
126
|
+
Math.min(b[3], clip[3]),
|
|
127
|
+
];
|
|
128
|
+
return out[0] <= out[2] && out[1] <= out[3] ? out : undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null
|
|
132
|
+
* where the source has nothing
|
|
133
|
+
*/
|
|
134
|
+
export function planTile(g, url, z, x, y, size) {
|
|
135
|
+
const tiles = 2 ** z;
|
|
136
|
+
if (g.bounds) {
|
|
137
|
+
const [w, s, e, n] = g.bounds;
|
|
138
|
+
if (longitude((x + 1) / tiles) <= w || longitude(x / tiles) >= e)
|
|
139
|
+
return null;
|
|
140
|
+
if (latitude(y / tiles) <= s || latitude((y + 1) / tiles) >= n)
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// The mesh in the source CRS
|
|
144
|
+
const points = new Float64Array(2 * (N + 1) ** 2);
|
|
145
|
+
for (let j = 0; j <= N; j += 1) {
|
|
146
|
+
const lat = latitude((y + j / N) / tiles);
|
|
147
|
+
for (let i = 0; i <= N; i += 1) {
|
|
148
|
+
const [px = Number.NaN, py = Number.NaN] = g.crs.forward([longitude((x + i / N) / tiles), lat]);
|
|
149
|
+
points[2 * (j * (N + 1) + i)] = px;
|
|
150
|
+
points[2 * (j * (N + 1) + i) + 1] = py;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let b = box(points);
|
|
154
|
+
if (!b)
|
|
155
|
+
return null;
|
|
156
|
+
if (g.extent) {
|
|
157
|
+
const e = g.extent;
|
|
158
|
+
b = [Math.max(b[0], e[0]), Math.max(b[1], e[1]), Math.min(b[2], e[2]), Math.min(b[3], e[3])];
|
|
159
|
+
if (b[0] >= b[2] || b[1] >= b[3])
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const mesh = new Float32Array(points.length);
|
|
163
|
+
if (g.matrices.length === 0) {
|
|
164
|
+
// One image of the tile's box, a pixel larger on each side
|
|
165
|
+
const [sx, sy] = pixelSize(points, size);
|
|
166
|
+
const m = Number.isFinite(sx + sy) ? Math.max(sx, sy) : 0;
|
|
167
|
+
const [x0, y0, x1, y1] = [b[0] - m, b[1] - m, b[2] + m, b[3] + m];
|
|
168
|
+
for (let k = 0; k < points.length; k += 2) {
|
|
169
|
+
mesh[k] = ((points[k] - x0) / (x1 - x0)) * size;
|
|
170
|
+
mesh[k + 1] = ((y1 - points[k + 1]) / (y1 - y0)) * size;
|
|
171
|
+
}
|
|
172
|
+
const source = { url: sourceUrl(url, z, x, y, [x0, y0, x1, y1], size, size), x: 0, y: 0, w: size, h: size };
|
|
173
|
+
return { size, width: size, height: size, sources: [source], n: N, mesh };
|
|
174
|
+
}
|
|
175
|
+
// The level of the same pixel size, along the axis the grid stretches least (up to MAX_BOOST levels finer)
|
|
176
|
+
const [sx, sy] = pixelSize(points, size);
|
|
177
|
+
const across = Math.max(sx, sy);
|
|
178
|
+
const target = Number.isFinite(across) ? Math.max(Math.min(sx, sy), across / 2 ** MAX_BOOST) : (b[2] - b[0]) / size;
|
|
179
|
+
// Where the pixels of the tile are sampled: the centers of its edge pixels and the mesh, within the source's extent
|
|
180
|
+
const centers = sampled(points, size, b);
|
|
181
|
+
if (!centers)
|
|
182
|
+
return null;
|
|
183
|
+
let best = 0;
|
|
184
|
+
g.matrices.forEach((m, i) => {
|
|
185
|
+
const r = g.matrices[best]?.resolution ?? m.resolution;
|
|
186
|
+
if (Math.abs(Math.log2(m.resolution / target)) < Math.abs(Math.log2(r / target)))
|
|
187
|
+
best = i;
|
|
188
|
+
});
|
|
189
|
+
for (let level = best; level >= 0; level -= 1) {
|
|
190
|
+
const m = g.matrices[level];
|
|
191
|
+
const [ox, oy] = m.origin;
|
|
192
|
+
const [tw, th, res] = [m.tileWidth, m.tileHeight, m.resolution];
|
|
193
|
+
const [l0, r0, l1, r1] = m.limits ?? [0, 0, Infinity, Infinity];
|
|
194
|
+
// The tiles of the source pixels sampled (those of a weight over a thousandth: a tile edge on a source tile edge
|
|
195
|
+
// does not fetch the next source tile for nothing)
|
|
196
|
+
const c0 = Math.max(0, l0, Math.floor(((centers[0] - ox) / res - 0.5 + 1e-3) / tw));
|
|
197
|
+
const c1 = Math.min(m.matrixWidth - 1, l1, Math.floor(((centers[2] - ox) / res + 0.5 - 1e-3) / tw));
|
|
198
|
+
const t0 = Math.max(0, r0, Math.floor(((oy - centers[3]) / res - 0.5 + 1e-3) / th));
|
|
199
|
+
const t1 = Math.min(m.matrixHeight - 1, r1, Math.floor(((oy - centers[1]) / res + 0.5 - 1e-3) / th));
|
|
200
|
+
if (c0 > c1 || t0 > t1)
|
|
201
|
+
return null;
|
|
202
|
+
const [width, height] = [(c1 - c0 + 1) * tw, (t1 - t0 + 1) * th];
|
|
203
|
+
if (width * height > MAX_MOSAIC)
|
|
204
|
+
continue;
|
|
205
|
+
const sources = [];
|
|
206
|
+
for (let row = t0; row <= t1; row += 1) {
|
|
207
|
+
for (let col = c0; col <= c1; col += 1) {
|
|
208
|
+
const bbox = [ox + col * tw * res, oy - (row + 1) * th * res, ox + (col + 1) * tw * res, oy - row * th * res];
|
|
209
|
+
const placed = { x: (col - c0) * tw, y: (row - t0) * th, w: tw, h: th };
|
|
210
|
+
sources.push({ url: sourceUrl(url, m.id, col, row, bbox, tw, th), ...placed });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
for (let k = 0; k < points.length; k += 2) {
|
|
214
|
+
mesh[k] = (points[k] - ox) / res - c0 * tw;
|
|
215
|
+
mesh[k + 1] = (oy - points[k + 1]) / res - t0 * th;
|
|
216
|
+
}
|
|
217
|
+
return { size, width, height, sources, n: N, mesh };
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where
|
|
223
|
+
* the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix
|
|
224
|
+
*/
|
|
225
|
+
export function gridZooms(g) {
|
|
226
|
+
const coarse = g.matrices[0];
|
|
227
|
+
const fine = g.matrices.at(-1);
|
|
228
|
+
if (!coarse || !fine)
|
|
229
|
+
return { minZoom: 0, maxZoom: 19 };
|
|
230
|
+
let lonLat = [0, 0];
|
|
231
|
+
if (g.bounds)
|
|
232
|
+
lonLat = [(g.bounds[0] + g.bounds[2]) / 2, (g.bounds[1] + g.bounds[3]) / 2];
|
|
233
|
+
else {
|
|
234
|
+
const [l0, r0, l1, r1] = coarse.limits ?? [0, 0, coarse.matrixWidth - 1, coarse.matrixHeight - 1];
|
|
235
|
+
const span = coarse.resolution * coarse.tileWidth;
|
|
236
|
+
const [cx, cy] = [(l0 + l1 + 1) / 2, (r0 + r1 + 1) / 2];
|
|
237
|
+
if (Number.isFinite(cx + cy))
|
|
238
|
+
lonLat = g.crs.inverse([coarse.origin[0] + cx * span, coarse.origin[1] - cy * span]);
|
|
239
|
+
}
|
|
240
|
+
// CRS units per pixel of a 256 px tile at zoom 0 there
|
|
241
|
+
const [mx, my] = [mercatorX(lonLat[0] ?? 0), mercatorY(lonLat[1] ?? 0)];
|
|
242
|
+
const d = 1e-7;
|
|
243
|
+
const p = g.crs.forward([longitude(mx), latitude(my)]);
|
|
244
|
+
const q = g.crs.forward([longitude(mx + d), latitude(my)]);
|
|
245
|
+
const zero = Math.hypot((q[0] ?? 0) - (p[0] ?? 0), (q[1] ?? 0) - (p[1] ?? 0)) / (d * 256);
|
|
246
|
+
if (!(zero > 0))
|
|
247
|
+
return { minZoom: 0, maxZoom: 19 };
|
|
248
|
+
return {
|
|
249
|
+
minZoom: Math.max(0, Math.floor(Math.log2(zero / coarse.resolution)) - 2),
|
|
250
|
+
maxZoom: Math.max(0, Math.round(Math.log2(zero / fine.resolution))),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:
|
|
255
|
+
* planned here, drawn in a worker of the map through `remote` when it can, else in the page
|
|
256
|
+
*/
|
|
257
|
+
export function gridLoader(url, grid, size, remote) {
|
|
258
|
+
let local;
|
|
259
|
+
return async (z, x, y, signal) => {
|
|
260
|
+
const job = planTile(grid, url, z, x, y, size);
|
|
261
|
+
if (!job)
|
|
262
|
+
return null;
|
|
263
|
+
const drawn = remote?.(job, [z, x, y], signal);
|
|
264
|
+
if (drawn)
|
|
265
|
+
return drawn;
|
|
266
|
+
local ??= resampler().draw;
|
|
267
|
+
return local(job, signal);
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=grid.js.map
|
package/dist/grid.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAA0B,MAAM,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAAyB,SAAS,EAAE,MAAM,eAAe,CAAC;AAoCjE,kDAAkD;AAClD,MAAM,CAAC,GAAG,EAAE,CAAC;AACb;+BAC+B;AAC/B,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,gGAAgG;AAChG,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;AAgB/B,6FAA6F;AAC7F,SAAS,GAAG,CAAC,MAAyB;IACpC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAW,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QACzD,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACrB,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACrB,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACrB,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAE,CAAC,EAAU,EAAE,CAAC,CAAC;QACjB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC;QACb,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;QAC7B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,GAAG;QAC/B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,QAAQ;QACtC,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,QAAQ;QACxC,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CACH;SACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,oGAAoG;QACpG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9G,CAAC;QACD,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;AACxD,CAAC;AAED;sGACsG;AACtG,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,QAAgB;IACpE,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,KAAK,IAAI,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACzD,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AACxC,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,QAAgB,EAAE,CAAkB,EAAE,CAAS,EAAE,CAAS,EAAE,IAAc,EAAE,CAAS,EAAE,CAAS;IACjH,OAAO,QAAQ;SACZ,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;SAC5B,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;SAC5B,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;SAC5B,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACpC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;SAChC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,2GAA2G;AAC3G,SAAS,SAAS,CAAC,MAAoB,EAAE,IAAY;IACnD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CACjC,IAAI,CAAC,KAAK,CAAE,MAAM,CAAC,CAAC,CAAY,GAAI,MAAM,CAAC,CAAC,CAAY,EAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAY,GAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC,CAAC;IACnH,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACtF,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,MAAoB,EAAE,IAAY,EAAE,IAAc;IACjE,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC;IAC5F,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;QAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrG,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAU,EAAE,EAAE;QACrC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAC/D,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAC9E,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACZ,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,MAAM,GAAG,GAAqC;QAC5C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAW,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAW,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAW,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAW,CAAC;KAClC,CAAC;IACF,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAW,EAAE,GAAW,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,IAAY;IAC9F,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAC9B,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9E,IAAI,QAAQ,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9E,CAAC;IACD,6BAA6B;IAC7B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAChG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YACnC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACnB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAChD,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,2DAA2D;QAC3D,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,MAAM,CAAC,CAAC,CAAY,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;YAC5D,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;QACtE,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5G,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IAC5E,CAAC;IACD,2GAA2G;IAC3G,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACpH,oHAAoH;IACpH,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC;QACvD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAAE,IAAI,GAAG,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IACH,KAAK,IAAI,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAW,CAAC;QACtC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChE,iHAAiH;QACjH,mDAAmD;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpG,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrG,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACjE,IAAI,KAAK,GAAG,MAAM,GAAG,UAAU;YAAE,SAAS;QAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,IAAI,GAAG,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YACvC,KAAK,IAAI,GAAG,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC;gBAC9G,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,CAAC,CAAC,GAAG,CAAE,MAAM,CAAC,CAAC,CAAY,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;YACvD,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,CAAW;IACnC,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACzD,IAAI,MAAM,GAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,CAAC,MAAM;QAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACrF,CAAC;QACJ,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,WAAW,GAAG,CAAC,EAAE,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QAClG,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;QAClD,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;YAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IACrH,CAAC;IACD,uDAAuD;IACvD,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,CAAC,GAAG,IAAI,CAAC;IACf,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IAC1F,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACpD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC;QACzE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;KACpE,CAAC;AACJ,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAc,EAAE,IAAY,EAAE,MAA2B;IAC/F,IAAI,KAAuD,CAAC;IAC5D,OAAO,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,KAAK,KAAK,SAAS,EAAE,CAAC,IAAI,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Rasters in another tile grid, the planning half: a WMTS-like tile matrix set in any CRS (Lambert-93, UTM, longitudes\n * and latitudes…), or a WMS asked for a box in that CRS, reprojected into the Web Mercator tiles the engine draws. For\n * each Mercator tile the page projects a mesh of 17 × 17 points of the tile into the source CRS (the only projection\n * work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source\n * images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.\n */\nimport { type Crs, type CrsLike, getCrs } from './crs.ts';\nimport { latitude, longitude, mercatorX, mercatorY } from './geo.ts';\nimport { type Job, type Placed, resampler } from './resample.ts';\n\n/** One level of a tile grid, as a `TileMatrix` of WMTS */\nexport interface TileMatrix {\n /** What replaces {z} in the URL (the `TILEMATRIX` of a WMTS; default the index of the matrix in the grid) */\n id?: string | number;\n /** Size of a pixel, CRS units (WMTS: its `ScaleDenominator` × 0.00028 m, in CRS units) */\n resolution: number;\n /** Top-left corner of the tile (0, 0), CRS units (x east, y north) */\n origin: [x: number, y: number];\n /** Size of a tile, pixels (default 256) */\n tileWidth?: number;\n tileHeight?: number;\n /** Tiles across and down (default unbounded) */\n matrixWidth?: number;\n matrixHeight?: number;\n /** The tiles the source has (a WMTS's `TileMatrixLimits`), inclusive: none is asked for outside */\n limits?: [minCol: number, minRow: number, maxCol: number, maxRow: number];\n}\n\n/**\n * A raster's tile grid in a CRS of its own, reprojected into Web Mercator by the map: `matrices` for tiles ({z}, {x},\n * {y} in the URL: matrix, column, row, rows from the north), none for a WMS whose URL has `{bbox}` (the box of each\n * Mercator tile in that CRS: minimum x, minimum y, maximum x, maximum y, asked for at the tile's size)\n */\nexport interface TileGrid {\n /** `'EPSG:2154'`, another built-in or registered name, or an object with `forward` and `inverse` (proj4's) */\n crs: CrsLike;\n /** The levels of the grid, in any order */\n matrices?: TileMatrix[];\n /** Longitudes and latitudes the source covers (west, south, east, north): nothing is asked for outside */\n bounds?: [west: number, south: number, east: number, north: number];\n /** Identifier of the tile matrix set (a WMTS's `TILEMATRIXSET`), for the helpers that write the URL */\n name?: string;\n}\n\n/** Cells of the mesh along each side of a tile */\nconst N = 16;\n/** Source levels finer at most than the pixel size across, where the grid stretches one axis (towards the poles in\n * longitudes and latitudes) */\nconst MAX_BOOST = 3;\n/** Pixels of a mosaic at most: coarser levels beyond, nothing if even the coarsest is larger */\nconst MAX_MOSAIC = 2048 * 2048;\n\ninterface Matrix extends Required<Omit<TileMatrix, 'limits' | 'id'>> {\n id: string | number;\n limits: [number, number, number, number] | undefined;\n}\n\ninterface Resolved {\n crs: Crs;\n /** Coarsest first */\n matrices: Matrix[];\n bounds: [number, number, number, number] | undefined;\n /** The bounds in the CRS: minimum x, minimum y, maximum x, maximum y */\n extent: [number, number, number, number] | undefined;\n}\n\n/** A box of the CRS around points of it (x, y, x, y…), NaN ignored; undefined without any */\nfunction box(points: ArrayLike<number>): [number, number, number, number] | undefined {\n let [x0, y0, x1, y1] = [Infinity, Infinity, -Infinity, -Infinity];\n for (let k = 0; k + 1 < points.length; k += 2) {\n const [x, y] = [points[k] as number, points[k + 1] as number];\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n x0 = Math.min(x0, x);\n y0 = Math.min(y0, y);\n x1 = Math.max(x1, x);\n y1 = Math.max(y1, y);\n }\n return x0 <= x1 ? [x0, y0, x1, y1] : undefined;\n}\n\n/** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */\nexport function resolveGrid(grid: TileGrid): Resolved {\n const crs = getCrs(grid.crs);\n const matrices = (grid.matrices ?? [])\n .map(\n (m, i): Matrix => ({\n id: m.id ?? i,\n resolution: m.resolution,\n origin: m.origin,\n tileWidth: m.tileWidth ?? 256,\n tileHeight: m.tileHeight ?? 256,\n matrixWidth: m.matrixWidth ?? Infinity,\n matrixHeight: m.matrixHeight ?? Infinity,\n limits: m.limits,\n }),\n )\n .sort((a, b) => b.resolution - a.resolution);\n let extent: Resolved['extent'];\n if (grid.bounds) {\n // Its outline and inside, projected: the box of the CRS around them, a little larger (curved edges)\n const [w, s, e, n] = grid.bounds;\n const points: number[] = [];\n for (let i = 0; i <= 8; i += 1) {\n for (let j = 0; j <= 8; j += 1) points.push(...crs.forward([w + ((e - w) * i) / 8, s + ((n - s) * j) / 8]));\n }\n const b = box(points);\n if (b) {\n const margin = 0.01 * Math.max(b[2] - b[0], b[3] - b[1]);\n extent = [b[0] - margin, b[1] - margin, b[2] + margin, b[3] + margin];\n }\n }\n return { crs, matrices, bounds: grid.bounds, extent };\n}\n\n/** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows\n * from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */\nexport function equirectangularGrid(minLevel: number, maxLevel: number): TileGrid {\n const matrices: TileMatrix[] = [];\n for (let level = minLevel; level <= maxLevel; level += 1) {\n const n = 2 ** level;\n matrices.push({ id: level, resolution: 180 / 256 / n, origin: [-180, 90], matrixWidth: 2 * n, matrixHeight: n });\n }\n return { crs: 'EPSG:4326', matrices };\n}\n\n/** A URL of the source: {z}, {x}, {y}, {bbox}, {width} and {height} replaced */\nfunction sourceUrl(template: string, z: string | number, x: number, y: number, bbox: number[], w: number, h: number) {\n return template\n .replaceAll('{z}', String(z))\n .replaceAll('{x}', String(x))\n .replaceAll('{y}', String(y))\n .replaceAll('{bbox}', bbox.join(','))\n .replaceAll('{width}', String(w))\n .replaceAll('{height}', String(h));\n}\n\n/** CRS units per pixel along the mesh's x and y around its middle (NaN where the CRS has nothing there) */\nfunction pixelSize(points: Float64Array, size: number): [number, number] {\n const c = N / 2;\n const at = (i: number, j: number) => 2 * (j * (N + 1) + i);\n const d = (p: number, q: number) =>\n Math.hypot((points[q] as number) - (points[p] as number), (points[q + 1] as number) - (points[p + 1] as number));\n const step = (2 * size) / N;\n return [d(at(c - 1, c), at(c + 1, c)) / step, d(at(c, c - 1), at(c, c + 1)) / step];\n}\n\n/**\n * The box (CRS) of the points a tile samples: the centers of its edge pixels, interpolated in the mesh as `resample`\n * does, and the inner points of the mesh (should the projection bend); within `clip`. Undefined if none is\n */\nfunction sampled(points: Float64Array, size: number, clip: number[]): [number, number, number, number] | undefined {\n const at = (i: number, j: number, k: number) => points[2 * (j * (N + 1) + i) + k] as number;\n const centers: number[] = [];\n for (let j = 1; j < N; j += 1) for (let i = 1; i < N; i += 1) centers.push(at(i, j, 0), at(i, j, 1));\n const cell = size / N;\n const add = (px: number, py: number) => {\n const [fx, fy] = [px / cell, py / cell];\n const [i, j] = [Math.min(N - 1, Math.floor(fx)), Math.min(N - 1, Math.floor(fy))];\n const [tx, ty] = [fx - i, fy - j];\n for (const k of [0, 1]) {\n const top = at(i, j, k) + (at(i + 1, j, k) - at(i, j, k)) * tx;\n const bottom = at(i, j + 1, k) + (at(i + 1, j + 1, k) - at(i, j + 1, k)) * tx;\n centers.push(top + (bottom - top) * ty);\n }\n };\n for (let p = 0.5; p < size; p += 1) {\n add(p, 0.5);\n add(p, size - 0.5);\n add(0.5, p);\n add(size - 0.5, p);\n }\n const b = box(centers);\n if (!b) return undefined;\n const out: [number, number, number, number] = [\n Math.max(b[0], clip[0] as number),\n Math.max(b[1], clip[1] as number),\n Math.min(b[2], clip[2] as number),\n Math.min(b[3], clip[3] as number),\n ];\n return out[0] <= out[2] && out[1] <= out[3] ? out : undefined;\n}\n\n/**\n * The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null\n * where the source has nothing\n */\nexport function planTile(g: Resolved, url: string, z: number, x: number, y: number, size: number): Job | null {\n const tiles = 2 ** z;\n if (g.bounds) {\n const [w, s, e, n] = g.bounds;\n if (longitude((x + 1) / tiles) <= w || longitude(x / tiles) >= e) return null;\n if (latitude(y / tiles) <= s || latitude((y + 1) / tiles) >= n) return null;\n }\n // The mesh in the source CRS\n const points = new Float64Array(2 * (N + 1) ** 2);\n for (let j = 0; j <= N; j += 1) {\n const lat = latitude((y + j / N) / tiles);\n for (let i = 0; i <= N; i += 1) {\n const [px = Number.NaN, py = Number.NaN] = g.crs.forward([longitude((x + i / N) / tiles), lat]);\n points[2 * (j * (N + 1) + i)] = px;\n points[2 * (j * (N + 1) + i) + 1] = py;\n }\n }\n let b = box(points);\n if (!b) return null;\n if (g.extent) {\n const e = g.extent;\n b = [Math.max(b[0], e[0]), Math.max(b[1], e[1]), Math.min(b[2], e[2]), Math.min(b[3], e[3])];\n if (b[0] >= b[2] || b[1] >= b[3]) return null;\n }\n const mesh = new Float32Array(points.length);\n if (g.matrices.length === 0) {\n // One image of the tile's box, a pixel larger on each side\n const [sx, sy] = pixelSize(points, size);\n const m = Number.isFinite(sx + sy) ? Math.max(sx, sy) : 0;\n const [x0, y0, x1, y1] = [b[0] - m, b[1] - m, b[2] + m, b[3] + m];\n for (let k = 0; k < points.length; k += 2) {\n mesh[k] = (((points[k] as number) - x0) / (x1 - x0)) * size;\n mesh[k + 1] = ((y1 - (points[k + 1] as number)) / (y1 - y0)) * size;\n }\n const source = { url: sourceUrl(url, z, x, y, [x0, y0, x1, y1], size, size), x: 0, y: 0, w: size, h: size };\n return { size, width: size, height: size, sources: [source], n: N, mesh };\n }\n // The level of the same pixel size, along the axis the grid stretches least (up to MAX_BOOST levels finer)\n const [sx, sy] = pixelSize(points, size);\n const across = Math.max(sx, sy);\n const target = Number.isFinite(across) ? Math.max(Math.min(sx, sy), across / 2 ** MAX_BOOST) : (b[2] - b[0]) / size;\n // Where the pixels of the tile are sampled: the centers of its edge pixels and the mesh, within the source's extent\n const centers = sampled(points, size, b);\n if (!centers) return null;\n let best = 0;\n g.matrices.forEach((m, i) => {\n const r = g.matrices[best]?.resolution ?? m.resolution;\n if (Math.abs(Math.log2(m.resolution / target)) < Math.abs(Math.log2(r / target))) best = i;\n });\n for (let level = best; level >= 0; level -= 1) {\n const m = g.matrices[level] as Matrix;\n const [ox, oy] = m.origin;\n const [tw, th, res] = [m.tileWidth, m.tileHeight, m.resolution];\n const [l0, r0, l1, r1] = m.limits ?? [0, 0, Infinity, Infinity];\n // The tiles of the source pixels sampled (those of a weight over a thousandth: a tile edge on a source tile edge\n // does not fetch the next source tile for nothing)\n const c0 = Math.max(0, l0, Math.floor(((centers[0] - ox) / res - 0.5 + 1e-3) / tw));\n const c1 = Math.min(m.matrixWidth - 1, l1, Math.floor(((centers[2] - ox) / res + 0.5 - 1e-3) / tw));\n const t0 = Math.max(0, r0, Math.floor(((oy - centers[3]) / res - 0.5 + 1e-3) / th));\n const t1 = Math.min(m.matrixHeight - 1, r1, Math.floor(((oy - centers[1]) / res + 0.5 - 1e-3) / th));\n if (c0 > c1 || t0 > t1) return null;\n const [width, height] = [(c1 - c0 + 1) * tw, (t1 - t0 + 1) * th];\n if (width * height > MAX_MOSAIC) continue;\n const sources: Placed[] = [];\n for (let row = t0; row <= t1; row += 1) {\n for (let col = c0; col <= c1; col += 1) {\n const bbox = [ox + col * tw * res, oy - (row + 1) * th * res, ox + (col + 1) * tw * res, oy - row * th * res];\n const placed = { x: (col - c0) * tw, y: (row - t0) * th, w: tw, h: th };\n sources.push({ url: sourceUrl(url, m.id, col, row, bbox, tw, th), ...placed });\n }\n }\n for (let k = 0; k < points.length; k += 2) {\n mesh[k] = ((points[k] as number) - ox) / res - c0 * tw;\n mesh[k + 1] = (oy - (points[k + 1] as number)) / res - t0 * th;\n }\n return { size, width, height, sources, n: N, mesh };\n }\n return null;\n}\n\n/**\n * The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where\n * the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix\n */\nexport function gridZooms(g: Resolved): { minZoom: number; maxZoom: number } {\n const coarse = g.matrices[0];\n const fine = g.matrices.at(-1);\n if (!coarse || !fine) return { minZoom: 0, maxZoom: 19 };\n let lonLat: readonly number[] = [0, 0];\n if (g.bounds) lonLat = [(g.bounds[0] + g.bounds[2]) / 2, (g.bounds[1] + g.bounds[3]) / 2];\n else {\n const [l0, r0, l1, r1] = coarse.limits ?? [0, 0, coarse.matrixWidth - 1, coarse.matrixHeight - 1];\n const span = coarse.resolution * coarse.tileWidth;\n const [cx, cy] = [(l0 + l1 + 1) / 2, (r0 + r1 + 1) / 2];\n if (Number.isFinite(cx + cy)) lonLat = g.crs.inverse([coarse.origin[0] + cx * span, coarse.origin[1] - cy * span]);\n }\n // CRS units per pixel of a 256 px tile at zoom 0 there\n const [mx, my] = [mercatorX(lonLat[0] ?? 0), mercatorY(lonLat[1] ?? 0)];\n const d = 1e-7;\n const p = g.crs.forward([longitude(mx), latitude(my)]);\n const q = g.crs.forward([longitude(mx + d), latitude(my)]);\n const zero = Math.hypot((q[0] ?? 0) - (p[0] ?? 0), (q[1] ?? 0) - (p[1] ?? 0)) / (d * 256);\n if (!(zero > 0)) return { minZoom: 0, maxZoom: 19 };\n return {\n minZoom: Math.max(0, Math.floor(Math.log2(zero / coarse.resolution)) - 2),\n maxZoom: Math.max(0, Math.round(Math.log2(zero / fine.resolution))),\n };\n}\n\n/** Draws a Mercator tile `z`/`x`/`y`: its image, null where the source has nothing; rejects on errors */\ntype Draw = (z: number, x: number, y: number, signal: AbortSignal) => Promise<ImageBitmap | null>;\n\n/** A planned tile drawn in a worker; undefined when the map has no workers (drawn in the page) */\nexport type RemoteReprojection = (\n job: Job,\n tile: [z: number, x: number, y: number],\n signal: AbortSignal,\n) => Promise<ImageBitmap | null> | undefined;\n\n/**\n * A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:\n * planned here, drawn in a worker of the map through `remote` when it can, else in the page\n */\nexport function gridLoader(url: string, grid: Resolved, size: number, remote?: RemoteReprojection): Draw {\n let local: ReturnType<typeof resampler>['draw'] | undefined;\n return async (z, x, y, signal) => {\n const job = planTile(grid, url, z, x, y, size);\n if (!job) return null;\n const drawn = remote?.(job, [z, x, y], signal);\n if (drawn) return drawn;\n local ??= resampler().draw;\n return local(job, signal);\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export { OPENFREEMAP_ATTRIBUTION, TERRAIN_TILES_ATTRIBUTION } from './basemaps.ts';
|
|
15
15
|
export { AttributionControl, type AttributionOptions, type Control, type ControlPosition, DEFAULT_ATTRIBUTION, NavigationControl, type NavigationOptions, } from './controls.ts';
|
|
16
|
+
export { type Crs, type CrsLike, getCrs, lambertConformalConic, registerCrs, reproject, transverseMercator, } from './crs.ts';
|
|
16
17
|
export type { DecoderUrls } from './decoders.ts';
|
|
17
18
|
export type { ExtrusionOptions, ExtrusionStyle, PolygonArrays, TileKey } from './extrusions.ts';
|
|
18
19
|
export { ExtrusionLayer } from './extrusions.ts';
|
|
@@ -21,14 +22,19 @@ export { CircleLayer, FeatureLayer, FillLayer, interpolate, LineLayer, parseColo
|
|
|
21
22
|
export { geoplateformeWfs, geoplateformeWms, geoplateformeWmts, IGN_ATTRIBUTION } from './geoplateforme.ts';
|
|
22
23
|
export type { TextPart } from './glyphs.ts';
|
|
23
24
|
export { DEFAULT_FONT, GLYPHS_URL } from './glyphs.ts';
|
|
25
|
+
export { parseGpx } from './gpx.ts';
|
|
26
|
+
export type { TileGrid, TileMatrix } from './grid.ts';
|
|
27
|
+
export { parseKml } from './kml.ts';
|
|
24
28
|
export type { GroundOptions, GroundTexture } from './layers.ts';
|
|
25
29
|
export { GroundLayer, Layer, NetworkLayer, RasterLayer, Tiles3dLayer } from './layers.ts';
|
|
26
30
|
export { GeoMap } from './map.ts';
|
|
27
31
|
export { type Anchor, Marker, type MarkerEvent, type MarkerEvents, type MarkerOptions, Popup, type PopupEvents, type PopupOptions, } from './overlay.ts';
|
|
28
32
|
export type { SymbolOptions, SymbolStyle } from './symbols.ts';
|
|
29
33
|
export { SymbolLayer } from './symbols.ts';
|
|
30
|
-
export
|
|
34
|
+
export { parseTopoJson, type TopoGeometry, type Topology } from './topojson.ts';
|
|
35
|
+
export type { AnimationOptions, AtmosphereOptions, Basemap, BasemapName, BodyOptions, CelestialBody, FeatureHit, FlyToOptions, GeoMapOptions, LegacyBasemap, LoadingMode, LonLat, MapEvents, MapHoverFeatureEvent, MapPointerEvent, NetworkOptions, NetworkStyle, Point, Projection, RasterGrid, RasterOptions, RasterStyle, TerrainEncoding, TerrainModel, TerrainOptions, Tiles3dOptions, Tiles3dStyle, } from './types.ts';
|
|
31
36
|
export type { Json, LabelCandidate, RasterSource, Style, StyleLayer } from './vectorstyle.ts';
|
|
32
37
|
export type { VectorTilesOptions } from './vectortiles.ts';
|
|
33
38
|
export { OPENFREEMAP_STYLES, PLAN_STYLES, VectorTiles } from './vectortiles.ts';
|
|
34
39
|
export type { Camera, NetworkStats, PickHit, PickResult, RasterLayerStats, Tiles3dStats } from './wasm/isard.js';
|
|
40
|
+
export { parseWmtsGrid, wmtsGrid } from './wmts.ts';
|
package/dist/index.js
CHANGED
|
@@ -13,13 +13,18 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export { OPENFREEMAP_ATTRIBUTION, TERRAIN_TILES_ATTRIBUTION } from "./basemaps.js";
|
|
15
15
|
export { AttributionControl, DEFAULT_ATTRIBUTION, NavigationControl, } from "./controls.js";
|
|
16
|
+
export { getCrs, lambertConformalConic, registerCrs, reproject, transverseMercator, } from "./crs.js";
|
|
16
17
|
export { ExtrusionLayer } from "./extrusions.js";
|
|
17
18
|
export { CircleLayer, FeatureLayer, FillLayer, interpolate, LineLayer, parseColor } from "./features.js";
|
|
18
19
|
export { geoplateformeWfs, geoplateformeWms, geoplateformeWmts, IGN_ATTRIBUTION } from "./geoplateforme.js";
|
|
19
20
|
export { DEFAULT_FONT, GLYPHS_URL } from "./glyphs.js";
|
|
21
|
+
export { parseGpx } from "./gpx.js";
|
|
22
|
+
export { parseKml } from "./kml.js";
|
|
20
23
|
export { GroundLayer, Layer, NetworkLayer, RasterLayer, Tiles3dLayer } from "./layers.js";
|
|
21
24
|
export { GeoMap } from "./map.js";
|
|
22
25
|
export { Marker, Popup, } from "./overlay.js";
|
|
23
26
|
export { SymbolLayer } from "./symbols.js";
|
|
27
|
+
export { parseTopoJson } from "./topojson.js";
|
|
24
28
|
export { OPENFREEMAP_STYLES, PLAN_STYLES, VectorTiles } from "./vectortiles.js";
|
|
29
|
+
export { parseWmtsGrid, wmtsGrid } from "./wmts.js";
|
|
25
30
|
//# sourceMappingURL=index.js.map
|
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,mBAAmB,EACnB,iBAAiB,GAElB,MAAM,eAAe,CAAC;
|
|
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,mBAAmB,EACnB,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,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE5G,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAEL,MAAM,EAIN,KAAK,GAGN,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAoC,MAAM,eAAe,CAAC;AAgChF,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEhF,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 DEFAULT_ATTRIBUTION,\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 { geoplateformeWfs, geoplateformeWms, geoplateformeWmts, IGN_ATTRIBUTION } 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 { parseKml } from './kml.ts';\nexport type { GroundOptions, GroundTexture } from './layers.ts';\nexport { GroundLayer, Layer, NetworkLayer, RasterLayer, Tiles3dLayer } from './layers.ts';\nexport { GeoMap } from './map.ts';\nexport {\n type Anchor,\n Marker,\n type MarkerEvent,\n type MarkerEvents,\n type MarkerOptions,\n Popup,\n type PopupEvents,\n type PopupOptions,\n} from './overlay.ts';\nexport type { 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 FlyToOptions,\n GeoMapOptions,\n LegacyBasemap,\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 TerrainEncoding,\n TerrainModel,\n TerrainOptions,\n Tiles3dOptions,\n Tiles3dStyle,\n} from './types.ts';\nexport type { Json, LabelCandidate, RasterSource, Style, StyleLayer } from './vectorstyle.ts';\nexport type { VectorTilesOptions } from './vectortiles.ts';\nexport { OPENFREEMAP_STYLES, PLAN_STYLES, VectorTiles } from './vectortiles.ts';\nexport type { Camera, NetworkStats, PickHit, PickResult, RasterLayerStats, Tiles3dStats } from './wasm/isard.js';\nexport { parseWmtsGrid, wmtsGrid } from './wmts.ts';\n"]}
|
package/dist/interaction.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mouse, touch and keyboard controls. Every gesture only updates the camera and asks for a frame: the engine draws at most
|
|
3
|
-
* once per display refresh, whatever the event rate of the device.
|
|
4
|
-
*/
|
|
5
1
|
import type { GeoMap } from './map.ts';
|
|
6
2
|
import type { Point } from './types.ts';
|
|
7
3
|
import type { Camera } from './wasm/isard.js';
|
|
@@ -31,6 +27,9 @@ export declare class Interaction {
|
|
|
31
27
|
/** Recent pan moves, for the release speed: [time, dx, dy] */
|
|
32
28
|
private trail;
|
|
33
29
|
private moved;
|
|
30
|
+
/** The canvas's place on the page, read once: reading it on every pointer move would force a layout each time.
|
|
31
|
+
* Read again after a resize, a scroll, and when a pointer comes in or goes down */
|
|
32
|
+
private rect;
|
|
34
33
|
constructor(map: GeoMap, options?: {
|
|
35
34
|
keyboard?: boolean;
|
|
36
35
|
});
|
package/dist/interaction.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mouse, touch and keyboard controls. Every gesture only updates the camera and asks for a frame: the engine draws at most
|
|
3
|
+
* once per display refresh, whatever the event rate of the device.
|
|
4
|
+
*/
|
|
5
|
+
import { latitude, mercatorX, mercatorY } from "./geo.js";
|
|
1
6
|
/** Zoom levels per wheel pixel (a mouse notch is about 100 px: 1/3 of a level) */
|
|
2
7
|
const WHEEL_RATE = 1 / 300;
|
|
3
8
|
/** Share of the remaining wheel zoom applied per frame (smooth, about 150 ms to settle) */
|
|
@@ -58,11 +63,10 @@ export function keyCamera(action, camera) {
|
|
|
58
63
|
const dx = (sx * Math.cos(b) - sy * Math.sin(b)) / world;
|
|
59
64
|
const dy = (sx * Math.sin(b) + sy * Math.cos(b)) / world;
|
|
60
65
|
const [lon, lat] = camera.center;
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const y = Math.max(0, Math.min(1, (1 - Math.log(Math.tan(phi) + 1 / Math.cos(phi)) / Math.PI) / 2 + dy));
|
|
66
|
+
const x = mercatorX(lon) + dx;
|
|
67
|
+
const y = Math.max(0, Math.min(1, mercatorY(lat) + dy));
|
|
64
68
|
const wrapped = ((((x * 360) % 360) + 360) % 360) - 180;
|
|
65
|
-
return { center: [wrapped, (
|
|
69
|
+
return { center: [wrapped, latitude(y)] };
|
|
66
70
|
}
|
|
67
71
|
/** An element that takes the keys typed in it */
|
|
68
72
|
function editable(target) {
|
|
@@ -78,6 +82,9 @@ export class Interaction {
|
|
|
78
82
|
/** Recent pan moves, for the release speed: [time, dx, dy] */
|
|
79
83
|
trail = [];
|
|
80
84
|
moved = false;
|
|
85
|
+
/** The canvas's place on the page, read once: reading it on every pointer move would force a layout each time.
|
|
86
|
+
* Read again after a resize, a scroll, and when a pointer comes in or goes down */
|
|
87
|
+
rect;
|
|
81
88
|
constructor(map, options = {}) {
|
|
82
89
|
this.map = map;
|
|
83
90
|
const canvas = map.canvas;
|
|
@@ -85,7 +92,20 @@ export class Interaction {
|
|
|
85
92
|
canvas.addEventListener(type, handler, options);
|
|
86
93
|
this.cleanup.push(() => canvas.removeEventListener(type, handler));
|
|
87
94
|
};
|
|
88
|
-
|
|
95
|
+
const moved = () => {
|
|
96
|
+
this.rect = undefined;
|
|
97
|
+
};
|
|
98
|
+
listen('pointerenter', moved);
|
|
99
|
+
// Scrolls of the page or of any element holding the map
|
|
100
|
+
if (typeof addEventListener === 'function') {
|
|
101
|
+
addEventListener('scroll', moved, { capture: true, passive: true });
|
|
102
|
+
this.cleanup.push(() => removeEventListener('scroll', moved, { capture: true }));
|
|
103
|
+
}
|
|
104
|
+
this.cleanup.push(map.on('resize', moved));
|
|
105
|
+
listen('pointerdown', (e) => {
|
|
106
|
+
this.rect = undefined;
|
|
107
|
+
this.down(e);
|
|
108
|
+
});
|
|
89
109
|
listen('pointermove', (e) => this.move(e));
|
|
90
110
|
listen('pointerup', (e) => this.up(e));
|
|
91
111
|
listen('pointercancel', (e) => this.up(e));
|
|
@@ -118,8 +138,8 @@ export class Interaction {
|
|
|
118
138
|
return this.pointers.size > 0;
|
|
119
139
|
}
|
|
120
140
|
local(e) {
|
|
121
|
-
|
|
122
|
-
return [e.clientX -
|
|
141
|
+
this.rect ??= this.map.canvas.getBoundingClientRect();
|
|
142
|
+
return [e.clientX - this.rect.left, e.clientY - this.rect.top];
|
|
123
143
|
}
|
|
124
144
|
down(e) {
|
|
125
145
|
this.map.canvas.setPointerCapture(e.pointerId);
|