---
suivi: 1109
date: 2026-07-30
sujet: Foncier — affichage cadastral d’une parcelle (carte + import IGN)
chantier: module-foncier
type: feature
statut: poussé
hash: ed699d06
fichiers:
  - tools/diag/parcelle_geometries_srid_1109.php
  - app/Services/Foncier/IgnCadastreParcelleService.php
  - app/Services/Foncier/ParcelleGeometrieImportService.php
  - app/Models/ParcelleGeometrie.php
  - app/Http/Controllers/Foncier/ParcelleController.php
  - app/Http/Middleware/HandleInertiaRequests.php
  - routes/web.php
  - resources/js/Components/Foncier/ParcelleMap.vue
  - resources/js/Pages/Foncier/Parcelles/Show.vue
  - package.json
  - package-lock.json
  - public/build/
  - tests/Feature/Foncier/FoncierParcelleGeometrieIgnTest.php
  - tests/Feature/Foncier/FoncierParcelleGeometrieIgnSourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - docs/suivi/SUIVI_1109_foncier_affichage_cadastral_parcelle.md
---

## PROMPT ENVOYÉ

SUIVI #1109 — carte + import géométrie IGN pour UNE parcelle (hors Phase 2 multi).

## PHASE 1 — VÉRIFICATIONS

### SRID
- Migration #1074 : `geom GEOMETRY NOT NULL SRID 4326` + `SPATIAL INDEX`.
- Script `tools/diag/parcelle_geometries_srid_1109.php` (require relatif, lecture seule).
- Local (MariaDB) : table absente — syntaxe `SRID 4326` non supportée (prod = MySQL 8.4.10).
- **À exécuter en prod OVH** avant premier import massif : coller la sortie brute.
- Si SRS_ID=0 → STOP + migration corrective (non livrée ici car migration source = 4326).

### Dépendances carte
Aucune (Leaflet / MapLibre / OL / Google) dans package.json avant ce lot.
→ **Leaflet ajouté** (`leaflet`), chargé en **import dynamique** (chunk séparé).

### CSP
Aucune Content-Security-Policy applicative (middleware / headers PHP / public).
Tuiles `data.geopf.fr` et OSM accessibles (HTTP 200 testés sans clé).

## PHASE 2 — IMPORT IGN

### Forme réelle API
`GET https://apicarto.ign.fr/api/cadastre/parcelle?code_insee=&section=&numero=`
→ FeatureCollection GeoJSON :
- `features[].geometry` : MultiPolygon ou Polygon, coords lon/lat WGS84
- `features[].properties` : section, numero, contenance (m²), code_insee, idu, nom_com…

### Normalisation
- Section 1 car. → pad `0` (`A` → `0A`) ; 2 car. inchangé (`AB`).
- Numéro digits → pad 4 (`12` → `0012`).
- Variantes tentées si échec : normalisé, brut, section sans zéro, numéro non paddé.

### Persistance
`ST_GeomFromGeoJSON(geojson, 2, 4326)` (bit 2 = ordre lon/lat GeoJSON).
Upsert 1⇄1 ; source=`ign` ; centroide_lat/lng ; inversion anneaux si échec.

### Surface
ST_Area comparé à surface_cadastrale_m2 ; écart affiché ; Log::error si facteur >10 ou area minuscule.

### Réseau
Route WEB `POST …/geometrie/ign` uniquement — pas de commande artisan / job.

## PHASE 3 — AFFICHAGE

- `ParcelleMap.vue` : polygone, fitBounds, zoom, pas d’édition.
- Fond : **Plan IGN V2** via `data.geopf.fr` WMTS — **sans clé**, attribution « © IGN — Plan IGN V2 (Géoplateforme) ».
- Bouton import si `foncier.gestion` ; carte visible en lecture.
- GeoJSON manuel conservé.

### Poids bundle
- Leaflet chunk : ~149 Ko / **gzip ~43 Ko** (< 100 Ko compressés) — import dynamique OK.
- app.js : ~769 Ko gzip ~188 Ko (légèrement ↓ vs avant).

## NOTE A 1012 / INSEE
Le ticket cite « Clapiers, 34057 » : **34057 = Castelnau-le-Lez** ; Clapiers = 34077.
Appels réels IGN (2026-07-30) : `0A/1012` et variantes → **0 feature** (remaniement probable).
Import validé via Http::fake + polygone ~1000 m² ; AB/0001 (34057) existe réellement côté IGN (contenance 10570).

## LEÇON

Un SRID non vérifié produit des surfaces fausses mais plausibles — c’est la classe
d’erreur la plus difficile à détecter après coup.
