Borner la mémoire de la carte (OOM du Pi) et rallumer le relief orienté par défaut

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 10:50:03 +02:00
parent 93317dadd0
commit 934e2dab55
6 changed files with 71 additions and 8 deletions

View File

@ -320,6 +320,31 @@ def test_defaults_roundtrip(tmp_path, monkeypatch):
assert mapserve.map_meta()["defaults_saved"] is False
def test_defaults_obsolete_layers_fall_back(tmp_path, monkeypatch):
"""Défauts figés sur des couches qui ne sont plus servies : registre.
Sinon un nouveau navigateur arrive sur une carte sans aucune couche
LiDAR allumée (cas de la prod après le passage au seul relief orienté).
"""
import json
import lidar_pipeline.mapserve as mapserve
_setup(tmp_path, monkeypatch, layers=("relief_oriente",))
defaults = tmp_path / ".map-defaults.json"
monkeypatch.setattr(mapserve, "DEFAULTS_FILE", defaults)
defaults.write_text(json.dumps({
"order": ["aspect", "positive_openness"],
"on": ["aspect", "positive_openness"], "opacity": {}, "blend": {},
"base": {"on": True, "opacity": 0.85, "dark": True},
"stack_blend": "normal"}), encoding="utf-8")
meta = mapserve.map_meta()
assert meta["default_layers"] == ["relief_oriente"]
# Tout éteint volontairement (couches connues) : respecté
defaults.write_text(json.dumps({
"order": ["relief_oriente"], "on": [], "opacity": {}, "blend": {},
"base": {}, "stack_blend": "normal"}), encoding="utf-8")
assert mapserve.map_meta()["default_layers"] == []
def test_defaults_sanitised(tmp_path, monkeypatch):
"""Couches inconnues écartées, opacités bornées, fusions validées."""
import lidar_pipeline.mapserve as mapserve

View File

@ -361,6 +361,27 @@ def test_source_cache_respects_memory_budget(tmp_path, monkeypatch):
assert tiles._source_cache == {}
def test_source_cache_holds_plain_decoded_images(tmp_path):
"""Le cache ne retient que les pixels : ni fichier ouvert ni décodeur.
Une image AVIF ouverte garde son décodeur (tampons libavif/dav1d) :
~43 Mo retenus par quadrant 2500² au lieu de 25 — le conteneur du Pi
(1 Go) était tué par l'OOM killer en navigation à fort zoom. Le budget
compte 4 octets/pixel : PIL stocke le RGB sur 32 bits.
"""
from PIL import Image
from lidar_pipeline import tiles
tiles.clear_source_cache()
f = tmp_path / "src.png"
Image.new("RGB", (40, 30), (10, 20, 30)).save(str(f))
img = tiles._open_source(str(f), f.stat().st_mtime)
assert type(img) is Image.Image
assert getattr(img, "fp", None) is None
assert img.info["_bytes"] == 40 * 30 * 4
assert img.getpixel((0, 0))[:3] == (10, 20, 30)
tiles.clear_source_cache()
def test_source_cache_keyed_by_mtime(tmp_path):
"""Une source réécrite n'est pas resservie depuis le cache."""
import os