Ajouter la fiche de dalle IGN et la rose des vents, imposer la génération
Un clic sélectionne toujours la dalle sous le curseur (cadre sur la carte), générée ou non : emprise, rendu et recalage des passes s'affichent tout de suite ; la fiche IGN (date et heure du scan LiDAR, capteurs, mission, édition, nombre de points, lien de téléchargement du .copc.laz) arrive à part via /api/map/ign, mise en cache, sans jamais bloquer la sélection. Une rose des vents donne la couleur de chaque orientation de pente du relief orienté, avec la même formule CIELAB que le rendu. La génération impose la classification IGN (sol) et le raccord de 100 m avec les dalles voisines : plus de réglage dans la carte, défauts CLI alignés. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@ -70,6 +70,17 @@ def _bbox_wgs84(col, row):
|
||||
ys = [(row - 1) * 1000] * 2 + [row * 1000] * 2
|
||||
lons, lats = warp_transform('EPSG:2154', 'EPSG:4326', xs, ys)
|
||||
except Exception:
|
||||
lons = None
|
||||
if lons is None:
|
||||
try: # image légère (carte) : pyproj sans rasterio
|
||||
from pyproj import Transformer
|
||||
tr = Transformer.from_crs("EPSG:2154", "EPSG:4326", always_xy=True)
|
||||
xs = [col * 1000, (col + 1) * 1000, col * 1000, (col + 1) * 1000]
|
||||
ys = [(row - 1) * 1000] * 2 + [row * 1000] * 2
|
||||
lons, lats = tr.transform(xs, ys)
|
||||
except Exception:
|
||||
lons = None
|
||||
if lons is None:
|
||||
from .index import _approx_l93_to_wgs84
|
||||
pts = [_approx_l93_to_wgs84(x, y)
|
||||
for x in (col * 1000, (col + 1) * 1000)
|
||||
@ -93,12 +104,48 @@ def match_feature(features, col, row):
|
||||
def find_tile_url(col, row, timeout=20, max_pages=5):
|
||||
"""Cherche l'URL de téléchargement de la dalle (col,row) dans le catalogue STAC.
|
||||
|
||||
Suit la pagination du catalogue (lien rel=next) : sans elle, une dalle
|
||||
au-delà de la première page de résultats semblait « introuvable ».
|
||||
|
||||
Returns:
|
||||
URL (str) ou None si la dalle n'est pas (encore) publiée par l'IGN.
|
||||
"""
|
||||
feature = find_tile_feature(col, row, timeout=timeout, max_pages=max_pages)
|
||||
return feature.get("assets", {}).get("data", {}).get("href") if feature else None
|
||||
|
||||
|
||||
def tile_ign_metadata(col, row, timeout=10):
|
||||
"""Fiche IGN d'une dalle : acquisition, capteurs, édition, téléchargement.
|
||||
|
||||
Returns:
|
||||
dict normalisé (found=False si la dalle n'est pas publiée).
|
||||
"""
|
||||
feature = find_tile_feature(col, row, timeout=timeout)
|
||||
if not feature:
|
||||
return {"found": False}
|
||||
p = feature.get("properties", {})
|
||||
self_link = next((link.get("href") for link in feature.get("links", [])
|
||||
if link.get("rel") == "self"), None)
|
||||
return {
|
||||
"found": True,
|
||||
"download_url": feature.get("assets", {}).get("data", {}).get("href"),
|
||||
"acquisition_start": p.get("start_datetime") or p.get("lidarhd:date_debut_acquisition"),
|
||||
"acquisition_end": p.get("end_datetime") or p.get("lidarhd:date_fin_acquisition"),
|
||||
"sensors": p.get("lidarhd:capteur") or [],
|
||||
"mission": p.get("lidarhd:code_mission"),
|
||||
"acquisition_operator": p.get("lidarhd:moe_acquisition"),
|
||||
"acquisition_owner": p.get("lidarhd:moa_acquisition"),
|
||||
"edition_date": p.get("lidarhd:date_edition"),
|
||||
"classification_process": p.get("lidarhd:procede_classement"),
|
||||
"points": p.get("lidarhd:nombre_points") or p.get("pc:count"),
|
||||
"altimetry": p.get("lidarhd:systeme_altimetrique"),
|
||||
"stac_url": self_link,
|
||||
}
|
||||
|
||||
|
||||
def find_tile_feature(col, row, timeout=20, max_pages=5):
|
||||
"""Item STAC de la dalle (col,row), ou None si non publiée.
|
||||
|
||||
Suit la pagination du catalogue (lien rel=next) : sans elle, une dalle
|
||||
au-delà de la première page de résultats semblait « introuvable ».
|
||||
"""
|
||||
w, s, e, n = _bbox_wgs84(col, row)
|
||||
query = urllib.parse.urlencode({"bbox": f"{w:.6f},{s:.6f},{e:.6f},{n:.6f}", "limit": 50})
|
||||
url = f"{_STAC_ITEMS_URL}?{query}"
|
||||
@ -108,7 +155,7 @@ def find_tile_url(col, row, timeout=20, max_pages=5):
|
||||
data = json.loads(response.read().decode("utf-8"))
|
||||
feature = match_feature(data.get("features", []), col, row)
|
||||
if feature:
|
||||
return feature.get("assets", {}).get("data", {}).get("href")
|
||||
return feature
|
||||
nxt = next((link.get("href") for link in data.get("links", [])
|
||||
if link.get("rel") == "next" and link.get("href")), None)
|
||||
if not nxt:
|
||||
|
||||
Reference in New Issue
Block a user