Skip to content

Karten: Geografische Annotation mit Punkten, Linien, Polygonen und Regionen

In Potato beschriftete Punkte, Linien und Polygone auf eine Karte zeichnen, Orte markieren oder Regionen beschriften, über einem GeoJSON-Umriss, einem georeferenzierten Bild, einem GeoTIFF oder eigenen Kacheln.

Neu in v2.12.0

geo_annotation bringt eine Karte auf die Annotationsseite. Annotatoren zeichnen darauf beschriftete Punkte, Linien und Polygone, setzen Stecknadeln an Orte oder vergeben Labels an die Regionen einer Umrisskarte. Die Karte ist OpenLayers 10.9.0, das Potato selbst ausliefert, sodass keine Kartenbibliothek aus dem Internet geladen wird.

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

Das Potato-Repository enthält zwei lauffähige Beispiele. examples/advanced/dialect-map/ ist eine Draw-a-Map-Dialektbefragung über ein fiktives Land, die alle drei Aufgaben verwendet (Perzeptive Dialektologie), und examples/image/geo-annotation/ umrandet die Landbedeckung auf georeferenzierten Bildern, ein Bild pro Item, mit einem vorgeschlagenen Polygon auf dem ersten Item.

Aufgaben

taskWas der Annotator tutWas gespeichert wird
draw (Standard)Zeichnet Punkte, Linien, Polygone und Freihandpolygone und gibt jedem ein Label, mit feature_text dazu einen eingetippten NamenEin GeoJSON-Feature pro Zeichnung
pinSetzt einen Punkt für jedes Label. Jedes Label ist eine Frage, etwa "Where were you born?"Ein Punkt pro Label
classify_regionWählt ein Label und klickt dann auf Regionen des Grundkartenumrisses, um ihnen dieses Label zu geben. Ein erneuter Klick auf eine Region mit demselben Label hebt es aufEin Feature pro beschrifteter Region, mit geometry: null und der Regions-ID

Die Grundkarte

Jedes Schema braucht eine Grundkarte, in basemap oder pro Item über basemap_field, und ohne eine weisen potato validate und der Server die Konfiguration zurück. Potato greift nicht auf eine Internetkarte zurück, sodass eine Studie keine Karte aus dem Internet lädt, sofern ihre Konfiguration keine nennt.

QuelleKonfigurationHinweise
GeoJSON-Umrissbasemap: {geojson: maps/regions.geojson}Eine Datei unter task_dir, die in die Seite eingebettet wird. Halten Sie sie vereinfacht, höchstens einige hundert KB, weil sie Teil jeder Annotationsseite ist
Georeferenziertes Bildbasemap: {image: /media/area.png, extent: [min_lon, min_lat, max_lon, max_lat]}Ein PNG oder JPEG in Plate-Carrée-Projektion (abstandstreue Zylinderprojektion), das extent abdeckt
GeoTIFF oder Cloud Optimized GeoTIFFbasemap: {geotiff: /media/area.tif}Gelesen mit geotiff.js 3.0.5, das mit Potato ausgeliefert wird. Die Datei muss in EPSG:4326 oder EPSG:3857 vorliegen, und der Browser braucht WebGL
XYZ-Kachelnbasemap: {tiles: "https://tiles.example.org/{z}/{x}/{y}.png", attribution: "..."}Ihr eigener Kachelserver oder ein Anbieter, mit dem Sie eine Vereinbarung haben. attribution ist für eine externe URL erforderlich, und {-y} wird für TMS-Nummerierung akzeptiert

Ein GeoJSON-Umriss lässt sich mit einer Rasterquelle kombinieren, wobei der Umriss obenauf gezeichnet wird.

Die Kachelserver der OpenStreetMap Foundation laufen auf gespendeten Ressourcen, und ihre Richtlinie zur Kachelnutzung verbietet intensive Nutzung. Eine Studie, in der viele Annotatoren eine Karte verschieben, ist intensive Nutzung, daher akzeptiert Potato die URL mit einer Warnung im Log. Hosten Sie eigene Kacheln oder verwenden Sie einen kommerziellen Anbieter.

basemap_field nennt ein Item-Feld, das die Grundkarte des Items enthält: eine GeoJSON-FeatureCollection, eine URL als String (.tif und .tiff werden als GeoTIFF gelesen, alles andere als GeoJSON) oder ein Objekt mit denselben Schlüsseln wie basemap. Der Server prüft die Grundkarte jedes Items nach denselben Regeln, bevor er das Item sendet, und ein Item darf einen externen Server nur nennen, wenn die eigene basemap des Schemas eine URL auf diesem Host nennt.

Bei classify_region ist jedes Feature des Umrisses eine Region. Ihre ID ist die Eigenschaft region_id_property (Standard id), dann die GeoJSON-Feature-ID, dann r<index>, und ihr Name ist die Eigenschaft region_name_property (Standard name).

Optionen

