#!/usr/bin/env bash # OpenStreetMap protected areas outside the US and Canada → geo.osm_public_lands → public-lands-osm.pmtiles # (docs/07 §5 and §12, roadmap 3.2b). Run through the geotools image: # # tools/geodata/run public-land/osm # Slovenia (dev default) # HG_OSM_EXTRACT=europe/france HG_OSM_COUNTRIES=FR tools/geodata/run public-land/osm # HG_OSM_PBF=/data/downloads/osm/planet.osm.pbf HG_OSM_COUNTRIES=ALL tools/geodata/run public-land/osm # # HG_OSM_COUNTRIES names the countries the file fully covers: only they are kept and replaced (a country extract # also holds slivers of its neighbours, which must not wipe a full import of those countries). # # ODbL: the rows live in their own table and tileset, never mixed with other licences (CLAUDE.md). One public-land # source per region: anything whose country is covered by PAD-US or CPCAD is dropped. Countries come from Natural # Earth (public domain). set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$HERE/../lib/common.sh" EXTRACT="${HG_OSM_EXTRACT:-europe/slovenia}" PBF="${HG_OSM_PBF:-}" COUNTRIES="${HG_OSM_COUNTRIES:-$([[ -z "${HG_OSM_EXTRACT:-}${PBF}" ]] && echo SI)}" [[ -n "$COUNTRIES" ]] || die "set HG_OSM_COUNTRIES to the ISO codes the file fully covers (or ALL for the planet)" countries_sql="null" if [[ "$COUNTRIES" != "ALL" ]]; then for c in $COUNTRIES; do [[ "$c" =~ ^[A-Z]{2}$ ]] || die "bad country code: $c"; done list="$(printf "'%s'," $COUNTRIES)" countries_sql="array[${list%,}]" fi COUNTRIES_URL="${HG_NATURAL_EARTH_COUNTRIES:-https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson}" if [[ -z "$PBF" ]]; then [[ "$EXTRACT" =~ ^[a-z0-9/-]+$ ]] || die "bad extract name: $EXTRACT" PBF="/data/downloads/osm/${EXTRACT//\//-}-latest.osm.pbf" SOURCE_URL="https://download.geofabrik.de/$EXTRACT-latest.osm.pbf" mkdir -p /data/downloads/osm # Geofabrik refreshes extracts daily; reuse a download from the last day. if [[ -z "$(find "$PBF" -mtime -1 2>/dev/null)" ]]; then log "Downloading $SOURCE_URL" curl -fsSL --retry 3 -A "HuntGrid geodata pipeline" -o "$PBF.part" "$SOURCE_URL" mv -f "$PBF.part" "$PBF" fi else SOURCE_URL="file://$PBF" fi [[ -f "$PBF" ]] || die "no OSM file at $PBF" VERSION="OpenStreetMap $(date -u -r "$PBF" +%Y-%m-%d)" psql_run -c "create schema if not exists staging" log "Countries (Natural Earth)" ogr2ogr -f PostgreSQL "PG:$HG_DB_URL" "/vsicurl/$COUNTRIES_URL" -nln staging.ne_countries -overwrite \ -lco GEOMETRY_NAME=geom -nlt PROMOTE_TO_MULTI -t_srs EPSG:4326 -select iso_a2_eh --config OGR_TRUNCATE YES log "Protected areas from $(basename "$PBF")" ogr2ogr -f PostgreSQL "PG:$HG_DB_URL" "$PBF" multipolygons -oo CONFIG_FILE="$HERE/osmconf.ini" \ -where "boundary IN ('protected_area','national_park') OR leisure = 'nature_reserve'" \ -nln staging.osm_protected -overwrite -lco GEOMETRY_NAME=geom -lco SPATIAL_INDEX=NONE -nlt PROMOTE_TO_MULTI \ --config OSM_MAX_TMPFILE_SIZE 1024 --config OGR_TRUNCATE YES fetched="$(psql_run -tA -c "select count(*) from staging.osm_protected")" log "Found $fetched areas" [[ "$fetched" -gt 0 ]] || die "no protected areas found; refusing to replace existing data" log "Catalog layer public-lands-osm" upsert_layer "$HERE/public-lands-osm.layer.json" log "Normalising into geo.osm_public_lands" psql_run <