Vector tiles · any grid
Almost every vector-tile server speaks one projection: Web Mercator, the grid of the whole web map world. This demo serves the same OpenStreetMap tiles on the Swiss national grid instead (swissLV95, EPSG:2056), the grid swisstopo actually uses. Same engine, same tiles, a grid most stacks simply can't do. It is also the most honest demo we have: getting a whole country into a browser has real limits, and this page is about running straight into them.

The approach
TerraServe serves the same vector tiles on any tile grid: the four built-in ones (Web Mercator, geographic, and the two polar grids) or a custom one you hand it as a single OGC TileMatrixSet JSON. Here that file is the Swiss national grid, and the engine had never seen it before. No code, no plugin, just the file.
Pre-baking tiles used to be a Mercator-only trick. Now the offline baker takes the same grid file, so a Swiss-grid layer gets the same treatment a Web-Mercator one always had: a whole-country tile becomes a 35 ms read off disk instead of a 1.2 s live render. That is the actual capability on show here.
Here is the catch, and we would rather say it than hide it. Precompute makes the server instant. It does nothing for your browser, which still has to download and hold every shape. A whole country in full detail is gigabytes of geometry in one tab. That is the interesting problem, and the rest of this page is how we deal with it.
The honest part
The land-cover polygons are detailed: each tile of the country at overview zoom is about 2.5 MB, and roughly eighteen of them fill the screen. That is around 45 MB of shapes for the browser to decode and keep, and in testing it climbed to 5.8 GB and locked up. The precomputed archive served all of it in milliseconds. The browser still could not hold it.
The reflex fix, dropping small shapes, did nothing: this is a handful of large polygons with very detailed edges, not many small ones. Simplifying the outlines only halved the size. What worked was a dominant-class mosaic: at low zoom, replace the polygons with a coarse grid of cells, each coloured by the class that covers it. That is 145× lighter, and it is the blocky pixel-art you see when the whole country is on screen. It is honest about what it is: a pattern, not every parcel.
Then you zoom in, and the real shapes come back, because the close-up zoom levels are served live at full detail:

Web Mercator tiles the entire planet as a neat square that doubles every zoom. A national grid does not: the Swiss grid's overview level is 8 × 5 tiles, clipped to the country, not a full square. A viewer written for the square world asks for a few tiles past that edge, out in the empty black area beyond Switzerland, and the server answers "no such tile". They are harmless, they hold no data, and they are a real property of national grids, not a fault.
The viewer can render on other grids too, but only the Swiss grid has the light precomputed mosaic. Switch to Web Mercator here and the browser would try to draw the country at full detail again, and hit the same wall. So this demo stays on its own grid, which is the whole point of it anyway.
How it's served
The live demo runs the first command. The second is how the light overview tiles were baked, once, before it started. Every flag, explained below.
terraserve serve # Swiss OSM land cover on the national LV95 grid --config /data/swiss.yaml # layers: ch_landuse, ch_water, each on grid swissLV95 --mvt-style /data/swiss.mvt-style.json --font /data/DejaVuSans.ttf --mvt-cache 512 --max-inflight 8 # and how the light overview tiles are baked, once, offline: terraserve build-pmtiles --vector /data/ch_landuse.fgb --grid /data/grids/swissLV95.json --mvt-cell-px 8 --mvt-cell-field fclass --min-zoom 0 --max-zoom 16 --out /data/ch_landuse.lv95.pmtiles
| --config swiss.yaml | The layer list: which OpenStreetMap themes to serve (here just landuse and water), where each file lives, and, for each one, the grid it publishes on. |
| grids: [swissLV95.json] | The Swiss national grid, EPSG:2056, written out as one OGC TileMatrixSet JSON file. That single file is all it takes to serve tiles on a grid the engine has never seen. No code, no build. |
| --grid swissLV95.json | The same grid file, handed to the offline tile baker. build-pmtiles used to only know Web Mercator; now it bakes a pyramid on any grid, so a non-Mercator layer gets the same fast pre-baked tiles a Mercator one always had. |
| --mvt-cell-px 8 --mvt-cell-field fclass | The mosaic. When zoomed out, replace the polygons with a coarse grid of cells, each coloured by its dominant class. It's about 145× lighter, which is the whole difference between a browser that loads the country and one that freezes on it (more below). |
| --pmtiles ch_landuse.lv95.pmtiles | The baked archive for the Swiss grid. A whole-country tile is now a 17 KB read off disk instead of a 2.5 MB live render, about 35 ms versus 1.2 s. |
| --mvt-min-feature-px 8 | Skip shapes smaller than 8 pixels at the zoom you're at. It helps most datasets a lot; it did almost nothing here, and that turned out to be the key clue (again, below). |
Measured on the live server: a whole-country overview tile comes back in about 35 ms from the baked archive, versus roughly 1.2 s to render it live. The overview mosaic drops the whole country to about 360 KB of tiles, from the 45 MB that froze the browser. Zoom past the overview and tiles are rendered live at full detail, small enough per tile that the browser is comfortable again.
Source & attribution. Land cover: OpenStreetMap, Switzerland extract via Geofabrik, © OpenStreetMap contributors, ODbL. Tile grid: the swisstopo LV95 national grid (EPSG:2056), written as an OGC TileMatrixSet.