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 boundarieseez_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 polygonseez <- 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.
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 regionxbig <-c(125,250)ybig <-c(45,-45)# Make a matrix of coordinates - we have to repeat the last one to make a circuitbig_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 polygonbig_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 datasf_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 in1:nrow(eez)){if(nrow(st_intersection(eez[i,], sf_big_pacific)) >0){ eez_pacific_list[[i]] <- eez[i,] }}# Collapse the list into eez_pacificeez_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.
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.