Search code examples
rggplot2openstreetmaprasterosmar

Plotting roads from an osmar object on a ggplot map


I have created an elevation map from a raster object (elevation data from worldclim) of my study sites in China, using ggplot code (simplified version of the code). The relevant raster objects have been downloaded from worldclim.org and converted to a data.frame using the raster package. Here is a link to the data used for this plot.

# load library
library("tidyverse")
load(file = "gongga.RData")

ggplot() +
 geom_raster(data = gongga, aes(x=x, y=y, fill = elev)) +
 coord_equal() +
 scale_fill_gradient(name = "Elevation", low = "grey0", high = "grey100") + 
 scale_x_continuous(expand = c(0,0)) +
 scale_y_continuous(expand = c(0,0)) +
 theme(aspect.ratio=1/1, text = element_text(size=15))

Picture of the map created in ggplot

For clarity I would like to add roads to the map. I came across the osmar package that extracts roads from Openstreetmap.

Using code from here, I extract the roads for the right section, but I don't know how to plot them to my existing ggplot.

# EXTRACT ROADS FROM OPENSTREETMAP AND PLOT THEM WITH RANDOM POINTS
# Load libraries
library('osmar')
library('geosphere')

# Define the spatial extend of the OSM data we want to retrieve
moxi.box <- center_bbox(center_lon = 102.025, center_lat = 29.875, 
width =  10000, height = 10000)

# Download all osm data inside this area
api <- osmsource_api()
moxi <- get_osm(moxi.box, source = api)

# Find highways
ways <- find(moxi, way(tags(k == "highway")))
ways <- find_down(moxi, way(ways))
ways <- subset(moxi, ids = ways)

# SpatialLinesDataFrame object
hw_lines <- as_sp(ways, "lines") 

# Plot points
plot(hw_lines, xlab = "Lon", ylab = "Lat")
box() 

Does the object need any transformation to plot it in ggplot? Or is there a better solution than osmar package for my purpose?


Solution

  • You can fortify the SpatialLinesDataFrame and then plot that with ggplot

    fortify(hw_lines) %>% 
      ggplot(aes(x = long, y = lat, group = group)) + 
      geom_path()
    

    The group aesthetic stops ggplot from joining all the roads together into one long line.