datex-nl-geo-fr
Conversion canonique entre langage naturel, DATEX II v3 et GeoJSON pour la signalisation routière française.
Bibliothèque Python autonome extraite du projet audit-iisr pour servir de brique réutilisable par tout outil traitant de la signalisation routière en France (gestionnaires de voirie, plateformes territoriales, applications de mobilité, exploitants DATEX II).
Vue d'ensemble
┌─── GeoSituation (modèle pivot canonique) ──┐
┌─────────┐ │ │ ┌──────────┐
│ Texte │ ─────▶│ from_pipeline_result / from_carto_click / │ ────▶│ DATEX II │
│ NL │ │ from_carto_polygon │ │ v3 XML │
└─────────┘ │ │ └──────────┘
│ to_text / to_datex_xml / to_geojson / │
┌─────────┐ │ to_pivot_context │ ┌──────────┐
│ Carto │ ─────▶│ │ ────▶│ GeoJSON │
│ (clic) │ │ merge() — patches NL + carto │ │ RFC 7946 │
└─────────┘ └────────────────────────────────────────────┘ └──────────┘
Installation
pip install datex-nl-geo-fr
ou depuis la source :
git clone https://gitlab.cerema.fr/nicolas.laval/datex-nl-geo-fr.git
cd datex-nl-geo-fr
pip install -e .[dev]
Utilisation rapide
Configuration LLM (provider-agnostique)
import os
from datex_nl_geo_fr.llm import OpenAICompatibleClient, set_default_llm
# Albert (DINUM) — recommandé secteur public français
set_default_llm(OpenAICompatibleClient(
base_url="https://albert.api.etalab.gouv.fr/v1",
api_key=os.environ["ALBERT_API_KEY"],
model="mistralai/Mistral-Small-3.2-24B-Instruct-2506",
))
# Ou OpenAI :
# set_default_llm(OpenAICompatibleClient(
# base_url="https://api.openai.com/v1",
# api_key=os.environ["OPENAI_API_KEY"],
# model="gpt-4o-mini",
# ))
# Ou Ollama local :
# set_default_llm(OpenAICompatibleClient(
# base_url="http://localhost:11434/v1",
# model="qwen2.5:14b",
# ))
# Ou un adapter custom (Anthropic SDK, vLLM custom, etc.) en
# implémentant le protocole LLMClient
NL → DATEX II + GeoJSON
import asyncio
from datex_nl_geo_fr.pipeline import resolve_location
from datex_nl_geo_fr.translator import GeoDatexTranslator
async def main():
text = "Zone 30 permanente avenue Pasteur à Bordeaux du numéro 10 au numéro 50"
result = await resolve_location(text) # utilise le LLM par défaut configuré
situation = GeoDatexTranslator.from_pipeline_result(result)
# Projections vers les formats cibles
print(GeoDatexTranslator.to_text(situation))
print(GeoDatexTranslator.to_geojson(situation))
print(GeoDatexTranslator.to_datex_xml(situation))
asyncio.run(main())
Cache géocodage personnalisé
from datex_nl_geo_fr.cache import GeoCache, set_default_cache
class RedisGeoCache:
"""Backend Redis pour partage inter-processus."""
def __init__(self, redis_url): ...
def get(self, key): ...
def set(self, key, value, ttl_seconds=86400): ...
set_default_cache(RedisGeoCache("redis://localhost:6379"))
# Désormais geocode_ban() et tous les drivers utilisent ce cache.
Sélection runtime du driver de référentiel routier
# Production (BD TOPO IGN Géoplateforme — recommandé)
export IISR_GEO_DRIVER=ign
# Fallback hors ligne
export IISR_GEO_DRIVER=osm
# PostGIS local (post-MVP, pour gros volumes)
export IISR_GEO_DRIVER=pgis
export PGIS_DSN="postgres://user@localhost/bdtopo"
Architecture
GeoSituation — modèle pivot canonique
Tout passe par cette structure Pydantic v2. Les méthodes from_* produisent une GeoSituation, les méthodes to_* la projettent vers un format cible. Les round-trips sont testés en CI.
| Champ | Type | Description |
|---|---|---|
troncons |
list[TronconMatch] |
Tronçons BD TOPO matchés (cleabs pérennes) |
repere_debut, repere_fin |
Optional[PointRepere] |
PR autoroute, numéro de voirie, BAN, etc. |
polygon_geojson |
Optional[dict] |
Polygone si zone dessinée |
commune_nom, commune_insee |
str |
Localisation administrative |
gestionnaires |
list[str] |
Domanialité (commune / dept / État) |
nature_voie, numero_route, nom_voie |
str |
Attributs métier |
sens |
Literal["aller","retour","bidirectionnel"] |
Sens de circulation |
type_zone |
Literal["lineaire","ponctuel","rayon","polygon"] |
Topologie |
Drivers de référentiel routier
| Driver | Source | Usage |
|---|---|---|
ign_geoplateforme |
WFS BD TOPO IGN | Recommandé prod — cleabs pérennes officiels |
osm_overpass |
Overpass API | Fallback hors ligne, démos rapides |
bdtopo_postgis |
PostGIS local | Volumes massifs (>10k tronçons par requête) |
Tous exposent la même interface : pick_at_point, troncons_by_name_in_commune, commune_geom, pois_around, etc.
Modules
| Module | Rôle |
|---|---|
translator.py |
GeoDatexTranslator — façade unique des conversions |
schema.py |
Modèles Pydantic v2 (GeoSituation, TronconMatch, PointRepere, POI) |
datex_builder.py |
Construction XML DATEX II v3 (linearByCode + linearByCoordinates + areaExtension) |
datex_merger.py |
Fusion DATEX importé + extraction interne |
openlr_encoder.py |
Encodeur OpenLR base64 pour linearByCode |
extractor.py |
Extraction NL → schema (LLM-driven optionnel) |
geocoders.py |
Wrappers BAN api-adresse, Nominatim |
map_matcher.py |
Map matching tronçons à partir d'un set de coordonnées |
pipeline.py |
Orchestration 4 phases (extraction → géocodage → matching → encodage) |
pipeline_inverse.py |
DATEX → NL via VLM PDF + résolution multi-voies BD TOPO |
drivers/ |
Plug-ins référentiels routiers |
cli.py |
Commande datex-geo standalone |
Tests
# Tests unitaires (sans réseau)
pytest -m "not network"
# Tests intégration (BAN + IGN WFS — vérité terrain)
pytest -m network
Licence
Distribué sous EUPL-1.2 (Licence Publique de l'Union Européenne) — compatible avec l'ouverture des composants logiciels du secteur public français.
Contributions
Issues et merge requests bienvenus sur gitlab.cerema.fr/nicolas.laval/datex-nl-geo-fr.
Crédits
Extrait du projet audit-iisr (CEREMA Méditerranée) — outil d'audit et de rédaction juridique pour la signalisation routière française. Voir CHANGELOG.md pour l'historique de cette extraction.
Metadata
Release files for datex-nl-geo-fr 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datex_nl_geo_fr-1.2.0.tar.gz | 72.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| datex_nl_geo_fr-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 144.6 kB
Release files / datex_nl_geo_fr-1.2.0.tar.gz
| Download URL | datex_nl_geo_fr-1.2.0.tar.gz |
|---|---|
| Size | 72.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4fb973be6309b46d72198ab3dc0dc43bb80510cb69e141479201fef4d55f4799
|
|
BLAKE2b-256 checksum How to use checksums |
6668831fc4d548812d46146268454da8c92810590c397cc0380457de471f5823
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.9
|
Release files / datex_nl_geo_fr-1.2.0-py3-none-any.whl
| Download URL | datex_nl_geo_fr-1.2.0-py3-none-any.whl |
|---|---|
| Size | 71.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1acf54c6ba95ada5611bf59ee58bc5e3220463568f6d070c0d636acb96ab3e21
|
|
BLAKE2b-256 checksum How to use checksums |
0a6b8223cd3cfd40ca53b7b91d7c4b46ac62809128daad44f991ab135b13ed6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.9
|