@versatiles/versatiles-rs 4.8.0 → 4.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/versatiles-rs",
3
- "version": "4.8.0",
3
+ "version": "4.9.0",
4
4
  "description": "Node.js bindings for VersaTiles - convert, serve, and process map tiles",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -102,14 +102,14 @@
102
102
  "vitest": "^4.1.10"
103
103
  },
104
104
  "optionalDependencies": {
105
- "@versatiles/versatiles-rs-darwin-arm64": "4.8.0",
106
- "@versatiles/versatiles-rs-darwin-x64": "4.8.0",
107
- "@versatiles/versatiles-rs-linux-arm64-gnu": "4.8.0",
108
- "@versatiles/versatiles-rs-linux-arm64-musl": "4.8.0",
109
- "@versatiles/versatiles-rs-linux-x64-gnu": "4.8.0",
110
- "@versatiles/versatiles-rs-linux-x64-musl": "4.8.0",
111
- "@versatiles/versatiles-rs-win32-arm64-msvc": "4.8.0",
112
- "@versatiles/versatiles-rs-win32-x64-msvc": "4.8.0"
105
+ "@versatiles/versatiles-rs-darwin-arm64": "4.9.0",
106
+ "@versatiles/versatiles-rs-darwin-x64": "4.9.0",
107
+ "@versatiles/versatiles-rs-linux-arm64-gnu": "4.9.0",
108
+ "@versatiles/versatiles-rs-linux-arm64-musl": "4.9.0",
109
+ "@versatiles/versatiles-rs-linux-x64-gnu": "4.9.0",
110
+ "@versatiles/versatiles-rs-linux-x64-musl": "4.9.0",
111
+ "@versatiles/versatiles-rs-win32-arm64-msvc": "4.9.0",
112
+ "@versatiles/versatiles-rs-win32-x64-msvc": "4.9.0"
113
113
  },
