Skip to content

Cartes : annotation géographique avec des points, des lignes, des polygones et des régions

Tracez des points, des lignes et des polygones étiquetés sur une carte dans Potato, épinglez des lieux ou étiquetez des régions, sur un contour GeoJSON, une image géoréférencée, un GeoTIFF ou vos propres tuiles.

Nouveau dans la v2.12.0

geo_annotation place une carte sur la page d'annotation. Les annotateurs y tracent des points, des lignes et des polygones étiquetés, épinglent des lieux, ou attribuent des étiquettes aux régions d'un fond de carte. La carte est OpenLayers 10.9.0, que Potato sert lui-même ; aucune bibliothèque cartographique n'est donc chargée depuis Internet.

yaml
annotation_schemes:
  - annotation_type: geo_annotation
    name: land_cover
    description: "Outline the land cover"
    task: draw
    tools: [polygon, freehand, point]
    labels:
      - {name: Water, color: "#0072B2"}
      - {name: Forest, color: "#009E73"}
    basemap:
      geojson: maps/regions.geojson

Le dépôt Potato contient deux exemples exécutables. examples/advanced/dialect-map/ est une enquête dialectale par dessin sur carte portant sur un pays fictif, qui utilise les trois tâches (Dialectologie perceptive), et examples/image/geo-annotation/ délimite l'occupation du sol sur des images géoréférencées, une image par item, avec un polygone suggéré sur le premier item.

Tâches

taskCe que fait l'annotateurCe qui est stocké
draw (par défaut)Trace des points, des lignes, des polygones et des polygones à main levée, et attribue à chacun une étiquette, plus un nom saisi avec feature_textUne entité GeoJSON par tracé
pinPlace un point pour chaque étiquette. Chaque étiquette est une question, comme "Where were you born?"Un point par étiquette
classify_regionChoisit une étiquette, puis clique sur des régions du contour du fond de carte pour leur attribuer cette étiquette. Cliquer de nouveau sur une région avec la même étiquette l'effaceUne entité par région étiquetée, avec geometry: null et l'identifiant de la région

Le fond de carte

Chaque schéma a besoin d'un fond de carte, dans basemap ou par item via basemap_field, et sans fond de carte potato validate et le serveur refusent la configuration. Potato ne se replie pas sur une carte en ligne ; une étude ne charge donc aucune carte depuis Internet, sauf si sa configuration en désigne une.

SourceConfigurationRemarques
Contour GeoJSONbasemap: {geojson: maps/regions.geojson}Un fichier sous task_dir, intégré à la page. Gardez-le simplifié, quelques centaines de Ko au plus, car il fait partie de chaque page d'annotation
Image géoréférencéebasemap: {image: /media/area.png, extent: [min_lon, min_lat, max_lon, max_lat]}Un PNG ou un JPEG en projection plate carrée (équirectangulaire) couvrant extent
GeoTIFF ou Cloud Optimized GeoTIFFbasemap: {geotiff: /media/area.tif}Lu avec geotiff.js 3.0.5, fourni avec Potato. Le fichier doit être en EPSG:4326 ou EPSG:3857, et le navigateur doit prendre en charge WebGL
Tuiles XYZbasemap: {tiles: "https://tiles.example.org/{z}/{x}/{y}.png", attribution: "..."}Votre propre serveur de tuiles ou un fournisseur avec lequel vous avez un accord. attribution est obligatoire pour une URL externe, et {-y} est accepté pour la numérotation TMS

Un contour GeoJSON peut être combiné avec une source raster, et le contour est tracé par-dessus.

Les serveurs de tuiles de l'OpenStreetMap Foundation fonctionnent grâce à des ressources données, et leur politique d'utilisation des tuiles interdit un usage intensif. Une étude où de nombreux annotateurs font défiler une carte constitue un usage intensif ; Potato accepte donc l'URL avec un avertissement dans le journal. Hébergez vos propres tuiles ou utilisez un fournisseur commercial.

basemap_field désigne un champ de l'item qui contient son fond de carte : une FeatureCollection GeoJSON, une URL sous forme de chaîne (.tif et .tiff sont lus comme GeoTIFF, tout le reste comme GeoJSON), ou un objet avec les mêmes clés que basemap. Le serveur vérifie le fond de carte de chaque item selon les mêmes règles avant d'envoyer l'item, et un item ne peut désigner un serveur externe que si le basemap du schéma lui-même désigne une URL sur cet hôte.

Pour classify_region, chaque entité du contour est une région. Son identifiant est la propriété region_id_property (id par défaut), puis l'identifiant de l'entité GeoJSON, puis r<index>, et son nom est la propriété region_name_property (name par défaut).

Options

