From cc8378b2de37c0ec8bc0f8deeba5c2c01f019319 Mon Sep 17 00:00:00 2001 From: Francesco Sabatini <francesco.sabatini@idiv.de> Date: Fri, 21 Jun 2019 18:44:31 +0200 Subject: [PATCH] Expanded 01_Extract_elevation to run in tiles. Added chunk to recompose output --- .gitignore | 3 +- code/01_Extract_elevation.Rmd | 78 ++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 07bb462..34e0cc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.html code/*_cache/* code/*_files/* -sPlot_data_export/* \ No newline at end of file +sPlot_data_export/* +_derived/* \ No newline at end of file diff --git a/code/01_Extract_elevation.Rmd b/code/01_Extract_elevation.Rmd index f9f0d51..fc37717 100644 --- a/code/01_Extract_elevation.Rmd +++ b/code/01_Extract_elevation.Rmd @@ -91,25 +91,83 @@ header <- readr::read_csv("../sPlot_data_export/sPlot_data_header_fix1.csv", )) ``` -Split data into tiles of 5 x 5 degrees, and create sp files +Split data into tiles of 5 x 5 degrees, and create sp files. Only for plots having a location uncertainty < 50 km ```{r create tiles} header.sp <- header %>% - dplyr::select(PlotObservationID, Longitude, Latitude) %>% + dplyr::select(PlotObservationID, Dataset, Longitude, Latitude, `Location uncertainty (m)`) %>% mutate_at(.vars=vars(Longitude, Latitude), - .funs=list(tile=~cut(., breaks = seq(-180,180, by=5)))) %>% + .funs=list(tile=~cut(., breaks = seq(-180,180, by=3)))) %>% filter(!is.na(Longitude_tile) & !is.na(Latitude_tile) ) %>% - mutate(tilenam=factor(paste(Longitude_tile, Latitude_tile))) + mutate(tilenam=factor(paste(Longitude_tile, Latitude_tile))) %>% + filter(`Location uncertainty (m)`<= 50000) %>% + mutate(`Location uncertainty (m)`=abs(`Location uncertainty (m)`)) + #group_by(Longitude_tile, Latitude_tile) %>% #summarize(n()) +``` + +Extract elevation for each plot. Loops over tiles of 5 x 5°, projects to mercator, and extract elevation for plot coordinates, as well as 2.5, 50, and 97.5 quantiles for a buffer area having a radius equal to the location uncertainty of each plot (but only if location uncertainty < 50 km). DEM derive from package [elevatr](https://cran.r-project.org/web/packages/elevatr/vignettes/introduction_to_elevatr.html#get_raster_elevation_data), which uses the [Terrain Tiles on Amazon Web Services](https://registry.opendata.aws/terrain-tiles/). Resolutions of DEM rasters vary by region. I set a zoom factor z=10, which corresponds to ~ 75-150 m. Sources are: SRTM, data.gov.at in Austria, NRCAN in Canada, SRTM, NED/3DEP 1/3 arcsec, data.gov.uk in United Kingdom, INEGI in Mexico, ArcticDEM in latitudes above 60°, LINZ in New Zealand, Kartverket in Norway, as described [here](https://github.com/tilezen/joerd/blob/master/docs/data-sources.md) + +```{r eval=F} +require(parallel) +require(doParallel) +cl <- makeForkCluster(8, outfile="") +registerDoParallel(cl) -#create sp -sp.tile <- SpatialPoints(coords=header.sp %>% - filter(tilenam %in% levels(header.sp$tilenam)[1]) %>% - dplyr::select(Longitude, Latitude), - proj4string = CRS("+init=epsg:4326")) +clusterEvalQ(cl, { + library(raster) + library(sp) + library(elevatr) + library(dplyr) + }) +foreach(i = 1:nlevels(header.sp$tilenam)) %dopar% { + print("create sp and project data") + sp.tile <- SpatialPointsDataFrame(coords=header.sp %>% + filter(tilenam %in% levels(header.sp$tilenam)[i]) %>% + dplyr::select(Longitude, Latitude), + data=header.sp %>% + filter(tilenam %in% levels(header.sp$tilenam)[i]) %>% + dplyr::select(-Longitude, -Latitude), + proj4string = CRS("+init=epsg:4326")) + sp.tile <- spTransform(sp.tile, CRSobj = CRS("+init=epsg:3857")) #project to mercator + + print("retrieve dem raster") + raster.tile <- get_elev_raster(sp.tile, z=10, expand=max(sp.tile$`Location uncertainty (m)`), clip="bbox") + print("extract and summarize elevation data") + elev.tile <- raster::extract(raster.tile, sp.tile, small=T) + elev.tile.buffer <- raster::extract(raster.tile, sp.tile, buffer=sp.tile$`Location uncertainty (m)`, small=T) + elev.q95 <- t(round(sapply(elev.tile.buffer,stats::quantile, probs=c(0.025, 0.5, 0.975), na.rm=T))) + output.tile <- data.frame(PlotObservationID=sp.tile$PlotObservationID, + elevation=round(elev.tile), + elev.q95, + DEM.res=res(raster.tile)[1]) %>% + rename(Elevation_q2.5=X2.5., Elevation_median=X50., Elevation_q97.5=X97.5.) + + print("save output") + save(output.tile, file = paste("../_derived/elevatr/elevation_tile_", i, ".RData", sep="")) + print(i) +} + +``` +Compose output +```{r} +path <- "../_derived/elevatr/" +#create empty data.frame +elevation.out <- data.frame(PlotObservationID=header.sp$PlotObservationID, + elevation=NA, + Elevation_q2.5=NA, + Elevation_median=NA, + Elevation_q97.5=NA, + DEM.res=NA) +for(i in 1:nlevels(header.sp$tilenam)){ + load(paste(path, list.files(path)[i], sep="")) + #attach results to empty data.frame + mymatch <- match(output.tile$PlotObservationID, elevation.out$PlotObservationID) + elevation.out[mymatch,] <- output.tile +} -raster.tile <- get_elev_point(sp.tile ) +write_csv(elevation.out, file="../_derived/elevatr/Elevation_out.csv") ``` -- GitLab