-
Notifications
You must be signed in to change notification settings - Fork 2
269 lines (238 loc) · 9.7 KB
/
Copy pathci.yml
File metadata and controls
269 lines (238 loc) · 9.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
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