OpenStreetMaps (OSM) es un proyecto colaborativo que busca crear un mapa del mundo de código abierto y gratuito. Los datos en OpenStreetMaps son creados y mantenidos por una comunidad global de mapeadores voluntarios, quienes contribuyen con información geoespacial detallada, como carreteras, edificios, lugares de interés y más. Estos datos pueden ser utilizados por cualquier persona para diversos propósitos, desde la navegación hasta el análisis geoespacial, y se distribuyen bajo una licencia abierta que permite su uso y redistribución libremente.
Esta ficha se centra en las Estaciones de Policía en el municipio de Valencia, como puntos geográficos a estudiar. Aunque podemos obtener los datos de la página web de OpenStreetMaps, nosotros utilizaremos una query para importarlos y poder trabajar con ellos.
A priori la herramienta de OSM parece ventajosa dada su amplia cobertura y actualización continua, con gran flexibilidad y detalles. Sin embargo, su carácter colaborativo y abierto también implica una calidad variable en los datos, falta de estandarización o desigualdades, entre otros errores.
Con esta práctica pretendemos demostrar cómo a partir de datos geográficos importados de OpenStreetMaps es muy probable encontrar errores, además de mostrar técnicas que puedan ayudarnos a solucionar este problema y así obtener finalmente datos de mayor valor o calidad.
Attaching package: 'dbscan'
The following object is masked from 'package:stats':
as.dendrogram
Antes de construir la consulta o query con la que importaremos la base de datos, es necesario definir el lugar (bounding box) de donde queremos extraer la información. En este caso, es el municipio de Valencia.
# Extraemos el municipio con el paquete 'mapSpain'val_mun<-mapSpain::esp_get_munic()%>%filter(LAU_CODE=="46250")# Transformamos a bounding boxbbox_val_mun<-sf::st_bbox(val_mun)
Ahora sí, pasamos a construir la consulta con la que obtendremos nuestra base de datos.
# Estaciones de Policía en Valenciaq<-bbox_val_mun%>%osmdata::opq(timeout =1000)%>%osmdata::add_osm_feature(key ="amenity", value ="police")
Los datos espaciales resultantes de la consulta pueden obtenerse en distintos formatos: simple feature, en formato espacial (spatial) o en XML. A nosotros nos interesará tenerlos en simple feature (sf).
# Obtenemos los datos en formato sfestaciones_policia_sf<-osmdata::osmdata_sf(q)
Vemos que el resultado es una lista de diferentes objetos espaciales. En nuestro caso, solamente nos fijaremos en los ‘osm_points’, que corresponden con las ubicaciones de las estaciones de policía.
# Extraemos los puntos estaciones_policia_sf<-estaciones_policia_sf$osm_points# Características de los datos class(estaciones_policia_sf)# Objeto sf
[1] "sf" "data.frame"
dim(estaciones_policia_sf)# 479 observaciones y 23 variables
[1] 479 23
Para poder representar los datos extraídos con ‘leaflet’, necesitaremos cambiar el CRS previamente:
# Cambiamos el CRSestaciones_policia_sf<-st_transform(estaciones_policia_sf,crs =st_crs(val_mun))# Representación de los datos estaciones_policia_sf%>%leaflet::leaflet()%>%leaflet::addTiles()%>%leaflet::addCircles()
Warning: sf layer has inconsistent datum (+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs).
Need '+proj=longlat +datum=WGS84'
Al representar los datos podemos detectar claramente un par de problemas. En primer lugar, que muchos de los puntos representados aparecen superpuestos en el gráfico, lo que es indicador de que algunas localizaciones están repetidas en la base de datos. Y en segundo lugar, que muchos de los puntos representados se encuentran fuera del municipio de Valencia.
Tratamiento
La primera de las problemáticas, la solucionaremos con DBSCAN, un algoritmo de agrupamiento espacial basado en la densidad de aplicaciones con ruido.
# Obtenemos las coordenadas de los puntoscoords<-sf::st_coordinates(estaciones_policia_sf)# Aplicación del Método DBSCANres<-dbscan(coords, eps =0.001, minPts =1)estaciones_policia_sf$cluster<-data.frame(res$cluster)# Cálculo del punto medio de cada clústerestaciones_policia_sf2<-estaciones_policia_sf%>%group_by(cluster)%>%summarise(geometry =st_centroid(st_combine(geometry)))# Representaciónggplot()+geom_sf(data =val_mun)+geom_sf(data =estaciones_policia_sf2)+theme_void()+labs(title ="Estaciones de Policía en Valencia (tras DBSCAN)")
Warning: sf layer has inconsistent datum (+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs).
Need '+proj=longlat +datum=WGS84'
Pasamos de tener 459 observaciones en la base de datos inicial, a solamente 55. Era importantísimo corregir estas duplicaciones.
Ahora, pasamos a solucionar el segundo de los problemas. Con la función “st_difference” del paquete “sf”, obtendremos los puntos fuera del municipio de Valencia. Fijémonos en que utilizamos los datos tras la clusterización, para así seguir trabajando sin las duplicaciones. Son 27 observaciones en total las que se encuentran fuera del municipio de Valencia y aparecen en nuestra base de datos.
# Detección de los Outliersestaciones_out<-sf::st_difference(estaciones_policia_sf2,val_mun)
Warning: attribute variables are assumed to be spatially constant throughout
all geometries
Como estas observaciones no nos interesan, las eliminaremos y nos quedaremos solamente con las observaciones resultado de “st_intersection”. Son 28 estaciones las que realmente pertenecen a Valencia.
# Estaciones de Policía dentro del municipio de Valenciaestaciones_in<-sf::st_intersection(estaciones_policia_sf2,val_mun)
Warning: attribute variables are assumed to be spatially constant throughout
all geometries
Tras darnos cuenta que los datos extraídos de OpenStreetMaps contenían observaciones duplicadas y algunas fuera de la zona deseada; con la ayuda del algoritmo DBSCAN, que clusteriza los datos, y funciones del paquete “sf”, hemos conseguido tener una base de datos libre de estos errores y que contiene las Estaciones de Policía en el municipio de Valencia.