Aim

The aim of this code is to demonstrate one way of creating the shortest paths between the release and recovery locations of a tagged tuna while avoiding land using a rasterized vector world map. It is adapted from a shipping application after the blog by Thiemo Fetzer found here.

Step 1

Here I attach to the internal PostgreSQL database maintained at ICCAT HQ and read in the data directly using ODBC. It may be possible that this can be set up on an external server but for now it will currently not work outside ICCAT. The code could be adapted to work with the geopackage or csv files available here, AOTTP tag recapture data

## Read in AOTTP data from DB ##
odbcCloseAll()
aottp <-  odbcConnect("aottp-local", case ="tolower",DBMSencoding='utf8')
rel_rec <- sqlQuery(aottp,'SELECT * from releases_recoveries')
rel_rec <- subset(rel_rec, select = -rcnotes )

Step 2

Add on useful vectors such as Exclusive Economic Zone which is used here to select those fish tagged around the Canary Islands. This (e.g. function spatialVectors) requires the library ‘FLTag’ which is available from AOTTP Coordination.

# Add on useful vectors, e.g. julian day, month, year, EEZ
rel_rec <- formatTagdata(input=rel_rec);
rel_rec <- timeVectors(input=rel_rec,orig.date="2016-01-01");
rel_rec <- spatialVectors(input=rel_rec);

Step 3

Generate the raster from the world map, create the transition matrix with 16 directions possible and make a geocorrection since the diagonal moves are longer than those in a straight line.

## Use rasterized map as basis for transition matrix
data(wrld_simpl)
shp <- wrld_simpl
r <- raster(nrow=1440,ncol=1440) # This can be increased or decreased
r <-rasterize(shp, r, silent=TRUE)

## Make landmassess impassable for tuna ##
#make all sea = -999
r[is.na(r)] <- -999
#this turns all landmass to missing
r[r>-999] <- NA
#assign unit cost to all grid cells in water
r[r==-999] <- 1
## Transition Layer matrix
tr <- transition(r, mean, directions = 16)
tr <- geoCorrection(tr, "c")

## Use bathymetry as basis of transition matrix instead.

lon <- c(-35, 0)
lat <- c(-15, 40)
# bathy <- get.bathy(lon=lon, lat=lat, main="Baltic Sea", cbpos='r')
rb<-get.bathy(lon=lon,lat=lat,main="Canary Islands", cbpos='r',verbose=F,resolution =3) # from oceanmap library
## loading bathymetry data at a resolution of 3 minutes
## Querying NOAA database ...
## This may take seconds to minutes, depending on grid size
## 
## no region (v_area) defined, run add.region to add region definitions and to save settings for the plot region, colorbar and window size!
## Make landmassess impassable for tuna ##
#make all sea = -999
rb[!is.na(rb)] <- -999
#this turns all landmass to missing
rb[rb>-999] <- NA
#assign unit cost to all grid cells in water
rb[rb==-999] <- 1

## Transition Layer matrix
trb <- transition(rb, mean, directions = 16)
trb <- geoCorrection(trb, "c")

Step 4

In this example we are selecting the first 50 distances by magnitude to reduce comptuter time of bigeye tagged in the EEZ of the Canaries for which locations are ‘EXACT’.

## Select data for all BET tagged in the Canaries ##

recs_can <- rel_rec[rel_rec$reeez == "Spanish EEZ (Canary Islands)",]
recs_can  <- recs_can[!is.na(recs_can$distance_nm),] 
recs_can <- orderBy(~ -distance_nm + days_at_liberty ,data=recs_can) # order by distance and days
recs_can <- recs_can[recs_can$locqualitycode == 'EXACT',] # only data with 'exact' locations
recs_can_bet <- recs_can[recs_can$speciescode == 'BET',]  # BET

how.many <- 50
ind <- 1:how.many
recs_can_bet <- recs_can_bet[ind,] # Select top 50 distances to lessen compute time

Step 5

Estimate the shortest paths using Dijkstra’s Algorithm.

#Using map

AtoB <- as.list(1:how.many) # create a list

for(i in 1:how.many) #loop
{
  AtoB[[i]] <- shortestPath(tr, c(recs_can_bet$relonx[i],recs_can_bet$relaty[i]), 
    c(recs_can_bet$rclonx[i],recs_can_bet$rclaty[i]),
    output = "SpatialLines")
}

names(AtoB) <- as.character(recs_can_bet$specimenid[ind]) # name each element

# Using bathymetry

AtoBb <- as.list(1:how.many) # create a list

for(i in 1:how.many) #loop
{
  AtoBb[[i]] <- shortestPath(trb, c(recs_can_bet$relonx[i],recs_can_bet$relaty[i]), 
    c(recs_can_bet$rclonx[i],recs_can_bet$rclaty[i]),
    output = "SpatialLines")
}

names(AtoBb) <- as.character(recs_can_bet$specimenid[ind]) # name each element

Step 6

Plot the first fifty tracks using the map (by distance) and add the release and recovery locations.

rr <- bbox(AtoB[[1]])
xl <- rr[1,]
yl <- rr[2,]

plot(AtoB[[how.many]],xlim=xl,ylim=c(yl[1],yl[2]+8),axes=T)
for(i in 1:how.many){
  lines(AtoB[[i]],col='orange',lwd=1)
}
plot(shp,col='green',add=T)

points(recs_can_bet$relonx[ind],recs_can_bet$relaty[ind],pch='.',col='blue',cex=2)
points(recs_can_bet$rclonx[ind],recs_can_bet$rclaty[ind],pch='.',col='red',cex=2)
**Figure 1: BET tagged (50 longest tracks) in the Canary Islands using map**

Figure 1: BET tagged (50 longest tracks) in the Canary Islands using map

rr <- bbox(AtoBb[[1]])
xl <- rr[1,]
yl <- rr[2,]

plot(rb)
for(i in 1:how.many){
  plot(AtoBb[[i]],add=T,col='black',lwd=1)
}
points(recs_can_bet$relonx[ind],recs_can_bet$relaty[ind],pch='.',col='blue',cex=2)
points(recs_can_bet$rclonx[ind],recs_can_bet$rclaty[ind],pch='.',col='red',cex=2)
plot(shp,add=T)
**Figure 2: BET tagged (50 longest tracks) in the Canary Islands using bathymetry**

Figure 2: BET tagged (50 longest tracks) in the Canary Islands using bathymetry

Step 7

Calculate the difference between distance estimated by the shortest path avoiding land algorithm and that estimated naively assuming the direct Great Circle distance between tag release and recovery locations.

For the longest track so far observed for BET tagged in the Canary islands, the direct distance is 1813kms while that calculated using the vector map land avoidance scheme above is 3603kms, and the bathymetry raster 3485kms .

Discussion

Obviously the differences in estimated distances traveled are large. Both methods work adequately but the resolution of the input maps or bathymetries need to be increased substantially for it to be useful for small archipelagos like the Canary Islands. The tracks also seem to go too near land (e.g. Africa in Figure 1) but this could be solved by using a buffer around the vector map or better by using depth preferences of the different tuna species; obviously most easily effected using the bathymetry grid.