Translate the whole project to English and fix outdated comments and help

Comments, docstrings, logs, CLI help, map UI, legends, PDF sheet, scripts,
compose files and AGENTS.md are now English. Data keys stay unchanged
(relief_oriente, densite_sol, visualisations/, API JSON keys, link params).
Wrong comments and help defaults found along the way are corrected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine
2026-09-27 23:16:45 +02:00
parent cc1c22d2b8
commit fb892ea9f2
52 changed files with 4356 additions and 4323 deletions

View File

@ -1,15 +1,15 @@
"""Tests du téléchargement des dalles LiDAR HD de l'IGN (fetch_ign)."""
"""Tests for IGN LiDAR HD tile downloads (fetch_ign)."""
def test_parse_tile_specs():
"""Accepte 'col,row', 'col:row' et ignore les espaces."""
"""Accepts 'col,row', 'col:row' and ignores whitespace."""
from lidar_pipeline.fetch_ign import parse_tile_specs
assert parse_tile_specs(["1055,6882"]) == [(1055, 6882)]
assert parse_tile_specs(["1055:6883", " 651 , 6630 "]) == [(1055, 6883), (651, 6630)]
def test_parse_tile_specs_rejects_invalid():
"""Les spécifications mal formées lèvent une erreur explicite."""
"""Malformed specifications raise an explicit error."""
import pytest
from lidar_pipeline.fetch_ign import parse_tile_specs
with pytest.raises(ValueError):
@ -21,14 +21,14 @@ def test_parse_tile_specs_rejects_invalid():
def test_tile_filename_pads_coordinates():
"""Le nom de fichier DALLE utilise des coordonnées à 4 chiffres."""
"""The tile file name uses 4-digit coordinates."""
from lidar_pipeline.fetch_ign import tile_filename
assert tile_filename(1055, 6882) == "LHD_FXX_1055_6882_PTS_LAMB93_IGN69.copc.laz"
assert tile_filename(651, 6630) == "LHD_FXX_0651_6630_PTS_LAMB93_IGN69.copc.laz"
def test_match_feature_uses_coordonnees_nw():
"""La correspondance se fait sur lidarhd:coordonnees_NW (format 0816-6847)."""
"""Matching uses lidarhd:coordonnees_NW (0816-6847 format)."""
from lidar_pipeline.fetch_ign import match_feature
features = [
{"id": "LHD_FXX_1054_6882_PTS_LAMB93_IGN69_NE",
@ -43,7 +43,7 @@ def test_match_feature_uses_coordonnees_nw():
def test_find_tile_url_matches_and_returns_href(monkeypatch):
"""find_tile_url interroge le STAC et retourne l'href de l'asset data."""
"""find_tile_url queries the STAC API and returns the data asset href."""
from lidar_pipeline import fetch_ign
class FakeResponse:
@ -75,7 +75,7 @@ def test_find_tile_url_matches_and_returns_href(monkeypatch):
def test_fetch_tiles_skips_existing_and_generated(tmp_path, monkeypatch):
"""Pas de téléchargement si le LAZ existe ou si les visualisations existent."""
"""No download if the LAZ exists or if visualisations exist."""
from lidar_pipeline import fetch_ign
input_dir = tmp_path / "input"
@ -84,13 +84,13 @@ def test_fetch_tiles_skips_existing_and_generated(tmp_path, monkeypatch):
vis_dir = output_dir / "visualisations" / "LHD_FXX_1054_6882_PTS_LAMB93_IGN69"
vis_dir.mkdir(parents=True)
# 1054,6882 : visualisations déjà générées
# 1055,6882 : LAZ déjà présent
# 1054,6882: visualisations already generated
# 1055,6882: LAZ already present
existing = input_dir / fetch_ign.tile_filename(1055, 6882)
existing.write_bytes(b"naze")
def fail_download(*args, **kwargs):
raise AssertionError("ne doit pas être appelé")
raise AssertionError("must not be called")
monkeypatch.setattr(fetch_ign, "find_tile_url", fail_download)
result = fetch_ign.fetch_tiles(input_dir, [(1054, 6882), (1055, 6882)],
@ -99,10 +99,10 @@ def test_fetch_tiles_skips_existing_and_generated(tmp_path, monkeypatch):
def _make_viz_dirs(output_dir, col, row, viz_keys, resolutions=(0.5, 0.2)):
"""Crée les dossiers de visualisations d'une tuile (une entrée par résolution).
"""Create a tile's visualisation directories (one per resolution).
Le suffixe de résolution n'est que sur le DOSSIER : les fichiers gardent
le basename nu (cf. _expected_output_path dans le pipeline).
The resolution suffix is only on the DIRECTORY: files keep the bare
basename (see _expected_output_path in the pipeline).
"""
base = f"LHD_FXX_{col:04d}_{row:04d}_PTS_LAMB93_IGN69"
for res in resolutions:
@ -114,21 +114,21 @@ def _make_viz_dirs(output_dir, col, row, viz_keys, resolutions=(0.5, 0.2)):
def test_fetch_tiles_downloads_incomplete_tile(tmp_path, monkeypatch):
"""Une tuile incomplète (visualisation manquante) est téléchargée, une complète non."""
"""An incomplete tile (missing visualisation) is downloaded, a complete one is not."""
from pathlib import Path
from lidar_pipeline import fetch_ign
input_dir = tmp_path / "input"
input_dir.mkdir()
output_dir = tmp_path / "output"
_make_viz_dirs(output_dir, 1054, 6882, ["aspect"]) # slope manquant
_make_viz_dirs(output_dir, 1055, 6882, ["aspect", "slope"]) # complète
_make_viz_dirs(output_dir, 1054, 6882, ["aspect"]) # slope missing
_make_viz_dirs(output_dir, 1055, 6882, ["aspect", "slope"]) # complete
calls = []
def fake_find_tile_url(col, row, timeout=20):
calls.append((col, row))
return "https://example.org/dalle.copc.laz"
return "https://example.org/tile.copc.laz"
def fake_download(url, dest, timeout=120, chunk=1024 * 1024):
Path(dest).write_bytes(b"laz")
@ -141,13 +141,13 @@ def test_fetch_tiles_downloads_incomplete_tile(tmp_path, monkeypatch):
output_dir=output_dir,
only_viz=["aspect", "slope"],
resolutions=(0.5, 0.2))
# Seule la tuile incomplète est retéléchargée
# Only the incomplete tile is downloaded again
assert calls == [(1054, 6882)]
assert [p.name for p in result] == [fetch_ign.tile_filename(1054, 6882)]
def test_fetch_tiles_promotes_edge_neighbor_copy(tmp_path, monkeypatch):
"""Une dalle déjà téléchargée comme voisine est déplacée dans input/ sans réseau."""
"""A tile already downloaded as a neighbour is moved to input/ without network access."""
from lidar_pipeline import fetch_ign
input_dir = tmp_path / "input"
@ -159,7 +159,7 @@ def test_fetch_tiles_promotes_edge_neighbor_copy(tmp_path, monkeypatch):
neighbor_copy.write_bytes(b"laz-voisine")
def fail(*args, **kwargs):
raise AssertionError("ne doit pas être appelé (pas de réseau attendu)")
raise AssertionError("must not be called (no network expected)")
monkeypatch.setattr(fetch_ign, "find_tile_url", fail)
monkeypatch.setattr(fetch_ign, "download_file", fail)
@ -168,27 +168,27 @@ def test_fetch_tiles_promotes_edge_neighbor_copy(tmp_path, monkeypatch):
assert not neighbor_copy.exists()
assert (input_dir / name).read_bytes() == b"laz-voisine"
assert result == [] # promotion = "skip", comme le cas déjà-présent
assert result == [] # promotion = "skip", like the already-present case
def test_fetch_tiles_does_not_promote_when_called_on_edge_dir(tmp_path, monkeypatch):
"""Appel avec input_dir=edge_dir (cas _fetch_edge_neighbors) : jamais de promotion."""
"""Call with input_dir=edge_dir (_fetch_edge_neighbors case): never promotes."""
from lidar_pipeline import fetch_ign
edge_dir = tmp_path / "input" / "edge_neighbors"
edge_dir.mkdir(parents=True)
inner_edge = edge_dir / "edge_neighbors"
name = fetch_ign.tile_filename(1055, 6882)
# Même si un dossier edge_neighbors/edge_neighbors/<name> existait par
# accident, il ne doit jamais être déplacé vers edge_dir/<name>.
# Even if an edge_neighbors/edge_neighbors/<name> directory existed by
# accident, it must never be moved to edge_dir/<name>.
inner_edge.mkdir()
(inner_edge / name).write_bytes(b"ne-doit-pas-bouger")
(inner_edge / name).write_bytes(b"must-not-move")
calls = []
def fake_find_tile_url(col, row, timeout=20):
calls.append((col, row))
return "https://example.org/dalle.copc.laz"
return "https://example.org/tile.copc.laz"
def fake_download(url, dest, timeout=120, chunk=1024 * 1024):
from pathlib import Path
@ -200,14 +200,14 @@ def test_fetch_tiles_does_not_promote_when_called_on_edge_dir(tmp_path, monkeypa
result = fetch_ign.fetch_tiles(edge_dir, [(1055, 6882)])
assert calls == [(1055, 6882)] # téléchargée normalement, pas promue
assert (inner_edge / name).read_bytes() == b"ne-doit-pas-bouger"
assert calls == [(1055, 6882)] # downloaded normally, not promoted
assert (inner_edge / name).read_bytes() == b"must-not-move"
assert (edge_dir / name).read_bytes() == b"laz"
assert len(result) == 1
def test_fetch_tiles_force_downloads_complete(tmp_path, monkeypatch):
"""force=True télécharge même une tuile complète (régénération avec --force)."""
"""force=True downloads even a complete tile (regeneration with --force)."""
from pathlib import Path
from lidar_pipeline import fetch_ign
@ -220,7 +220,7 @@ def test_fetch_tiles_force_downloads_complete(tmp_path, monkeypatch):
def fake_find_tile_url(col, row, timeout=20):
calls.append((col, row))
return "https://example.org/dalle.copc.laz"
return "https://example.org/tile.copc.laz"
def fake_download(url, dest, timeout=120, chunk=1024 * 1024):
Path(dest).write_bytes(b"laz")