Borner le comblement du MNT à l'enveloppe des points, ajouter la couche précision et un affichage relief/précision, encoder les sous-tuiles une seule fois en q75
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@ -217,3 +217,52 @@ class TestCoreTileWindow:
|
||||
(637900, 6626900, 639100, 6628100), 1200)
|
||||
with rasterio.open(tif) as src:
|
||||
assert _core_tile_window(tif, src) is None
|
||||
|
||||
|
||||
class TestDensiteSolCrop:
|
||||
"""Densité de points : WebP sans perte en niveaux de gris, sous-tuiles
|
||||
écrites depuis l'image d'origine (un seul encodage)."""
|
||||
|
||||
def test_lossless_gray_levels_and_subtiles(self, tmp_path):
|
||||
from PIL import Image as PILImage
|
||||
from lidar_pipeline.rendering import tif_to_crop
|
||||
base = "LHD_FXX_0660_6701_PTS_LAMB93_IGN69"
|
||||
vis = tmp_path / "visualisations" / f"{base}_r0p2"
|
||||
vis.mkdir(parents=True)
|
||||
levels = np.tile(np.arange(16, dtype=np.float32).repeat(4), (64, 1)) # 64 × 64
|
||||
tif = TestTifToCrop._write_named_tif(vis, f"{base}_densite_sol.tif", levels)
|
||||
out = tif_to_crop(tif, vis, 0.2, output_format='avif', subtiles_dir=tmp_path)
|
||||
assert out is not None and out.suffix == ".webp"
|
||||
# WebP n'a pas de mode gris : relu en RGB à canaux égaux
|
||||
rgb = np.asarray(PILImage.open(str(out)).convert("RGB")).astype(int)
|
||||
assert (rgb[..., 0] == rgb[..., 1]).all() and (rgb[..., 1] == rgb[..., 2]).all()
|
||||
img = PILImage.fromarray(rgb[..., 0].astype(np.uint8))
|
||||
row = np.asarray(img)[0, ::4].astype(int)
|
||||
assert len(set(row.tolist())) == 16 and np.all(np.diff(row) > 0)
|
||||
# Sous-tuiles 2 × 2 (0,2 m/px) en WebP sans perte, identiques à la dalle
|
||||
q = tmp_path / "index_subtiles" / f"{base}_r0p2_densite_sol_0_1.webp"
|
||||
assert q.exists()
|
||||
assert np.array_equal(np.asarray(PILImage.open(str(q)).convert("L")), np.asarray(img)[:32, :32])
|
||||
assert (tmp_path / "index_subtiles" / f"{base}_r0p2_densite_sol_0_1_mid.webp").exists()
|
||||
|
||||
def test_relief_subtiles_encoded_from_source(self, tmp_path):
|
||||
"""Relief : sous-tuiles AVIF écrites par tif_to_crop, plus récentes que la dalle."""
|
||||
import pytest
|
||||
from lidar_pipeline.rendering import tif_to_crop
|
||||
base = "LHD_FXX_0660_6701_PTS_LAMB93_IGN69"
|
||||
vis = tmp_path / "visualisations" / f"{base}_r0p2"
|
||||
vis.mkdir(parents=True)
|
||||
rgb = np.random.default_rng(1).integers(0, 255, (3, 64, 64)).astype('uint8')
|
||||
tif = vis / f"{base}_relief_oriente.tif"
|
||||
with rasterio.open(tif, 'w', driver='GTiff', height=64, width=64, count=3,
|
||||
dtype='uint8', crs='EPSG:2154',
|
||||
transform=from_bounds(660000, 6700000, 661000, 6701000, 64, 64)) as dst:
|
||||
dst.write(rgb)
|
||||
try:
|
||||
out = tif_to_crop(tif, vis, 0.2, output_format='avif', subtiles_dir=tmp_path)
|
||||
except Exception:
|
||||
pytest.skip("encodeur AVIF indisponible")
|
||||
sub = tmp_path / "index_subtiles"
|
||||
quads = sorted(sub.glob(f"{base}_r0p2_relief_oriente_?_?.avif"))
|
||||
assert len(quads) == 4
|
||||
assert all(q.stat().st_mtime_ns >= out.stat().st_mtime_ns for q in quads)
|
||||
|
||||
Reference in New Issue
Block a user