lidar-maps : navigation en cache seule et pyramide entretenue en tâche de fond
Sur une petite machine (Raspberry Pi), LIDAR_TILE_CACHE_ONLY sert les tuiles depuis le cache uniquement (tuile absente = transparente non mémorisable, X-Tile-Pending) et LIDAR_TILE_BACKGROUND fait surveiller les dalles par un sondeur : chaque dalle nouvelle ou régénérée par le worker remet sa pyramide en file, rendue à basse priorité et au ralenti. Scan et état pilotables via /api/map/background, pré-calcul exhaustif toujours via /api/map/warm.
This commit is contained in:
@ -325,6 +325,15 @@ def _cell_bounds(col, row):
|
||||
return (col * 1000.0, (row - 1) * 1000.0, (col + 1) * 1000.0, row * 1000.0)
|
||||
|
||||
|
||||
def cell_bounds_wgs84(col, row):
|
||||
"""Emprise WGS84 [ouest, sud, est, nord] d'une dalle LHD (4 coins L93)."""
|
||||
min_x, min_y, max_x, max_y = _cell_bounds(col, row)
|
||||
xs = (min_x, min_x, max_x, max_x)
|
||||
ys = (min_y, max_y, min_y, max_y)
|
||||
lons, lats = _transformer("EPSG:2154", "EPSG:4326").transform(xs, ys)
|
||||
return (min(lons), min(lats), max(lons), max(lats))
|
||||
|
||||
|
||||
def _dir_mtime(path):
|
||||
try:
|
||||
return path.stat().st_mtime
|
||||
@ -780,6 +789,37 @@ def empty_marker_exists(output_dir, layer, z, x, y, scale=1, fmt="png"):
|
||||
scale, fmt).with_suffix(".empty").exists()
|
||||
|
||||
|
||||
def cached_tile(output_dir, layer, z, x, y, scale=1, fmt="png"):
|
||||
"""Tuile depuis le cache UNIQUEMENT — jamais de rendu (mode cache seule).
|
||||
|
||||
Retourne ``(data, état)`` :
|
||||
- ``"fresh"`` : tuile en cache et plus récente que ses dalles sources ;
|
||||
- ``"empty"`` : aucune source n'intersecte (marqueur `.empty` posé) ;
|
||||
- ``"pending"``: donnée présente mais tuile absente ou périmée — à rendre
|
||||
ailleurs (tâche de fond, pré-chauffage), pas au fil de la navigation.
|
||||
"""
|
||||
cache = tile_cache_path(output_dir, layer, z, x, y, scale, fmt)
|
||||
empty = cache.with_suffix(".empty")
|
||||
sources = _contributing(output_dir, layer, z, x, y, scale)
|
||||
if not sources:
|
||||
if not empty.exists():
|
||||
_write_atomic(empty, b"")
|
||||
return None, "empty"
|
||||
if empty.exists():
|
||||
return None, "empty"
|
||||
newest = 0.0
|
||||
for src in sources:
|
||||
m = src.mtime()
|
||||
if m and m > newest:
|
||||
newest = m
|
||||
try:
|
||||
if cache.stat().st_mtime >= newest:
|
||||
return cache.read_bytes(), "fresh"
|
||||
except OSError:
|
||||
pass
|
||||
return None, "pending"
|
||||
|
||||
|
||||
def transparent_tile(scale=1, fmt="png"):
|
||||
"""Tuile entièrement transparente (zone sans donnée)."""
|
||||
from PIL import Image
|
||||
|
||||
Reference in New Issue
Block a user