SchlüsselStandardBedeutung
taskdrawdraw, pin oder classify_region
labelserforderlichStrings oder {name, color, description}. Die Farben folgen standardmäßig einer Okabe-Ito-Palette. Setzen Sie Yes, No und On in Anführungszeichen, die YAML sonst als Booleans lädt
tools[point, line, polygon, freehand]Nur draw. Ein Werkzeug zum Auswählen und Verschieben wird immer hinzugefügt
feature_textaustrue oder {prompt, required, placeholder}: ein Textfeld pro Feature, gespeichert als properties.text
basemapkeinergeojson, image, extent, geotiff, tiles, attribution, max_zoom, region_id_property, region_name_property
basemap_fieldkeinerItem-Feld mit einer Grundkarte pro Item
preannotation_fieldkeinerItem-Feld mit GeoJSON-Features als Ausgangspunkt (nicht für classify_region)
coordinate_orderlonlatlatlon, wenn die Vorannotationsdaten oder der Umriss den Breitengrad zuerst schreiben. Die Ausgabe ist immer [lon, lat]
projectionEPSG:3857Anzeigeprojektion, EPSG:3857 (Web Mercator) oder EPSG:4326. Gespeichert wird immer in EPSG:4326
center, zooman die Grundkarte angepasstAnfangsansicht, mit center: [lon, lat]
height440Kartenhöhe in Pixeln, von 200 bis 1200
snappingfalseRastet neue Eckpunkte an bestehenden Features und am Umriss ein
min_features, max_features1, falls erforderlich, sonst keinerNur draw. Beim Maximum werden die Zeichenwerkzeuge deaktiviert
require_all_regionsfalseclassify_region: Jede Region muss vor Next ein Label erhalten
label_requirementkeiner{required: true} blockiert Next, bis die eigene Bedingung der Aufgabe erfüllt ist: min_features Features bei draw, eine Stecknadel für jedes Label bei pin, mindestens eine Region (oder alle) bei classify_region

Die Karte verwenden

Wählen Sie zum Zeichnen ein Label und dann ein Werkzeug. Ein Punkt ist ein Klick. Eine Linie ist ein Klick pro Punkt und ein Doppelklick auf den letzten. Ein Polygon ist ein Klick pro Ecke, abgeschlossen durch einen Klick auf die erste Ecke, einen Doppelklick oder Enter, wobei Backspace die letzte Ecke entfernt und Esc abbricht. Freihand ist Drücken und Ziehen. Das Auswahlwerkzeug formt ein Feature über seinen Umriss oder einen Eckpunkt um, und Delete entfernt es. Jedes Feature erscheint in der Liste unter der Karte mit einem Label-Menü, dem Namensfeld, Show und Delete.

Bei Stecknadeln zeigt die Liste eine Zeile pro Label, und ein Klick auf die Karte setzt die aktive. Bei Regionen wählen Sie eine Label-Schaltfläche und klicken auf Regionen.

Gehen Sie mit der Tastatur per Tab zur Karte; dann verschieben die Pfeiltasten die Ansicht, und + und - zoomen. Add point at map centre und Use map centre setzen Punkte ohne Maus, und Label, Name und Löschen jedes Features sind über die Liste erreichbar.

Features aus preannotation_field sind mit "(suggested)" gekennzeichnet. Sie werden erst dann als Antwort des Annotators gespeichert, wenn der Annotator eines bearbeitet oder Accept suggestions drückt, sodass ein Item, das der Annotator nur geöffnet hat, nicht als beschriftet zählt.

Gespeicherte Daten

Die Antwort ist eine GeoJSON-FeatureCollection in EPSG:4326 nach RFC 7946: Positionen sind [longitude, latitude], äußere Ringe verlaufen gegen den Uhrzeigersinn und Löcher im Uhrzeigersinn, Koordinaten haben 7 Nachkommastellen (etwa 1 cm), und Längengrade werden in den Bereich -180 bis 180 umgebrochen.

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"}}
]}

Das Schema funktioniert auch auf Umfrageseiten, wo es kein Item gibt, sodass basemap_field und preannotation_field dort nichts bewirken.

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/

Der GeoJSON-Export normalisiert jedes Feature erneut und fügt seinen Eigenschaften item_id, user_id, schema und feature_id hinzu. Features, die sich nicht normalisieren lassen, etwa eine Position außerhalb des gültigen Bereichs oder ein Ring ohne Fläche, werden ausgelassen und in den Exportwarnungen aufgeführt. Antworten aus classify_region erhalten ihre Regionsgeometrie aus dem Umriss zurück. geo_overlap wird in Perzeptive Dialektologie beschrieben.

Grenzen

  • Ein Polygon, das den 180. Längengrad überquert, wird nicht geteilt; zeichnen Sie daher zwei Polygone.
  • Ein GeoTIFF in einer anderen Projektion als EPSG:4326 oder EPSG:3857 wird nicht angezeigt, und ohne WebGL wird überhaupt kein GeoTIFF angezeigt. Die Seite weist darauf hin, und der Umriss funktioniert weiterhin.
  • Ein GeoTIFF wird ohne Interpolation gezeichnet, sodass beim Hineinzoomen die tatsächlichen Pixelgrenzen sichtbar werden.
  • Für Pixelkoordinaten auf einem gewöhnlichen Bild statt geografischer Koordinaten verwenden Sie die Bildannotation.

Weiterführende Informationen

Implementierungsdetails finden Sie in der Quelldokumentation.