terrain2/verify_mbtiles_metadata.py
Fabio Micheluz 9603735519 first commit
2026-02-12 17:21:04 +01:00

122 lines
3.5 KiB
Python

#!/usr/bin/env python3
import sqlite3
import json
import subprocess
import sys
from pathlib import Path
def read_gdal_bounds(raster):
"""Legge i bounds WGS84 dal TIFF usando gdalinfo -json."""
info = subprocess.check_output(["gdalinfo", "-json", raster])
info = json.loads(info)
if "wgs84Extent" in info:
coords = info["wgs84Extent"]["coordinates"][0]
minlon, minlat = coords[0]
maxlon, maxlat = coords[2]
else:
cc = info["cornerCoordinates"]
minlon, minlat = cc["lowerLeft"]
maxlon, maxlat = cc["upperRight"]
# Normalizzazione latitudine
if minlat > maxlat:
minlat, maxlat = maxlat, minlat
return (minlon, minlat, maxlon, maxlat)
def read_mbtiles_metadata(mbtiles):
"""Legge metadata e tile info da un MBTiles."""
conn = sqlite3.connect(mbtiles)
cur = conn.cursor()
# Verifica tabella tiles
cur.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='tiles';")
if cur.fetchone()[0] == 0:
raise RuntimeError("La tabella 'tiles' non esiste nell'MBTiles.")
# Conta tile
cur.execute("SELECT COUNT(*) FROM tiles;")
tile_count = cur.fetchone()[0]
if tile_count == 0:
raise RuntimeError("La tabella 'tiles' è vuota.")
# Zoom min/max
cur.execute("SELECT MIN(zoom_level), MAX(zoom_level) FROM tiles;")
minzoom, maxzoom = cur.fetchone()
# Metadata
cur.execute("SELECT name, value FROM metadata;")
metadata = dict(cur.fetchall())
conn.close()
return tile_count, minzoom, maxzoom, metadata
def main():
if len(sys.argv) != 3:
print("Uso: python3 verify_mbtiles_metadata.py <raster.tif> <file.mbtiles>")
sys.exit(1)
raster = Path(sys.argv[1])
mbtiles = Path(sys.argv[2])
if not raster.exists():
print(f"Raster non trovato: {raster}")
sys.exit(1)
if not mbtiles.exists():
print(f"MBTiles non trovato: {mbtiles}")
sys.exit(1)
print("== Verifica metadata MBTiles ==")
# 1) Bounds dal TIFF
minlon, minlat, maxlon, maxlat = read_gdal_bounds(raster)
print(f"Bounds TIFF: {minlon},{minlat},{maxlon},{maxlat}")
# 2) Lettura MBTiles
tile_count, minzoom, maxzoom, metadata = read_mbtiles_metadata(mbtiles)
print(f"Tile count: {tile_count}")
print(f"Zoom effettivi: {minzoom}..{maxzoom}")
# 3) Confronto bounds
mb_bounds = metadata.get("bounds", None)
if mb_bounds:
mb_minlon, mb_minlat, mb_maxlon, mb_maxlat = map(float, mb_bounds.split(","))
print(f"Bounds MBTiles: {mb_bounds}")
if abs(mb_minlon - minlon) < 1e-4 and \
abs(mb_minlat - minlat) < 1e-4 and \
abs(mb_maxlon - maxlon) < 1e-4 and \
abs(mb_maxlat - maxlat) < 1e-4:
print("✔ Bounds OK")
else:
print("✘ Bounds NON corrispondono al TIFF")
else:
print("✘ Metadata 'bounds' mancante")
# 4) Confronto minzoom/maxzoom
if "minzoom" in metadata and "maxzoom" in metadata:
mz = int(metadata["minzoom"])
xz = int(metadata["maxzoom"])
if mz == minzoom and xz == maxzoom:
print("✔ minzoom/maxzoom OK")
else:
print(f"✘ minzoom/maxzoom NON coerenti: metadata={mz}..{xz}, reali={minzoom}..{maxzoom}")
else:
print("✘ Metadata minzoom/maxzoom mancanti")
# 5) Center
if "center" in metadata:
print(f"Center: {metadata['center']}")
else:
print("✘ Metadata 'center' mancante")
print("\n== Verifica completata ==")
if __name__ == "__main__":
main()