library(raster) # Raster Data handling
library(tidyverse) # Data Manipulation
library(getlandsat) # keyless Landsat data (2013-2017)
library(sf) # Vector data processing
library(mapview) # Rapid Interactive visualization
#Question 1
bb <- read_csv("~/github/geog-176A-labs/data/uscities.csv") %>%
filter(city == "Palo") %>%
st_as_sf(coords = c("lng", "lat"), crs = 4326) %>%
st_transform(5070) %>%
st_buffer(5000) %>%
st_bbox() %>%
st_as_sfc() %>%
st_as_sf()
plot(bb)
#Question 2
bbwgs = bb %>% st_transform(4326)
bb = st_bbox(bbwgs)
meta = read_csv("~/github/geog-176A-labs/data/palo-flood.csv")
files = lsat_scene_files(meta$download_url) %>%
filter(grepl(paste0("B", 1:6, ".TIF$", collapse = "|"), file)) %>%
arrange(file) %>%
pull(file)
st = sapply(files, lsat_image)
s = stack(st) %>%
setNames(paste0("band", 1:6))
plot(s)
s
## class : RasterStack
## dimensions : 7811, 7681, 59996291, 6 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 518085, 748515, 4506585, 4740915 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=15 +datum=WGS84 +units=m +no_defs
## names : band1, band2, band3, band4, band5, band6
## min values : 0, 0, 0, 0, 0, 0
## max values : 65535, 65535, 65535, 65535, 65535, 65535
cropper = bbwgs %>%
st_transform(crs(s))
r = crop(s, cropper)
r = r %>%
setNames(c("Coastal Aerosol", "Blue", "Green", "Red", "Near Infrared", "SWIR 1"))
plot(r)
r
## class : RasterBrick
## dimensions : 340, 346, 117640, 6 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 594075, 604455, 4652535, 4662735 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=15 +datum=WGS84 +units=m +no_defs
## source : memory
## names : Coastal.Aerosol, Blue, Green, Red, Near.Infrared, SWIR.1
## min values : 8566, 7721, 6670, 6057, 5141, 4966
## max values : 18482, 19079, 19592, 21965, 24772, 23896
#Question 3
R-G-B (Natural Color Image)
plotRGB(r, r = 4, g = 3, b = 2)
NIR-R-G(fa) (Traditional Color Infrared (CIR) Image)
plotRGB(r, r = 5, g = 4, b = 3)
NIR-SWIR1-R (False Color good for picking out land from water)
plotRGB(r, r = 5, g = 6, b = 4)
SWIR2-SWIR1-R (False Color useful for visualizing urban environments)
plotRGB(r, r = 7, g = 6, b = 4)
Colored stretch is an effective and simple way to keep a visual track of different products because colored stretch is easier for people to quickly identify and separate different elements, ensuring a specific element isn’t mixed up with others.
RGB image comparison w stretch=“hist”
par(mfrow = c(2,2))
plotRGB(r, r = 4, g = 3, b = 2, stretch = "hist")
plotRGB(r, r = 5, g = 4, b = 3, stretch = "hist")
plotRGB(r, r = 5, g = 6, b = 4, stretch = "hist")
plotRGB(r, r = 7, g = 6, b = 4, stretch = "hist")
RGB image comparison w stretch=“lin”
par(mfrow = c(2,2))
plotRGB(r, r = 4, g = 3, b = 2, stretch = "lin")
plotRGB(r, r = 5, g = 4, b = 3, stretch = "lin")
plotRGB(r, r = 5, g = 6, b = 4, stretch = "lin")
plotRGB(r, r = 7, g = 6, b = 4, stretch = "lin")
#Question 4
ndvi = (r$Near.Infrared - r$Red) / (r$Near.Infrared + r$Red)
ndwi = (r$Green - r$Near.Infrared) / (r$Green + r$Near.Infrared)
mndwi = (r$Green - r$SWIR.1) / (r$Green + r$SWIR.1)
wri = (r$Green + r$Red) / (r$Near.Infrared + r$SWIR.1)
swi = 1 / (sqrt(r$Blue - r$SWIR.1))
stack = stack(ndvi, ndwi, mndwi, wri, swi) %>%
setNames(c("NDVI", "NDWI", "MNDWI", "WRI", "SWI"))
palette = colorRampPalette(c("blue","white","red"))
plot(stack, col = palette(256))
All 5 images emphasize the water feature, and all of them are in blue and red. However, the water features are presented in different color. In NDVI and SWI, the threshold of water features are less than 0. In NDWI, MNDWI, and WIR, the threshold of water features are greater than 0. The range of the water threshold is the greatest in MNDWI and the least in SWI
ndvi2 = function(x){ifelse(x <= 0,1, 0)}
ndwi2 = function(x){ifelse(x >= 0,1, 0)}
mndwi2 = function(x){ifelse(x >= 0,1, 0)}
wri2 = function(x){ifelse(x <= 1,1, 0)}
swi2 = function(x){ifelse(x<=5, 1, 0)}
ndvi3 = calc(ndvi, ndvi2)
ndwi3 = calc(ndwi, ndwi2)
mndwi3 = calc(mndwi, mndwi2)
wri3 = calc(wri, wri2)
swi3 = calc(swi, swi2)
threshold = stack(ndvi3, ndwi3, mndwi3, wri3, swi3) %>%
setNames(c("NDVI", "NDWI", "MNDWI", "WRI", "SWI"))
palette = colorRampPalette(c("white","blue"))
plot(threshold, col = palette(256))
#Question 5
set.seed(09072020)
values = getValues(r) %>%
na.omit(values)
dim(values)
## [1] 117640 6
There are 117,640 rows, 6 columns.
k12 = kmeans(values, 12, iter.max = 100)
kmeans_raster = r$Coastal.Aerosol
values(kmeans_raster) = k12$cluster
plot(kmeans_raster)
kmeans_vals = getValues(kmeans_raster)
binary_vals = getValues(ndvi3)
table <- table(binary_vals,kmeans_vals)
which.max(table)
## [1] 13
t_kmeans = function(x){ifelse(x == 3, 1, 0)}
f_kmeans = calc(kmeans_raster, t_kmeans)
threshold = addLayer(threshold, f_kmeans) %>%
setNames(c("ndvi", "ndwi", "mndwi", "wri", "swi", "kmeans"))
palette = colorRampPalette(c("white","blue"))
plot(threshold, col = palette(256))
#Question 6
kabletable = cellStats(threshold, sum)
knitr::kable(kabletable, caption = "Number of Flooded Cells", col.names = c("Number"))
Number | |
---|---|
ndvi | 6666 |
ndwi | 7212 |
mndwi | 11939 |
wri | 109172 |
swi | 15201 |
kmeans | 7395 |
areakable = kabletable * 900
knitr::kable(areakable, caption = "Area of Flooded Cells (m^2)", col.names = c("Area"))
Area | |
---|---|
ndvi | 5999400 |
ndwi | 6490800 |
mndwi | 10745100 |
wri | 98254800 |
swi | 13680900 |
kmeans | 6655500 |
point = st_point(c(-91.78948,42.06306)) %>%
st_sfc(crs = 4326) %>%
st_transform(crs(threshold)) %>%
as_Spatial()
print("-91.78948,42.06306")
## [1] "-91.78948,42.06306"
raster::extract(threshold, point)
## ndvi ndwi mndwi wri swi kmeans
## [1,] 1 1 1 0 1 0