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.
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.geojsonEl 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
task | Qué hace el anotador | Qué 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_text | Una entidad GeoJSON por dibujo |
pin | Coloca un punto por cada etiqueta. Cada etiqueta es una pregunta, como "Where were you born?" | Un punto por etiqueta |
classify_region | Elige 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 borra | Una 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.
| Origen | Configuración | Notas |
|---|---|---|
| Contorno GeoJSON | basemap: {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 georreferenciada | basemap: {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 GeoTIFF | basemap: {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 XYZ | basemap: {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
| Clave | Valor por defecto | Significado |
|---|---|---|
task | draw | draw, pin o classify_region |
labels | obligatorio | Cadenas 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_text | desactivado | true, o {prompt, required, placeholder}: un cuadro de texto por entidad, guardado como properties.text |
basemap | ninguno | geojson, image, extent, geotiff, tiles, attribution, max_zoom, region_id_property, region_name_property |
basemap_field | ninguno | Campo del ítem con un mapa base por ítem |
preannotation_field | ninguno | Campo del ítem con entidades GeoJSON de partida (no para classify_region) |
coordinate_order | lonlat | latlon si los datos de preanotación o el contorno escriben primero la latitud. La salida es siempre [lon, lat] |
projection | EPSG:3857 | Proyección de visualización, EPSG:3857 (Web Mercator) o EPSG:4326. El almacenamiento es siempre EPSG:4326 |
center, zoom | ajustar al mapa base | Vista inicial, con center: [lon, lat] |
height | 440 | Altura del mapa en píxeles, de 200 a 1200 |
snapping | false | Ajusta los vértices nuevos a las entidades existentes y al contorno |
min_features, max_features | 1 si es obligatorio, ninguno | Solo draw. Las herramientas de dibujo se desactivan al llegar al máximo |
require_all_regions | false | classify_region: todas las regiones tienen que recibir una etiqueta antes de Next |
label_requirement | ninguno | {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.
{"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
# 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
- Dialectología perceptiva - Encuestas dialectales de dibujo en mapa y mapas de calor de solapamiento
- Cámaras trampa - Revisión de detecciones con exportación de ocurrencias de Darwin Core
- Anotación sin conexión a la red - Ejecutar Potato sin acceso a internet
Para detalles de implementación, consulta la documentación fuente.