Skip to main content

The Map Bakery

The Map Bakery is a specialized CLI tool designed to reduce Mapbox API usage costs. Instead of rendering interactive Mapbox GL JS maps for static use-cases (like Ward Overview cards), we pre-generate (“bake”) static PNG images and serve them from our own Supabase Storage.

The Problem

Interactive maps are expensive (Mapbox charges per load). For a list of 4,000 wards, rendering a live map for each visit is inefficient and costly, especially when the ward geometry rarely changes.

The Solution

We use a “Bakery” script that:
  1. Fetches Ward Geometry (Polygons) from PostGIS.
  2. Simplifies the geometry specific for Static Map URLs.
  3. Generates a Mapbox Static Image URL with the geometry as an overlay.
  4. Downloads the image and uploads it to Supabase Storage (ward-maps bucket).
  5. Updates the wards table with the permanent map_image_url.

Usage

The bakery is located at scripts/bake-ward-maps.ts.

Bake a Single Ward

Useful for testing or fixing a specific ward.
npx tsx scripts/bake-ward-maps.ts --ward=79700026

Bake All Missing Maps

Runs through all wards that do not yet have a map_image_url.
npx tsx scripts/bake-ward-maps.ts

Force Rebake

Updates existing maps (e.g., if map styles changed).
npx tsx scripts/bake-ward-maps.ts --force

Architecture Details

Geometry Simplification

Mapbox Static API URLs have a character limit. Complex ward boundaries can exceed this limit. We use @turf/simplify with an adaptive tolerance loop to reduce the coordinate count until the URL fits, ensuring the visual shape remains recognizable.

Storage

Images are stored in the ward-maps bucket in Supabase Storage.
  • Path: ward-maps/map-[ward_code].png
  • Cache Control: 1 year (31536000 seconds)

Frontend Integration

The WardMap component (components/ward/WardMap.tsx) accepts a mapImageUrl prop.
<WardMap
  wardCode={wardCode}
  center={center}
  isStatic={true}
  mapImageUrl={ward.mapImageUrl} // Priority
/>
If mapImageUrl is present and isStatic is true, the component renders a standard <img> tag instead of the Mapbox library, incurring zero Mapbox cost for that view.