+++
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()
```
