Search code examples
rspatial

Adding a constant offshore line in rnaturalearth


I am producing a map of Greenland using the package rnaturalearth and would like to add a line which indicates an offshore zone (60m from the coast) to the plot.

library("rnaturalearth")
library("rnaturalearthdata")
library("sf")


world <- ne_countries(scale = "medium", returnclass = "sf")
offshore_line <- st_buffer(simplified_world, dist = 0.06)

ggplot(data = world) +
  geom_sf(fill = "antiquewhite") +
  coord_sf(xlim = c(-60, -45), ylim = c(59, 72), expand = FALSE) +
  geom_sf(data = offshore_line, colour = "blue", linetype = "solid", size = 1)
  

I thought this would do the job but it returns the error:

Error in wk_handle.wk_wkb(wkb, s2_geography_writer(oriented = oriented,  : 
  Loop 0 is not valid: Edge 14 crosses edge 25

Cheers.


Solution

  • Rather than trying to apply an st_buffer to the whole world, you could just get the data for Greenland and apply st_buffer to that. Due to the way that st_buffer works, you would probably best to transform to a planar projection for the buffering part, otherwise you will get a 'jagged' result. You can always transform it back again afterwards.

    When plotting you need to ensure that your buffer zone explicitly has its fill set to fill = NA, otherwise the filled polygon will be drawn over your map.

    Note that adding another geom_sf layer after setting coord_sf removes your coord_sf and resets it to the second layer's co-ordinate system, so set the coord_sf after all the geom layers.

    It's going to be difficult to see a 60m buffer if you are zoomed out enough to see hundreds of miles of coastline: it will be so close to the coast itself that it will look as though you have just drawn the coastline blue. Ensure that you are drawing 60 metres by specifying the units as well as the values in st_buffer

    Here is a blue line drawn around the coast at 60m:

    library("rnaturalearth")
    library("rnaturalearthdata")
    library("sf")
    
    greenland <- ne_countries(scale = 'large', country = 'Greenland', 
                              returnclass = 'sf')
    
    
    offshore_line <- greenland |>
                     st_transform(crs = '+proj=utm +zone=22 +datum=WGS84') |>
                     st_buffer(dist = units::set_units(60, 'metre')) |>
                     st_transform(st_crs(greenland))
    
    ggplot(data = greenland) +
      geom_sf(fill = "antiquewhite") +
      geom_sf(data = offshore_line, colour = "blue", 
              linetype = "solid", size = 1, fill = NA) +
      coord_sf(xlim = c(-60, -45), ylim = c(59, 72), expand = FALSE) 
    

    enter image description here

    To show that this is the correct line, we can set the buffer distance to 20,000m and show a line 20km from the shore:

    enter image description here

    This is probably close to the type of picture you expected, but the top image is the one that is 60m.