#!/usr/bin/env bash # HuntGrid Backcountry's OpenStreetMap portages, canoe and hiking routes, whitewater and fire pits (docs/backcountry/PLAN.md # B2.2a) → data/tiles/backcountry-osm.pmtiles: layers `portages`, `water` and `camp` (Planetiler, backcountry-osm.yml) # and `routes` (GDAL + tippecanoe, backcountry-osm/routes), one ODbL tileset with the licence and the extract date in # its metadata. Unofficial data, never joined with official trails or portages (geo.outdoor_trails, B2.1). # # tools/geodata/backcountry-osm/build # Minnesota (dev default, a few minutes) # HG_OSM_EXTRACT=north-america/canada/ontario tools/geodata/backcountry-osm/build # HG_OSM_PBF=downloads/osm/ontario-latest.osm.pbf tools/geodata/backcountry-osm/build # a file already under data/ # # Every US state and Canadian province and territory, joined: backcountry-osm/build-all (owner, on the PC). Extracts # are shared with outdoor/build and offroad-osm/build in data/downloads/osm (reused for a day). Runs on Linux, macOS # and Git Bash on Windows. Needs: bash, curl, docker. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" EXTRACT="${HG_OSM_EXTRACT:-north-america/us/minnesota}" PLANETILER_IMAGE="${HG_PLANETILER_IMAGE:-ghcr.io/onthegomap/planetiler:0.9.2}" JAVA_MEMORY="${HG_PLANETILER_MEMORY:-3g}" log() { printf '\033[1;32m==>\033[0m %s\n' "$*"; } die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; } [[ "$EXTRACT" =~ ^[a-z0-9/-]+$ ]] || die "bad extract: $EXTRACT" host_path() { if command -v cygpath >/dev/null 2>&1; then cygpath -w "$1"; else printf '%s' "$1"; fi; } mkdir -p "$ROOT/data/build" "$ROOT/data/tiles" "$ROOT/data/downloads/osm" if [[ -n "${HG_OSM_PBF:-}" ]]; then # A file already under data/ (e.g. the audit's extracts): used as it is, never downloaded. [[ "$HG_OSM_PBF" =~ ^[A-Za-z0-9._/-]+\.osm\.pbf$ && "$HG_OSM_PBF" != *..* ]] || die "bad HG_OSM_PBF: $HG_OSM_PBF" [[ -f "$ROOT/data/$HG_OSM_PBF" ]] || die "no data/$HG_OSM_PBF" pbf="$HG_OSM_PBF" else pbf="downloads/osm/${EXTRACT//\//-}-latest.osm.pbf" if [[ -z "$(find "$ROOT/data/$pbf" -mtime -1 2>/dev/null)" ]]; then log "Downloading https://download.geofabrik.de/$EXTRACT-latest.osm.pbf" # -R keeps the server's date on the file: the extract date the tileset records. curl -fsSL -R --retry 3 -A "HuntGrid geodata pipeline" -o "$ROOT/data/$pbf.part" \ "https://download.geofabrik.de/$EXTRACT-latest.osm.pbf" mv -f "$ROOT/data/$pbf.part" "$ROOT/data/$pbf" fi fi log "Planetiler: backcountry portages, water and camp for $pbf" # MSYS_NO_PATHCONV: Git Bash must pass the container paths through unchanged. MSYS_NO_PATHCONV=1 docker run --rm -e JAVA_TOOL_OPTIONS="-Xmx$JAVA_MEMORY" \ -v "$(host_path "$ROOT/data"):/data" -v "$(host_path "$ROOT/tools/geodata/backcountry-osm"):/schema:ro" \ "$PLANETILER_IMAGE" generate-custom --schema=/schema/backcountry-osm.yml --osm_path="/data/$pbf" \ --tmpdir=/data/build/planetiler-backcountry-tmp --output=/data/build/backcountry-osm-features.pmtiles --force rm -rf "$ROOT/data/build/planetiler-backcountry-tmp" # The routes layer and the join run in the geotools image; they use no database (HG_DB_URL only satisfies `run`). # HG_DATA_DIR is pinned to ./data: Planetiler above read ./data, so `run` must mount the same folder as /data even when # the shell still exports another one (e.g. the fishing gazetteer build's HG_DATA_DIR). HG_DATA_DIR="$ROOT/data" HG_DB_URL="${HG_DB_URL:-unused}" HG_OSM_PBF="/data/$pbf" \ HG_FEATURES=/data/build/backcountry-osm-features.pmtiles "$ROOT/tools/geodata/run" backcountry-osm/routes rm -f "$ROOT/data/build/backcountry-osm-features.pmtiles" log "Done: data/tiles/backcountry-osm.pmtiles ($(du -h "$ROOT/data/tiles/backcountry-osm.pmtiles" | cut -f1))"