Skip to content

Repository files navigation

vector-tile-generator

Tile generators for the imagineRio Mapbox map. Two parallel pipelines:

  • Vector (index.js) — pulls features from an ArcGIS Online FeatureServer, merges + cleans them with mapshaper, and emits an XYZ pyramid of Mapbox vector tiles via tippecanoe, then syncs to S3.
  • Raster (raster.js) — takes a georeferenced GeoTIFF from an S3 bucket and emits a TMS PNG pyramid via GDAL (gdal2tiles), synced to the raster bucket as s3://<BUCKET_TARGET>/<ssid>/{z}/{x}/{y}.png — the layout the map loads as a raster overlay (scheme tms), keyed by the item's ssid.

Prerequisites

  • Node 20.6+ (see .nvmrc)
  • tippecanoe on PATH — vector (or use Docker)
  • GDAL (gdalinfo, gdalwarp, gdal2tiles.py) on PATH — raster (or use Docker)
  • AWS CLI v2 on PATH with credentials configured (or use Docker)

Environment

Copy .env.example to .env (loaded by Node's built-in --env-file-if-exists):

Var Pipeline Required Notes
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_DEFAULT_REGION both yes AWS CLI credentials
ARCGIS_API_KEY vector yes ArcGIS Online key for the imagineRio_GDB FeatureServer
AWS_BUCKET vector yes Plain S3 URI prefix, e.g. s3://imaginerio-vector/base/
MIN_ZOOM / MAX_ZOOM vector no Tippecanoe -Z / -z, default 9 / 17
PROJECT raster no Label, default imaginerio
BUCKET_SOURCE raster no Source GeoTIFF bucket, default imaginerio-rasters-temp
BUCKET_TARGET raster no Tile target bucket, default imaginerio-rasters
RASTER_MIN_ZOOM / RASTER_MAX_ZOOM raster no Override zoom range; max defaults to the source's native resolution, min to max − 8
SEARCH_API raster no imagineRio search API base URL (the site's NEXT_PUBLIC_SEARCH_API); enables the read-only DB metadata check

On a host like Render there is no .env file — set these as the service's environment variables instead. --env-file-if-exists loads .env locally when it's present and skips it (rather than aborting) when it isn't.

The vector pipeline's FeatureServer URL is hardcoded in index.js.

Usage

nvm use            # switches to Node 20
npm install

# vector
npm start          # full pipeline: fetch → merge → tile → upload
npm run upload     # rebuild tiles from existing geojson/final/ and upload

# raster
npm run raster                        # tile every SSID*.tif in BUCKET_SOURCE (skips already-tiled)
npm run raster -- --ssid 41988749     # one item: s3://BUCKET_SOURCE/SSID41988749.tif
npm run raster -- --key some.tif      # one explicit source key
npm run raster -- --ssid 41988749 --force   # re-tile even if target tiles exist

npm run lint
npm run format

Vector: per-page GeoJSON is cached under geojson/; re-running npm start skips already-fetched pages. Raster: source TIFs download to raster-src/ and tiles build under raster-tiles/<ssid>/ before upload (both git-ignored).

Docker

docker build -t vector-tile-generator .
# vector (default)
docker run --rm --env-file .env -v "$HOME/.aws:/home/node/.aws:ro" vector-tile-generator
# raster (override the command)
docker run --rm --env-file .env -v "$HOME/.aws:/home/node/.aws:ro" \
  vector-tile-generator raster.js --ssid 41988749

The image is multi-stage: tippecanoe is compiled in a builder; the runtime is node:20-bookworm-slim with awscli, GDAL, and the tippecanoe binary. The entrypoint is node --env-file-if-exists=.env, defaulting to index.js.

About

Generate vector tiles from ArcGIS REST API

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages