Skip to content

Mapas: anotación geográfica con puntos, líneas, polígonos y regiones

Dibuja puntos, líneas y polígonos etiquetados sobre un mapa en Potato, coloca chinchetas en lugares o etiqueta regiones, sobre un contorno GeoJSON, una imagen georreferenciada, un GeoTIFF o tus propias teselas.

Nuevo en v2.12.0

geo_annotation pone un mapa en la página de anotación. Los anotadores dibujan en él puntos, líneas y polígonos etiquetados, colocan chinchetas en lugares o dan etiquetas a las regiones de un mapa de contornos. El mapa es OpenLayers 10.9.0, que Potato sirve por sí mismo, así que ninguna biblioteca de mapas se carga desde 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

El repositorio de Potato tiene dos ejemplos ejecutables. examples/advanced/dialect-map/ es una encuesta dialectal de dibujo en mapa sobre un país ficticio que usa las tres tareas (Dialectología perceptiva), y examples/image/geo-annotation/ delimita la cobertura del suelo sobre imágenes georreferenciadas, una imagen por ítem, con un polígono sugerido en el primer ítem.

Tareas

taskQué hace el anotadorQué se guarda
draw (por defecto)Dibuja puntos, líneas, polígonos y polígonos a mano alzada, y da a cada uno una etiqueta, más un nombre escrito con feature_textUna entidad GeoJSON por dibujo
pinColoca un punto por cada etiqueta. Cada etiqueta es una pregunta, como "Where were you born?"Un punto por etiqueta
classify_regionElige una etiqueta y después hace clic en regiones del contorno del mapa base para darles esa etiqueta. Hacer clic de nuevo en una región con la misma etiqueta la borraUna entidad por región etiquetada, con geometry: null y el ID de la región

El mapa base

Todo esquema necesita un mapa base, en basemap o por ítem mediante basemap_field, y sin él potato validate y el servidor rechazan la configuración. Potato no recurre a un mapa de internet, así que un estudio no carga ningún mapa de internet a menos que su configuración lo nombre.

OrigenConfiguraciónNotas
Contorno GeoJSONbasemap: {geojson: maps/regions.geojson}Un archivo bajo task_dir, incrustado en la página. Mantenlo simplificado, como mucho unos pocos cientos de KB, porque forma parte de cada página de anotación
Imagen georreferenciadabasemap: {image: /media/area.png, extent: [min_lon, min_lat, max_lon, max_lat]}Un PNG o JPEG en proyección plate carrée (equirrectangular) que cubre extent
GeoTIFF o Cloud Optimized GeoTIFFbasemap: {geotiff: /media/area.tif}Se lee con geotiff.js 3.0.5, que viene con Potato. El archivo tiene que estar en EPSG:4326 o EPSG:3857, y el navegador necesita WebGL
Teselas XYZbasemap: {tiles: "https://tiles.example.org/{z}/{x}/{y}.png", attribution: "..."}Tu propio servidor de teselas o un proveedor con el que tengas un acuerdo. attribution es obligatorio para una URL externa, y se acepta {-y} para la numeración TMS

Un contorno GeoJSON puede combinarse con una fuente ráster, y el contorno se dibuja encima.

Los servidores de teselas de la OpenStreetMap Foundation funcionan con recursos donados, y su política de uso de teselas prohíbe el uso intensivo. Un estudio con muchos anotadores desplazándose por un mapa es un uso intensivo, así que Potato acepta la URL con una advertencia en el registro. Aloja tus propias teselas o usa un proveedor comercial.

basemap_field nombra un campo del ítem que contiene el mapa base del ítem: una FeatureCollection GeoJSON, una URL como cadena (.tif y .tiff se leen como GeoTIFF, cualquier otra cosa como GeoJSON), o un objeto con las mismas claves que basemap. El servidor comprueba el mapa base de cada ítem con las mismas reglas antes de enviar el ítem, y un ítem solo puede nombrar un servidor externo cuando el propio basemap del esquema nombra una URL en ese mismo host.

Para classify_region, cada entidad del contorno es una región. Su ID es la propiedad region_id_property (id por defecto), después el ID de la entidad GeoJSON, después r<index>, y su nombre es la propiedad region_name_property (name por defecto).

Opciones

