starter-academic-mpvd/content/publication/acceso-datos-openstreetmap-r/index.md

171 lines
6.7 KiB
Markdown
Raw Normal View History

2023-03-28 11:45:37 +02:00
+++
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](https://commons.wikimedia.org/wiki/File:Orion_aveugle_cherchant_le_soleil.jpg), 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](https://dominicroye.github.io/en/2018/accessing-openstreetmap-data-with-r/). 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 {#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.
```R
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 {#se-activan-las-librerías}
Y se activan las librerías:
```R
library(tidyverse)
library(osmdata)
library(sf)
library(ggmap)
```
## Hacer una consulta {#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()`:
```R
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()`:
```R
head(available_tags("tourism"))
```
## La primera consulta: dónde están las peluquerías en Murcia {#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](https://www.datacamp.com/community/tutorials/pipe-r-tutorial) 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`.
```R
consulta <- getbb("Murcia Spain") %>%
opq() %>%
add_osm_feature("shop", "hairdresser")
str(consulta)
```
```R
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 {#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.
```R
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 {#dónde-hay-una-zapatería}
```R
q_murcia_shoes <- getbb("Murcia Spain") %>%
opq() %>%
add_osm_feature("shop", "shoes")
str(q_murcia_shoes)
```
```R
murcia_shoes <- osmdata_sf(q_murcia_shoes)
murcia_shoes
```
```R
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 {#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:
```R
m <- c(-10, 30, 5, 46)
```
Se hace la consulta:
```R
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:
```R
ggplot(mercadona$osm_points)+
geom_sf(colour = "#08519c",
fill = "#08306b",
alpha = 5,
size = 1,
shape = 21) +
theme_void()
```