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/