« Sur les rives du Léman » — Apprendre aux machines à comprendre ce que vous voulez dire par un lieu
Frédéric Junod
Le problème
C’est un problème qui revient constamment dans les produits géospatiaux, et que presque personne n’a résolu proprement.
Les utilisateurs décrivent les lieux comme des humains :
« quelque part près du lac », « dans la vieille ville », « le long du Rhône », « à quelques kilomètres au nord de Zurich ».
C’est naturel, expressif et riche de sens.
Votre application, en revanche, attend une bounding box ou un polygone. Elle parle en coordonnées.
Ces deux représentations ne sont pas équivalentes, et c’est dans cet écart qu’une grande partie de la qualité produit se perd.
La solution naïve consiste à utiliser un géocodeur : transformer « Lausanne » en coordonnées puis dessiner un cercle. Cela fonctionne… jusqu’au moment où l’on traite « sur les rives du Léman » (qui ne correspond pas au centre du lac, mais à une bande de 1 km juste à l’extérieur du plan d’eau), ou « rive droite du Rhône » (qui dépend du sens d’écoulement, pas seulement de la géographie), ou encore « au cœur de Genève » (où l’on veut le noyau central de la ville, pas un simple tampon autour de l’hôtel de ville).
Ce ne sont pas des cas marginaux. Ce sont précisément les requêtes qui font qu’une application géolocalisée paraît intelligente… ou complètement à côté de la plaque.
Pourquoi nous avons créé etter
Chez Camptocamp, nous travaillons beaucoup à l’intersection de trois domaines : les infrastructures géospatiales, les systèmes de recherche et, désormais, les LLMs.
Un projet client a réuni ces trois dimensions. Nous devions interpréter des requêtes géographiques d’utilisateurs — en français, allemand, italien et anglais — puis les transformer en filtres spatiaux fiables exploitables par une base PostGIS.
Nous avons cherché une bibliothèque existante capable de gérer ce problème de bout en bout. Nous n’en avons trouvé aucune qui couvre l’ensemble de la chaîne : pas seulement le géocodage, pas seulement le NLP, mais bien l’enchaînement :
extraire l’intention spatiale → résoudre le lieu → appliquer une transformation géométrique
Nous avons donc construit notre propre solution, puis nous l’avons publiée en open source sous le nom etter — un mot du suisse allemand médiéval désignant la limite marquant le bord d’un village. Cela nous semblait approprié.
Comment ça fonctionne : l’architecture en trois couches
etter repose sur une architecture claire en trois couches. Comprendre ces couches est essentiel pour comprendre pourquoi la bibliothèque fonctionne.
Couche 1 — Analyse linguistique
Un GeoFilterParser prend une requête en langage naturel et utilise un LLM pour extraire un objet structuré GeoQuery.
Cet objet contient :
la relation spatiale (north_of, on_shores_of, right_bank)
le lieu de référence (Lausanne, Rhône, Lac Léman)
des paramètres optionnels comme une distance
Le LLM fait ce qu’il sait faire de mieux : compréhension sémantique, gestion multilingue, désambiguïsation.
Le résultat est un modèle Pydantic typé — aucune chaîne libre ne fuit vers les couches suivantes.
Couche 2 — Résolution géographique
Le GeoDataSource prend le lieu de référence extrait à l’étape précédente et le transforme en véritable géométrie.
etter est livré avec des adaptateurs pour :
SwissNames3D (toponymie fédérale suisse)
IGN BD-CARTO (données géographiques nationales françaises)
PostGIS (vos propres données)
Mais cette couche est volontairement flexible : le protocole repose sur une simple interface Python. Vous pouvez donc l’implémenter sur n’importe quelle source :
une API REST
un fichier GeoJSON
un dataset en mémoire
un géocodeur tiers
toute base de données spatiale compatible avec votre infrastructure
Aucun backend spécifique n’est imposé. Combiner ou remplacer des sources de données est un cas d’usage prévu dès la conception.
Couche 3 — Opérations spatiales
C’est ici que la géométrie est réellement façonnée.
La fonction apply_spatial_relation() prend la géométrie résolue et applique la transformation spatiale définie par la relation.
Par exemple :
« au nord de Lausanne » devient un secteur de 10 km orienté vers le nord
« sur les rives du Léman » devient un anneau tampon de 1 km autour du contour du lac, sans inclure l’eau
« rive droite du Rhône » utilise le sens d’écoulement du fleuve pour déterminer quel côté correspond à la rive droite
Le résultat final est une géométrie GeoJSON directement exploitable comme filtre spatial dans une requête de recherche.
Le catalogue de relations spatiales
etter prend actuellement en charge 15 relations spatiales réparties en trois catégories.
Contenance
in — correspondance exacte avec une limite géographique
Proximité / tampon
near — distance contextuelle (5 km par défaut, mais le LLM adapte l’échelle selon l’intention de la requête — « près de la Tour Eiffel » n’implique pas la même distance que « près de Paris »)
on_shores_of — anneau de 1 km depuis la frontière d’un plan d’eau, sans inclure l’eau
along — tampon de 500 m autour d’éléments linéaires (rivières, routes)
left_bank / right_bank — tampon d’un seul côté d’un élément linéaire, relatif au sens d’écoulement
in_the_heart_of — érosion de la géométrie pour isoler son noyau central
Directionnelles
Toutes les directions cardinales et diagonales sont supportées :
north_of
south_of
east_of
west_of
northeast_of
southeast_of
southwest_of
northwest_of
Chaque relation génère un secteur géométrique de 10 km couvrant 90°.
Chaque relation possède sa propre logique géométrique. Un tampon depuis le centre d’un lac n’est pas équivalent à un tampon depuis sa frontière. Un secteur directionnel n’est pas un demi-cercle.
Ces distinctions sont importantes.
Le catalogue est extensible : vous pouvez définir et enregistrer vos propres relations spatiales et implémenter la logique géométrique adaptée à votre domaine métier.
La stack technique
Python, évidemment.
Les principales dépendances sont :
LangChain — pour l’intégration des LLMs. etter utilise init_chat_model, ce qui permet de brancher OpenAI, Anthropic, un modèle local ou toute autre infrastructure. La bibliothèque est indépendante du fournisseur par conception.
Shapely — pour les opérations géométriques
Pydantic — pour garantir des structures de données typées tout au long du pipeline
Installation :
pip install etter
# ou avec le support PostGIS :
pip install etter[postgis]
Exemple minimal
Voici un exemple fonctionnel minimal :
from langchain.chat_models import init_chat_model
from etter import GeoFilterParser
llm = init_chat_model(model="gpt-4o", temperature=0, api_key="...")
parser = GeoFilterParser(llm=llm)
result = parser.parse("sur les rives du Léman")
# result.spatial_relation → "on_shores_of"
# result.reference_location → "Lake Geneva"
# result.confidence → 0.97
Les couches 2 et 3 résolvent ensuite le lieu et produisent la géométrie finale.
L’API de démonstration fournie avec etter utilise SwissNames3D et montre le flux complet de bout en bout.
La bibliothèque prend également en charge le streaming, ce qui est utile pour les interfaces réactives : vous obtenez une transparence en temps réel sur le raisonnement du LLM pendant le traitement de la requête, et pas seulement un résultat final.
Ce qui manque encore
etter gère déjà correctement les requêtes simples.
Les requêtes composées (« au nord de Lausanne mais pas trop près de l’autoroute ») et les requêtes fractionnées (« entre Berne et Zurich ») ne sont pas encore implémentées.
Ces fonctionnalités figurent sur la feuille de route, mais nous voulions publier le cœur de la bibliothèque avant tout.
Pourquoi l’open source
Camptocamp construit des solutions open source depuis plus de 25 ans. Nous contribuons à QGIS, OpenLayers, GeoServer et de nombreux autres projets.
etter s’inscrit naturellement dans cette tradition : nous avons créé quelque chose d’utile pour résoudre un problème réel, et nous préférons le rendre accessible à la communauté plutôt que de le laisser dormir dans un dépôt privé.
Si vous construisez quelque chose avec etter, nous serions ravis de le savoir.
Et si vous trouvez la bibliothèque utile et souhaitez un accompagnement expert en ingénierie géospatiale autour de ce type de problématique, c’est exactement ce que fait Camptocamp.
Mais sans aucune obligation : la bibliothèque fonctionne très bien de manière autonome.
Le dépôt GitHub est disponible ici : https://github.com/geoblocks/etter
La documentation est disponible ici : https://geoblocks.github.io/etter/
Carrière
Vous souhaitez travailler dans un environnement inspirant et rejoindre nos équipes motivées et multiculturelles ?