Un programma per scaricare in automatico immagini Emit L2A da EarthData minizzando l'overlap, selezionando almeno una percentuale minima di terra ed una copertura nuvola
Da notare che Emit vola su ISS e quindi non e' eliosincrona
import earthaccess
import geopandas as gpd
from shapely.geometry import Polygon
from shapely.ops import unary_union
# ---------- parametri ----------
SHORT_NAME = "EMITL2ARFL"
VERSION = "002"
CLOUD_MAX = 5 # % nuvolosità massima del granulo
TEMPORAL = ("2022-08-01", "2026-10-18")
MIN_LAND = 0.20 # frazione minima del granulo su terra italiana
MAX_OVERLAP = 0.10 # max sovrapposizione con l'area già coperta
OUT_DIR = "./emit_italia"
DRY_RUN = False # True = solo elenco, senza scaricare, False scaricare le immagini
# ---------- contorno Italia ----------
URL = "https://naturalearth.s3.amazonaws.com/10m_cultural/ne_10m_admin_0_countries.zip"
world = gpd.read_file(URL)
italia = (world[world["ADM0_A3"] == "ITA"]
.to_crs(4326)
.union_all()
.buffer(0.05))
# ---------- ricerca ----------
earthaccess.login(persist="True")
granules = earthaccess.search_data(
short_name=SHORT_NAME,
version=VERSION,
bounding_box=(6.6, 35.5, 18.6, 47.1),
cloud_cover=(0, CLOUD_MAX),
temporal=TEMPORAL,
count=-1,
)
print(f"{len(granules)} granuli trovati nel box (versione {VERSION})")
def footprint(g):
pts = (g["umm"]["SpatialExtent"]["HorizontalSpatialDomain"]
["Geometry"]["GPolygons"][0]["Boundary"]["Points"])
return Polygon([(p["Longitude"], p["Latitude"]) for p in pts])
def cloud(g):
return float(g["umm"].get("CloudCover", 100))
# ---------- filtro: abbastanza terra italiana ----------
cands = []
for g in granules:
poly = footprint(g)
land = poly.intersection(italia)
if land.area / poly.area >= MIN_LAND:
cands.append((g, land))
print(f"{len(cands)} granuli con almeno {MIN_LAND:.0%} su terra italiana")
# ---------- greedy anti-sovrapposizione (solo parte terrestre) ----------
cands.sort(key=lambda x: cloud(x[0]))
selected, covered = [], None
for g, land in cands:
overlap = 0.0 if covered is None else land.intersection(covered).area / land.area
if overlap <= MAX_OVERLAP:
selected.append(g)
covered = land if covered is None else unary_union([covered, land])
print(f"{len(selected)} granuli selezionati")
if covered is not None:
print(f"copertura dell'Italia: {covered.intersection(italia).area / italia.area:.1%}")
for g in selected:
print(g["umm"]["GranuleUR"], f"cloud={cloud(g):.1f}%")
# ---------- link da scaricare (senza RFLUNCERT) ----------
links = []
for g in selected:
links += [u for u in g.data_links() if "RFLUNCERT" not in u]
print(f"{len(links)} file da scaricare")
for u in links[:6]:
print(" ", u.split("/")[-1])
# ---------- download ----------
if not DRY_RUN:
earthaccess.download(links, OUT_DIR)
165 granuli trovati nel box (versione 002)
52 granuli con almeno 20% su terra italiana
22 granuli selezionati
copertura dell'Italia: 31.7%
EMIT_L2A_RFL_002_20230204T101735 cloud=0.0%

Nessun commento:
Posta un commento