#!/usr/bin/env bash set -euo pipefail # -------------------------------------------------------------------- # Imposta metadati essenziali in un file .mbtiles (schema XYZ) # - Calcola bounds (ovest,sud,est,nord) dal raster sorgente (GeoTIFF/COG) # - Calcola center (lon,lat,zoom) # - Legge min/max zoom dalla tabella 'tiles' e li scrive nella 'metadata' # - Imposta name/format/type/attribution # # Requisiti: gdalinfo (GDAL), jq, sqlite3 # -------------------------------------------------------------------- # USO: # ./mbtiles_set_metadata.sh \ # --mbtiles aa.mbtiles \ # --raster aa_rgb.tif \ # [--name "Terrain RGB Adamello"] \ # [--type overlay|baselayer] \ # [--format png|jpg] \ # [--zoom ] \ # [--attribution " Copernicus DEM (GLO-30), ESA"] # # NOTE: # - 'bounds' e 'center' sono calcolati in EPSG:4326 (lon/lat). # - Se il raster non riassume esattamente lestensione delle tile, # passa un raster "clip" coerente con larea tilata. # - Lo script usa REPLACE INTO per compatibilit con SQLite < 3.24. # -------------------------------------------------------------------- # ---------- parsing argomenti ---------- MBTILES="" RASTER="" LAYER_NAME="" LAYER_TYPE="overlay" FORMAT="png" CENTER_Z="" ATTRIBUTION="" while [[ $# -gt 0 ]]; do case "$1" in --mbtiles) MBTILES="$2"; shift 2;; --raster) RASTER="$2"; shift 2;; --name) LAYER_NAME="$2"; shift 2;; --type) LAYER_TYPE="$2"; shift 2;; --format) FORMAT="$2"; shift 2;; --zoom) CENTER_Z="$2"; shift 2;; --attribution) ATTRIBUTION="$2"; shift 2;; -h|--help) sed -n '1,80p' "$0"; exit 0;; *) echo "Argomento sconosciuto: $1" >&2; exit 1;; esac done if [[ -z "$MBTILES" || -z "$RASTER" ]]; then echo "Uso: $0 --mbtiles --raster [opzioni]" >&2 exit 1 fi if [[ ! -f "$MBTILES" ]]; then echo "File MBTiles non trovato: $MBTILES" >&2; exit 1 fi if [[ ! -f "$RASTER" ]]; then echo "Raster non trovato: $RASTER" >&2; exit 1 fi command -v gdalinfo >/dev/null || { echo "gdalinfo non trovato"; exit 1; } command -v jq >/dev/null || { echo "jq non trovato"; exit 1; } command -v sqlite3 >/dev/null || { echo "sqlite3 non trovato"; exit 1; } # ---------- step 1: calcolo bounds dal raster (EPSG:4326) ---------- # Usiamo wgs84Extent se presente, altrimenti cornerCoordinates. # gdalinfo -json fornisce geometrie e corner coords in lon/lat. export LC_ALL=C export LANG=C GDAL_JSON="$(gdalinfo -json "$RASTER")" has_wgs84=$(echo "$GDAL_JSON" | jq 'has("wgs84Extent")') if [[ "$has_wgs84" == "true" ]]; then # Polygon ring: [ [minLon,minLat], [maxLon,minLat], [maxLon,maxLat], [minLon,maxLat], ... ] read -r MINLON MINLAT MAXLON MAXLAT <<<"$(echo "$GDAL_JSON" \ | jq -r '.wgs84Extent.coordinates[0] | [.[0][0], .[0][1], .[2][0], .[2][1]] | @tsv')" else # cornerCoordinates: upperLeft, lowerLeft, upperRight, lowerRight (lon,lat) read -r MINLON MINLAT MAXLON MAXLAT <<<"$(echo "$GDAL_JSON" \ | jq -r '.cornerCoordinates as $c | [$c.lowerLeft[0], $c.lowerLeft[1], $c.upperRight[0], $c.upperRight[1]] | @tsv')" fi # Arrotonda a 6 decimali per compattare la stringa printf -v BOUNDS "%.6f,%.6f,%.6f,%.6f" "$MINLON" "$MINLAT" "$MAXLON" "$MAXLAT" # ---------- step 2: calcolo center (lon,lat,zoom) ---------- # lon,lat = met dei bounds; zoom: se non fornito, media tra min e max zoom presenti nelle tile CTR_LON=$(awk -v a="$MINLON" -v b="$MAXLON" 'BEGIN{printf "%.6f",(a+b)/2.0}') CTR_LAT=$(awk -v a="$MINLAT" -v b="$MAXLAT" 'BEGIN{printf "%.6f",(a+b)/2.0}') # Leggi min/max zoom dalla tabella 'tiles' read -r TMIN TMAX <<<"$(sqlite3 "$MBTILES" "SELECT MIN(zoom_level), MAX(zoom_level) FROM tiles;")" if [[ -z "$TMIN" || -z "$TMAX" ]]; then echo "Attenzione: tabella 'tiles' vuota o mancante in $MBTILES" >&2 TMIN=0; TMAX=0 fi if [[ -z "${CENTER_Z}" ]]; then CENTER_Z=$(( (TMIN + TMAX) / 2 )) fi CENTER="${CTR_LON},${CTR_LAT},${CENTER_Z}" # ---------- step 3: definisci name/format/type/attribution ---------- if [[ -z "$LAYER_NAME" ]]; then # Usa il nome file come default base="$(basename "$MBTILES")" LAYER_NAME="${base%.*}" fi # ---------- step 4: crea tabella metadata (se non esiste) e scrivi i metadati ---------- sqlite3 "$MBTILES" < METADATA scritti in: $MBTILES" sqlite3 "$MBTILES" "SELECT name,value FROM metadata ORDER BY name;" echo echo "Zoom effettivi nelle tile: $(sqlite3 "$MBTILES" "SELECT MIN(zoom_level)||'..'||MAX(zoom_level) FROM tiles;")" echo "Bounds: $BOUNDS" echo "Center: $CENTER"