25 Feb 2019 Descarga inteligente de datos OSM con Overpass API
Actualmente cualquier usuario de SIG conoce (o debería conocer) OpenStreetMap como el mapa del mundo de datos libres y abiertos. Libres porque son gratuitos y abiertos porque cualquiera puede modificarlos y acceder a su descarga, por ejemplo, con Overpass API.
En el último post os explicamos cómo descargar datos de OpenStreetMap desde QGIS utilizando el plugin QuickOSM. Ahora vamos a ver la estructura de una petición de datos a través de Overpass API y mostraremos algunos ejemplos para ver cómo podemos descargar únicamente aquellos datos que sean de nuestro interés.
Antes de entrar en detalle con Overpass API debemos considerar que OSM describe los datos espaciales como puntos (nodes), líneas (ways) y relaciones (relations), siguiendo un extenso sistema de etiquetado (tags). Una carretera principal, por ejemplo, se caracteriza por tener una etiqueta highway con un valor primary. El sistema de etiquetado de OSM permite definir cualquier elemento cartografiable en cualquier lugar del mundo. Se trata, por lo tanto, de un sistema de etiquetado tremendamente exhaustivo. Para más detalles podéis consultar la página del proyecto.
Overpass API
Overpass reconoce dos lenguajes distintos para describir qué datos queremos descargar. Estos lenguajes son XML y Overpass Query Language (QL). Overpass se diseñó para atender las peticiones en formato XML (bastante legible desde el punto de vista humano) aunque, de forma paralela, se desarrolló el lenguaje QL para permitir la obtención de datos OSM a partir de una simple petición de tipo HTTP GET (URL).
A continuación podemos ver la estructura de una petición URL de descarga. El parámetro data es obligatorio y define los datos que deseamos descargar mediante el lenguaje QL.
http://overpass-api.de/api/interpreter?data=ajustes;expresion_QL
Ajustes (settings)
Los ajustes son opcionales y permiten dar un toque personalizado a nuestras consultas. Algunos ejemplos:
[out:json]; Indica el format JSON de la descarga. [timeout:180]; Indica un tiempo de ejecución de la descarga de 180 segundos. [bbox: sur, oeste, norte, este]; Indica que la descarga solo debe aplicar a la región indicada en las coordenadas.
Expresion_QL
Toda expresión QL consta de un conjunto de sentencias y cada sentencia termina con el carácter punto y coma (;). Por lo general, una expresión QL simple debe empezar con alguna de las siguientes palabras node, way, relation o area y terminar con la sentencia out; De este modo estaremos indicando qué tipo de geometría queremos consultar (node, way o relation) y descargar (out). area se utiliza para identificar un tipo concreto de relaciones.
En el siguiente ejemplo aparecen dos sentencias. Todas las sentencias se ejecutan de forma secuencial.
node(50.745,7.17,50.75,7.18);out;
En primer lugar, la sentencia node(50.745,7.17,50.75,7.18); obtiene un conjunto de datos (A) formado por los nodos que se encuentran dentro de una región espacial de tipo rectangular o geometría de caja (bounding box). Una geometría de caja se define por la coordenada de la esquina inferior izquierda (latitud_minima, longitud_minima) y por la esquina superior derecha (latitud_maxima, longitud_maxima).
En segundo lugar, la sentencia out; recoge los datos del conjunto (A) , obtenidos por la primera sentencia, y los prepara para su descarga.
Podemos probar la descarga de datos anteriores con la siguiente URL:
http://overpass-api.de/api/interpreter?data=node(50.745,7.17,50.75,7.18);out;
Si queremos obtener los datos en formato json podemos añadir un ajuste ([out:json]) a la URL anterior.
http://overpass-api.de/api/interpreter?data=[out:json];node(50.745,7.17,50.75,7.18);out;
Además del servidor http://overpass-api.de/api utilizado en el ejemplo anterior, podemos consultar la documentación de Overpass API para identificar otros servidores disponibles para la descarga de datos.
Sentencias y conjuntos de datos
En el ejemplo anterior hemos visto que existe una relación directa entre las sentencias de una expresión QL y los conjuntos de datos con los que opera cada sentencia. En el siguiente ejemplo vamos a tratar con más detalle esa relación entre sentencias y conjuntos de datos.
La expresión QL que vamos a analizar a continuación retornará todas las entidades (nodos, líneas y relaciones) almacenadas dentro de un bounding box concreto.
http://overpass-api.de/api/interpreter?data=(node(41.9391,2.7703,41.9929,2.8844);<;);out meta;
El archivo descargado contiene los nodos con la latitud y la longitud.
Veamos las piezas que componen la sentencia anterior:
( node(51.249,7.148,51.251,7.152); <; ); out meta;
En primer lugar observamos el uso de paréntesis. Dentro de esos paréntesis aparecen dos sentencias que, como ya hemos dicho, se ejecutan de forma secuencial.
– node(51.249,7.148,51.251,7.152); Retorna los nodos que se encuentran dentro la geometría de caja indicada. Estos datos (conjunto A) se ponen a disposición de la segunda sentencia.
– <; A partir de los nodos obtenidos con la sentencia anterior (conjunto A), esta sentencia retorna otro conjunto de datos (conjunto B) compuesto por todas las entidades espaciales que contienen alguno de los nodos del conjunto A.
Como hemos visto, cada una de las sentencias anteriores retorna un conjunto de datos distinto. Esos dos conjuntos (A y B), al encontrarse dentro de un mismo paréntesis, se unen para formar un solo conjunto de datos (A+B). Finalmente la sentencia out meta; permite la descarga del conjunto final (A+B) añadiendo información de los metadatos, como por ejemplo, el usuario que ha editado cada entidad.
Podemos suprimir el uso de los paréntesis anteriores y ver qué sucede.
http://overpass-api.de/api/interpreter?data=node(41.9391,2.7703,41.9929,2.8844);<;out meta;
En esta ocasión, solo obtenemos el conjunto de datos retornado por la segunda sentencia (conjunto B). Es decir, obtendremos las entidades compuestas por ciertos nodos (con sus respectivas etiquetas), pero no dispondremos de la información relativa a los nodos (latitud y longitud) que componen esas entidades.
Aspecto del nuevo archivo en el que desaparece toda la información relativa a los nodos (conjunto A)
Overpass QL también permite otro tipo de operaciones entre los distintos conjuntos de datos, como la diferencia o la intersección. En el siguiente apartado veremos algunos ejemplos.
Ejemplos de uso
Queda lejos del objetivo de este post elaborar una guía detallada de Overpass API, pero sí podemos mostrar la gran potencia y versatilidad de esta herramienta para definir criterios de búsqueda tan complejos y detallados como los que podemos ver a continuación.
Cartografía relacionada con los carriles bici en el centro de Valencia
http://overpass-api.de/api/interpreter?data=(way["highway"="cycleway"](39.4585,-0.4026,39.4877,-0.3456);>;);out meta;
Obtenemos, primero, las líneas (way) etiquetadas como carriles bici ([highway=cicleway]). La sentencia >; retorna los nodos que componen el conjunto de datos inicial. No confundir <; con >;
<; Retorna todas las entidades compuestas por un conjunto de datos.
>; Retorna todas las entidades que componen un conjunto de datos.
Todos los puntos de interés (amenities) excepto los marcados como café
https://lz4.overpass-api.de/api/interpreter?data=(node[amenity](40.41450,-3.70914,40.42041,-3.69643);- node[amenity=cafe](40.41450,-3.70914,40.42041,-3.69643););out;
En esta ocasión tenemos una operación de tipo difference (-) entre el conjunto de datos de la primera instrucción (todas las amenities) y el segundo conjunto (solo los cafe).
Estacionamientos cerca del ayuntamiento de Madrid
https://lz4.overpass-api.de/api/interpreter?data=way(16322055)->.ayuntamiento;(node(around.ayuntamiento:1000)[amenity=parking];);out meta;
En este ejemplo, partimos de un conjunto inicial formado, únicamente, por el perímetro del ayuntamiento de Madrid (way con id=16322055). En esta ocasión asignamos el nombre «ayuntamiento» al conjunto de datos retornado por la primera sentencia. En la segunda sentencia, utilizamos el conjunto anterior (ayuntamiento) con la instrucción around para obtener todos los nodos que se encuentran a menos de 1000 metros del conjunto «ayuntamiento» y que tienen, en la etiqueta amenity, el valor parking.
Todos los límites administrativos de España
http://overpass-api.de/api/interpreter?data=area[name="España"];(way["admin_level"](area);>;);out;
Ahora tenemos cuatro sentencias. En primer lugar obtenemos el área definida por España. En segundo lugar se obtiene todas las líneas (way) que están etiquetadas con «admin_level«, independientemente de cual sea el valor de la etiqueta, y que se encuentran dentro del área obtenida anteriormente. En tercer lugar, la sentencia >; se encarga de obtener todos los nodos que forman las líneas anteriores y finalmente, la sentencia out; se ocupa de solicitar la descarga de los datos.
Para saber más sobre Overpass API podéis consultar los siguientes enlaces.
- Guía del lenguaje Query Language
- Ejemplos prácticos de Overpass API
- Convertidor de expresiones XML – QL
- Ejemplos avanzados de Overpass API