starter-academic-mpvd/content/publication/acceso-datos-openstreetmap-r/index.md
2023-03-28 11:45:37 +02:00

6.7 KiB

+++ title = "Acceso a datos de OpenStreetMap con R" date = 2021-01-09T00:00:00+01:00 lastmod = 2021-01-14T01:41:34+01:00 draft = false subtitle = "Cómo acceder a datos de OpenStreetMap" math = true diagram = true publication_types = "" publication = "MPVD" featured = true projects = ["periodismodatos"] abstract_short = "Cómo acceder a datos de OpenStreetMap con R" authors = ["adolfo_anton"] abstract = "Cómo acceder a datos de OpenStreetMap con R"

[image] caption = "Orion aveugle cherchant le soleil, Nicolas Poussin / Public domain" focal_point = "BottomLeft" placement = 3 preview_only = false +++

Cuando Christian Burkhart creó su mapa del callejero con R se fijó mucho en el trabajo de Dominique Royé con las librerías que trabajan con datos de OpenStreetMap como el de las estaciones de servicio de Europa. Para ello utilizó POI (Point of Interest, puntos de interés en la terminología de las representaciones espaciales de datos, puntos geográficos al fin y al cabo).

Para obtener los datos se utiliza una pasarela de la API.

Instalación de paquetes

Lo primer paso es instalar las librerías necesarias como las librerías tidyverse, que es una colección de distintas librerías entre las que se incluye dplyr para la manipulación de datos o ggplot2 para la visualización; sf que es el nuevo estándar para trabajar con datos espaciales y es compatible con ggplot y dplyr. Finalmente ggmap nos ayuda a crear mapas.

if(!require("osmdata")) install.packages("osmdata")
if(!require("tidyverse")) install.packages("tidyverse")
if(!require("ggmap")) install.packages("ggmap")
if(!require("sf")) install.packages("sf")

Se activan las librerías

Y se activan las librerías:

library(tidyverse)
library(osmdata)
library(sf)
library(ggmap)

Hacer una consulta

Antes de hacer una consulta hay que saber lo que se puede filtrar. Para ello se puede probar con la función available_features() que devuelve las características espaciales o features de OSM, algo común en el idioma de la representación espacial geográfica.

Para no cargar mucho la consulta incluimos la función en la función head():

head(available_features())

Estas son las cinco primeras features que devueve la consulta.

Se pueden ver las etiquetas de cualquiera de ellas a través de la función available_tags():

head(available_tags("tourism"))

La primera consulta: dónde están las peluquerías en Murcia

Para construir una consulta se usa el operador %>% que ayuda a encadenar varias funciones sin asignar el resultado a un nuevo objeto. Su uso está muy extendido entre la colección de librerías de tidyverse. Este tutorial de datacamp lo explica más.

En la primera parte de la consulta tenemos que indicar el lugar para el que queremos extraer información. Eso se consigue con la función getbb() que crea unos límites para un lugar según un nombre dado.

La función principal es opq() que crea la consulta final.

Se filtra la información que se busca con la función add_osm_feature().

En esta primera consulta se buscan los cines de Madrid, con amenity como feature y cinema como tag. Se pueden obtener los resultados espaciales en varios formatos. la función osmdata_*() envía la consulta al servidor y según si el sufijo es sf, sp o xml devuelve una característica simple (de single feature), espacial (de spatial) o en formato XML.

consulta <- getbb("Murcia Spain") %>%
  opq() %>%
   add_osm_feature("shop", "hairdresser")
str(consulta)
pelus <- osmdata_sf(consulta)
pelus

El resultado es una lista de diferentes objetos espaciales. En nuestro caso solo nos interesan los puntos osm_points.

Visualizar

Lo bueno de los objetos sf es que para ggplot ya existe una función geométrica llamada geom_sf(). De fondo se puede añadir un mapa con la librería ggmap y la función get_map() que descarga un mapa para un lugar dado. También podría ser una dirección, latitud/longitud o bounding box. El argumento del tipo de mapa permite indicar el estilo o tipo de mapa. Más información sobre esto se puede encontrar en la ayuda ?get_map

Cuando se hace un gráfico con ggplot se suele empezar con la función ggplot(). En este caso se empieza con ggmap() que incluye el objeto con el mapa de fondo. Entonces se añaden los puntos de las peluquerías de Murcia con geom_sf(). Es importante indicar con el argumento inherit.aes = FALSE que use los aesthetic mappings del objeto espacial osm_points. Además, se cambia el color, relleno, transparencia tipo y tamaño de los círculos.

murcia_se_peina <- get_map(c(left = -1.18, bottom = 37.91, right = -1.05, top = 38.04), maptype = "watercolor")

ggmap(murcia_se_peina) +
geom_sf(data = pelus$osm_points, inherit.aes = FALSE, colour = "#238443", fill = "#004529", alpha = .5, size = 4, shape = 21) +
labs(x = "", y = "")

Dónde hay una zapatería

q_murcia_shoes <- getbb("Murcia Spain") %>%
  opq() %>%
   add_osm_feature("shop", "shoes")
str(q_murcia_shoes)
murcia_shoes <- osmdata_sf(q_murcia_shoes)
murcia_shoes
murcia_shoes <- get_map(getbb("Murcia Spain"), maptype = "watercolor", source = "stamen")

ggmap(murcia_shoes) +
geom_sf(data = q_murcia_shoes$osm_points, inherit.aes = FALSE, colour = "#238443", fill = "#004529", alpha = .5, size = 4, shape = 21) +
labs(x = "", y = "")

Mercadona

En vez de obtener un bounding box con la función getbb() se puede crear sabiendo los puntos oeste, sur, este y norte. En la consulta hay dos características: el nombre y la tienda para filtrar supermercados de esta marca en particular. Según el area o volumen de la consulta se puede alargar el tiempo de espera. Por defecto el límite se establece en 25 segundos antes del timeout.

Lo que nos interesa son los puntos donde hay supermercados por lo que se usa la geometría a través de geom_sf(). La función theme_void() borra todo menos los puntos.

Se crean los límites:

m <- c(-10, 30, 5, 46)

Se hace la consulta:

    q <- m %>%
    opq (timeout = 25*100) %>%
    add_osm_feature("name", "Mercadona") %>%
    add_osm_feature("shop", "supermarket")
  mercadona <- osmdata_sf(q)
mercadona

Y el mapa final:

ggplot(mercadona$osm_points)+
geom_sf(colour = "#08519c",
      fill = "#08306b",
    alpha = 5,
  size = 1,
shape = 21) +
theme_void()