Ajouter la géométrie de planche PDF, l'accès aux sources par emprise L93 et reportlab

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 15:35:21 +02:00
parent 3b4d106cc2
commit 0955856876
6 changed files with 235 additions and 17 deletions

View File

@ -0,0 +1,69 @@
"""Tests de l'export PDF (planche d'impression terrain)."""
import pytest
def test_layout_landscape_a4_dimensions():
from lidar_pipeline.export_pdf import layout
lay = layout("A4", "paysage", 2000)
assert (lay.page_w, lay.page_h) == (297.0, 210.0) and lay.dpi == 300
assert lay.map_w > 150 and lay.map_h > 150
assert lay.panel_x >= lay.map_x + lay.map_w # bandeau à droite
assert lay.map_x + lay.map_w <= lay.page_w and lay.map_y + lay.map_h <= lay.page_h
def test_layout_portrait_a3_panel_below():
from lidar_pipeline.export_pdf import layout
lay = layout("A3", "portrait", 5000)
assert (lay.page_w, lay.page_h) == (297.0, 420.0) and lay.dpi == 250
assert lay.panel_y + lay.panel_h <= lay.map_y # bandeau en bas
@pytest.mark.parametrize("args", [("A5", "paysage", 2000), ("A4", "biais", 2000),
("A4", "paysage", 1234)])
def test_layout_rejects_invalid(args):
from lidar_pipeline.export_pdf import layout
with pytest.raises(ValueError):
layout(*args)
def test_map_bbox_matches_paper_times_scale():
from lidar_pipeline.export_pdf import layout, map_bbox
lay = layout("A4", "paysage", 2000)
b = map_bbox(652500.0, 6861500.0, lay)
assert abs((b[2] - b[0]) - lay.map_w / 1000 * 2000) < 1e-6
assert abs((b[3] - b[1]) - lay.map_h / 1000 * 2000) < 1e-6
assert abs((b[0] + b[2]) / 2 - 652500.0) < 1e-6
def test_pixel_size_and_grid_step():
from lidar_pipeline.export_pdf import grid_step, layout, pixel_size
assert pixel_size(layout("A4", "paysage", 1000)) == 0.2 # plafonné au natif
assert abs(pixel_size(layout("A3", "paysage", 10000)) - 10000 * 0.0254 / 250) < 1e-9
assert [grid_step(s) for s in (1000, 2000, 5000, 10000)] == [100, 100, 500, 1000]
def test_center_l93_rejects_non_finite():
from lidar_pipeline.export_pdf import center_l93
with pytest.raises(ValueError):
center_l93(float("nan"), 2.0)
def test_frame_roundtrip():
from lidar_pipeline.export_pdf import center_l93, frame
lat, lon = 48.85, 2.35
f = frame(lat, lon, "A4", "paysage", 2000)
cx, cy = center_l93(lat, lon)
assert abs(f["cx"] - cx) < 1e-6 and abs(f["cy"] - cy) < 1e-6
assert len(f["corners"]) == 4
nw, ne, se, sw = f["corners"]
assert nw[0] > sw[0] and ne[1] > nw[1] # [lat, lon] : nord en haut, est à droite
assert f["width_m"] > f["height_m"] > 0
def test_export_modules_import_without_numpy():
import subprocess, sys
code = ("import sys; sys.modules['numpy'] = None; "
"import lidar_pipeline.export_pdf, lidar_pipeline.tiles; print('ok')")
r = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
assert r.returncode == 0, r.stderr

View File

@ -166,6 +166,20 @@ def test_pick_tier_by_resolution(tmp_path):
assert tiles._pick_tier(tiers, 0.01)[0].res == tiers[-1][0].res
def test_sources_in_bbox_picks_tier(tmp_path):
from lidar_pipeline import tiles
_make_dalle(tmp_path, 1054, 6882, ["aspect"], px=64)
tiles.source_index(tmp_path, force=True)
bbox = (1054000.0, 6881000.0, 1055000.0, 6882000.0)
fine = tiles.sources_in_bbox(tmp_path, "aspect", bbox, 0.2)
coarse = tiles.sources_in_bbox(tmp_path, "aspect", bbox, 50.0)
assert fine and coarse and fine[0][0] == (1054, 6882)
assert min(s.res for _c, s in fine) <= min(s.res for _c, s in coarse)
assert tiles.sources_in_bbox(tmp_path, "aspect", (0, 0, 10, 10), 0.2) == []
img = tiles.load_source(fine[0][1])
assert img is not None and img.mode in ("RGB", "RGBA")
def test_subtiles_preferred_over_full_dalle(tmp_path):
"""Les quadrants index_subtiles servent de palier fin (4× moins à décoder)."""
import pytest