Street Maps by osmdata and ggplot

1 Library

library(tidyverse)
library(osmdata) # package for working with streets
library(showtext) # for custom fonts
library(ggmap)
library(rvest)

2 OSM Data

# The avilable_tags() function shows you the available features of the different classifications of streets and other map features this package works with
available_tags("highway")
##  [1] "bridleway"              "bus_guideway"           "bus_stop"              
##  [4] "busway"                 "construction"           "corridor"              
##  [7] "crossing"               "cycleway"               "elevator"              
## [10] "emergency_access_point" "emergency_bay"          "escape"                
## [13] "footway"                "give_way"               "living_street"         
## [16] "milestone"              "mini_roundabout"        "motorway"              
## [19] "motorway_junction"      "motorway_link"          "passing_place"         
## [22] "path"                   "pedestrian"             "platform"              
## [25] "primary"                "primary_link"           "proposed"              
## [28] "raceway"                "residential"            "rest_area"             
## [31] "road"                   "secondary"              "secondary_link"        
## [34] "service"                "services"               "speed_camera"          
## [37] "steps"                  "stop"                   "street_lamp"           
## [40] "tertiary"               "tertiary_link"          "toll_gantry"           
## [43] "track"                  "traffic_mirror"         "traffic_signals"       
## [46] "trailhead"              "trunk"                  "trunk_link"            
## [49] "turning_circle"         "turning_loop"           "unclassified"

2.1 Location

# We can then use getbb() to return the geographic location of a city simply by passing it a string.
getbb("Atlanta Georgia")
##         min       max
## x -84.55107 -84.28956
## y  33.64781  33.88682

2.2 Highway

# grab certain categories of streets from this package
big_streets <- getbb("Asheville United States")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("motorway", "primary", "motorway_link", "primary_link")) %>%
  osmdata_sf() # format that ggmap know 

big_streets
View(big_streets[["osm_lines"]])
# grab two more dataframes of streets: medium streets and small streets
med_streets <- getbb("Asheville United States")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("secondary", "tertiary", "secondary_link", "tertiary_link")) %>%
  osmdata_sf()


small_streets <- getbb("Asheville United States")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("residential", "living_street",
                            "unclassified",
                            "service", "footway"
                  )) %>%
  osmdata_sf()

2.3 Waterway

river <- getbb("Asheville United States")%>%
  opq()%>%
  add_osm_feature(key = "waterway", value = "river") %>%
  osmdata_sf()

2.4 Railway

railway <- getbb("Asheville United States")%>%
  opq()%>%
  add_osm_feature(key = "railway", value="rail") %>%
  osmdata_sf()
available_tags("railway")
##  [1] "abandoned"        "buffer_stop"      "crossing"         "derail"          
##  [5] "disused"          "funicular"        "halt"             "level_crossing"  
##  [9] "light_rail"       "miniature"        "monorail"         "narrow_gauge"    
## [13] "platform"         "preserved"        "rail"             "railway_crossing"
## [17] "razed"            "roundhouse"       "signal"           "station"         
## [21] "subway"           "subway_entrance"  "switch"           "tram"            
## [25] "tram_stop"        "traverser"        "turntable"        "wash"            
## [29] "water_crane"

3 Plot

3.1 Plot big street

ggplot() + 
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black")

3.2 Plot river

ggplot() +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "black")

3.3 Plot big street & river

3.3.1 Combination

ggplot() +
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black") +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "black")

3.3.2 Adjust size

Note: the axes are far too large because of the river. Let’s limit them using coord_sf().

ggplot() +
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black") +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "black") +
   coord_sf(xlim = c(-82.65, -82.48), 
           ylim = c(35.5, 35.65)) # Zoom in data, X-Y value see: getbb("Atlanta Georgia")

3.3.3 Add other features

Let’s add the remaining features as well as some coloring, size, and alpha aesthetics.

ggplot() +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "steelblue",
          size = .8,
          alpha = .3) +
  geom_sf(data = railway$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .2,
          linetype="dotdash",
          alpha = .5) +
  geom_sf(data = med_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .3,
          alpha = .5) +
  geom_sf(data = small_streets$osm_lines,
          inherit.aes = FALSE,
          color = "#666666",
          size = .2,
          alpha = .3) +
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .5,
          alpha = .6) +
  coord_sf(xlim = c(-82.65, -82.48), 
           ylim = c(35.5, 35.65))

NB: the order in which you layer the features (e.g., river before the streets) really makes a difference and can be altered.

3.3.4 Add custom fonts and label the map

font_add_google(name = "Lato", family = "lato") # add custom fonts
showtext_auto()
ggplot() +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "steelblue",
          size = .8,
          alpha = .3) +
  geom_sf(data = railway$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .2,
          linetype="dotdash",
          alpha = .5) +
  geom_sf(data = med_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .3,
          alpha = .5) +
  geom_sf(data = small_streets$osm_lines,
          inherit.aes = FALSE,
          color = "#666666",
          size = .2,
          alpha = .3) +
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .5,
          alpha = .6) +
  coord_sf(xlim = c(-82.65, -82.48), 
           ylim = c(35.5, 35.65)) +
  theme_void() + # get rid of background color, grid lines, etc.
  theme(plot.title = element_text(size = 20, family = "lato", face="bold", hjust=.5),
        plot.subtitle = element_text(family = "lato", size = 8, hjust=.5, margin=margin(2, 0, 5, 0))) +
  labs(title = "ASHEVILLE", subtitle = "35.595°N / 82.552°W")

# save it
ggsave(file = "asheville.pdf", units = "in", width = 6, height = 7)

4 Extensions

4.1 Highlighting individual streets

# Extract the famous Blue Ridge Parkway:
blue_ridge <- med_streets[["osm_lines"]] %>% 
  filter(name=="Blue Ridge Parkway")
ggplot() +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "steelblue",
          size = .8,
          alpha = .3) +
  geom_sf(data = railway$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .2,
          linetype="dotdash",
          alpha = .5) +
  geom_sf(data = med_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .3,
          alpha = .5) +
  geom_sf(data = small_streets$osm_lines,
          inherit.aes = FALSE,
          color = "#666666",
          size = .2,
          alpha = .3) +
  geom_sf(data = big_streets$osm_lines,
          inherit.aes = FALSE,
          color = "black",
          size = .5,
          alpha = .6) +
  geom_sf(data = blue_ridge, # Add Blue Ridge street 
          inherit.aes = FALSE,
          color = "orange",
          size = 1,
          alpha = 1) +
  coord_sf(xlim = c(-82.65, -82.45), 
           ylim = c(35.5, 35.65))  +
  theme_void()

4.2 Adding other external geo data

To be continued: how to use “rvest”