Concept
Tiles & sources.
X-GIS reads three kinds of source — PMTiles archives, vector tiles (MVT), and GeoJSON. Each frame it picks the tiles the current camera can actually resolve, then uploads their geometry into shared GPU arenas that evict by byte budget, not tile count.
Three source formats
The format is chosen from the URL — a
.pmtiles archive opens the
PMTiles loader, while a
.json /
.tilejson manifest and a
{z}/{x}/{y} tile template
both feed the vector-tile (MVT) loader. GeoJSON is handed straight to
the tessellator.
PMTiles archives
z/x/y
with range requests against that one file. No per-tile HTTP endpoint
and no separate manifest are required.
Vector tiles (MVT) over TileJSON or XYZ
.mvt /
.pbf XYZ template, feeds the
Mapbox-Vector-Tile path. A template with no manifest is wrapped in a
minimal synthetic TileJSON so the rest of the pipeline never has to
know whether a real manifest existed.
GeoJSON tessellated to GPU meshes
earcut, line strings expanded to
stroke geometry, and GeometryCollection
features flattened one level (matching Mapbox / MapLibre). The output is
a packed float vertex array plus a 32-bit index array.
Selecting tiles per view
Nothing loads the whole pyramid. Every frame, X-GIS works out which tiles the current camera can actually resolve and asks only for those.
Screen-space error picks the level of detail
Recomputed each frame, capped for safety
The GPU arena
Selected tiles don't each get their own GPU buffer. Their geometry is uploaded into a small set of large shared buffers — linear arenas — so the draw loop binds each arena once and draws every tile from its own slice.
One shared buffer, bump-allocated
setVertexBuffer /
setIndexBuffer requirement. This
replaces a buffer-per-tile pool and is what makes a single
bound-once-then-draw-per-slice loop possible.
Freed slots reused by exact footprint
Byte-aware eviction
An arena fills on bytes, not on a tile count — a few large globe or extruded tiles can exhaust it long before any count limit is reached. Eviction is therefore driven by the byte high-water mark.
Trigger at 75%, drain to 60%
Visible and skeleton tiles are protected
Untrusted-input guards
Tiles and GeoJSON often come from a third-party host, so the loaders treat their bytes as untrusted.
Decompression-bomb and ingest caps
FeatureCollection can't OOM the
tab.
Where it is going
Roadmap · not yet shipped
These are planned, not built. They are on the roadmap, not in the engine today:
- → 3D tiles — streamed 3D mesh content as a source type.
- → Terrain — elevation tiles draped on the surface.
- → Polar-cap tile synthesis — generating cap tiles beyond the Web-Mercator ±85° band that the pyramid leaves empty.
Tracked in the repo ROADMAP.md ↗.
See it live
Real PMTiles and vector sources render in the
examples gallery.
To turn a Mapbox / MapLibre style or a tile source into an
.xgis program, use the in-browser
convert tool.
Specifications
- RFC 7946GeoJSON
- MapboxVector Tile Specification (MVT)
- ProtomapsPMTiles specification (v3)
- MapboxTileJSON 3.0.0
See also
- →Sources — The reference for declaring PMTiles, vector, and GeoJSON sources in an `.xgis` program.
- →Projection switching — Why the same tiles re-project per frame on a single uniform write — no re-tiling.
- →Globe & 3D — The 3D scene those tiles are uploaded into, kept f32-precise from streets to orbit.
Problem on this page?