Skip to content

sources

sources is the single home for everything external: document-scoped files (brushes, images, fonts) sit next to tile-scoped pyramids (MVT, PMTiles, DEM, raster imagery). Each entry’s type selects the variant. brush and image name their file with src, sprite with image and index, and every other variant with url (geojson may carry its document inline as data instead).

"sources": {
"glazing": { "type": "brush", "src": "file:brushes/watercolor_glazing.myb" },
"basemap": { "type": "mvt", "url": "https://papers.reearth.land/protomaps/tilejson.json" },
"terrain": { "type": "dem", "encoding": "terrarium",
"max-zoom": 14, "on-missing": "upsample",
"url": "https://terrain.reearth.land/…/{z}/{x}/{y}.webp" }
}

Nothing is bundled into the library — see sources and assets for why, and for how the host binds the bytes.

A brush or image src, a sprite’s image, and a font’s url take:

Scheme Resolves to
file:PATH local file, relative to --assets-dir (or absolute). The extension may be omitted — it is inferred from the source type
http(s)://… fetched by the host before the first render, then cached in the in-memory bank
data:[<mediatype>][;base64],… decoded in-process, no I/O — works in every host including wasm. image/* loads as an image; anything else is tried as a brush
builtin:NAME whatever the host registered under NAME at runtime
system:FAMILY font only — a face resolved from installed fonts. Machine-dependent, unavailable on wasm

brush — a MyPaint .myb brush. Any .myb works; the example styles ship CC0 brushes by David Revoy next to their style JSON.

image — a PNG/WebP image, for place, tiling, and texture work.

sprite — a sprite sheet: an atlas image plus an index mapping icon names to atlas sub-rects. The index is a URL/path to a sprite .json or an inline map of the same shape. An icon node crops a named rect into a Sprite for stamp (symbol icons) or tiling (fill-pattern). Nine-slice stretchX/stretchY/ content metadata is honoured by icon-text-fit.

font — outline font bytes (TTF/OTF/TTC) for the text node’s font stack, named with a url.

glyphs — a MapLibre glyph-PBF endpoint ({fontstack}/{range} template) serving pre-rendered SDF ranges, fetched lazily. The no-font-files alternative to font, and what ezu translate falls back to.

mvt — an XYZ MVT URL template, or a TileJSON document. The host fetches one tile per render, decodes every layer, and binds each under <source>.<layer> — the source and layer a features node names. A style may declare any number of mvt / pmtiles sources (a basemap and an overlay, say, or one per data set); each is fetched and bound under its own name.

Optional min-zoom / max-zoom give the zoom range the source serves, as a MapLibre source’s minzoom / maxzoom do: below min-zoom the source binds nothing and its layers draw nothing; past max-zoom each tile is cut from the covering ancestor at max-zoom, its geometry reprojected into the requested tile.

pmtiles — a PMTiles archive (local path or http(s)://). Layers bind exactly as mvt, and it takes the same min-zoom / max-zoom.

dem — a raster-DEM pyramid. encoding is terrarium or mapbox-rgb and must match the data, since the RGB channels mean different things. The host stitches the 3×3 neighbourhood into a per-tile ScalarField with geo_scale populated, so hillshade and slope produce real-world angles, and binds it under tile.<source-name> for the dem node.

raster — an RGBA imagery pyramid (satellite, pre-rendered basemaps; PNG / WebP / JPEG). url may be an XYZ template, a TileJSON document, or a .pmtiles archive. Stitched over the padded canvas and bound under the source name for the raster node.

geojson — GeoJSON in WGS84 lon/lat, carried inline as data or named by url. Either way the host reads the document once per style and projects it into each tile’s frame, binding it as one layer named <source>.<source>. A url may be http(s)://, file: (resolved against --assets-dir, so features can sit beside the style rather than inside it), or a data: URL:

"sources": {
// The whole document, in the style.
"pins": { "type": "geojson", "data": { "type": "FeatureCollection", "features": [] } },
// Or beside it.
"routes": { "type": "geojson", "url": "file:routes.geojson" },
// Or anywhere.
"places": { "type": "geojson", "url": "https://example.com/places.geojson" }
}

Unlike the tiled sources, a GeoJSON document is not tile-addressed: one document covers the world, so rendering a whole pyramid reads it exactly as many times as rendering one tile does.

For raster and dem:

Field Meaning
max-zoom deepest zoom the source has. Deeper requests always upsample from this ancestor
neighbor-fetch fetch the 8 neighbouring tiles too and stitch them, so the pad region holds real pixels (and, for dem, slopes stay seamless across tile edges). Default true
on-missing in-range 404 policy: empty (default — transparent / zero elevation), upsample (walk up parents and upsample the covered sub-region), or error (fail the render, so a server can answer 404)
elevation-offset dem only: metres subtracted from every decoded sample, to rebase a geoid-relative dataset. Default 0

A pyramid’s tile size is not declared, unlike MapLibre’s tileSize: each tile’s edge is read from its decoded image, which may be any square size, and the tile is resampled onto the canvas, so a 256 px and a 512 px pyramid render the same ground. dem still accepts a tile-size from older styles and ignores it.

Any source may declare an attribution string. Sources that do not inherit upstream metadata — TileJSON’s attribution field, or PMTiles archive metadata — when the host opens them. The document’s own top-level attribution is merged in. Document::attributions() returns the declared list; GET /style/attribution and the wasm renderer.attribution return the merged result.

Map renders on this site are made fromOpenStreetMap data viaProtomaps (© OpenStreetMap contributors), elevation from Re:Earth Terrain,Mapterhorn andEGM2008 (NGA), and aerial imagery from GSI Japan(© 国土地理院). The painterly styles use CC0 brushes byDavid Revoy.