CléValeur par défautSignification
taskdrawdraw, pin ou classify_region
labelsobligatoireDes chaînes ou {name, color, description}. Les couleurs suivent par défaut une palette Okabe-Ito. Mettez entre guillemets Yes, No et On, que YAML charge sinon comme des booléens
tools[point, line, polygon, freehand]draw uniquement. Un outil de sélection et de déplacement est toujours ajouté
feature_textdésactivétrue, ou {prompt, required, placeholder} : un champ de texte par entité, stocké dans properties.text
basemapaucunegeojson, image, extent, geotiff, tiles, attribution, max_zoom, region_id_property, region_name_property
basemap_fieldaucuneChamp de l'item contenant un fond de carte propre à l'item
preannotation_fieldaucuneChamp de l'item contenant les entités GeoJSON de départ (pas pour classify_region)
coordinate_orderlonlatlatlon si les données de pré-annotation ou le contour écrivent la latitude en premier. La sortie est toujours [lon, lat]
projectionEPSG:3857Projection d'affichage, EPSG:3857 (Web Mercator) ou EPSG:4326. Le stockage est toujours en EPSG:4326
center, zoomajusté au fond de carteVue initiale, avec center: [lon, lat]
height440Hauteur de la carte en pixels, de 200 à 1200
snappingfalseAimante les nouveaux sommets aux entités existantes et au contour
min_features, max_features1 si obligatoire, aucunedraw uniquement. Les outils de dessin sont désactivés au maximum
require_all_regionsfalseclassify_region : chaque région doit recevoir une étiquette avant Next
label_requirementaucune{required: true} bloque Next tant que la condition propre à la tâche n'est pas remplie : min_features entités pour draw, une épingle par étiquette pour pin, au moins une région (ou toutes) pour classify_region

Utiliser la carte

Pour dessiner, choisissez une étiquette, puis un outil. Un point se place en un clic. Une ligne se trace avec un clic par point et un double-clic sur le dernier. Un polygone se trace avec un clic par sommet, et se termine en cliquant sur le premier sommet, en double-cliquant ou en appuyant sur Entrée ; Retour arrière supprime le dernier sommet et Échap annule. La main levée se trace en appuyant et en faisant glisser. L'outil de sélection remodèle une entité par son contour ou par un sommet, et Suppr la supprime. Chaque entité apparaît dans la liste sous la carte avec un menu d'étiquette, le champ de nom, Show et Delete.

Pour les épingles, la liste affiche une ligne par étiquette, et cliquer sur la carte place l'étiquette active. Pour les régions, choisissez un bouton d'étiquette et cliquez sur des régions.

Au clavier, allez jusqu'à la carte avec Tab ; les touches fléchées font alors défiler la carte, et + et - zooment. Add point at map centre et Use map centre placent des points sans souris, et l'étiquette, le nom et la suppression de chaque entité sont accessibles depuis la liste.

Les entités issues de preannotation_field sont marquées "(suggested)". Elles ne sont enregistrées comme réponse de l'annotateur que lorsque celui-ci en modifie une ou appuie sur Accept suggestions ; un item que l'annotateur a seulement ouvert ne compte donc pas comme étiqueté.

Données stockées

La réponse est une FeatureCollection GeoJSON en EPSG:4326 conforme à la RFC 7946 : les positions sont [longitude, latitude], les anneaux extérieurs tournent dans le sens inverse des aiguilles d'une montre et les trous dans le sens des aiguilles, les coordonnées ont 7 décimales (environ 1 cm), et les longitudes sont ramenées entre -180 et 180.

json
{"type": "FeatureCollection", "features": [
  {"type": "Feature", "id": "f1",
   "geometry": {"type": "Polygon", "coordinates": [[[-29.0, -38.3], [-28.2, -38.3], [-28.6, -37.5], [-29.0, -38.3]]]},
   "properties": {"label": "Very different", "text": "Coast talk", "tool": "polygon"}}
]}

Le schéma fonctionne aussi sur les pages de questionnaire, où il n'y a pas d'item ; basemap_field et preannotation_field n'y ont donc aucun effet.

Export

bash
# Every feature as GeoJSON, one file per item (geojson/<item>.geojson)
python -m potato.export --config config.yaml --format geojson --output out/
# ... or one file for the whole project
python -m potato.export --config config.yaml --format geojson --output out/ --option layout=single
 
# Heat maps of overlapping polygons, plus CSVs of names and region labels
python -m potato.export --config config.yaml --format geo_overlap --output out/

L'export GeoJSON normalise de nouveau chaque entité et ajoute item_id, user_id, schema et feature_id à ses propriétés. Les entités qui ne peuvent pas être normalisées, comme une position hors limites ou un anneau sans superficie, sont laissées de côté et listées dans les avertissements de l'export. Les réponses classify_region récupèrent la géométrie de leur région depuis le contour. geo_overlap est décrit dans Dialectologie perceptive.

Limites

  • Un polygone qui traverse le méridien de 180° n'est pas découpé ; tracez donc deux polygones.
  • Un GeoTIFF dans une projection autre qu'EPSG:4326 ou EPSG:3857 ne s'affiche pas, pas plus qu'un GeoTIFF quelconque sans WebGL. La page le signale, et le contour fonctionne toujours.
  • Un GeoTIFF est affiché sans interpolation ; zoomer montre donc les véritables limites des pixels.
  • Pour des coordonnées en pixels sur une image ordinaire plutôt que des coordonnées géographiques, utilisez l'annotation d'images.

Pour aller plus loin

Pour les détails d'implémentation, consultez la documentation source.