DESCARGA Y ANÁLISIS DE DATOS GEOGRÁFICOS DESDE OPENSTREETMAP

Hasta acá estuvimos trabajando con datos que fueron descargados de portales open data oficiales de diferentes Ciudades del mundo, pero esa no es la única fuente de información que existe para analizar Ciudades! Por suerte hay varios repositorios online de donde podemos descargarnos información georreferenciada muy interesante, cómo por ejemplo: OpenStreetMap (OSM, https://www.openstreetmap.org/)

¿Qué es y cómo funciona OpenStreerMap?

OSM es una plataforma creada por una gran comunidad de colaboradores que aportan datos geoespaciales de muchas Ciudades del mundo (calles, rutas, restaurants, museos, hospitales, escuelas, etc.) y los mantienen actualizados. Esta información es consumida por miles de sitios web y aplicaciones ya que puede ser utilizada libremente para cualquier propósito siempre y cuando se respeten los derechos de autor y licencia. Se puede consultar más información en la wiki de OSM.

Por suerte, en R existe un paquete llamado osmdata que nos permitirá conectarnos directamente a OSM y descargarnos toda la información que necesitemos. Así que, comencemos activando las ya conocidas tidyverse, sf y ggmap e instalemos y activemos osmdata:

#install.packages("tidyverse")
library(tidyverse)
#install.packages("sf")
library(sf)
#install.packages("ggmap")
library(ggmap)
#install.packages("osmdata")
library(osmdata)

Cualquier duda sobre el paquete osmdata pueden consultarlo en su documentación oficial.

¿QUÉ INFORMACIÓN PODEMOS BUSCAR?

Antes de comenzar a descargar información, utilicemos unos minutos para analizar y conocer que información tenemos disponible. En este este link podrán encontrar una lista detallada de las categorías y tipo de elementos que existen en OSM, pero si quisiésemos también podríamos hacer algunas consultas desde RStudio con available_features() y available_tags(). La primer función nos permitirá obtener el encabezado de la información que contiene la base de datos que nos podemos descargar:

available_features()
##   [1] "4wd_only"                "abandoned"              
##   [3] "abutters"                "access"                 
##   [5] "addr"                    "addr:city"              
##   [7] "addr:conscriptionnumber" "addr:country"           
##   [9] "addr:county"             "addr:district"          
##  [11] "addr:flats"              "addr:full"              
##  [13] "addr:hamlet"             "addr:housename"         
##  [15] "addr:housenumber"        "addr:inclusion"         
##  [17] "addr:interpolation"      "addr:place"             
##  [19] "addr:postbox"            "addr:postcode"          
##  [21] "addr:province"           "addr:state"             
##  [23] "addr:street"             "addr:subdistrict"       
##  [25] "addr:suburb"             "addr:unit"              
##  [27] "admin_level"             "aeroway"                
##  [29] "agricultural"            "alt_name"               
##  [31] "amenity"                 "area"                   
##  [33] "atv"                     "backward"               
##  [35] "barrier"                 "basin"                  
##  [37] "bdouble"                 "bicycle"                
##  [39] "bicycle_road"            "biergarten"             
##  [41] "boat"                    "border_type"            
##  [43] "boundary"                "bridge"                 
##  [45] "building"                "building:colour"        
##  [47] "building:fireproof"      "building:flats"         
##  [49] "building:levels"         "building:material"      
##  [51] "building:min_level"      "building:part"          
##  [53] "building:soft_storey"    "bus_bay"                
##  [55] "busway"                  "castle_type"            
##  [57] "change"                  "charge"                 
##  [59] "construction"            "construction#Railways"  
##  [61] "covered"                 "craft"                  
##  [63] "crossing"                "crossing:island"        
##  [65] "cuisine"                 "cutting"                
##  [67] "cycleway"                "denomination"           
##  [69] "destination"             "diet"                   
##  [71] "diplomatic"              "direction"              
##  [73] "dispensing"              "disused"                
##  [75] "disused:shop"            "drive_in"               
##  [77] "drive_through"           "ele"                    
##  [79] "electric_bicycle"        "electrified"            
##  [81] "embankment"              "embedded_rails"         
##  [83] "emergency"               "end_date"               
##  [85] "entrance"                "est_width"              
##  [87] "fee"                     "fire_object:type"       
##  [89] "fire_operator"           "fire_rank"              
##  [91] "foot"                    "footway"                
##  [93] "ford"                    "forestry"               
##  [95] "forward"                 "frequency"              
##  [97] "fuel"                    "gauge"                  
##  [99] "golf_cart"               "goods"                  
## [101] "hazmat"                  "healthcare"             
## [103] "healthcare:counselling"  "healthcare:speciality"  
## [105] "height"                  "hgv"                    
## [107] "highway"                 "historic"               
## [109] "horse"                   "ice_road"               
## [111] "incline"                 "industrial"             
## [113] "inline_skates"           "inscription"            
## [115] "internet_access"         "junction"               
## [117] "kerb"                    "landuse"                
## [119] "lanes"                   "lanes:bus"              
## [121] "lanes:psv"               "layer"                  
## [123] "leaf_cycle"              "leaf_type"              
## [125] "leisure"                 "lhv"                    
## [127] "lit"                     "location"               
## [129] "man_made"                "maxaxleload"            
## [131] "maxheight"               "maxlength"              
## [133] "maxspeed"                "maxstay"                
## [135] "maxweight"               "maxwidth"               
## [137] "military"                "minspeed"               
## [139] "mofa"                    "moped"                  
## [141] "motor_vehicle"           "motorboat"              
## [143] "motorcar"                "motorcycle"             
## [145] "motorroad"               "mountain_pass"          
## [147] "mtb:description"         "mtb:scale:imba"         
## [149] "mtb_scale"               "name"                   
## [151] "name:left"               "name:right"             
## [153] "narrow"                  "natural"                
## [155] "noexit"                  "non_existent_levels"    
## [157] "note"                    "nudism"                 
## [159] "office"                  "official_name"          
## [161] "old_name"                "oneway"                 
## [163] "opening_hours"           "operator"               
## [165] "organic"                 "oven"                   
## [167] "overtaking"              "parking:condition"      
## [169] "parking:lane"            "passing_places"         
## [171] "place"                   "power"                  
## [173] "priority_road"           "produce"                
## [175] "proposed"                "protected_area"         
## [177] "psv"                     "public_transport"       
## [179] "railway"                 "railway:preserved"      
## [181] "railway:track_ref"       "recycling_type"         
## [183] "ref"                     "religion"               
## [185] "residential"             "roadtrain"              
## [187] "route"                   "sac_scale"              
## [189] "service"                 "service_times"          
## [191] "shelter_type"            "shop"                   
## [193] "short_name"              "sidewalk"               
## [195] "site"                    "ski"                    
## [197] "smoothness"              "social_facility"        
## [199] "sorting_name"            "speed_pedelec"          
## [201] "start_date"              "step_count"             
## [203] "substation"              "surface"                
## [205] "tactile_paving"          "tank"                   
## [207] "tidal"                   "toilets:wheelchair"     
## [209] "toll"                    "tourism"                
## [211] "tracks"                  "tracktype"              
## [213] "traffic_calming"         "traffic_sign"           
## [215] "trail_visibility"        "trailblazed"            
## [217] "trailblazed:visibility"  "tunnel"                 
## [219] "turn"                    "type"                   
## [221] "usage"                   "vehicle"                
## [223] "vending"                 "voltage"                
## [225] "water"                   "wheelchair"             
## [227] "wholesale"               "width"                  
## [229] "winter_road"             "wood"

Tenemos 230 keys, y como verán, son muy variadas. A su vez, dentro de cada key (amenity, shop, railway, etc.) encontraremos diferentes tags que podemos consultarlos de la siguiente forma:

available_tags("amenity")
##   [1] "animal_boarding"        "animal_breeding"        "animal_shelter"        
##   [4] "arts_centre"            "atm"                    "baby_hatch"            
##   [7] "baking_oven"            "bank"                   "bar"                   
##  [10] "bbq"                    "bench"                  "bicycle_parking"       
##  [13] "bicycle_rental"         "bicycle_repair_station" "biergarten"            
##  [16] "boat_rental"            "boat_sharing"           "brothel"               
##  [19] "bureau_de_change"       "bus_station"            "cafe"                  
##  [22] "car_rental"             "car_sharing"            "car_wash"              
##  [25] "casino"                 "charging_station"       "childcare"             
##  [28] "cinema"                 "clinic"                 "clock"                 
##  [31] "college"                "community_centre"       "conference_centre"     
##  [34] "courthouse"             "crematorium"            "dentist"               
##  [37] "dive_centre"            "doctors"                "dog_toilet"            
##  [40] "drinking_water"         "driving_school"         "embassy"               
##  [43] "events_venue"           "fast_food"              "ferry_terminal"        
##  [46] "fire_station"           "food_court"             "fountain"              
##  [49] "fuel"                   "funeral_hall"           "gambling"              
##  [52] "give_box"               "grave_yard"             "grit_bin"              
##  [55] "gym"                    "hospital"               "hunting_stand"         
##  [58] "ice_cream"              "internet_cafe"          "kindergarten"          
##  [61] "kitchen"                "kneipp_water_cure"      "language_school"       
##  [64] "library"                "lounger"                "love_hotel"            
##  [67] "marketplace"            "monastery"              "motorcycle_parking"    
##  [70] "music_school"           "nightclub"              "nursing_home"          
##  [73] "parcel_locker"          "parking"                "parking_entrance"      
##  [76] "parking_space"          "pharmacy"               "photo_booth"           
##  [79] "place_of_mourning"      "place_of_worship"       "planetarium"           
##  [82] "police"                 "post_box"               "post_depot"            
##  [85] "post_office"            "prison"                 "pub"                   
##  [88] "public_bath"            "public_bookcase"        "public_building"       
##  [91] "ranger_station"         "recycling"              "refugee_site"          
##  [94] "restaurant"             "sanitary_dump_station"  "school"                
##  [97] "shelter"                "shower"                 "social_centre"         
## [100] "social_facility"        "stripclub"              "studio"                
## [103] "swingerclub"            "taxi"                   "telephone"             
## [106] "theatre"                "toilets"                "townhall"              
## [109] "toy_library"            "university"             "vehicle_inspection"    
## [112] "vending_machine"        "veterinary"             "waste_basket"          
## [115] "waste_disposal"         "waste_transfer_station" "water_point"           
## [118] "watering_place"

Podemos ver que, por ejemplo dentro de la key llamada amenity se encuentran diferentes tags o values como por ejemplo: bar, restaurant, heladería, hospital, biblioteca, etc.

Listo, hasta acá ya tenemos un poco más de información sobre el contenido posible de descargar. Ahora elijamos de que lugar del mundo queremos descargar la información!

¿DE QUÉ LUGAR DEL MUNDO QUEREMOS DATOS GEORREFERENCIADOS?

Llegó el momento de decidir el sitio/lugar de donde queremos traernos información ya que no podremos descargar todos los datos que tiene OSM porque son millones! Para esto debemos crear un cuadro delimitador o bounding box con la función getbb() y el nombre de la Ciudad de interés:

bbox_montevideo <- getbb("Montevideo, Uruguay")

La función anterior nos devolverá 4 coordenadas (longitud máxima, longitud mínima, latitud máxima, latitud mínima) que representan los límites de la información a descargar. Esto nos servirá como insumo principal al momento de hacer una descarga de información geográfica de OSM. Es importante tener en cuenta que la Ciudad tiene que estar escrita con el mayor detalle posible (Ciudad, Provincia, País), así se evita que OSM descargue información de otra Ciudad que no sea la elegida. Para conocer el nombre exacto con el que OSM reconoce las Ciudades, pueden hacer una búsqueda rápida directamente en su sitio web.

Revisemos el resultado que obtuvimos:

bbox_montevideo
##         min       max
## x -56.43140 -56.02250
## y -34.93806 -34.70185

Aprovechemos lo que aprendimos en clases anteriores y descarguemos un mapa base a partir de get_stamenmap():

mapa_montevideo <- get_stamenmap(bbox=bbox_montevideo,
                                 zoom=12)

Y veamos el resultado:

ggmap(mapa_montevideo)

Listo! Parece que todo salió bien! El mapa efectivamente es de Montevideo, Uruguay.

Para poder comprender mejor que extensión de territorio cubre Montevideo, sería muy útil que también tengamos mapeados los límites de la Ciudad, ¿No?

Por suerte podemos conseguirlo ajustando el parámetro format_out=“sf_polygon” en la función getbb() de la siguiente forma:

polygon_montevideo <- getbb("Montevideo, Uruguay",
                            format_out = "sf_polygon")

Veamos el resultado:

polygon_montevideo
## Simple feature collection with 2 features and 0 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -56.4314 ymin: -34.93806 xmax: -56.0225 ymax: -34.70185
## Geodetic CRS:  WGS 84
##                         geometry
## 1 POLYGON ((-56.4314 -34.8281...
## 2 POLYGON ((-56.4314 -34.8281...

Al parecer nos descargamos 2 polígonos, pero solo queríamos 1 con los límites de Montevideo. Hagamos un breve análisis para ver si se trata de información duplicada:

  1. Agreguemos un ID para poder diferenciar ambos polígonos:
polygon_montevideo <- polygon_montevideo %>%
         mutate(ID=row.names(polygon_montevideo))
  1. Hagamos un mapeo facetado por ID:
ggplot()+
  geom_sf(data=polygon_montevideo)+
  facet_wrap(~ID)

Efectivamente se trata de un polígono duplicado. Eliminemos uno de los 2 para evitar posibles problemas a la hora de descargar información.

polygon_montevideo <- polygon_montevideo[1,]

Ahora si, veamos como queda el mapa (recuerden que para agregar capas a un ggmap() debemos agregarle a cada capa extra el parámetro inherit.aes = FALSE):

ggmap(mapa_montevideo)+
  geom_sf(data=polygon_montevideo, inherit.aes = FALSE)

Lo logramos! Hagamos algunos ajustes para mejorar la visualización: quitemos el relleno del polígono y pongamos título y fuente:

ggmap(mapa_montevideo)+
  geom_sf(data=polygon_montevideo, fill=NA, color="red", size=1, inherit.aes = FALSE)+
  labs(title="Montevideo, Uruguay",
       caption="Fuente: Open Street Map")+
  theme_void()

¿CÓMO DESCARGAMOS LA INFORMACIÓN?

Para traernos información de OSM usaremos 3 funciones: opq() y add_osm_feature() para generar la consulta/requerimiento y osmdata_sf() para hacer la descarga. Tengamos en cuenta que con osmdata podemos descargar solamente datos vectoriales/geometrías representadas a partir de líneas, polígonos y puntos. Veamos un ejemplo de cada uno de ellos.

LÍNEAS

Como primer paso, asignemos el bounding box correspondiente a nuestro área de estudio dentro de opq() y en add_osm_feature() especifiquemos que key y/o values queremos.

En este caso probemos descargando los principales ejes viales (líneas) de toda la Ciudad de Montevideo, y que en OSM las encontramos con la key = “highway” y el value = c(“motorway”, “trunk”, “primary”, “secondary”):

vialidad_montevideo <- opq(bbox_montevideo) %>%
                      add_osm_feature(key = "highway", value = c("motorway", "trunk", "primary", "secondary"))

El segundo paso es utilizar la función osmdata_sf() para descargar toda la información seleccionada en el paso anterior:

vialidad_montevideo <- osmdata_sf(vialidad_montevideo)

Veamos que nos descargamos:

vialidad_montevideo

Nos pudimos descargar toda la información relacionada a los principales ejes viales que se encontró dentro de los límites establecidos: 9.523 puntos, 1.891 líneas y 3 polígonos.

Sin embargo solo necesitamos quedarnos con las líneas que representan los ejes de calles. Por lo tanto, el paso 3 es seleccionarlas con \(osm_lines* (cabe destacar que, si estaríamos buscando quedarnos con los puntos utilizaríamos *\)osm_points y con los polígonos $osm_polygons):

vialidad_montevideo <- vialidad_montevideo$osm_lines

Ahora si ya tenemos nuestros datos geográficos y podemos explorar el tamaño del dataset con dim():

dim(vialidad_montevideo)
## [1] 1891   71

Efectivamente tenemos las 1.891 líneas junto a 71 columnas/variables. Sumemos esto a nuestro mapa base:

ggmap(mapa_montevideo)+
  geom_sf(data=polygon_montevideo, fill=NA, color="red", size=1, inherit.aes = FALSE)+
    geom_sf(data = vialidad_montevideo, inherit.aes = FALSE)+
  labs(title="Ejes Viales Principales",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map")+
  theme_void()

Podrán ver que las líneas se descargaron de acuerdo al límite del bounding box y no por los límites geográficos de Montevideo. Para solucionarlo alcanza con hacer una intersección entre ambos datos geográficos utilizando st_intersection():

vialidad_montevideo <- st_intersection(vialidad_montevideo, polygon_montevideo)

Veamos el resultado:

ggmap(mapa_montevideo)+
  geom_sf(data=polygon_montevideo, fill=NA, color="red", size=1, inherit.aes = FALSE)+
    geom_sf(data = vialidad_montevideo, inherit.aes = FALSE)+
  labs(title="Ejes Viales Principales",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map")+
  theme_void()

También podemos colorear los ejes viales de acuerdo a algún atributo que tengan, como por ejemplo su tipología, su velocidad máxima, la cantidad de carriles, etc. Probemos con la tipología (highway):

ggmap(mapa_montevideo)+
    geom_sf(data = vialidad_montevideo, aes(color=highway), size=1, inherit.aes = FALSE)+
  labs(title="Ejes Viales Principales",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map",
       color="Tipo de Eje")+
  scale_color_manual(values = c("firebrick3", "darkorange1", "blue4"))+
  theme_void()

Los colores elegidos en el mapa anterior y muchos más pueden verse en este link. También se podrían utilizar los códigos HEX clásicos.

Y con la velocidad máxima (maxspeed):

ggmap(mapa_montevideo)+
    geom_sf(data = vialidad_montevideo, aes(color=maxspeed), size=1, inherit.aes = FALSE)+
  labs(title="Ejes Viales Principales",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map",
       color="Vel. Máx.")+
  theme_void()

El campo maxspeed está en formato character a pesar de ser numérico porque en todos los campos que se descargan de OSM vienen con formato texto.

Vamos a tener que modificarlo agregando as.numeric() y de aprovechemos para ajustar la paleta de colores:

ggmap(mapa_montevideo)+
    geom_sf(data = vialidad_montevideo, aes(color=as.numeric(maxspeed)), size=1, inherit.aes = FALSE)+
  labs(title="Ejes Viales Principales",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map",
       color="Vel. Máx.")+
  scale_color_distiller(palette = "YlOrRd", direction = 1)+
  theme_void()

Listo, ya tenemos nuestro mapa con una escala de colores continua que nos permite fácilmente interpretar donde está permitida mayor y donde menor velocidad.

POLÍGONOS

Ahora descarguemos polígonos utilizando los mismos 3 pasos que hicimos para descargar líneas. Primer paso, asignemos el bounding box correspondiente a nuestro área de estudio dentro de opq() y en add_osm_feature() especifiquemos que key y/o values queremos.

Ahora descarguemos los parques (polígonos) de toda la Ciudad de Montevideo, y que en OSM las encontramos con la key = “leisure” y el value = “park”:

parques_montevideo <- opq(bbox_montevideo) %>%
  add_osm_feature(key = "leisure", value = "park")

Como segundo paso utilicemos la función osmdata_sf() para descargar toda la información seleccionada en el paso anterior:

parques_montevideo <- osmdata_sf(parques_montevideo)

Veamos que nos descargamos:

parques_montevideo

Nos descargamos toda la información relacionada a parques que se encontró dentro de los límites establecidos: 3.579 puntos, 23 líneas y 111 polígonos.

En el paso 3, esta vez solo necesitamos quedarnos con los polígonos. Hagamos la selección con $osm_polygons:

parques_montevideo <- parques_montevideo$osm_polygons

Exploremos el tamaño del dataset resultante con dim():

dim(parques_montevideo)
## [1] 110  46

Efectivamente tenemos los 111 polígonos junto a 46 columnas/variables. Realicemos la intersección con los límites de Montevideo:

parques_montevideo <- st_intersection(parques_montevideo, polygon_montevideo)

Sumemos el resultado a nuestro mapa base:

ggmap(mapa_montevideo)+
    geom_sf(data = parques_montevideo, fill="forestgreen", color=NA, inherit.aes = FALSE)+
  labs(title="Ubicación de Parques",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map")+
  theme_void()

PUNTOS

Por último, descarguemos geometrías de tipo puntos, como por ejemplo los restaurant y bares de Montevideo:

Por último, descarguemos geometrías de tipo puntos, como por ejemplos los restaurantes y bares de toda la Ciudad de Montevideo, y que en OSM las encontramos con la key = “amenity” y el value = c(“restaurant”, “bar”):

gastronomia_montevideo <- opq(bbox_montevideo) %>% 
                  add_osm_feature(key = "amenity", value = c("restaurant", "bar"))

Como segundo paso utilicemos la función osmdata_sf() para descargar toda la información seleccionada en el paso anterior:

gastronomia_montevideo <- osmdata_sf(gastronomia_montevideo) 
gastronomia_montevideo

Nos descargamos toda la información relacionada a restaurantes y bares que se encontró dentro de los límites establecidos: 952 puntos, 0 líneas y 100 polígonos.

En el paso 3, esta vez solo necesitamos quedarnos con los puntos. Hagamos la selección con $osm_points:

gastronomia_montevideo <- gastronomia_montevideo$osm_points
dim(gastronomia_montevideo)
## [1] 953  71

Efectivamente tenemos los 952 puntos junto a 71 columnas/variables. Realicemos la intersección con los límites de Montevideo:

gastronomia_montevideo <- st_intersection(gastronomia_montevideo, polygon_montevideo)

Sumemos el resultado a nuestro mapa base:

ggmap(mapa_montevideo)+
    geom_sf(data = gastronomia_montevideo, aes(color=amenity), inherit.aes = FALSE)+
  labs(title="Ubicación de Parques",
       subtitle="Montevideo, Uruguay",
       caption="Fuente: Open Street Map")+
  theme_void()

MAPAS INTERACTIVOS

¿Cómo hacemos si queremos ubicar todos los bares y restaurantes en un mapa interactivo así podemos ir haciendo diferentes “zooms” en todas las zonas de interés?

Bueno, para esto sirve el paquete leaflet . Procedamos a instalarlo y activarlo:

#install.packages("leaflet")
library(leaflet)

Y hagamos nuestro primer leaflet():

leaflet()

Como verán quedó vacío! Agreguemos la información mínima que necesitamos para poder visibilizar resultados:

  1. Incorporar dentro del leaflet() el nombre del dataset geográfico a mapear.

  2. Sumar la función addTiles() que nos permite agregar un mapa de fondo.

  3. Sumar una función que indique en que formato queremos mapear la información geográfica que se encuentra dentro del leaflet(), por ejemplo a partir de marcadores de tipo círculo con la función addCircleMarkers().

leaflet(gastronomia_montevideo) %>%
  addTiles() %>%
  addCircleMarkers()

Lo logramos! Creamos nuestro primer mapa interactivo con información de locales gastronómicos en Montevideo. Pero todavía podríamos agregar información extra que nos ayude a sacar mayores conclusiones al recorrer el mapa, por ejemplo tipología y nombre. Para esto, filtremos aquellos registros que tienen valores nulos en dichos campos:

gastronomia_montevideo <- gastronomia_montevideo %>%
          filter(!is.na(name), !is.na(amenity))

Y ajustemos el encoding para evitar que tildes y “ñ” salgan mal:

gastronomia_montevideo <- gastronomia_montevideo %>%
mutate_if(is.character, iconv, from="UTF-8", to="latin1" )

Ahora si, primero armemos la paleta de color que diferencie por tipología:

factpal <- colorFactor(palette = c("seagreen4","deeppink4"), 
               levels = gastronomia_montevideo$amenity)

Y luego el mapa final:

leaflet(gastronomia_montevideo) %>%
  addTiles() %>%
  addCircleMarkers(popup = paste("Tipo:", gastronomia_montevideo$amenity, "<br>",
                           "Nombre:", gastronomia_montevideo$name),
             color = ~factpal(amenity))%>%
  addLegend("bottomright", pal = factpal, values = ~amenity,
            title = "Tipo",
            opacity = 1)

EJERCICIOS DE PRÁCTICA

  1. Elegir una Ciudad del mundo, descargar de OpenStreetMap su grilla de calles y mapearla por uno de sus atributos (velocidad mínima, velocidad máxima, cantidad de carriles, etc).

  2. Descargar de OpenStreetMap una (o más) capas de datos de tipo puntos o polígonos.

  3. Proyectar los datos descargados en un mapa y comentar los resultados: ¿Cómo se distribuyen en la Ciudad?