Vector tiles with tippecanoe and MBTiles
Vector tiles changed web mapping. tippecanoe is the industry-standard generator. This week you take a GeoJSON of 10,000 satellites and produce a smooth, multi-zoom vector tile set.
If you wanted to show 10,000 satellites on a map and still scroll smoothly, how would you do it?
The answer is vector tiles. Same underlying idea as the slippy-tile maps you scroll on your phone — but for vector data instead of pre-rendered pixels. This week you'll build the pipeline.
Learning objectives
- Generate vector tiles from GeoJSON with tippecanoe
- Understand MBTiles file format and PMTiles cloud-optimized variant
- Serve tiles via TiTiler or martin
- Configure zoom-dependent tile generalization
Primer
The TLE catalog has 10,000+ active objects. Plotting them all as GeoJSON in a browser brings any vector renderer to its knees — every feature must be loaded, parsed, indexed, and drawn. Vector tiles solve this elegantly: instead of one giant GeoJSON, you generate a pre-indexed pyramid of small tiles, each containing only the features visible at that zoom and location.
The vector tile pyramid
A vector tile is a Protocol Buffers (PBF) file containing a subset of features for a specific (z, x, y) tile address. The pyramid follows the standard slippy-tile convention: z=0 is the entire world in one tile, z=1 splits it into 4 tiles, z=2 into 16, and so on. At z=10, the world is 1,048,576 tiles. Each tile is small (typically 5–50 KB) and the renderer fetches only the tiles in the current viewport.
tippecanoe
tippecanoe (now MIT-licensed at github.com/felt/tippecanoe) is the industry-standard generator: it takes a GeoJSON and produces an MBTiles or PMTiles archive. It's a C++ tool you install via Homebrew (brew install tippecanoe) or build from source.
tippecanoe \
-o satellites.pmtiles \
--maximum-zoom=10 \
--minimum-zoom=0 \
--layer=satellites \
--drop-densest-as-needed \
--extend-zooms-if-still-dropping \
satellites.geojson
The key flags:
--minimum-zoom / --maximum-zoom— what zoom range to generate. Generate fewer zooms when your features don't need them.--drop-densest-as-needed— at low zooms, drop the densest features to keep tile size manageable. Essential for large catalogs.--extend-zooms-if-still-dropping— if you're still dropping features at the max zoom, automatically extend.--layer— the layer name inside the tiles. Use it for styling later.
MBTiles vs PMTiles
MBTiles is the original spec: a SQLite database file containing every tile in the pyramid. Easy to generate, easy to serve via a tile server (martin, TiTiler, mbtileserver), but requires running infrastructure.
PMTiles is the modern improvement: a single file with an internal index that lets HTTP range requests fetch individual tiles directly. No tile server needed — just upload the PMTiles file to S3 (or any HTTP host) and configure the renderer to range-request from the URL. This is the modern default for static deployments.
// MapLibre with PMTiles
const protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile);
map.addSource('satellites', {
type: 'vector',
url: 'pmtiles://https://my-bucket.s3.amazonaws.com/satellites.pmtiles'
});
Tile size optimization
Aim for tiles to be 50 KB or smaller. If a tile is too large, MapLibre's frame rate drops. Strategies:
- Lower max zoom — at z=10, each tile covers ~40 km on a side; rarely do you need higher resolution for satellite data.
- Drop attributes — every feature can have N properties; if you don't render them, drop them with
--includefilters in tippecanoe. - Simplify geometries — for lines and polygons, set
--simplificationto reduce vertex count.
The lab
You'll download the active CelesTrak satellite catalog (10,000+ TLEs), compute current sub-satellite points for all of them with skyfield, export as GeoJSON, generate vector tiles with tippecanoe across zoom levels 0–10, serve via PMTiles directly from local file system, and render in MapLibre. The result is a smooth, pannable map of every satellite in orbit — at 60 fps even on a 5-year-old laptop.
This is the architecture LaunchDetect uses for the /atlas/ page's spaceport layer (smaller catalog but same pipeline). PMTiles + S3 + CloudFront = no tile server to maintain.
Connecting to Hawaiʻi: Vector tiles and reef monitoring at scale
The Hawaiian Islands Humpback Whale Sanctuary publishes vessel-traffic maps that include thousands of AIS data points per day. The Pacific Disaster Center, headquartered on Maui, runs interactive damage-assessment maps that show tens of thousands of features. Both use vector-tile pipelines: pre-index the data into a pyramid of small tiles, serve only the tiles in view. Same architecture works whether you're plotting whales or satellites.
Hands-on lab: 10,000 satellites in vector tiles
Download the active CelesTrak TLE catalog. Compute current sub-satellite points. Export as GeoJSON. Generate vector tiles with tippecanoe across zoom levels 0–10. Serve via PMTiles and render with MapLibre.
Quiz — click an answer to check it
No grade, no shame. Tap any option; you'll see if it's right plus the answer if not. The point is to notice what you already know and what's still settling.
- Mapbox (now MIT-licensed)
- ESRI
- NASA
- A SQLite file containing tile data
- A JSON manifest
- A binary protocol
- A streaming format
- Being a single file servable directly from S3 via HTTP range requests
- Higher resolution
- Vector-only
- More compression
- 0 (whole Earth) to ~22 (street level)
- 1 to 10
- 100 to 200
- -5 to +5
- Drops the densest features at low zooms to keep tile size manageable
- Drops random features
- Deletes the source
- Increases tile size
Reflection
Take five minutes with this. Write your answer somewhere. Carry it into next week.