How far does sound propagate from a boat traveling in the Florida Keys?

The visualization below shows the predicted sound levels from a single boat traveling in the Florida Keys. The boat track modeled is shown in black, the sound levels are shown in color, and the boundaries of the Florida National Marine Sanctuaries are shown in light gray. When the mouse moves over the figure, a pop-up will show information on the name of the reserve (if mouse is over the reserve) or the SPL (received sound level) in the current cell. Use this visualization to explore how sound propagates in this area, and whether certain reserves are receiving noise levels above levels that could impact marine animals (90 dB).

For my final visualization product I used ggplot and plotly (ggplotly) to create an interactive visualization of vessel noise propagation model results.

First, load the required packages. Raster and sf (simple features) packages are used to handle the spatial data.

#load required packages
library(sf)
library(raster)
library(ggplot2)
library(plotly)
library(ggmap)

Prepare data.

Set projections, crop layers to extent of raster.

#data preperation

#state outline shapefile
states<-st_read("/Users/swricci/Documents/gis711_database/US/states_48.shp")
## Reading layer `states_48' from data source `/Users/swricci/Documents/gis711_database/US/states_48.shp' using driver `ESRI Shapefile'
## Simple feature collection with 58 features and 9 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -124.7564 ymin: 24.52321 xmax: -66.94909 ymax: 49.38447
## epsg (SRID):    4269
## proj4string:    +proj=longlat +datum=NAD83 +no_defs
states_reproj<-st_transform(states,32617)

#Florida Keys National Marine Sanctuary boundaries
fknms_zones<-st_read("/Users/swricci/Documents/gis714_geocomp/dBSea_results/FKNMS_marine_zones.shp")
## Reading layer `FKNMS_marine_zones' from data source `/Users/swricci/Documents/gis714_geocomp/dBSea_results/FKNMS_marine_zones.shp' using driver `ESRI Shapefile'
## Simple feature collection with 25 features and 12 fields
## geometry type:  POLYGON
## dimension:      XYZ
## bbox:           xmin: -83.15 ymin: 24.3 xmax: -80.2 ymax: 25.2355
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
fknms_reproj<-st_transform(fknms_zones,32617)

#Noise propagation model results
boatSPL<-raster("data/passenger_captblinky_vislevelsSPL.asc")
crs(boatSPL)<-CRS("+init=epsg:32617")
boatSPL_proj<-projectRaster(boatSPL,crs=CRS("+init=epsg:4326"))

#get data ready to plot - crop to extent of study area.
studyarea_proj<-extent(boatSPL)

fknms_crop<-st_crop(fknms_reproj,studyarea_proj)
fknms<-st_transform(fknms_crop,4326)

states_crop<-st_crop(states_reproj,studyarea_proj)
fl.keys<-st_transform(states_crop,4326)

boat_df<-as.data.frame(boatSPL_proj,xy=T)
colnames(boat_df)<-c("x","y","SPL")

Baseplot comparison:

plot(boatSPL_proj)
plot(st_geometry(fknms_zones),add=T)
plot(st_geometry(states),add=T)

Draft ggplotly object.

The plot is built with three data layers: raster with sound levels, the state shapefile and the FKNMS zones shapefile.

draft<-ggplot()+
  geom_raster(data=boat_df, aes(x=x,y=y,fill = SPL,text=paste('SPL (dB):', round(SPL,2))))+
  scale_fill_viridis_c(option = "magma")+
  geom_sf(data=fknms, aes(text=Name),color = "white",fill="gray",alpha=0.6)+
  geom_sf(data=fl.keys, color = "black", fill="white")+
  #coord_sf()+
  theme_dark()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  labs(
    title = "Vessel noise propagation in FKNMS",
    y = "Latitude",
    x = "Longitude"
  )

ggplotly(draft, tooltip = "text")

Final ggplotly visualization

Based on feedback, decided to add a basemap tile of satellite imagery. The easiest way to do this was to use the ggmap package. ggmap is a package that extends spatial visualization using ggplot2. This required setting up a Google Maps API to use the google satellite or other base maps.

Addition of the basemap gives more context to where the location is within the Florida Keys and provides some local bathymetry information. Bathymetry is an important factor when considering noise propagation so including this in the visualization should help with understanding the results. I also added the track line for the modeled vessel track. I decided to make the line dotted so that you can still see the sound levels under the track.

library(sf)
library(raster)
library(ggplot2)
library(ggmap)
library(plotly)
library(ggmap)

#data preperation
fknms_zones<-st_read("/Users/swricci/Documents/gis714_geocomp/dBSea_results/FKNMS_marine_zones.shp")
## Reading layer `FKNMS_marine_zones' from data source `/Users/swricci/Documents/gis714_geocomp/dBSea_results/FKNMS_marine_zones.shp' using driver `ESRI Shapefile'
## Simple feature collection with 25 features and 12 fields
## geometry type:  POLYGON
## dimension:      XYZ
## bbox:           xmin: -83.15 ymin: 24.3 xmax: -80.2 ymax: 25.2355
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
fknms_reproj<-st_transform(fknms_zones,32617)

boat_path<-st_read("data/passenger_captblinky_trackline.shp")
## Reading layer `passenger_captblinky_trackline' from data source `/Users/swricci/Documents/gis715_geovis/geovisR-lab/data/passenger_captblinky_trackline.shp' using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 0 fields
## geometry type:  LINESTRING
## dimension:      XY
## bbox:           xmin: 417400.4 ymin: 2703102 xmax: 419351.7 ymax: 2716847
## epsg (SRID):    NA
## proj4string:    NA
st_crs(boat_path)<-32617
boat_path<-st_transform(boat_path,4326)

boatSPL<-raster("data/passenger_captblinky_vislevelsSPL.asc")
crs(boatSPL)<-CRS("+init=epsg:32617")
boatSPL_proj<-projectRaster(boatSPL,crs=CRS("+init=epsg:4326"))

#get data ready to plot
studyarea<-st_bbox(c(xmin= 24.31, ymin= -82.25, xmax= 24.73,ymax= -80.75),crs = st_crs(4326))
studyarea_proj<-extent(boatSPL)

fknms_crop<-st_crop(fknms_reproj,studyarea_proj)
fknms<-st_transform(fknms_crop,4326)

boat_df<-as.data.frame(boatSPL_proj,xy=T)
colnames(boat_df)<-c("x","y","SPL")

#register_google(key='')

basemap <- ggmap(get_map(location = c(lon = -81.6, lat = 24.5),
                    zoom = 9, scale = 1,
                    maptype ='satellite'))

SPL.map<- basemap + 
  geom_raster(data=boat_df, 
              aes(x=x,y=y,fill = SPL,text=paste('SPL (dB):', round(SPL,2))), 
              inherit.aes = F) +
  scale_fill_viridis_c(option = "magma",na.value="transparent",alpha = 0.8) +
  geom_sf(data=boat_path, color = "black",linetype = "dotted", alpha = 0.6, 
          inherit.aes = F) + 
  geom_sf(data=fknms, aes(text=Name),color = "black",fill="white",alpha=0.6,
          inherit.aes = FALSE) +
  theme_classic() +
  labs(
    title = "Vessel noise propagation in FKNMS",
    y = "Latitude",
    x = "Longitude"
  )

ggplotly(SPL.map, tooltip = "text")

While ggmap allows for greater spatial visualization capabilities, there are some issues using ggmap basemaps and sf objects. The easiest fix for this was to add the inherit.aes = F for all the data layers plotted on top of the basemap.