114
114
  "allowScripts": {
115
115
  "esbuild": true,
package/vpl.d.ts CHANGED
@@ -109,8 +109,10 @@ export interface FromColorOptions {
109
109
  format?: "avif" | "bin" | "geojson" | "jpg" | "json" | "mvt" | "png" | "svg" | "topojson" | "webp";
110
110
  }
111
111
  export interface FromContainerOptions {
112
- /** The filename of the tile container (relative to the VPL file path), or a URL (http/https). For example: `filename="world.versatiles"` or `filename="https://example.com/world.versatiles"`. */
112
+ /** The filename of the tile container (relative to the VPL file path), or a URL (`http`, `https`, or `sftp`). For example: `filename="world.versatiles"` or `filename="https://example.com/world.versatiles"`. See `versatiles help source` for URL and authentication details. */
113
113
  filename: string;
114
+ /** The private key file to authenticate this `sftp://` source with, for example `ssh_identity="/home/deploy/.ssh/id_ed25519"`. A relative path resolves against the VPL file, like `filename`. It applies to this source alone and overrides `--ssh-identity` and `VERSATILES_SSH_IDENTITY`, which apply to every source — so one pipeline can read from two SFTP hosts that need different keys. Ignored for other schemes. Note that naming a key makes the VPL file specific to machines that have it. */
115
+ sshIdentity?: string;
114
116
  }
115
117
  export interface FromCsvOptions {
116
118
  /** Filename of the CSV file (relative to the VPL file path). */
@@ -184,6 +186,48 @@ export interface FromGeoOptions {
184
186
  /** If `true`, drop the GeoJSON / Shapefile `id` field from every feature before encoding. Useful for sources where the id is a string (e.g. USGS earthquakes — those would be silently dropped at MVT encode anyway, since MVT requires `uint64` ids), or when the id is just noise. Defaults to `false` — keep the id when it's a non-negative integer. */
185
187
  ignoreId?: boolean;
186
188
  }
189
+ export interface FromGridOptions {
190
+ /** EPSG code of the grid's coordinate reference system. Without GDAL: `3035` (ETRS89-LAEA, what European gridded statistics use), `3857` (web mercator) and `4326` (WGS84 lon/lat). */
191
+ epsg: number;
192
+ /** Edge length of a cell, in the CRS's own units — meters for a projected CRS, degrees for `epsg=4326`. For example: `size=1000` for the 1 km grid Eurostat publishes. */
193
+ size: number;
194
+ /** The area to cover, as `[west, south, east, north]` in WGS84 degrees. Required: an unbounded grid has no pyramid to derive, and at most cell sizes it is more tiles than can be written. */
195
+ bbox: [number, number, number, number];
196
+ /** Where the cell with index `(0, 0)` has its lower-left corner, in CRS units. Default: `[0,0]`, which is what published grids align to. */
197
+ offset?: unknown;
198
+ /** Roughly how many cells one tile may hold. Decides the lowest zoom level this source offers. Default: `1024`. */
199
+ maxCellsPerTile?: number;
200
+ /** Highest zoom level to generate. Defaults to three levels above the derived minimum, since further levels repeat the same cells. */
201
+ maxZoom?: number;
202
+ /** Ready-made id format. Either `"inspire"` (default), which produces `CRS3035RES1000mN2691000E4341000`, or `"geostat"`, which produces `1kmN2689E4337`. */
203
+ idPreset?: string;
204
+ /** Id format spelled out, for a grid whose publisher uses neither preset. `{x}` and `{y}` are the lower-left corner, each taking an optional divisor and zero-padded width: `E{x/100:04}N{y/100:04}` produces `E0643N4567`, the form Dutch grid statistics use. Overrides `id_preset`. */
205
+ idTemplate?: string;
206
+ /** Name of the string property holding the cell id. Default: `"id"`. */
207
+ idField?: string;
208
+ /** Names of the number properties holding the lower-left corner. Defaults: `"x"` and `"y"`, mirroring the `X_LLC` / `Y_LLC` columns Eurostat ships beside its ids. */
209
+ xField?: string;
210
+ /** See `x_field`. */
211
+ yField?: string;
212
+ /** How far a cell edge may stray from its true curve, in tile pixels. Only matters for a CRS whose straight lines bend in mercator; in `3857` and `4326` no vertices are added whatever this says. Default: `0.5`. */
213
+ densifyTolerance?: number;
214
+ /** Name of the layer in the generated tiles. Default: `"grid"`. */
215
+ layerName?: string;
216
+ }
217
+ export interface FromH3Options {
218
+ /** H3 resolution, `0` (cells of ~4,250,000 km²) to `15` (~0.9 m²). For example: `resolution=8` for cells of roughly 0.7 km². See <https://h3geo.org/docs/core-library/restable/> for the full table. */
219
+ resolution: number;
220
+ /** The area to cover, as `[west, south, east, north]` in WGS84 degrees. For example: `bbox=[13.0,52.3,13.8,52.7]` for Berlin. Required: a grid without bounds would be generated for the whole planet, which at most resolutions is more tiles than can be written. */
221
+ bbox: [number, number, number, number];
222
+ /** Roughly how many cells one tile may hold. Decides the lowest zoom level this source offers: below it a single tile would carry more cells than a tile can usefully hold. Default: `1024`. */
223
+ maxCellsPerTile?: number;
224
+ /** Highest zoom level to generate. Defaults to three levels above the derived minimum, since further levels repeat the same cells. */
225
+ maxZoom?: number;
226
+ /** Name of the layer in the generated tiles. Default: `"grid"`. */
227
+ layerName?: string;
228
+ /** Name of the string property holding the H3 index, e.g. `"8928308280fffff"`. Default: `"h3"`, matching how H3 datasets usually name the column. */
229
+ idField?: string;
230
+ }
187
231
  export interface FromStackedRasterOptions {
188
232
  /** The tile format to use for the output tiles. Default: format of the first source. */
189
233
  format?: "avif" | "bin" | "geojson" | "jpg" | "json" | "mvt" | "png" | "svg" | "topojson" | "webp";
@@ -205,6 +249,8 @@ export interface FromTilejsonOptions {
205
249
  export interface FilterOptions {
206
250
  /** Bounding box in WGS84: [min lng, min lat, max lng, max lat]. */
207
251
  bbox?: [number, number, number, number];
252
+ /** Ring of extra tiles to keep around `bbox`, in tiles per zoom level. Note that this is the one parameter here that *widens*: every other parameter narrows the tile set, but `bbox_border=2` keeps tiles the bbox alone would have dropped. Those tiles lie outside the crop, so the advertised bounds are extended to cover them and a client actually requests them. This matters wherever a cropped tileset is rendered rather than just stored: without a border, labels and geometry near the edge have no neighbouring tiles to be laid out against. Requires `bbox`; setting it alone is an error rather than a no-op. */
253
+ bboxBorder?: number;
208
254
  /** minimal zoom level */
209
255
  levelMin?: number;
210
256
  /** maximal zoom level */
@@ -242,6 +288,14 @@ export interface MetaUpdateOptions {
242
288
  /** Path to a file containing the `vector_layers` array as JSON, resolved relative to the VPL file. Use instead of `vector_layers`. Mutually exclusive with `vector_layers`. */
243
289
  vectorLayersFile?: string;
244
290
  }
291
+ export interface RemapCoordsOptions {
292
+ /** Mirror horizontally within each zoom level: `x` becomes `2^z - 1 - x`. No tile scheme uses this on its own; it is what makes the rotations reachable. Defaults to `false`. */
293
+ flipX?: boolean;
294
+ /** Mirror vertically within each zoom level: `y` becomes `2^z - 1 - y`. This is the TMS ↔ XYZ correction. Defaults to `false`. */
295
+ flipY?: boolean;
296
+ /** Exchange the axes: `(x, y)` becomes `(y, x)`, for sources laid out as `z/y/x`. Applied after the flips. Defaults to `false`. */
297
+ swapXy?: boolean;
298
+ }
245
299
  export interface DemOverviewOptions {
246
300
  /** Use this zoom level to build the overview. Defaults to the maximum zoom level of the source. */
247
301
  level?: number;
@@ -375,7 +429,11 @@ export declare class VPL {
375
429
  static fromDebug(options?: FromDebugOptions): VPL;
376
430
  /** Reads a GeoJSON or Shapefile and emits MVT vector tiles. */
377
431
  static fromGeo(options: FromGeoOptions): VPL;
378
- /** Merges multiple vector tile sources. */
432
+ /** Generates vector tiles containing the cells of a projected square grid, ready to be joined with data keyed on the cell id. */
433
+ static fromGrid(options: FromGridOptions): VPL;
434
+ /** Generates vector tiles containing H3 grid cells, ready to be joined with data keyed on the H3 index. */
435
+ static fromH3(options: FromH3Options): VPL;
436
+ /** Merges multiple vector tile sources. Each resulting tile will contain all the features and properties from all the sources. */
379
437
  static fromMergedVector(sources: VPL[]): VPL;
380
438
  /** Overlays multiple raster tile sources on top of each other. */
381
439
  static fromStackedRaster(sources: VPL[], options?: Omit<FromStackedRasterOptions, 'sources'>): VPL;
@@ -383,12 +441,14 @@ export declare class VPL {
383
441
  static fromStacked(sources: VPL[]): VPL;
384
442
  /** Reads a single tile file and uses it as a template for all tile requests. */
385
443
  static fromTile(options: FromTileOptions): VPL;
386
- /** Reads tiles from a remote tile server via a TileJSON endpoint. */
444
+ /** Reads tiles from a remote tile server via a TileJSON endpoint. The TileJSON is fetched from the given URL, and tiles are loaded individually using the URL template from the TileJSON `tiles` array. */
387
445
  static fromTilejson(options: FromTilejsonOptions): VPL;
388
446
  /** Filter tiles by bounding box, zoom levels, and/or the tile coordinates present in another container. */
389
447
  filter(options?: FilterOptions): VPL;
390
448
  /** Update metadata, see also <https://github.com/mapbox/tilejson-spec/tree/master/3.0.0> */
391
449
  metaUpdate(options?: MetaUpdateOptions): VPL;
450
+ /** Relabels tile coordinates, e.g. to correct a source that uses TMS row order or `z/y/x` paths. */
451
+ remapCoords(options?: RemapCoordsOptions): VPL;
392
452
  /** Generate lower-zoom DEM overview tiles by averaging 24-bit elevation values. */
393
453
  demOverview(options?: DemOverviewOptions): VPL;
394
454
  /** Quantize DEM (elevation) raster tiles by rounding to a per-tile power-of-two step. */
@@ -401,7 +461,7 @@ export declare class VPL {
401
461
  rasterFormat(options?: RasterFormatOptions): VPL;
402
462
  /** Adjust brightness, contrast and gamma of raster tiles. */
403
463
  rasterLevels(options?: RasterLevelsOptions): VPL;
404
- /** Apply a polygon mask from GeoJSON to raster tiles. */
464
+ /** Apply a polygon mask from GeoJSON to raster tiles. Pixels outside the polygon become transparent. */
405
465
  rasterMask(options: RasterMaskOptions): VPL;
406
466
  /** Raster overscale operation - generates tiles beyond the source's native resolution. */
407
467
  rasterOverscale(options?: RasterOverscaleOptions): VPL;
@@ -409,7 +469,7 @@ export declare class VPL {
409
469
  rasterOverview(options?: RasterOverviewOptions): VPL;
410
470
  /** Convert the size of tiles by splitting or merging them to a width of 256px or 512px. */
411
471
  rasterTileResize(options?: RasterTileResizeOptions): VPL;
412
- /** Drops vector features in selected layers that do not satisfy a boolean CEL expression. */
472
+ /** Drops vector features in selected layers that do not satisfy a boolean CEL expression. Features in layers outside `layer` pass through untouched. */
413
473
  vectorFilterFeatures(options: VectorFilterFeaturesOptions): VPL;
414
474
  /** Filters vector tile layers by name. */
415
475
  vectorFilterLayers(options: VectorFilterLayersOptions): VPL;
package/vpl.js CHANGED
@@ -39,6 +39,8 @@ export class VPL {
39
39
  static fromContainer(options) {
40
40
  const params = {};
41
41
  params['filename'] = options.filename;
42
+ if (options.sshIdentity !== undefined)
43
+ params['ssh_identity'] = options.sshIdentity;
42
44
  return new VPL([{ name: 'from_container', params }]);
43
45
  }
44
46
  /** Reads a CSV file with longitude/latitude columns and emits MVT point tiles. */
@@ -118,7 +120,50 @@ export class VPL {
118
120
  params['ignore_id'] = options.ignoreId;
119
121
  return new VPL([{ name: 'from_geo', params }]);
120
122
  }
121
- /** Merges multiple vector tile sources. */
123
+ /** Generates vector tiles containing the cells of a projected square grid, ready to be joined with data keyed on the cell id. */
124
+ static fromGrid(options) {
125
+ const params = {};
126
+ params['epsg'] = options.epsg;
127
+ params['size'] = options.size;
128
+ params['bbox'] = options.bbox;
129
+ if (options.offset !== undefined)
130
+ params['offset'] = options.offset;
131
+ if (options.maxCellsPerTile !== undefined)
132
+ params['max_cells_per_tile'] = options.maxCellsPerTile;
133
+ if (options.maxZoom !== undefined)
134
+ params['max_zoom'] = options.maxZoom;
135
+ if (options.idPreset !== undefined)
136
+ params['id_preset'] = options.idPreset;
137
+ if (options.idTemplate !== undefined)
138
+ params['id_template'] = options.idTemplate;
139
+ if (options.idField !== undefined)
140
+ params['id_field'] = options.idField;
141
+ if (options.xField !== undefined)
142
+ params['x_field'] = options.xField;
143
+ if (options.yField !== undefined)
144
+ params['y_field'] = options.yField;
145
+ if (options.densifyTolerance !== undefined)
146
+ params['densify_tolerance'] = options.densifyTolerance;
147
+ if (options.layerName !== undefined)
148
+ params['layer_name'] = options.layerName;
149
+ return new VPL([{ name: 'from_grid', params }]);
150
+ }
151
+ /** Generates vector tiles containing H3 grid cells, ready to be joined with data keyed on the H3 index. */
152
+ static fromH3(options) {
153
+ const params = {};
154
+ params['resolution'] = options.resolution;
155
+ params['bbox'] = options.bbox;
156
+ if (options.maxCellsPerTile !== undefined)
157
+ params['max_cells_per_tile'] = options.maxCellsPerTile;
158
+ if (options.maxZoom !== undefined)
159
+ params['max_zoom'] = options.maxZoom;
160
+ if (options.layerName !== undefined)
161
+ params['layer_name'] = options.layerName;
162
+ if (options.idField !== undefined)
163
+ params['id_field'] = options.idField;
164
+ return new VPL([{ name: 'from_h3', params }]);
165
+ }
166
+ /** Merges multiple vector tile sources. Each resulting tile will contain all the features and properties from all the sources. */
122
167
  static fromMergedVector(sources) {
123
168
  const params = {};
124
169
  return new VPL([{ name: 'from_merged_vector', params, sources }]);
@@ -143,7 +188,7 @@ export class VPL {
143
188
  params['filename'] = options.filename;
144
189
  return new VPL([{ name: 'from_tile', params }]);
145
190
  }
146
- /** Reads tiles from a remote tile server via a TileJSON endpoint. */
191
+ /** Reads tiles from a remote tile server via a TileJSON endpoint. The TileJSON is fetched from the given URL, and tiles are loaded individually using the URL template from the TileJSON `tiles` array. */
147
192
  static fromTilejson(options) {
148
193
  const params = {};
149
194
  params['url'] = options.url;
@@ -158,6 +203,8 @@ export class VPL {
158
203
  const params = {};
159
204
  if (options?.bbox !== undefined)
160
205
  params['bbox'] = options?.bbox;
206
+ if (options?.bboxBorder !== undefined)
207
+ params['bbox_border'] = options?.bboxBorder;
161
208
  if (options?.levelMin !== undefined)
162
209
  params['level_min'] = options?.levelMin;
163
210
  if (options?.levelMax !== undefined)
@@ -199,6 +246,17 @@ export class VPL {
199
246
  params['vector_layers_file'] = options?.vectorLayersFile;
200
247
  return new VPL([...this.steps, { name: 'meta_update', params }]);
201
248
  }
249
+ /** Relabels tile coordinates, e.g. to correct a source that uses TMS row order or `z/y/x` paths. */
250
+ remapCoords(options) {
251
+ const params = {};
252
+ if (options?.flipX !== undefined)
253
+ params['flip_x'] = options?.flipX;
254
+ if (options?.flipY !== undefined)
255
+ params['flip_y'] = options?.flipY;
256
+ if (options?.swapXy !== undefined)
257
+ params['swap_xy'] = options?.swapXy;
258
+ return new VPL([...this.steps, { name: 'remap_coords', params }]);
259
+ }
202
260
  /** Generate lower-zoom DEM overview tiles by averaging 24-bit elevation values. */
203
261
  demOverview(options) {
204
262
  const params = {};
@@ -259,7 +317,7 @@ export class VPL {
259
317
  params['gamma'] = options?.gamma;
260
318
  return new VPL([...this.steps, { name: 'raster_levels', params }]);
261
319
  }
262
- /** Apply a polygon mask from GeoJSON to raster tiles. */
320
+ /** Apply a polygon mask from GeoJSON to raster tiles. Pixels outside the polygon become transparent. */
263
321
  rasterMask(options) {
264
322
  const params = {};
265
323
  params['geojson'] = options.geojson;
@@ -296,7 +354,7 @@ export class VPL {
296
354
  params['tile_size'] = options?.tileSize;
297
355
  return new VPL([...this.steps, { name: 'raster_tile_resize', params }]);
298
356
  }
299
- /** Drops vector features in selected layers that do not satisfy a boolean CEL expression. */
357
+ /** Drops vector features in selected layers that do not satisfy a boolean CEL expression. Features in layers outside `layer` pass through untouched. */
300
358
  vectorFilterFeatures(options) {
301
359
  const params = {};
302
360
  params['layer'] = options.layer;