ClaveValor por defectoSignificado
taskdrawdraw, pin o classify_region
labelsobligatorioCadenas o {name, color, description}. Los colores toman por defecto una paleta Okabe-Ito. Pon entre comillas Yes, No y On, que YAML de lo contrario carga como booleanos
tools[point, line, polygon, freehand]Solo draw. Siempre se añade una herramienta de seleccionar y mover
feature_textdesactivadotrue, o {prompt, required, placeholder}: un cuadro de texto por entidad, guardado como properties.text
basemapningunogeojson, image, extent, geotiff, tiles, attribution, max_zoom, region_id_property, region_name_property
basemap_fieldningunoCampo del ítem con un mapa base por ítem
preannotation_fieldningunoCampo del ítem con entidades GeoJSON de partida (no para classify_region)
coordinate_orderlonlatlatlon si los datos de preanotación o el contorno escriben primero la latitud. La salida es siempre [lon, lat]
projectionEPSG:3857Proyección de visualización, EPSG:3857 (Web Mercator) o EPSG:4326. El almacenamiento es siempre EPSG:4326
center, zoomajustar al mapa baseVista inicial, con center: [lon, lat]
height440Altura del mapa en píxeles, de 200 a 1200
snappingfalseAjusta los vértices nuevos a las entidades existentes y al contorno
min_features, max_features1 si es obligatorio, ningunoSolo draw. Las herramientas de dibujo se desactivan al llegar al máximo
require_all_regionsfalseclassify_region: todas las regiones tienen que recibir una etiqueta antes de Next
label_requirementninguno{required: true} bloquea Next hasta que se cumple la condición propia de la tarea: min_features entidades para draw, una chincheta por cada etiqueta para pin, al menos una región (o todas) para classify_region

Usar el mapa

Para dibujar, elige una etiqueta y después una herramienta. Un punto es un clic. Una línea es un clic por punto y un doble clic en el último. Un polígono es un clic por vértice, y se termina haciendo clic en el primer vértice, con un doble clic o pulsando Enter; Backspace quita el último vértice y Esc cancela. La mano alzada es pulsar y arrastrar. La herramienta de selección cambia la forma de una entidad por su contorno o por un vértice, y Delete la elimina. Cada entidad aparece en la lista bajo el mapa con un menú de etiquetas, el cuadro del nombre, Show y Delete.

Para las chinchetas, la lista muestra una fila por etiqueta, y hacer clic en el mapa coloca la activa. Para las regiones, elige un botón de etiqueta y haz clic en las regiones.

Desde el teclado, con Tab se llega al mapa, y después las flechas desplazan el mapa y + y - cambian el zoom. Add point at map centre y Use map centre colocan puntos sin ratón, y la etiqueta, el nombre y la eliminación de cada entidad son accesibles a través de la lista.

Las entidades de preannotation_field se marcan como "(suggested)". No se guardan como respuesta del anotador hasta que el anotador edita una o pulsa Accept suggestions, así que un ítem que el anotador solo abrió no cuenta como etiquetado.

Datos guardados

La respuesta es una FeatureCollection GeoJSON en EPSG:4326 según el RFC 7946: las posiciones son [longitude, latitude], los anillos exteriores van en sentido antihorario y los huecos en sentido horario, las coordenadas tienen 7 decimales (alrededor de 1 cm), y las longitudes se ajustan al intervalo de -180 a 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"}}
]}

El esquema también funciona en páginas de encuesta, donde no hay ítem, así que basemap_field y preannotation_field no hacen nada allí.

Exportación

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/

La exportación GeoJSON vuelve a normalizar cada entidad y añade item_id, user_id, schema y feature_id a sus propiedades. Las entidades que no pueden normalizarse, como una posición fuera de rango o un anillo sin área, se dejan fuera y aparecen en las advertencias de la exportación. Las respuestas de classify_region recuperan la geometría de su región a partir del contorno. geo_overlap se describe en Dialectología perceptiva.

Limitaciones

  • Un polígono que cruza el meridiano de 180° no se divide, así que dibuja dos polígonos.
  • Un GeoTIFF en una proyección distinta de EPSG:4326 o EPSG:3857 no se muestra, y tampoco ningún GeoTIFF sin WebGL. La página lo indica, y el contorno sigue funcionando.
  • Un GeoTIFF se dibuja sin interpolación, así que al acercar el zoom se ven los límites reales de los píxeles.
  • Para coordenadas en píxeles sobre una imagen normal en lugar de coordenadas geográficas, usa la anotación de imágenes.

Lecturas adicionales

Para detalles de implementación, consulta la documentación fuente.