Runtime Map Bundle Builder¶
Use bin/build_map_bundles.py as the supported maintainer workflow for publishing map
data bundles. The builder now produces country archives only:
${COUNTRY_CODE}.tar.gz(one archive per selected ISO2 country)
<COUNTRY_CODE> stays ISO based (IN, FR, NL, and so on).
Shared map assets are no longer maintainer-published artifacts. They are prepared during backend image build from core-owned inputs and pinned upstream sources.
Required external inputs¶
bin/build_map_bundles.py requires:
- A world basemap PMTiles source (
--world-basemap) - A world terrain PMTiles source (
--world-terrain) - A world countries GeoJSON file (
--world-countries)
--world-basemap and --world-terrain accept either a URL or a local file path.
Build bundles (supported path)¶
From the repository root:
bin/build_map_bundles.py --country NL FR DE \
--world-basemap /mnt/datasets/maps/world-basemap.pmtiles \
--world-terrain /mnt/datasets/maps/world-terrain.pmtiles \
--world-countries /mnt/datasets/maps/world-countries.geojson
Build every ISO code found in the world countries dataset:
bin/build_map_bundles.py --all \
--world-basemap /mnt/datasets/maps/world-basemap.pmtiles \
--world-terrain /mnt/datasets/maps/world-terrain.pmtiles \
--world-countries /mnt/datasets/maps/world-countries.geojson \
--jobs 8
This command:
- Extracts ISO country boundaries from the world countries file.
- Builds merged PMTiles artifacts for each selected country.
- Writes
${COUNTRY_CODE}.tar.gzfor each selected country.
Default export directory is maps/dist/export (or --export-dir when provided).
Expected output layout:
Archive contents:
${COUNTRY_CODE}.tar.gzcontainstiles.pmtiles,contours.pmtiles, andcountry.geojson.
Publish with rclone (manual maintainer flow)¶
Publishing is intentionally manual so maintainers can review exactly what is uploaded.
1) Install rclone¶
2) Configure an S3-compatible remote¶
Create object-storage S3 credentials in your provider dashboard and note the access key and secret key.
Add a remote to ~/.config/rclone/rclone.conf (example for Hetzner Object Storage):
[hetzner-map-assets]
type = s3
provider = Other
access_key_id = <access_key>
secret_access_key = <secret_key>
region = hel1
endpoint = hel1.your-objectstorage.com
3) Upload country bundles to whitebox-maps.hel1.your-objectstorage.com¶
Use the same export directory that bin/build_map_bundles.py wrote to
(maps/dist/export by default, or your --export-dir value).
EXPORT_DIR="maps/dist/export"
REMOTE_BUCKET="hetzner-map-assets:whitebox-maps"
COUNTRY_CODE="NL"
# Upload one country bundle
rclone copyto "$EXPORT_DIR/${COUNTRY_CODE}.tar.gz" "$REMOTE_BUCKET/${COUNTRY_CODE}.tar.gz" --progress --stats=1s --stats-one-line
# Upload all country bundles from export dir (keeps existing remote objects)
rclone copy "$EXPORT_DIR" "$REMOTE_BUCKET" --include "*.tar.gz" --progress --stats=1s --stats-one-line
Expected object layout:
4) Verify object location and runtime URL mapping¶
REMOTE_BUCKET="hetzner-map-assets:whitebox-maps"
COUNTRY_CODE="NL"
rclone ls "$REMOTE_BUCKET/${COUNTRY_CODE}.tar.gz"
curl -I "${MAP_ASSETS_BASE_URL}/${COUNTRY_CODE}.tar.gz"
Runtime country bundle URLs should resolve to uploaded objects:
${MAP_ASSETS_BASE_URL}/${COUNTRY_CODE}.tar.gz
Shared style/resources are handled separately by backend image build; maintainers publish country bundles only.
PMTiles tool bootstrap¶
bin/build_map_bundles.pyusesPMTILES_BIN(if set) orpmtilesfromPATH.- If neither is available, it attempts an automatic download for Linux/macOS on x86_64 and arm64.
- On unsupported platforms, install
pmtilesmanually and setPMTILES_BIN(or add it toPATH).
Validate against dev runtime¶
Building and publishing bundle archives does not make compose use them automatically.
- Add
127.0.0.1 dev-serverto/etc/hostsand verifyping dev-serverworks. - Ensure
${MAP_ASSETS_BASE_URL}points at the storage path where you published country bundles. - Set matching
COUNTRY_CODEfor the runtime. - Start compose (
docker compose -f compose.dev.yml up). - Run backend and frontend as usual.
Shared style/resources in dev are prepared by backend image build from core-owned sources.
Style development notes¶
- For Maputnik-based editing, run: