Search code examples
rgeospatiallatitude-longituder-sf

Shifting the longitude of an sf object


I have a map of countries (sf object) and I would like to shift the longitude of the eastern portion of Russia so that it is not isolated from the rest of Russia. See Image

I found the backend code for st_shift_longitude https://github.com/r-spatial/sf/blob/master/R/shift_longitude.R, which shifts all coordinates by 180 degrees, so that the resulting map looks as follows: link

How can I modify this block of code to shift the eastern portion of Russia only?


shift_lon <- function(x){
  xcrs = st_crs(x)
  g = (x + c(360, 90)) %% c(360) - c(0, 90)
  st_wrap_dateline(st_set_crs(g - c(180, 0), xcrs)) + c(180, 0)
  st_set_crs(g, xcrs)
}

st_geometry(countries) <- shift_lon(st_geometry(countries))

Alternative solutions are also welcome.


Solution

  • You will need to break down your world object into two parts - one containing Russia, and other for the rest of world.

    Then apply the pacific view / sf::st_shift_longitude() on the Russia part, and merge it back with the "rest of world" dataset.

    In this example I am using the world dataset from giscoR package. It is my favorite, but it is not the only one available; and it has a feature (or a bug, depending on circumstances) of applying a thin interruption at the antimeridean; this results in an artefact around Chukotka in my map. Getting rid of it is a separate issue, and I am not certain you will be facing it with your version of the world dataset (so it may be, and may not be, relevant problem).

    Anyway, here is a possible code implementation:

    library(sf)
    
    world <- giscoR::gisco_get_countries() # or your own world dataset
    
    rossiya <- subset(world, ISO3_CODE == "RUS")
    
    # shift Russia to a more Pacific centric worldview
    pacified_rossiya <- st_shift_longitude(rossiya)
    
    rest_of_world <- subset(world, ISO3_CODE != "RUS")
    
    # this is the important section: bind together the shifted and unshifted parts
    world2 <- rbind(pacified_rossiya,
                    rest_of_world)
    
    plot(st_geometry(world2))
    

    enter image description here