makepad/tools/map_tiles
Admin 2492ad3bde map: rain radar overlay, flying 3D markers, Europe routing, geodata crate
- rain radar layer: pure-Rust KNMI HDF5 reader (superblock v0 walk,
  single-chunk deflate datasets, byte-exact vs h5py), ellipsoidal polar
  stereographic reprojection (20 m vs product corners), bilinear value
  sampling -> smooth banded isolines, textured quad overlay through the
  overlay camera, 25-frame nowcast animation; RadarSync polls at most
  once per 4 min through a disk-persisted gate and caches frames on disk
- makepad-geodata + makepad-tesla crates join the workspace (overlay
  builders, radar sync, NL open-data layers; transit routes now z7-14)
- Europe major-roads routing graph: nav-build --major-roads does a
  ways-first scan (5.7M ways / 46M nodes / 194 s / 971 MB) and the app
  falls back to it when a route leaves the regional graph — Amsterdam to
  Paris routes offline (501.8 km)
- 3D flying markers: chargers/POIs/stops ride thin stalks with DYNAMIC
  height (each pin clears its own building +8 m); labels, kW text,
  brand and tap zones all consume the baked per-marker lift; stalks and
  buildings grow together on the 2D->3D transition (per-tile flat->3D
  fade heights, no replay on zoom regens)
- markers depth-honest (small bias, buildings occlude them); phong-lit
  canopy/light spheres matching the buildings' NW sun; buildings tint by
  BAG age in 3D; district area tints (rank 60, alpha .32); transit line
  labels + stop names; follow-mode is an explicit attach/detach toggle;
  rotation release schedules the label re-place (no stuck upside-down
  labels after a fast spin)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 18:00:27 +02:00
..
src map: rain radar overlay, flying 3D markers, Europe routing, geodata crate 2026-07-28 18:00:27 +02:00
Cargo.toml map: Europe tile conversion pipeline + offline GPS navigator 2026-07-27 20:13:21 +02:00
README.md map: Europe tile conversion pipeline + offline GPS navigator 2026-07-27 20:13:21 +02:00

Makepad map tile tools

makepad-map-tiles prepares two complementary, disk-streamable map archives:

  • a compact Shortbread base pyramid copied from VersaTiles; and
  • an all-tag street-detail overlay built directly from a sorted OSM PBF.

Both outputs are standard gzip-MVT MBTiles files. The pure-Rust MBTiles writer orders rows in 256×256 tile blocks and records a makepad_rowid_scheme marker, so Makepad can seek directly to a requested tile without enumerating a zoom level. The raw PBF remains the canonical copy of the complete OSM graph.

Native OSM detail conversion

cargo build --release --package makepad-map-tiles

target/release/makepad-map-tiles pbf-detail \
    local/maps/europe-260726.osm.pbf \
    local/maps/europe-osm-detail.partial.mbtiles \
    --store local/maps/native-detail-europe.store \
    --zoom 14 \
    --sort-memory-mib 256

The input must advertise the standard PBF Sort.Type_then_ID optional feature. The converter performs bounded-memory sequential passes:

  1. build a bounded relation-way bitset and persist it for the later passes;
  2. project each node once and build a compressed, indexed coordinate store;
  3. resolve ways, retain relation-member way references, and clip tagged ways;
  4. assemble tagged relation geometry, including multipolygon rings; and
  5. externally sort 256×256 tile-block spools, encode MVT, gzip each tile, and stream the tiles into MBTiles.

No feature/tag allow-list or geometry simplification is applied. Every tagged node is emitted as a point. Every tagged way is emitted as a line; a closed way is also emitted as a polygon candidate so the conversion does not make an irreversible area interpretation. Tagged relation members are emitted as relation point/line geometry, and type=multipolygon relations also receive assembled polygon geometry.

The six MVT layers are:

  • osm_points
  • osm_lines
  • osm_polygons
  • osm_relation_points
  • osm_relation_lines
  • osm_relation_polygons

Each feature retains every original OSM tag as a string plus its MVT feature ID and the internal fields __makepad_osm_id, __makepad_osm_type, and __makepad_osm_closed.

Simple 3D Buildings tags are copied verbatim, including building, building:part, height, min_height, building:levels, building:min_level, roof shape/height/levels/direction/orientation/angle, building and roof materials, and building and roof colours. Keeping the raw strings avoids silently changing values with units; the renderer can normalize them once when preparing a 2.5D building mesh and fall back from explicit height to level counts.

The scratch directory is deliberately retained after a successful build. It contains compressed node/way indexes, the relation-way bitset, source block spools, native-detail-audit.txt, and an atomic spool.complete.json marker. If final MBTiles writing is interrupted, move the partial MBTiles aside and repeat the same command: the converter validates the source size and zoom, then restarts only the external-sort/MBTiles pass. An incomplete earlier pass is never guessed at or silently reused.

Performance notes

The hot path is designed around the scale of the pinned Europe extract: 3.79 billion nodes, 464 million ways, and 4.79 billion way-node references.

  • node/way group indexes use bounded direct lookup tables;
  • compressed coordinate groups are decoded once into an O(1) cache;
  • Web Mercator projection happens once per node, not once per way reference;
  • ordinary ways resolve directly from the PBF iterator without allocating a second node-reference vector;
  • source tags borrow the PBF string table and use inline storage for the common case, avoiding per-tag string copies and most small heap allocations;
  • tile-block writers use hash lookup and retain enough buffered handles to cover the Europe block set without per-feature reopen churn;
  • one reusable scratch buffer encodes records without allocating a payload vector for every tile record;
  • relation-member way references are borrowed from decoded groups rather than cloned; and
  • MVT dictionaries use deterministic insertion order with fast lookup.

On the same machine used for development, the release converter processed the 47,228,875-byte Luxembourg extract (4,208,128 nodes, 6,313,908 way-node references, and 1,617,855 tile records) into 3,953 checked tiles in 12.3 seconds. Pass 3 sustained about 1.29 million resolved references per second. Scaling the measured stages by the audited Europe object/reference counts gives a practical preflight estimate of roughly 23 hours, rather than four-plus, though final time depends on SSD throughput and tile density.

Other commands

# Inspect source ordering and bounds.
target/release/makepad-map-tiles inspect-pbf source.osm.pbf

# Count all source tags plus benches, playgrounds, buildings and 2.5D fields.
target/release/makepad-map-tiles audit-pbf source.osm.pbf

# Verify direct MBTiles lookup, gzip/MVT validity, layers, and detail tag keys.
target/release/makepad-map-tiles probe-mbtiles map.mbtiles 14/8414/5384

# Extract the Europe rectangle from a VersaTiles Shortbread planet archive.
target/release/makepad-map-tiles versatiles \
    source.versatiles output.mbtiles \
    --bbox=-32.683233,29.635548,46.753480,81.472990 \
    --max-zoom 14

download_map.sh pins and verifies the large upstream snapshots, builds the release utility, validates SQLite, probes a real MVT tile, and only then atomically renames a .partial.mbtiles output.