Projeter les coins du bbox de zone (PROJ) au lieu d exiger un rectangle plein
This commit is contained in:
@ -917,19 +917,44 @@ def _build_subtiles(tile, offered_viz_keys, output_dir, sub_dir_name):
|
||||
return usable
|
||||
|
||||
|
||||
def _l93_points_to_wgs84_corners(xs, ys):
|
||||
"""Transforme des points L93 en [[lat, lon], …] (ordre conservé).
|
||||
|
||||
rasterio.warp (PROJ exact) si disponible, sinon pyproj, sinon
|
||||
l'approximation affine (webapp légère sans GDAL — précision ~km).
|
||||
Même transformation que attach_gps_bounds : les coins produits
|
||||
coïncident exactement avec ceux des dalles.
|
||||
"""
|
||||
try:
|
||||
from rasterio.warp import transform as warp_transform
|
||||
lons, lats = warp_transform('EPSG:2154', 'EPSG:4326', list(xs), list(ys))
|
||||
except ImportError:
|
||||
try:
|
||||
from pyproj import Transformer
|
||||
tr = Transformer.from_crs('EPSG:2154', 'EPSG:4326', always_xy=True)
|
||||
lons, lats = tr.transform(list(xs), list(ys))
|
||||
except ImportError:
|
||||
pairs = [_approx_l93_to_wgs84(x, y) for x, y in zip(xs, ys)]
|
||||
lons = [p[0] for p in pairs]
|
||||
lats = [p[1] for p in pairs]
|
||||
return [[la, lo] for la, lo in zip(lats, lons)]
|
||||
|
||||
|
||||
def _build_overview(zone_records, output_dir):
|
||||
"""Assemble les mosaïques d'overview par couche pour la vue dézoomée.
|
||||
|
||||
Une image WebP par (zone géographique × couche), couvrant la grille L93
|
||||
Une image WebP par (zone géographique × couche), couvrant le bbox L93
|
||||
des dalles de la zone (cases sans dalle transparentes), assemblée depuis
|
||||
les vignettes index_thumbs (256 px/km) : au dézoom l'interface l'affiche
|
||||
à la place des vignettes individuelles — 1 requête et ~30 Mo décodés par
|
||||
couche et par zone au lieu de centaines. Une mosaïque par zone : les
|
||||
grilles distantes (plusieurs secteurs, parfois à des centaines de km)
|
||||
n'ont pas de coins partagés et surtout pas la même échelle utile.
|
||||
Résolution plafonnée à 256 px/km et 3072 px de côté : l'overview n'est
|
||||
affiché que tant qu'il reste au moins 1:1 avec l'écran, jamais étiré
|
||||
donc jamais flou.
|
||||
n'ont pas de coins partagés et surtout pas la même échelle utile. Les
|
||||
coins du bbox sont projetés par la même transformation que les dalles —
|
||||
la mosaïque s'emboîte exactement sur les vignettes, même si la zone
|
||||
n'est pas un rectangle plein. Résolution plafonnée à 256 px/km et
|
||||
3072 px de côté : l'overview n'est affiché que tant qu'il reste au
|
||||
moins 1:1 avec l'écran, jamais étiré donc jamais flou.
|
||||
|
||||
Args:
|
||||
zone_records: enregistrements par zone ({'tiles': [dalle...]}) avec
|
||||
@ -960,28 +985,18 @@ def _build_overview(zone_records, output_dir):
|
||||
max_col = max(t['col'] for t in have)
|
||||
min_row = min(t['row'] for t in have)
|
||||
max_row = max(t['row'] for t in have)
|
||||
# Lattice exact des coins (km L93 → WGS84) : les coins partagés de
|
||||
# dalles voisines proviennent de la même transformation pyproj →
|
||||
# cohérents, la mosaïque s'emboîte exactement comme les vignettes.
|
||||
lattice = {}
|
||||
for t in have:
|
||||
c = t['corners']
|
||||
lattice[(t['col'], t['row'])] = c[0] # SW
|
||||
lattice[(t['col'] + 1, t['row'])] = c[1] # SE
|
||||
lattice[(t['col'] + 1, t['row'] + 1)] = c[2] # NE
|
||||
lattice[(t['col'], t['row'] + 1)] = c[3] # NW
|
||||
quad = [(min_col, min_row), (max_col + 1, min_row),
|
||||
(max_col + 1, max_row + 1), (min_col, max_row + 1)]
|
||||
if any(k not in lattice for k in quad):
|
||||
logger.debug(f"Overview : coins de grille absents pour "
|
||||
f"{zone.get('label', '?')} — zone ignorée")
|
||||
continue
|
||||
km_w = max_col + 1 - min_col
|
||||
km_h = max_row + 1 - min_row
|
||||
px_per_km = max(4, min(_OVERVIEW_PX_PER_KM,
|
||||
_OVERVIEW_MAX_PX // max(km_w, km_h)))
|
||||
w, h = km_w * px_per_km, km_h * px_per_km
|
||||
corners = [lattice[k] for k in quad]
|
||||
# Coins SW, SE, NE, NW du bbox L93 (dalle (col,row) : Y ∈ [(row−1),
|
||||
# row] km — cf. attach_gps_bounds), projetés comme les coins de dalles.
|
||||
xs = [min_col * 1000, (max_col + 1) * 1000,
|
||||
(max_col + 1) * 1000, min_col * 1000]
|
||||
ys = [(min_row - 1) * 1000, (min_row - 1) * 1000,
|
||||
max_row * 1000, max_row * 1000]
|
||||
corners = _l93_points_to_wgs84_corners(xs, ys)
|
||||
viz_keys = []
|
||||
for t in have:
|
||||
for k in t['viz']:
|
||||
|
||||
Reference in New Issue
Block a user