EEZ data and R

Published

January 6, 2023

Introduction

When playing with spatial data, for example plotting maps or figuring out which EEZ a fishing operation took place in, you might want to have the EEZ data.

This document looks at available EEZ data and it can be used in R.

Accessing and loading the data

Exclusive Economic Zone data can be downloaded from https://marineregions.org. You can get it from the Downloads page. Get the Maritime boundaries vXX, 0-360 option. This wraps the coordinates from 0 to 360 like our map data. Version 11 (18/11/2019) was used for this document. It might take a while to download as it’s about 250 Mb. Unzip it and inside the folder you will see loads of files.

To read the EEZ data in, we use the sf package. We have a choice to read in the EEZs as lines or as polygons (actually MULTILINESTRINGs or MULTIPOLYGONs in sf speak). Reading in as polygons takes up a lot more memory as the objects are very detailed. It can also make plotting slow. However, if you need to do some GIS things like work out if a particular location is inside a EEZ you will need the polygons. Also, when plotting maps you can fill the polygons.

library(sf)
Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
# Read just the boundaries
eez_boundaries <- sf::st_read("World_EEZ_v11_20191118_HR_0_360", layer="eez_boundaries_v11_0_360")
Reading layer `eez_boundaries_v11_0_360' from data source 
  `C:\Work\PacificTunaManagementEvaluation\logmaster_stuff\World_EEZ_v11_20191118_HR_0_360' 
  using driver `ESRI Shapefile'
Simple feature collection with 2215 features and 26 fields
Geometry type: MULTILINESTRING
Dimension:     XY
Bounding box:  xmin: 0 ymin: -76.80012 xmax: 360 ymax: 86.99401
Geodetic CRS:  WGS 84
# Read the polygons
eez <- sf::st_read("World_EEZ_v11_20191118_HR_0_360", layer="eez_v11_0_360")
Reading layer `eez_v11_0_360' from data source 
  `C:\Work\PacificTunaManagementEvaluation\logmaster_stuff\World_EEZ_v11_20191118_HR_0_360' 
  using driver `ESRI Shapefile'
Simple feature collection with 281 features and 31 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 0 ymin: -85.5625 xmax: 360 ymax: 86.99401
Geodetic CRS:  WGS 84

What did we read in and how big is it?

is(eez_boundaries)
[1] "sf"       "oldClass"
is(eez)
[1] "sf"       "oldClass"
# Look at the size difference:
print(object.size(eez_boundaries), units="auto")
18.1 Mb
print(object.size(eez), units="auto")
205.7 Mb

The two EEZ data sets are of type sf. This is basically a data.frame where each row is a different EEZ. There is a complicated geometry column that holds the polygon or line or whatever.

Subsetting the EEZ polygon data

The EEZ polygon data is very useful. Unfortunately, it takes a very long to plot because it has all the EEZs from around the world. This problem remains even if we are zooming in a particular region.

The plot time can be slightly improved by only considering the EEZs that are within our region of interest. For example, if we’re interested in plotting the South Pacific, we don’t want the EEZ of Norway.

In this section we make a smaller EEZ data set. The approach is to define the region we are interested in, and then only keep the EEZs that overlap or are inside our region.

Some of the EEZs in our EEZ polygon data are ‘invalid’. These tend to be EEZs that cross from 0 to 360 latitude. To avoid ‘invalid geometry’ warnings we use the function sf_use_s2(). I’m really not sure what we’re doing with this but it seems to work. Something to do with spherical geometry. Maybe we can turn it back on again later?

sf_use_s2(FALSE)
Spherical geometry (s2) switched off

The first thing we do is to check if our EEZ data is a valid sf object.

# Validity check
valid_check <- st_is_valid(eez)
all(valid_check)
[1] TRUE

We define the region we are interested in and make an sf polygon object. We only want to consider EEZs that are in or straddle this region. Here we define a broad region in the Pacific (Figure Figure 1).

# Coordinates of big Pacific region
xbig <- c(125,250)
ybig <- c(45,-45)
# Make a matrix of coordinates - we have to repeat the last one to make a circuit
big_pacific <- matrix(c(xbig[1], ybig[1], xbig[1], ybig[2], xbig[2], ybig[2], xbig[2], ybig[1], xbig[1], ybig[1]),ncol=2, byrow=TRUE)
# Make a simple features polygon
big_pacific_poly <- sf::st_sfc(sf::st_polygon(x = list(big_pacific)))
sf_big_pacific <- sf::st_sf(geom=big_pacific_poly)
# Set the CRS to be the same as the EEZ data
sf_big_pacific <- st_set_crs(sf_big_pacific, st_crs(eez))

Figure 1: The region we are interested in getting the EEZs for.

We can use the st_intersection() function to check the intersection of each EEZ and our region of interest. If there is an intersection, we keep that EEZ. This gives a load of warnings about planar coordinates.

eez_pacific_list <- list()
for(i in 1:nrow(eez)){
  if(nrow(st_intersection(eez[i,], sf_big_pacific)) > 0){
    eez_pacific_list[[i]] <- eez[i,]
  }
}
# Collapse the list into eez_pacific
eez_pacific <- do.call("rbind", eez_pacific_list)

How many EEZs did we retain? The original EEZ data set has 281 entries. Our Pacific only EEZ data set has only 51.

Which ones did we retain?

sort(st_drop_geometry(eez_pacific)[,"TERRITORY1"])
 [1] "American Samoa"             "Australia"                 
 [3] "China"                      "Clipperton Island"         
 [5] "Cook Islands"               "East Timor"                
 [7] "Easter Island"              "Fiji"                      
 [9] "French Polynesia"           "Gilbert Islands"           
[11] "Guam"                       "Hawaii"                    
[13] "Howland and Baker islands"  "Indonesia"                 
[15] "Japan"                      "Jarvis Island"             
[17] "Johnston Atoll"             "Kuril Islands"             
[19] "Liancourt Rocks"            "Line Group"                
[21] "Marshall Islands"           "Matthew and Hunter Islands"
[23] "Mexico"                     "Micronesia"                
[25] "Nauru"                      "New Caledonia"             
[27] "New Zealand"                "Niue"                      
[29] "Norfolk Island"             "North Korea"               
[31] "Northern Mariana Islands"   "Palau"                     
[33] "Palmyra Atoll"              "Papua New Guinea"          
[35] "Papua New Guinea"           "Philippines"               
[37] "Phoenix Group"              "Pitcairn"                  
[39] "Russia"                     "Samoa"                     
[41] "Senkaku Islands"            "Solomon Islands"           
[43] "South Korea"                "South Korea"               
[45] "Tokelau"                    "Tonga"                     
[47] "Tuvalu"                     "United States"             
[49] "Vanuatu"                    "Wake Island"               
[51] "Wallis and Futuna"         

A quick look seems reasonable (although we have Russia which has a honking great EEZ). Let’s plot the whole world and superimpose our subset of EEZs (Figure Figure 2).

Figure 2: World map with only our EEZs of interest.

It looks good. We have Russia and the USA in there which have big and complicated EEZs so we could potentially make our region of interest even smaller. It will do for now.

Last thing to do is save our EEZ objects.

save(eez_boundaries, file="eez_boundaries.Rdata")
save(eez, file="eez.Rdata")
save(eez_pacific, file="eez_pacific.Rdata")