fix vecteur: extraction GPKG BD TOPO fiona >=1.9 (Geometry/date non s… #80
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI cross-platform | |
| on: | |
| push: | |
| paths: | |
| - 'lidar2map.py' | |
| - 'deploy.py' | |
| - 'tests/**' | |
| - 'providers/**' | |
| - 'pyproject.toml' | |
| - '.github/workflows/ci.yml' | |
| pull_request: | |
| paths: | |
| - 'lidar2map.py' | |
| - 'deploy.py' | |
| - 'tests/**' | |
| - 'providers/**' | |
| - 'pyproject.toml' | |
| - '.github/workflows/ci.yml' | |
| workflow_dispatch: | |
| jobs: | |
| # Lint rapide (quelques secondes) : échoue avant de payer la matrice 3 OS. | |
| # Règles F (pyflakes) seulement, config dans pyproject.toml : imports | |
| # inutilisés, variables mortes, noms non définis. Dès son premier run | |
| # local, a attrapé un F821 réel (variable supprimée encore référencée | |
| # dans une branche que ni py_compile ni les tests n'exercent). | |
| lint: | |
| name: ruff (pyflakes) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Installer ruff | |
| run: pip install ruff | |
| - name: Ruff check | |
| run: ruff check . | |
| test: | |
| name: ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| env: | |
| # Pas d'auto-install/venv dans le runner : les deps sont posées par pip | |
| # ci-dessous, et un manque doit échouer net (message clair) plutôt que | |
| # déclencher le bootstrap. | |
| LIDAR2MAP_BOOTSTRAP: none | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Installer les dependances Python | |
| # Liste alignée sur les deps OBLIGATOIRES de lidar2map (cf. | |
| # _installer_deps) : depuis le refactor rasterio, ijson/rasterio/ | |
| # fiona/certifi sont requis à l'import — l'ancienne ligne (pyproj | |
| # Pillow numpy scipy) est la raison des échecs CI d'avril 2026. | |
| run: pip install pyproj Pillow numpy scipy ijson rasterio fiona certifi | |
| - name: Syntaxe Python | |
| run: python -c "import ast; ast.parse(open('lidar2map.py', encoding='utf-8').read()); print('OK')" | |
| - name: Syntaxe _loader.py | |
| run: python -c "import ast; ast.parse(open('_loader.py', encoding='utf-8').read()); print('OK')" | |
| - name: Import complet sans erreur | |
| run: | | |
| python -c " | |
| import sys, types | |
| sys.argv = ['lidar2map.py', '--help'] | |
| try: | |
| import lidar2map | |
| except SystemExit: | |
| pass | |
| print('Import OK') | |
| " | |
| - name: help ignlidar | |
| run: python lidar2map.py --ignlidar --help | |
| - name: help ignraster | |
| run: python lidar2map.py --ignraster --help | |
| - name: help ignvecteur | |
| run: python lidar2map.py --ignvecteur --help | |
| - name: help fusionner | |
| run: python lidar2map.py --fusionner --source dummy.geojson --help | |
| - name: help osm | |
| run: python lidar2map.py --osm --help | |
| - name: _parser_departements | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| assert lidar2map._parser_departements('83') == ['83'] | |
| assert lidar2map._parser_departements('1-3') == ['01','02','03'] | |
| assert lidar2map._parser_departements('30,35,75') == ['30','35','75'] | |
| assert lidar2map._parser_departements('1-3,75,83') == ['01','02','03','75','83'] | |
| assert lidar2map._parser_departements('2A') == ['2A'] | |
| assert lidar2map._parser_departements('971') == ['971'] | |
| print('_parser_departements OK') | |
| " | |
| - name: _epsilon_depuis_surface_km2 | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| eps = lidar2map._epsilon_depuis_surface_km2 | |
| assert eps(100) == 3 / 111000 | |
| assert eps(500) == 8 / 111000 | |
| assert eps(9000) == 15 / 111000 | |
| assert eps(50000) == 25 / 111000 | |
| assert eps(200000)== 40 / 111000 | |
| print('_epsilon_depuis_surface_km2 OK') | |
| " | |
| - name: _hms | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| assert lidar2map._hms(5) == '5s' | |
| assert lidar2map._hms(90) == '1m30s' | |
| assert lidar2map._hms(3661) == '1h01m01s' | |
| print('_hms OK') | |
| " | |
| - name: normaliser_nom | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| assert lidar2map.normaliser_nom('Gareoult') == 'gareoult' | |
| assert lidar2map.normaliser_nom('Ile-de-France') == 'ile-de-france' | |
| assert lidar2map.normaliser_nom('Saint Jean') == 'saint_jean' | |
| print('normaliser_nom OK') | |
| " | |
| - name: _GEOFABRIK completude | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| codes = [f'{n:02d}' for n in range(1,20)] + [f'{n:02d}' for n in range(21,96)] | |
| codes += ['2A','2B','971','972','973','974','976'] | |
| print(f'Codes a couvrir : {len(codes)}') | |
| print('_GEOFABRIK structure OK') | |
| " | |
| - name: wgs84_to_lamb93_approx | |
| # Référence pyproj plutôt que bornes en dur : les anciennes bornes | |
| # (950000 < x) étaient fausses (X exact = 946880.8) et n'avaient | |
| # jamais été exercées, la CI tombant avant sur l'import. | |
| # Tolérance 50 m = précision documentée de l'approximation. | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| from pyproj import Transformer | |
| t = Transformer.from_crs('EPSG:4326', 'EPSG:2154', always_xy=True) | |
| xe, ye = t.transform(6.0423, 43.3156) | |
| x, y = lidar2map.wgs84_to_lamb93_approx(6.0423, 43.3156) | |
| assert abs(x - xe) < 50 and abs(y - ye) < 50, f'dx={x-xe:.1f}m dy={y-ye:.1f}m' | |
| print(f'wgs84_to_lamb93_approx OK : X={x:.1f} Y={y:.1f} (pyproj a {abs(x-xe)*100:.0f}/{abs(y-ye)*100:.0f} cm)') | |
| " | |
| - name: lamb93_to_wgs84_approx | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| from pyproj import Transformer | |
| t = Transformer.from_crs('EPSG:2154', 'EPSG:4326', always_xy=True) | |
| lon_e, lat_e = t.transform(960000, 6258000) | |
| lon, lat = lidar2map.lamb93_to_wgs84_approx(960000, 6258000) | |
| assert abs(lon - lon_e) < 0.0007 and abs(lat - lat_e) < 0.0005, f'dlon={lon-lon_e} dlat={lat-lat_e}' | |
| print(f'lamb93_to_wgs84_approx OK : lon={lon:.5f} lat={lat:.5f}') | |
| " | |
| - name: Historique lecture ecriture | |
| run: | | |
| python -c " | |
| import sys, tempfile, os | |
| from pathlib import Path | |
| sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| tmp = Path(tempfile.mkdtemp()) | |
| lidar2map._HISTORIQUE_PATH = tmp / 'historique.json' | |
| lidar2map._sauver_historique({'type':'osm','nom':'test','mode':'dep','dep':'83'}, 120, '/tmp/out') | |
| hist = lidar2map._lire_historique() | |
| assert len(hist) == 1 | |
| assert hist[0]['nom'] == 'test' | |
| assert hist[0]['dep'] == '83' | |
| assert hist[0]['duree'] == '2m00s' | |
| print('Historique OK') | |
| " | |
| - name: Platform flags | |
| run: | | |
| python -c " | |
| import sys; sys.argv=['lidar2map.py','--ignlidar','--help'] | |
| try: import lidar2map | |
| except SystemExit: pass | |
| import platform | |
| expected_win = platform.system() == 'Windows' | |
| expected_linux = platform.system() == 'Linux' | |
| expected_mac = platform.system() == 'Darwin' | |
| assert lidar2map.WINDOWS == expected_win, f'WINDOWS={lidar2map.WINDOWS}' | |
| assert lidar2map.LINUX == expected_linux, f'LINUX={lidar2map.LINUX}' | |
| assert lidar2map.MACOS == expected_mac, f'MACOS={lidar2map.MACOS}' | |
| print(f'Platform flags OK : WINDOWS={lidar2map.WINDOWS} LINUX={lidar2map.LINUX} MACOS={lidar2map.MACOS}') | |
| " | |
| # Tests de régression des calculs scientifiques (kernels Horn/SVF/openness, | |
| # LRM, RRIM, tuilage MBTiles/RMAP/SQLiteDB). Ubuntu uniquement : les calculs | |
| # sont identiques sur les 3 OS (numpy/numba), inutile de payer 3× la | |
| # compilation numba — le job 'test' ci-dessus couvre déjà la matrice OS | |
| # pour la syntaxe et les imports. | |
| tests-scientifiques: | |
| name: tests scientifiques (ubuntu) | |
| runs-on: ubuntu-latest | |
| env: | |
| LIDAR2MAP_BOOTSTRAP: none | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Installer les dependances calcul | |
| # numba pour les kernels + la liste obligatoire de lidar2map | |
| # (l'import sous bootstrap=none vérifie ijson/fiona/certifi aussi). | |
| run: pip install numpy scipy rasterio numba Pillow pyproj ijson fiona certifi | |
| - name: Tests calculs scientifiques | |
| run: python tests/_test_corrections.py | |
| - name: Tests tuilage MBTiles/RMAP/SQLiteDB | |
| run: python tests/_test_tiling.py |