Skip to content

Migrate map renderer: Leaflet → MapLibre GL JS with self-hosted PMTiles #120

@maorcc

Description

@maorcc

Motivation

The current Leaflet + OpenStreetMap raster tile setup has several limitations:

  • No language control — raster tiles bake in the labels at render time; Arabic towns show Arabic, not Hebrew
  • Raster-only — can't use vector tiles, so no data-driven styling for labels
  • CPU rendering — Leaflet uses Canvas/SVG; with 1,400+ polygons updating every 1–10s, WebGL would be noticeably smoother

Proposed stack

Component Solution
Renderer MapLibre GL JS
RTL text @mapbox/mapbox-gl-rtl-text plugin (required for Hebrew/Arabic)
Style OSM Bright (open source, warm beige, OpenMapTiles schema)
Tiles PMTiles (Israel extract) self-hosted on Cloudflare R2 — zero egress cost
Language Hebrew via MapLibre expression: ['coalesce', ['get', 'name:he'], ['get', 'name']] on all label layers

What it will look like

Key technical notes

  • MapLibre requires maplibregl.setRTLTextPlugin(...) before map init for correct Hebrew RTL rendering
  • OSM Bright uses the OpenMapTiles tile schema — compatible with PMTiles from Protomaps planet builds
  • PMTiles supports HTTP range requests and works natively from R2; MapLibre has built-in PMTiles support via pmtiles:// URL scheme
  • All label layers need their text-field expression patched to ['coalesce', ['get', 'name:he'], ['get', 'name']]
  • For places outside Israel where OSM lacks name:he (e.g. Jordanian cities), labels fall back to local script — acceptable for a map focused on Israel
  • Migration scope: ~300–500 lines touched; not a drop-in swap but a focused rewrite of the map init and polygon rendering code

Why not stay on Leaflet

  • No way to get Hebrew labels on Arabic-speaking towns (raster tile limitation)
  • MapTiler hosted tiles are limited to 5,000 sessions/month on the free tier — not enough for oref-map production scale
  • Self-hosted PMTiles on R2 solves both the cost and the language control, but requires MapLibre

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions