I'm creating a world map of elevation in R.
When I plot the raster of elevations around the world there are two problems
- I want to change the projection and the prime meridian (the centre point of the map)
- When I plot the raster, there is a 'streak' across the map where Russia crosses the map edge and runs across to the opposite map edge
How can I adjust the projection, meridian and remove the streak.
Repro example
pacman::p_load(
char = c(
"tidyverse",
"rnaturalearth", # For map data
"tmaptools", # For geo-coding city's lat/lon
"elevatr", # For elevation data
"rgeoboundaries",
"sf",
"raster",
"ggstar" # For hexagons in geom_point
)
)
devtools::install_github(
quiet = TRUE,
repo = c(
"ropensci/rnaturalearthhires",
"ropensci/rnaturalearthdata"
)
)
conflicted::conflict_prefer_all("dplyr", quiet = TRUE)
df_world <-
rnaturalearth::ne_countries(
type = "countries",
scale = "large",
returnclass = "sf"
) %>%
sf::st_make_valid()
df_elevation <-
elevatr::get_elev_raster(
locations = df_world,
z = 1, # Important, this is the resolution of the elevation data
clip = "locations") %>%
as.data.frame(xy = TRUE) %>%
rename(elevation = 3) %>%
filter(
!is.na(elevation),
elevation > 0)
ggplot() +
geom_raster(
data = df_elevation,
aes(
x = x,
fill = elevation,
y = y
)
) +
coord_sf()
And here's a solution I've created for sf objects. However, I don't know how to adapt this solution for raster images...
trim_sf_edge <- function(df, projection = "robin", prime_meridian = 10) {
df %>%
sf::st_difference(
sf::st_polygon(
x = list(
rbind(
c(-0.0001 - (180 - prime_meridian), 90),
c(0.0000 - (180 - prime_meridian), 90),
c(0.0000 - (180 - prime_meridian), -90),
c(-0.0001 - (180 - prime_meridian), -90),
c(-0.0001 - (180 - prime_meridian), 90)
)
)
) %>%
sf::st_sfc() %>%
sf::st_set_crs(4326)
) %>%
sf::st_transform(
crs = sf::st_crs(
paste0(
paste0("+proj=", projection, " "),
"+lon_0=0 ",
"+x_0=0 ",
"+y_0=0 ",
"+datum=WGS84 ",
"+units=m ",
paste0("+pm=", prime_meridian, " "), # Prime meridian
"+no_defs"
)
)
) %>%
return()
}
df_world <- df_world %>%
sf::st_union() %>%
trim_sf_edge(
prime_meridian = 10,
projection = "robin")
And do the same for elevation
df_elevation <- df_elevation %>%
trim_sf_edge(
prime_meridian = 10,
projection = "robin")
But the last piece of code gives the error: Error in UseMethod("st_difference") : no applicable method for 'st_difference' applied to an object of class "data.frame"