0

I want to display a map which doesn't have Greenwich as the meridian. For example, a Longitude of 130. When I do this, the map "wraps" backwards on the display.

In this case, parts of South America are drawn back across the map - as are parts of the poles.

enter image description here

The code I'm using is:

library("ggplot2")
theme_set(theme_bw())
library("sf")
library("rnaturalearth")
library("rnaturalearthdata")
world <- ne_countries(scale = "medium", returnclass = "sf")

ggplot(data = world) +
    geom_sf() +
    coord_sf(crs = "+proj=cea +lon_0=130 +x_0=0 +y_0=0 +lat_ts=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

I'm happy if the East of South America appears wraps over to the left of the map - I just don't want it drawing over the map. What can I do to prevent this weird graphical glitch?

Terence Eden
  • 14,034
  • 3
  • 48
  • 89
  • 1
    See this: https://stackoverflow.com/questions/10620862/use-different-center-than-the-prime-meridian-in-plotting-a-world-map – Nicolás Velasquez Jul 23 '21 at 22:36
  • 1
    See also https://stackoverflow.com/questions/68278789/how-to-rotate-world-map-using-mollweide-projection-with-sf-rnaturalearth-ggplot/68313482?noredirect=1#comment120862460_68313482 based on the previous answer – dieghernan Jul 25 '21 at 10:14

1 Answers1

3

See here a complete reprex of how to achieve that. The steps are:

  1. Get the data and make it valid with st_make_valid (needed if you use sf (>= 1.0.0)
  2. Create a slim and long polygon where the polygons would break given your desired longitude.
  3. Remove the created polygon from your shape. This would effectively "break" the polygon on the right place (I.e. on the new limits of the map after projecting it).
  4. Transform to your desired projection and map.

See full reprex here:

# Load libraries
library(ggplot2)
theme_set(theme_bw())

library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(rnaturalearth)
library(rnaturalearthdata)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union



# Set target crs

target_crs <- st_crs("+proj=cea +lon_0=130 +x_0=0 +y_0=0 +lat_ts=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")


# Get data and transform to lon/lat 4326
world <- ne_countries(scale = "medium", returnclass = "sf") %>%
  st_transform(4326) %>%
  st_make_valid()


# define a long & slim polygon that overlaps the meridian line & set its CRS to match
# that of world

# Centered in lon 130 on this example

offset <- 180 - 130


polygon <- st_polygon(x = list(rbind(
  c(-0.0001 - offset, 90),
  c(0 - offset, 90),
  c(0 - offset, -90),
  c(-0.0001 - offset, -90),
  c(-0.0001 - offset, 90)
))) %>%
  st_sfc() %>%
  st_set_crs(4326)

# Remove slim polygon
world_fixed <- world %>% st_difference(polygon)
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries

# Transform to desired projection

world_fixed <- st_transform(world_fixed, target_crs)


# Plot - no need ggplot2::coord_sf()

ggplot(data = world_fixed) +
  geom_sf()

world_fixed


sessionInfo()
#> R version 4.1.0 (2021-05-18)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 19042)
#> 
#> Matrix products: default
#> 
#> locale:
#> [1] LC_COLLATE=Spanish_Spain.1252  LC_CTYPE=Spanish_Spain.1252   
#> [3] LC_MONETARY=Spanish_Spain.1252 LC_NUMERIC=C                  
#> [5] LC_TIME=Spanish_Spain.1252    
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] dplyr_1.0.7             rnaturalearthdata_0.1.0 rnaturalearth_0.1.0    
#> [4] sf_1.0-1                ggplot2_3.3.5          
#> 
#> loaded via a namespace (and not attached):
#>  [1] Rcpp_1.0.7         pillar_1.6.1       compiler_4.1.0     highr_0.9         
#>  [5] class_7.3-19       tools_4.1.0        digest_0.6.27      lattice_0.20-44   
#>  [9] evaluate_0.14      lifecycle_1.0.0    tibble_3.1.3       gtable_0.3.0      
#> [13] pkgconfig_2.0.3    rlang_0.4.11       reprex_2.0.0       DBI_1.1.1         
#> [17] yaml_2.2.1         xfun_0.24          e1071_1.7-7        s2_1.0.6          
#> [21] withr_2.4.2        styler_1.5.1       stringr_1.4.0      knitr_1.33        
#> [25] rgeos_0.5-5        generics_0.1.0     fs_1.5.0           vctrs_0.3.8       
#> [29] classInt_0.4-3     grid_4.1.0         tidyselect_1.1.1   glue_1.4.2        
#> [33] R6_2.5.0           fansi_0.5.0        rmarkdown_2.9      sp_1.4-5          
#> [37] purrr_0.3.4        magrittr_2.0.1     units_0.7-2        backports_1.2.1   
#> [41] scales_1.1.1       ellipsis_0.3.2     htmltools_0.5.1.1  assertthat_0.2.1  
#> [45] colorspace_2.0-2   KernSmooth_2.23-20 utf8_1.2.2         proxy_0.4-26      
#> [49] stringi_1.7.3      wk_0.5.0           munsell_0.5.0      crayon_1.4.1

Created on 2021-07-27 by the reprex package (v2.0.0)

dieghernan
  • 2,690
  • 8
  • 16