Add a country-based region picker for offline data
Replaces "regenerate for the current viewport" with what Locus/OsmAnd- style apps give you: tick which countries you want offline (a Natural Earth-derived checklist, public domain, vendored), Apply rebuilds offline.pmtiles/terrain.pmtiles to cover the whole selection at once. Multiple regions can be offline simultaneously (e.g. Slovakia + Austria for a trip that crosses the border) — the selection itself is the source of truth (data/offline_regions.json), not a set of per-country files, so "remove a country" and "refresh a country" are both just "change the selection, then Apply." Confirmed against go-pmtiles' own source (not just its docs) before committing to this shape: `extract --region=<geojson>` treats a FeatureCollection's features as their union already (no dissolve/union math needed on our side — pmtiles/region.go's UnmarshalRegion just concatenates every feature's rings), and `merge` hard-errors on any overlapping tile id between inputs (merge.go's prepareInputs). That second fact rules out "extract each country separately, merge them all" — adjacent countries' region-extracts would share border tiles, since extraction copies whole tiles rather than clipping vector content to the polygon. The actual fix: extract per *source archive* (the Protomaps build, each intersecting Mapterhorn chunk), each call covering the whole current selection via one --region= file — the terrain pipeline already extracted-then-merged per source this way, it just needed a multi-country region instead of a single bbox.
This commit is contained in:
1 parent
f89dea5805
commit
53c9a82af2
10 files changed
+442
-170
No files matched your search
@@ -223,18 +223,38 @@ module Maptool
|
||||
send_file OFFLINE_PMTILES_PATH, type: "application/octet-stream"
|
||||
end
|
||||
|
||||
# Regenerates offline.pmtiles for the given bbox (the current map
|
||||
# viewport, same "visible area is the area" convention as the Overpass
|
||||
# POI plugin) by extracting it from Protomaps' own daily full-planet
|
||||
# basemap build — see lib/maptool/pmtiles_builder.rb. Runs in the
|
||||
# background; poll build-status below for progress.
|
||||
post "/api/offline-tiles/build" do
|
||||
# Lists the selectable countries and which of them are currently
|
||||
# selected (data/offline_regions.json) — read-only, no login needed,
|
||||
# same tier as the plain availability checks above.
|
||||
get "/api/offline-regions" do
|
||||
json available: PmtilesBuilder.available_regions, selected: PmtilesBuilder.selected_regions(DATA_DIR)
|
||||
end
|
||||
|
||||
# Just updates the selection — does not itself start a build, so
|
||||
# ticking several countries doesn't fire off several rebuilds. The
|
||||
# frontend follows this with the two build routes below once the user
|
||||
# is done choosing.
|
||||
post "/api/offline-regions" do
|
||||
require_login!
|
||||
bbox = %w[south west north east].map { |key| params[key].to_s }
|
||||
halt 400, json(error: "south, west, north, east are required") if bbox.any?(&:empty?)
|
||||
codes = Array(params[:codes])
|
||||
|
||||
begin
|
||||
PmtilesBuilder.build_offline(bbox.map(&:to_f), data_dir: DATA_DIR)
|
||||
PmtilesBuilder.set_selected_regions(DATA_DIR, codes)
|
||||
rescue PmtilesBuilder::BuildError => e
|
||||
halt 400, json(error: e.message)
|
||||
end
|
||||
json ok: true
|
||||
end
|
||||
|
||||
# Regenerates offline.pmtiles for the currently selected regions (see
|
||||
# POST /api/offline-regions above) by extracting them from Protomaps'
|
||||
# own daily full-planet basemap build — see
|
||||
# lib/maptool/pmtiles_builder.rb. Runs in the background; poll
|
||||
# build-status below for progress.
|
||||
post "/api/offline-tiles/build" do
|
||||
require_login!
|
||||
begin
|
||||
PmtilesBuilder.build_offline(data_dir: DATA_DIR)
|
||||
rescue PmtilesBuilder::BuildError => e
|
||||
halt 409, json(error: e.message)
|
||||
end
|
||||
@@ -260,11 +280,8 @@ module Maptool
|
||||
|
||||
post "/api/terrain-tiles/build" do
|
||||
require_login!
|
||||
bbox = %w[south west north east].map { |key| params[key].to_s }
|
||||
halt 400, json(error: "south, west, north, east are required") if bbox.any?(&:empty?)
|
||||
|
||||
begin
|
||||
PmtilesBuilder.build_terrain(bbox.map(&:to_f), data_dir: DATA_DIR)
|
||||
PmtilesBuilder.build_terrain(data_dir: DATA_DIR)
|
||||
rescue PmtilesBuilder::BuildError => e
|
||||
halt 409, json(error: e.message)
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user