@reearth/ezu 0.12.0 → 0.13.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/README.md +150 -3
- package/bundler/ezu.d.ts +517 -7
- package/bundler/ezu.js +1 -1
- package/bundler/ezu_bg.js +890 -11
- package/bundler/ezu_bg.wasm +0 -0
- package/bundler/ezu_bg.wasm.d.ts +38 -3
- package/nodejs/ezu.d.ts +517 -7
- package/nodejs/ezu.js +896 -11
- package/nodejs/ezu_bg.wasm +0 -0
- package/nodejs/ezu_bg.wasm.d.ts +38 -3
- package/package.json +1 -1
- package/simd/bundler/ezu.d.ts +517 -7
- package/simd/bundler/ezu.js +1 -1
- package/simd/bundler/ezu_bg.js +890 -11
- package/simd/bundler/ezu_bg.wasm +0 -0
- package/simd/bundler/ezu_bg.wasm.d.ts +38 -3
- package/simd/nodejs/ezu.d.ts +517 -7
- package/simd/nodejs/ezu.js +896 -11
- package/simd/nodejs/ezu_bg.wasm +0 -0
- package/simd/nodejs/ezu_bg.wasm.d.ts +38 -3
- package/simd/web/ezu.d.ts +555 -10
- package/simd/web/ezu.js +890 -11
- package/simd/web/ezu_bg.wasm +0 -0
- package/simd/web/ezu_bg.wasm.d.ts +38 -3
- package/simd/workerd/ezu.js +1 -1
- package/web/ezu.d.ts +555 -10
- package/web/ezu.js +890 -11
- package/web/ezu_bg.wasm +0 -0
- package/web/ezu_bg.wasm.d.ts +38 -3
- package/workerd/ezu.js +1 -1
package/README.md
CHANGED
|
@@ -103,12 +103,17 @@ bytes a browser may download, so for now the choice is explicit.
|
|
|
103
103
|
|
|
104
104
|
```ts
|
|
105
105
|
function simdEnabled(): boolean;
|
|
106
|
+
// How many node ops the module registered, and their names.
|
|
107
|
+
function opCount(): number;
|
|
108
|
+
function opNames(): string[];
|
|
106
109
|
|
|
107
110
|
class Renderer {
|
|
108
111
|
constructor(styleJson: string);
|
|
109
112
|
|
|
110
113
|
setStyle(styleJson: string): number; // → new node count
|
|
111
114
|
readonly tileSize: number;
|
|
115
|
+
readonly renderTileSize: number; // what renders use: setTileSize's, or tileSize
|
|
116
|
+
readonly warnings: string[]; // what building the style's graph warned about
|
|
112
117
|
|
|
113
118
|
// Bind tile bytes under a `sources.<name>` entry from the style.
|
|
114
119
|
// The renderer dispatches on the source's declared `type`:
|
|
@@ -136,16 +141,25 @@ class Renderer {
|
|
|
136
141
|
indexUrl?: string; // a sprite index that is a URL, not inline
|
|
137
142
|
}>;
|
|
138
143
|
|
|
139
|
-
// Cap the resident glyph bytes per fontstack.
|
|
140
|
-
// (
|
|
144
|
+
// Cap the resident glyph bytes per fontstack. clearGlyphBudget() lifts
|
|
145
|
+
// the cap, as does 0xFFFFFFFF (it reads back as `Infinity` from
|
|
146
|
+
// `memoryUsage().glyphBudget`).
|
|
141
147
|
setGlyphBudget(bytes: number): void;
|
|
148
|
+
clearGlyphBudget(): void;
|
|
149
|
+
|
|
150
|
+
// Let the render cache hold `bytes` of pixels instead of its default
|
|
151
|
+
// (8 MiB); clearCacheBudget() goes back. Kept through setStyle.
|
|
152
|
+
setCacheBudget(bytes: number): void;
|
|
153
|
+
clearCacheBudget(): void;
|
|
142
154
|
|
|
143
155
|
// Single unified render. `opts.format` picks the encoder; `tileSize`
|
|
144
|
-
// / `pad` override the canvas
|
|
156
|
+
// / `pad` override the canvas (in style pixels); `pixelRatio` renders
|
|
157
|
+
// the same tile at a higher density for hi-DPI screens.
|
|
145
158
|
renderTile(z: number, x: number, y: number, opts?: {
|
|
146
159
|
format?: "png" | "webp" | "rgba"; // default "png"
|
|
147
160
|
tileSize?: number;
|
|
148
161
|
pad?: number;
|
|
162
|
+
pixelRatio?: number; // 1 to 4, default 1
|
|
149
163
|
// Render-time overrides for the style's declared `params`, validated
|
|
150
164
|
// against the declarations (type, min/max) — an unknown name or an
|
|
151
165
|
// out-of-range value throws. Names left out keep their default. One
|
|
@@ -154,10 +168,141 @@ class Renderer {
|
|
|
154
168
|
png?: { compression?: "fast" | "default" | "best" };
|
|
155
169
|
}): Uint8Array;
|
|
156
170
|
|
|
171
|
+
// Decode a tile-scoped payload (mvt, pmtiles, dem, raster, remote
|
|
172
|
+
// geojson) once, to sit in the set of every render that reads it.
|
|
173
|
+
loadSource(name: string, bytes: Uint8Array): SourceData;
|
|
174
|
+
|
|
175
|
+
// renderTile, from a set of loaded data instead of what is bound. Does
|
|
176
|
+
// not trim glyphs to the budget; call trimGlyphs() after a batch.
|
|
177
|
+
renderTileWith(z: number, x: number, y: number, set: SourceSet,
|
|
178
|
+
opts?: object /* renderTile's opts */): Uint8Array;
|
|
179
|
+
|
|
180
|
+
// renderTileWith, also handing back what the named features nodes held:
|
|
181
|
+
// one { node, extent, geojson } per node, geojson being a GeoJSON
|
|
182
|
+
// FeatureCollection as text in tile units (0..extent). Pass
|
|
183
|
+
// { nodes, coords: "lonlat" | "px" } for WGS84 or the tile's pixels.
|
|
184
|
+
renderTileWithFeatures(z: number, x: number, y: number, set: SourceSet,
|
|
185
|
+
nodes: string[] | { nodes: string[];
|
|
186
|
+
coords?: "tile" | "lonlat" | "px" },
|
|
187
|
+
opts?: object): TileWithFeatures;
|
|
188
|
+
|
|
189
|
+
// neededCodepoints / neededGlyphRanges for the features in a set.
|
|
190
|
+
neededCodepointsIn(set: SourceSet): Record<string, number[]>;
|
|
191
|
+
neededGlyphRangesIn(set: SourceSet): Record<string, number[]>;
|
|
192
|
+
|
|
193
|
+
// Bring the glyph banks back under setGlyphBudget's budget.
|
|
194
|
+
trimGlyphs(): void;
|
|
195
|
+
|
|
196
|
+
// Render every tile at `size` px instead of the style's tile-size,
|
|
197
|
+
// without editing the style, until `clearTileSize()` or `setStyle`.
|
|
198
|
+
setTileSize(size: number): void;
|
|
199
|
+
clearTileSize(): void;
|
|
200
|
+
|
|
201
|
+
// Print frames — see "A page at a print scale" below.
|
|
202
|
+
computeFrame(req: FrameRequest): Frame;
|
|
203
|
+
renderFrame(
|
|
204
|
+
frame: Frame,
|
|
205
|
+
sources: ((tile: { z: number; x: number; y: number },
|
|
206
|
+
binder: FrameBinder) => SourceSet | Promise<SourceSet>)
|
|
207
|
+
| null | undefined,
|
|
208
|
+
opts?: { pad?: number; params?: Record<string, number | boolean | string> },
|
|
209
|
+
): Promise<Uint8Array>; // straight RGBA, width × height
|
|
210
|
+
// renderFrame, also gathering features nodes over the page: each node's
|
|
211
|
+
// page as the GeoJSON text `ezu frame --features` writes.
|
|
212
|
+
renderFrameWithFeatures(
|
|
213
|
+
frame: Frame, sources: /* as renderFrame */ any,
|
|
214
|
+
request: { nodes: { node: string; key?: string[] }[];
|
|
215
|
+
coords?: "lonlat" | "px" },
|
|
216
|
+
opts?: { pad?: number; params?: Record<string, number | boolean | string> },
|
|
217
|
+
): Promise<{ image: Uint8Array; features: { node: string; geojson: string }[] }>;
|
|
218
|
+
|
|
219
|
+
free(): void;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// One decoded tile. Sets that hold it keep it alive.
|
|
223
|
+
class SourceData {
|
|
224
|
+
readonly source: string; // the sources.<name> it is for
|
|
157
225
|
free(): void;
|
|
158
226
|
}
|
|
227
|
+
|
|
228
|
+
// The tile data one render reads, each at its place in the 3×3.
|
|
229
|
+
class SourceSet {
|
|
230
|
+
constructor();
|
|
231
|
+
bind(data: SourceData,
|
|
232
|
+
opts?: { coord?: [number, number]; sourceZoom?: number }): void;
|
|
233
|
+
contains(source: string): boolean;
|
|
234
|
+
isEmpty(): boolean;
|
|
235
|
+
clone(): SourceSet; // shares the data
|
|
236
|
+
free(): void;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Handed to renderFrame's sources: bindSource into the renderer (glyphs,
|
|
240
|
+
// fonts, sprites — not tile data, which goes in the set) for that tile
|
|
241
|
+
// only, until its sources returns or settles (then it throws StaleBinder).
|
|
242
|
+
class FrameBinder {
|
|
243
|
+
bindSource(name: string, bytes: Uint8Array,
|
|
244
|
+
opts?: { coord?: [number, number]; sourceZoom?: number }): void;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface FrameRequest {
|
|
248
|
+
centerLon: number; centerLat: number; // degrees, WGS84
|
|
249
|
+
scale: number; // 1000 for 1:1000
|
|
250
|
+
dpi: number;
|
|
251
|
+
width: number; height: number; // output pixels
|
|
252
|
+
zoom?: number; // the CLI's --zoom
|
|
253
|
+
styleTileSize?: number; // default: the style's
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
interface Frame {
|
|
257
|
+
zoom: number; tileSize: number; // what the tiles render at
|
|
258
|
+
scale: number; // the denominator met
|
|
259
|
+
width: number; height: number;
|
|
260
|
+
left: number; top: number; // corner, in world pixels
|
|
261
|
+
shift: [number, number]; // rounding, within ±0.5 px
|
|
262
|
+
tilesX: [number, number]; // start inclusive, end exclusive
|
|
263
|
+
tilesY: [number, number];
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## A page at a print scale
|
|
268
|
+
|
|
269
|
+
A printed page is asked for as "1:1000 at 200 dpi, 245 × 174 mm, centred
|
|
270
|
+
here", not as a zoom. `computeFrame` picks the zoom and tile size that
|
|
271
|
+
meet the scale and the tiles the page covers; `renderFrame` renders them,
|
|
272
|
+
calling you back for the `SourceSet` each one renders from, and crops them
|
|
273
|
+
into one RGBA page — the same page `ezu frame` writes, pixel for pixel:
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
const mm = (length, dpi) => Math.round(length / 25.4 * dpi);
|
|
277
|
+
const f = renderer.computeFrame({
|
|
278
|
+
centerLon: 139.70, centerLat: 35.68,
|
|
279
|
+
scale: 1000, dpi: 200,
|
|
280
|
+
width: mm(245, 200), height: mm(174, 200), // 1929 × 1370
|
|
281
|
+
});
|
|
282
|
+
const loaded = new Map(); // each fetched tile, decoded once
|
|
283
|
+
const rgba = await renderer.renderFrame(f, async ({ z, x, y }, binder) => {
|
|
284
|
+
const key = `${z}/${x}/${y}`;
|
|
285
|
+
if (!loaded.has(key)) {
|
|
286
|
+
loaded.set(key, renderer.loadSource("basemap", await fetchMvt(z, x, y)));
|
|
287
|
+
}
|
|
288
|
+
const set = new SourceSet();
|
|
289
|
+
set.bind(loaded.get(key)); // and the neighbours, at their coord
|
|
290
|
+
return set;
|
|
291
|
+
});
|
|
159
292
|
```
|
|
160
293
|
|
|
294
|
+
A page's tiles border each other, so a `SourceData` kept for the tiles
|
|
295
|
+
around it is decoded once however many of them read it. Until the promise
|
|
296
|
+
settles the renderer is the frame's: glyphs a set needs are bound through
|
|
297
|
+
the `binder` you are handed, which works only for its own tile and only
|
|
298
|
+
until that call returns or settles. Calls that would change the renderer —
|
|
299
|
+
`bindSource`, `clearSources`, `renderTile`, `trimGlyphs`, another
|
|
300
|
+
`renderFrame`, `setStyle`, `setTileSize`, `clearTileSize`,
|
|
301
|
+
`setGlyphBudget`, `clearGlyphBudget` — throw `FrameInProgress` meanwhile, so another request
|
|
302
|
+
cannot change the frame's tiles under it. `loadSource`, `renderTileWith`
|
|
303
|
+
and queries that only read, such as `sourceTile` and `neededCodepointsIn`,
|
|
304
|
+
still work.
|
|
305
|
+
|
|
161
306
|
## Output formats
|
|
162
307
|
|
|
163
308
|
- **`format: "png"`** (default) returns PNG bytes — feed to `<img>`
|
|
@@ -195,6 +340,8 @@ discriminates the kind:
|
|
|
195
340
|
| `RenderFailed` | A node `eval` failed (e.g. missing brush, downcast mismatch) |
|
|
196
341
|
| `PngEncode` | PNG encoding failed |
|
|
197
342
|
| `WebpEncode` | WebP encoding failed |
|
|
343
|
+
| `FrameInProgress` | A call would change a renderer that a `renderFrame` holds until its promise settles |
|
|
344
|
+
| `StaleBinder` | A frame's `binder` was used after its tile's `sources` returned or settled |
|
|
198
345
|
|
|
199
346
|
```js
|
|
200
347
|
try {
|