--- title: Bucket Atlas emoji: 🗺️ colorFrom: green colorTo: yellow sdk: docker app_port: 7860 pinned: true license: mit --- # Bucket Atlas A globe you can explore down to streets, streamed from one 137.8 GB PMTiles file in a private Hugging Face bucket. Built with Bun S3, MapLibre globe projection, and Protomaps. Includes an immersive globe with labels always on, a floating light/dark toggle, Hugging Face branding and a compact transfer panel, live byte/range counters, and browser caching. Bytes read include cached range bodies; they are not a wire-transfer measurement. ## Storage Space and bucket: `cfahlgren1/bucket-atlas` (both private). Space secrets: - `HF_S3_ACCESS_KEY_ID` - `HF_S3_SECRET_ACCESS_KEY` Defaults (override using environment variables): ```sh HF_S3_NAMESPACE=cfahlgren1 HF_S3_BUCKET=bucket-atlas PMTILES_KEY=maps/planet-20260907.pmtiles ``` The app serves `/maps/planet-20260907.pmtiles`. Bun signs upstream S3 requests, validates the exact Content-Range and status, and streams the body. Single ranges are limited to 8 MiB; full downloads and multiple ranges are rejected. The server does not download the planet archive into memory or its local disk. Changing Space visibility to public would make this selected map accessible through the app. ## Basemap provenance - Source: https://build.protomaps.com/20260907.pmtiles - Published September 7, 2026; Protomaps tileset 4.15.2. - Size: 137,838,277,849 bytes. - BLAKE3: `99796b90478828fd0f6db3eeec760ee5c8bb3c32cbc693d0462fca78c44bf1cc`. - World coverage, native zooms through 15; UI zooms through 18 by overzooming those tiles. - Style: `@protomaps/basemaps` 5.7.2, adapted for globe and daylight views. `scripts/import-planet.py` runs locally or on any machine with enough disk. It streams ranges using four connections and 1 MiB buffers, saves completed ranges to a checkpoint, checks the complete published BLAKE3 digest, and uploads only the verified archive through HF's bucket API. Rerunning resumes completed ranges. It needs Python, httpx, blake3, huggingface_hub, and an HF_TOKEN with bucket write permission. Allow 138 GB for the archive plus a 10 GiB free-space reserve. The app's S3 credential remains read-only. No HF Job is required. ```sh HF_XET_HIGH_PERFORMANCE=0 HF_XET_FIXED_UPLOAD_CONCURRENCY=8 \ uv run --no-project --with blake3 --with httpx --with huggingface-hub==1.6.0 \ python scripts/import-planet.py ``` The default target is `data/planet/planet-20260907.pmtiles`; `--target` chooses another disk. `--download-only` stops after checksum verification. Keep the archive and adjacent checkpoint together until import is complete. The map focuses on self-hosted vector cartography. Company research is retained separately in `community/` for future use; it is not rendered or fetched by the app. The directory currently contains 70 source-linked office records across 22 companies with explicitly approximate city coordinates. See [community contribution instructions](community/README.md). Map data © OpenStreetMap contributors, ODbL. [License and attribution](https://www.openstreetmap.org/copyright). Tiles by [Protomaps](https://docs.protomaps.com/basemaps/downloads). Glyphs and sprites come from Protomaps; fonts come from Google Fonts. ## Local development ```sh bun install --frozen-lockfile # Supply S3 secrets from your environment: bun start ``` There is no separate build step. `src/server.ts` imports `public/index.html` and Bun bundles the page, `src/client.ts`, and the Tailwind stylesheet at startup (`bunfig.toml` registers `bun-plugin-tailwind`). Requires Bun 1.4 or newer, matching the Dockerfile. Alternatively, with an existing `HF_TOKEN` environment variable, `bun run dev` serves the local frontend on localhost and proxies map reads through the private deployed Space. This avoids storing S3 credentials locally. For local HTTP unit tests, retain the small Florence fixture: ```sh mkdir -p data curl -fL 'https://pmtiles.io/protomaps(vector)ODbL_firenze.pmtiles' -o data/florence.pmtiles bun test bun run check ``` The tests explicitly use this local fixture through the production HTTP handler; they do not assert global coverage. `LOCAL_PMTILES` is a development-only backend and is not set in the deployed Space. No local archive is bundled in Docker. ## HTTP caching Map ranges use `private, max-age=300` and the bucket object's ETag. Browsers can reuse ranges across reloads for five minutes; shared caches are excluded. PMTiles detects ETag changes and retries. Object metadata refreshes every minute and invalid upstream range checks invalidate it immediately. Use a new dated archive path when switching snapshots rather than overwriting an existing version. The HTML page uses `no-cache` with a content ETag, allowing bodyless 304 validation; its hashed JS and CSS chunks are `public, max-age=31536000, immutable`. Configuration and storage errors remain no-store. Downloaded private bytes can remain on a viewer's device; browser caching is not an immediate revocation mechanism. The UI counts PMTiles payload bytes, including HTTP cache reuse, and range reads. These are not total network traffic. The status element's Resource Timing data attributes distinguish browser cache hits and transferred bytes. ## Verification `bun test` exercises real HTTP byte equality, range validation, HEAD, caching/validators, PMTiles metadata, and tile decoding against the small fixture. `bun run check` checks types. `HF_TOKEN=... bun scripts/verify-planet.ts` checks the deployed private Space: world bounds, detailed tiles in five cities across continents, and byte-for-byte source comparisons at the beginning, middle, and end of the planet archive. Do not put the token value in committed files or shell history; use an existing environment variable. See PERFORMANCE.md for measurements and their scope.