Un mapa de Montevideo con leaflet

Rafa · 2018/07/17 · 3 minute read

R tiene abstracciones para trabajar con información geográfica sin entender a fondo los detalles de cómo se hacen las proyecciones cartográficas y qué son los sistemas de coordenadas.

La API de StreetView publica un mapa con bastante información del terreno como calles, ríos y lugares importantes obtenidos a partir de fotos satelitales. Este es el tipo de mapas que suelen usar aplicaciones como Uber o Google Maps. Leaflet facilita el consumo de la API para hacer mapas interactivos generando un widget HTML con controles para moverse y hacer zoom.

library(tidyverse)
library(maptools)
library(leaflet)
library(dplyr)
library(rgdal)
library(shiny)

mvd <- list(lng=-56.164532, lat=-34.901112)

leaflet() %>% 
  setView(lng=mvd$lng, lat=mvd$lat, zoom=12) %>% 
  addTiles(group="Google") 

Para hacer este mapa llamamos a leaflet::leaflet() sin argumentos, setView() para especificar las coordenadas y zoom iniciales y addTiles() para dibujar el mapa. Leaflet sigue las convenciones del tidyverse, por lo que podemos encadenar las llamadas a las funciones con %>%.

Hay otro tipo de mapas que representan algun tipo de entidad geográfica (un país o un barrio) mediante un polígono. La información para construir estos mapas no está disponible en las imágenes satelitales, porque las fronteras entre estas entidades no es visible. En Uruguay, el INE publica shapefiles con la información cartográfica de los departamentos de Uruguay, los barrios de Montevideo, etc.

Los shapefiles se publican con otros archivos que incluyen datos y otros atributos de las formas. readOGR() devuelve un objeto SpatialPolygonsDataFrame:

# leer shapefile (cuidado que incluyen los shpx, dbf, etc.)
states <- readOGR("../../static/shps/barrios/ine_barrios_mvd_nbi85.shp",
                  layer = "ine_barrios_mvd_nbi85", GDAL1_integer64_policy = TRUE)
## OGR data source with driver: ESRI Shapefile 
## Source: "/Users/rafa/Desktop/data_science/work/blog/static/shps/barrios/ine_barrios_mvd_nbi85.shp", layer: "ine_barrios_mvd_nbi85"
## with 62 features
## It has 3 fields
crswgs84 <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
# proyeccion ine
prj <- CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

# asignar proy
proj4string(states) <- prj
# transformar la proyección
st <- spTransform(states, crswgs84)

El mapa que vamos a usar tiene un data_frame con tres columnas: un código para cada barrio, el nombre y el área. Estos datos estan en el archivo dbf que viene en el zip.

head(states@data)
##   AREA_KM     NOMBBARR NROBARRIO
## 0   2.111 Ciudad Vieja         1
## 1   1.297       Centro         2
## 2   0.694   Barrio Sur         3
## 3   2.279       Cordon         4
## 4   0.798      Palermo         5
## 5   0.766  Parque Rodo         6

Los shapefiles son útiles para dibujar choropleths, que pintan cada polígono con un color para mostrar alguna variable. Acá pintamos cada barrio según su área:

# Paleta de colores
qpal <- colorNumeric("YlOrRd", st@data$AREA_KM)

leaflet(st) %>%
  addPolygons(layerId=~NROBARRIO, color = "#444444", weight = 1, smoothFactor = 0.5,
              opacity = 1.0, fillOpacity = 0.5,
              fillColor = ~qpal(AREA_KM),
              highlightOptions = highlightOptions(color = "white", weight = 2,
                                                  bringToFront = TRUE), group="INE") %>% 
  addLegend(pal = qpal, values = ~AREA_KM)