library(sf) # vector manipulation
library(raster) # raster manipulation
library(fasterize) # "faster" raster
library(whitebox) # terrain analysis
library(tidyverse)
# Data libraries
library(osmdata) # OSM API
library(elevatr) # Elevation Web Tiles
#Basin boundary
basin = read_sf("https://labs.waterdata.usgs.gov/api/nldi/linked-data/nwissite/USGS-11119750/basin")
#Elevation data
elev = elevatr::get_elev_raster(basin, z = 13) %>%
crop(basin) %>%
mask(basin)
elev = elev*3.281 #convert m to feet
writeRaster(elev, "../data/goleta-area-elev.tif", overwrite = TRUE)
#Buildings and river-network data
bb = st_bbox(basin) %>% st_as_sfc() %>% st_transform(4326)
building = osmdata::opq(bb) %>%
add_osm_feature(key = 'building')%>%
osmdata_sf()
building = building$osm_polygons
building = st_centroid(building)
railway = filter(building, amenity == "railway")
#wbt_clip(building, basin, building, verbose_mode = FALSE) - This code kept giving me an error that I couldn't figure out (Error in system(args2, intern = TRUE) : error in running command)
building = building %>%
filter(st_contains(basin, ., sparse = FALSE))
stream = osmdata::opq(bb) %>%
add_osm_feature(key = 'waterway', value = "stream")%>%
osmdata_sf()
stream = stream$osm_lines
#wbt_clip(stream, basin, stream, verbose_mode = FALSE) - This also didn't seem to clip the data
stream = stream %>%
filter(st_contains(basin, ., sparse = FALSE))
#Hillshade
wbt_hillshade("../data/goleta-area-elev.tif", "../data/goleta-area-hillshade.tif")
## [1] "hillshade - Elapsed Time (excluding I/O): 0.34s"
hillshade = raster("../data/goleta-area-hillshade.tif")
plot(hillshade, legend = FALSE, col = gray.colors(256, alpha = .5))
plot(basin, add = TRUE)
plot(stream, col = "Red", add = TRUE)
#Height Above Nearest Drainage
#1 - Rasterize stream data
stream = stream %>%
st_transform(5070) %>%
st_buffer(10) %>%
st_cast("MULTIPOLYGON") %>%
st_transform(4326)
stream_raster = fasterize::fasterize(stream, elev)
writeRaster(stream_raster, "../data/goleta-area-stream.tif", overwrite = TRUE)
#2 - Creating the hydrologically corrected surface
wbt_breach_depressions("../data/goleta-area-elev.tif", "../data/goleta-area-hydro-correct.tif")
## [1] "breach_depressions - Elapsed Time (excluding I/O): 0.145s"
#3 - Creating the HAND raster
wbt_elevation_above_stream("../data/goleta-area-hydro-correct.tif", "../data/goleta-area-stream.tif", "../data/goleta-area-hand.tif")
## [1] "elevation_above_stream - Elapsed Time (excluding I/O): 0.44s"
#Correcting to local reference datum
hand = raster("../data/goleta-area-hand.tif")
hand = hand+3.69
hand[stream_raster ==1] = 0
stream_raster - hand
## class : RasterLayer
## dimensions : 1170, 830, 971100 (nrow, ncol, ncell)
## resolution : 7.864352e-05, 7.864352e-05 (x, y)
## extent : -119.7357, -119.6704, 34.40607, 34.49808 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## source : memory
## names : layer
## values : 1, 1 (min, max)
#The values produced here have a maximum of 1, which indicates that the stream_raster cells with a value of 1 have a HAND value of 0 (1-0 = 1)
writeRaster(hand, "../data/goleta-area-offset-hand.tif", overwrite = TRUE)
offset_hand = raster("../data/goleta-area-offset-hand.tif")
flood_thresh = function(x){ifelse(x <= 10.2, 1, NA)}
flood_map = calc(offset_hand, flood_thresh)*offset_hand
plot(hillshade, legend = FALSE, col = gray.colors(256, alpha = .5))
plot(basin, add = TRUE)
plot(stream$geometry, col = "Red", add = TRUE)
plot(flood_map, col = rev(blues9), add = TRUE)
plot(railway, col = "Green", cex = 1, pch = 16, add = TRUE)
This map shows flooding (in blue) along the length of the river, which is where we would expect to see most of the flood events.
flood_build = raster::extract(flood_map, building)
flood_build = as.data.frame(flood_build)
colSums(!is.na(flood_build))
## flood_build
## 725
#There are 1239 buildings that would have been effected by the 2017 flood according to this data
building = cbind(building, flood_build)
building$flood_build[is.na(building$flood_build)] <- 100
#Replacing the NA vaules with a number greater than the flooding threshold will allow the non-impacted buildings to be plotted within the same line of code below
floodbuild = raster::extract(flood_map, building)
floodbuild = as.data.frame(floodbuild)
floodbuild = cbind(floodbuild, building$geometry)
plot(floodbuild$geometry, col=ifelse(is.na(floodbuild$floodbuild),"black", "red"), cex = 0.1, pch = 16)
plot(hillshade, legend = FALSE, col = gray.colors(256, alpha = .5))
title(main = paste("2017 Flood Map with", colSums(!is.na(flood_build)), "Impacted Structures"))
plot(basin, add = TRUE)
plot(stream$geometry, col = "Red", add = TRUE)
plot(flood_map, col = rev(blues9), add = TRUE)
plot(building, col=ifelse(building$flood_build<=10.2,"red","black"), cex = 0.08, pch = 16, add = TRUE)
plot(railway$geometry, col = "Green", cex = 1, pch = 16, add = TRUE)
This task is to create a FIM library for Mission Creek for stage values ranging from 0 to 20 feet, and to animate this library as a GIF file showing the hillshade, flood level, and impacted buildings for each stage.
Last, the city is interested in zooming in on the lower portion of the basin contained within the “Santa Barbara” bounding box (defined in OSM).
#Get AOI boundary
sb = AOI::aoi_get("Santa Barbara") %>%
st_bbox()
#crop/clip the basin, HAND raster, and Hillshade raster to the AOI extent
sb_basin = basin %>%
st_crop(sb)
sb_hand = offset_hand %>%
raster::crop(sb_basin)
sb_hillshade = hillshade %>%
raster::crop(sb_basin)
##
Frame 1 (4%)
Frame 2 (9%)
Frame 3 (14%)
Frame 4 (19%)
Frame 5 (23%)
Frame 6 (28%)
Frame 7 (33%)
Frame 8 (38%)
Frame 9 (42%)
Frame 10 (47%)
Frame 11 (52%)
Frame 12 (57%)
Frame 13 (61%)
Frame 14 (66%)
Frame 15 (71%)
Frame 16 (76%)
Frame 17 (80%)
Frame 18 (85%)
Frame 19 (90%)
Frame 20 (95%)
Frame 21 (100%)
## Finalizing encoding... done!
## [1] "/Users/mikaleslie/github/geog-176A-labs/data/mission-creek-fim.gif"
There are likely still impacted buildings captured at stage 0 because the centroids of these buildings may be in tiles that are classified as river cells, but may not necessarily have been flooded.