I have an sf
object that contains road geoms and road types (e.g. secondary, highway, cycleway, etc.):
(code taken from this blog post)
library(osmdata)
library(tidyverse)
muenster <-
opq(bbox = c(7.61, 51.954, 7.636, 51.968)) %>%
add_osm_feature(key = 'highway') %>%
osmdata_sf() %>%
osm_poly2line()
muenster_center <- muenster$osm_lines %>%
dplyr::select(highway)
I want to convert this shapefile to a raster file where the road types are preserved so that I can calculate cost paths.
NOTE Use terra
which is the replacement for the raster
package and it will be much faster and you won't need stars. See Robert's answer
As you may have noticed rasterize is quite slow for large data sets. I created a function that wraps around stars::st_rasterize
so that it takes a RasterLayer and sf and returns a RasterLayer
rasterizeLine <- function(sfLine, rast, value){
# rasterize roads to template
tmplt <- stars::st_as_stars(sf::st_bbox(rast), nx = raster::ncol(rast),
ny = raster::nrow(rast), values = value)
rastLine <- stars::st_rasterize(sfLine,
template = tmplt,
options = "ALL_TOUCHED=TRUE") %>%
as("Raster")
return(rastLine)
}
library(osmdata)
library(tidyverse)
library(sf)
muenster <-
opq(bbox = c(7.61, 51.954, 7.636, 51.968)) %>%
add_osm_feature(key = 'highway') %>%
osmdata_sf() %>%
osm_poly2line()
muenster_center <- muenster$osm_lines %>%
select(highway) %>%
# Note you have to turn it into a factor for stars to use that column and it
# has to be the first column
mutate(highway = as.factor(highway))
r <- raster::raster(muenster_center, ncol=1000, nrow=1000)
system.time({
muenster_rast <- rasterizeLine(muenster_center, r, NA)
})
# user system elapsed
# 0.09 0.07 0.15
system.time({
muenster_rast2 <- raster::rasterize(muenster_center, r, "highway")
})
# user system elapsed
# 207.56 0.06 208.75
raster::freq(muenster_rast - muenster_rast2)
# value count
# [1,] -2 1
# [2,] 0 63676
# [3,] NA 936323
Output looks very similar between the two but the version that uses stars is much faster!