MapMath

CHAPTER 19

How maps render — tiles, vectors, and the GPU pipeline

From lat/lon to pixels on screen — the full rendering pipeline for raster tiles, vector tiles, and WebGL-based maps like MapLibre and Mapbox.

4 min read

Understanding how a map renders helps you make better performance decisions: when to use raster tiles, when to switch to vector, why overzooming looks blurry, and what actually happens when you call map.setCenter().

The raster tile pipeline

A traditional web map works like this:

  1. Pre-render: The server renders every zoom level (0–22) of the world into 256×256 PNG tiles, storing them as /tiles/{z}/{x}/{y}.png
  2. Request: The browser calculates which tiles cover the viewport and requests them
  3. Stitch: The browser lays the tiles on a grid with CSS absolute positioning
  4. Pan: Moving the map repositions the grid; new tiles load at the edges
Zoom 0: 1 tile   (1×1 grid) — whole world
Zoom 1: 4 tiles  (2×2 grid)
Zoom 2: 16 tiles (4×4 grid)
...
Zoom n: 4ⁿ tiles

Total tiles at zoom 14: 4¹⁴ ≈ 268 million. Pre-rendering the full world to zoom 14 takes terabytes. Most tile providers only pre-render land/sea separation at high zoom and compute city tiles on demand.

Raster tile pyramid

z2: 4×4 = 16 tiles

z01z14z216z364

Zoom

2

Tiles per axis

4

Total tiles

16

Tile coordinates

You saw the math in Chapter 5. The important rendering implication: at any zoom level, a tile is exactly 256×256 pixels (or 512×512 for HiDPI). The tile size never changes; the number of tiles grows.

Vector tiles (MVT)

optional — skip if familiarrefresher

MVT stands for Mapbox Vector Tile — now an open standard. Vector tiles are binary-encoded Protocol Buffer files, not images. Each tile contains geometry (points, lines, polygons) clipped to the tile boundary, plus attribute data for each feature.

Instead of pre-rendered images, vector tiles contain raw geometries and attributes. The browser renders them in real time using WebGL.

Raster tile: PNG image (opaque, ~50–200 KB)
Vector tile: Encoded features (lat/lon, properties, ~5–50 KB compressed)

Vector tiles enable:

  • Client-side styling — change colours, fonts, filters without new tiles
  • 3D extrusion — buildings, terrain
  • Interactivity — hover/click on individual features
  • Sharp text — labels re-render at native resolution

The Mapbox Vector Tile (MVT) format uses Protocol Buffers. Coordinates are quantised integers in a local tile coordinate space (usually 0–4096), not geographic degrees.

tile_x = Math.round((lon_merc - tile_origin_x) / tile_size * 4096)
tile_y = Math.round((lat_merc - tile_origin_y) / tile_size * 4096)

The quantisation to 4096 units per tile gives ~1/16th of a pixel resolution at zoom 14 (9.5 m/px), far more than visual precision requires. The integer encoding also compresses dramatically with delta-coding — consecutive vertices in a ring typically differ by small values.

The WebGL pipeline

Modern map renderers (Mapbox GL, MapLibre, deck.gl) use WebGL:

  1. Geometry upload — vertices uploaded to GPU memory as Float32Array
  2. Vertex shader — converts tile coordinates to clip space
  3. Rasterisation — GPU fills triangles and lines
  4. Fragment shader — computes final pixel colour (applies styles, lighting)
  5. Composite — multiple layers blended together

The vertex shader for a simple map tile looks roughly like:

uniform mat4 u_matrix;          // projection + view + model
attribute vec2 a_pos;           // tile coordinate (0–4096)

void main() {
  gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
}
Chapter 19 · Paid content

Continue reading "How maps render — tiles, vectors, and the GPU pipeline"

You've reached the end of the free preview. Unlock all 22 paid chapters, including distance math, bearings, polygons, spatial indexing, and 3D map rendering — plus a downloadable PDF and the companion code repo.

  • All 22 paid chapters with worked examples
  • Downloadable PDF for offline reading
  • Companion GitHub repo (JavaScript + Python)
  • Free updates for life

Multiple payment options including Wise, PayPal, and bank transfer.