Minimum elevation within km - r

Trying to find the minimum elevation within 10km of a certain latitude and longitude using R.
So far I have
dem <- getData("SRTM", lat=42.90, lon=-78.85, path = datadir)
plot(dem)
I know I need to create spatial points and eventually buffer/extract the information.
When I try:
buffdem <- buffer(dem, width=10000)
It does not work because I don't have any points.
I tried
dem <- getData("SRTM", lat=42.90, lon=-78.85, path = datadir)
coords <- data.frame(
x = rnorm(100),
y = rnorm(100)
)
coordinates(dem)
spdf = SpatialPointsDataFrame(coords, dem)
I get the following error:
Error in validObject(.Object) : invalid class
“SpatialPointsDataFrame” object: invalid object for slot "data" in
class "SpatialPointsDataFrame": got class "RasterLayer", should be or
extend class "data.frame"

I think this accomplishes what you need:
library(raster)
#elevation <- getData("SRTM", lat=42.90, lon=-78.85)
#poi <- cbind(lon=-78.85, lat=42.90)
using a smaller example data set for quicker download:
elevation <- getData('alt', country='CHE')
poi <- cbind(8.13, 46.47)
e <- extract(elevation, poi, buffer=10000)
sapply(e, min, na.rm=TRUE)
By the way, this is a duplicate of this and this question.

Related

R - extract part of .nc file and convert into raster (similar to WorldClim format)

I have a netcdf file I made which contains percentage values.
The file has 1 variable, 5 dimensions and 0 NetCDF attributes.
The dimensions are
"lon" "lat" "month" "CR" "yearSumm"
They were created using
lon <- ncdim_def("lon", "modis_degrees", -179.5:179.5, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Longitude")
lat <- ncdim_def("lat", "modis_degrees", -89.5:89.5, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Latitude")
month <- ncdim_def("month", "month_name", 1:13, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Month.and.Annual.Data")
CR <- ncdim_def("CR", "CR_numeric", 1:12, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Cloud.Regime")
yearSumm <- ncdim_def("yearSumm", "yearOrSummType", 1:21, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Year.and.Summary.Data")
I want to extract 13 layers (each latxlong with each cell a percentage value) from this and make them into a raster file like the bioclimatic data you can download from worldclim
I have tried extracting the data I want into an array, to then make a raster. I did that using
CR_RFO <- ncvar_get(CRnc, attributes(CRnc$var)$names[1])
CR_Ann <- as.array(CR_RFO[1:360, 1:180, 13, 1:12, 18])
This seems to have selected the data I want.
I then tried to make that into raster format.
raster(CR_Ann)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘raster’ for signature ‘"array"’
> CR_R <- as.raster(CR_Ann)
Error in array(if (d[3L] == 3L) rgb(t(x[, , 1L]), t(x[, , 2L]), t(x[, :
a raster array must have exactly 3 or 4 planes
> CR_R <- raster(CR_Ann)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘raster’ for signature ‘"array"’
> CR_R <- stack(CR_Ann)
Error in data.frame(values = unlist(unname(x)), ind, stringsAsFactors = FALSE) :
arguments imply differing number of rows: 777600, 0
> CR_R <- brick(CR_Ann)
Eventually brick worked, but I don't think that is actually what I want.
When I looked up the WorldClim files I downloaded, it is a zip file of .tifs
I also had tried
# set path and filename
ncpath <- "data/"
ncname <- "CR_RFO"
ncfname <- paste(ncpath, ncname, ".nc", sep="")
dname <- "Ann" # note: Ann means Annual
CR_raster <- brick(ncfname, varname="CR_RFO")
CR_raster; class(CR_raster)
which resulted in the error
CR_RFO has more than 4 dimensions, I do not know what to do with these data
I suspect I am going about it from the wrong angle, and maybe even have made my netcdf file incorrectly, as lat and long are not variables like in some of the examples I have read.
How can I extract these 13 lat x long layers and output them as .tif as per worldclim?
This is how I have ended up doing what I think I needed to. I haven't tested this in place of worldclim data yet, but I have successfully made the geotiff files.
CRnc <- nc_open("data/CR_RFO.nc")
CR_RFO <- ncvar_get(CRnc, attributes(CRnc$var)$names[1])
Repeat from here for each tif I want, selecting the correct number in the 4th place in the index, and changing the file names accordingly.
CR1_Ann <- as.matrix(CR_RFO[1:360, 1:180, 13, 1, 18])
CR1_Ann <- t(CR1_Ann)
CR1_Ann <- flipud(CR1_Ann)
CR1_Annr <- raster(CR1_Ann, ymn = -89.5, ymx = 89.5, xmn = -179.5, xmx = 179.5)
#plot(CR1_Annr)
writeRaster(CR1_Annr, "./data/CR_Ann/CR1_Ann", format = "GTiff")
This is not an elegant solution, so if anyone has a better way, please share.

R- plotting 2.5 grid netcdf data with country contour

I'm trying to plot precipitation data which has a 2.5 x 2.5 grid with the country contour on top, the data is available in this link: https://www.esrl.noaa.gov/psd/data/gridded/data.cmap.html "Mean (Enhanced Monthly)"
I was using the answer from: R - Plotting netcdf climate data. However I get an error.
This is what I have done:
library(ncdf4)
ncpath <- "C:/Users/"
ncname <- "precip.mon.mean"
ncfname <- paste(ncpath,ncname,".nc",sep="")
ncin <- nc_open(ncfname)
lon <- ncvar_get(ncin, "lon")
nlon <- dim(lon)
lat <- ncvar_get(ncin, "lat")
nlat <- dim(lat)
dname <-"precip"
ppt_array <- ncvar_get(ncin,dname)
dim(ppt_array)
pres <- ppt_array[ , ,25:444]
precip <- array(pres, , dim=c(nlon, nlat, 12, ano))
prec <- precip[97:115,21:34, ,1:ano] #I just want a piece of the map
Here is where I have the problem:
latlat <- rev(lat)
precipit <- prec[ , ,1,1] %Just to see if it works
lonlon <- lon-180
image(lonlon,latlat,precipit)
library(maptools)
data(wrld_simpl)
#however I don't know if this will work to plot just a portion of the map
plot(wrld_simpl,add=TRUE)
I get several errors, could someone please help?
EDIT:
The errors I got were these:
> image(lonlon,latlat,precipit)
Error in image.default(lonlon, latlat, precipit) :
increasing 'x' and 'y' values expected
> library(maptools)
> data(wrld_simpl)
> plot(wrld_simpl,add=TRUE)
Error in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col = col, :
plot.new has not been called yet
There's several things that need to be fixed:
1) ano does not seem to be defined anywhere. Perhaps it was defined interactively?
precip <- array(pres, , dim=c(nlon, nlat, 12, ano))
2) It appears you intended to add a comment but used an infix operator instead - replace this with a #, like so:
precipit <- prec[ , ,1,1] # Just to see if it works
3) If you want to only have part of the map, you can either ensure that both the lat and lon arrays match the area that you want to show (essentially cropping the world map) or define NAs outside the region you want to highlight (which will appear similar to the map here)

Masking raster from data in SpatialGridDataFrame and SpatialPolygonsDataFrame

I am trying to mask a raster file by including only some specific area (‘Koeppen Geiger’ climatic zones) with several locations. I got an error message running the final line of code:
Error in (function (classes, fdef, mtable) : unable to find an
inherited method for function ‘mask’ for signature
‘"SpatialGridDataFrame", "SpatialPolygonsDataFrame"’
.
##Read Countries file
library(sp)
library(maptools)
library(rworldmap)
countries = readShapeSpatial("D:/Studies/PhD/SCI/modeling/ne_10m_admin_0_countries/ne_10m_admin_0_countries.shp") [enter link description here][1]
asia.zone = countries[countries$ADMIN=="South Korea"|
countries$ADMIN=="North Korea"|
countries$ADMIN=="Japan"|
countries$ADMIN=="China"|
countries$ADMIN=="Taiwan",]
##Read Koeppen Geiger’ climatic zones
tst <- read.csv('D:/Studies/PhD/SCI/modeling/Koeppen-Geiger-ASCII.csv',as.is=TRUE) [enter link description here][1]
tst.l <- tst [tst$Cls=="Cfc"|
tst$Cls=="Cfa"|
tst$Cls=="Cfb"|
tst$Cls=="Cwa"|
tst$Cls=="Cwb"|
tst$Cls=="Aw"|
tst$Cls=="As"|
tst$Cls=="Am"|
tst$Cls=="Dwd"|
tst$Cls=="Dwb"|
tst$Cls=="Dwa"|
tst$Cls=="Dwc",]
#convert to sp SpatialPointsDataFrame
coordinates(tst.l) = c("Lon", "Lat")
# promote to SpatialPixelsDataFrame
gridded(tst.l) <- TRUE
# promote to SpatialGridDataFrame
tst.lsGDF = as(tst.l, "SpatialGridDataFrame")
# mask the specific climate zone from some locations
asia.zone2 <- mask(tst.lsGDF,asia.zone)
If you look up ?mask you will see that it has been implemented for Raster* objects, not for SpatialGridDataFrame objects. So you need to coerce your data to a Raster object. Something like this might work:
library(raster)
setwd("D:/Studies/PhD/SCI/modeling/")
countries <- shapefile("vne_10m_admin_0_countries/ne_10m_admin_0_countries.shp")
asia.zone <- countries[countries$ADMIN %in% c("South Korea", "North Korea","Japan", "China", "Taiwan"), ]
tst <- read.csv("Koeppen-Geiger-ASCII.csv", stringsAsFactor=FALSE)
tst.l <- tst [tst$Cls %in% c("Cfc", "Cfa", "Cfb", "Cwa", "Cwb", "Aw", "As", "Am", "Dwd", "Dwb", "Dwa", "Dwc"),]
coordinates(tst.l) = c("Lon", "Lat")
# promote to SpatialPixelsDataFrame
gridded(tst.l) <- TRUE
r <- raster(tst.l)
asia.zone2 <- mask(r, asia.zone)

Create spatial objects in R useful for coordinates() and spsample()

I'm trying to use this code, adapted from dataset meuse
data<-list(var1,var2,x,y)
coordinates(data)=~x+y
grid = spsample(data, type = "regular", cellsize = c(0.05,0.05))
vt <- variogram(var1 ~ var2,data=data)
vt.fit <- fit.variogram(vt, vgm(0.2, "Sph", 800, 0.05))
gstatobj <- gstat(id = 'var1', formula = var1 ~ var2, model=vt.fit, set = list(gls=1))
My goal is creating a grid, like meuse.grid. But coordinates doesn't work... list isn't the right command.
What shall I use?
Is correct the way I'm using to create the grid?
the following reproducible example shows jlhoward's comment is right, and Darko's reply is wrong:
library(gstat)
var1 = 1:3; var2 = 1:3; x = 1:3; y = 1:3
data<-list(var1,var2,x,y)
coordinates(data) = ~x+y
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘coordinates<-’ for signature ‘"list"’
data<-data.frame(var1,var2,x,y)
coordinates(data) = ~x+y
class(data)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
you may have been confused by doing this again, which would give:
coordinates(data) = ~x+y
Error in `coordinates<-`(`*tmp*`, value = ~x + y) :
setting coordinates cannot be done on Spatial objects, where they have already been set
but leaves the existing (and correct) data in tact.

Mosaic fails when reading rasters from disc but not from memory

I ran into a weird issue when trying to make a mosaic from several hundred rasters. The satellite imagery I'm using is not perfectly aligned or shares the exact same resolution, so I followed the steps found here to resample my rasters and then mosaic them.
I started off testing on a subset of only four images and had no problem doing this (had to manually calculate the full extent since unionExtent and the newer union only allows two extent arguments):
# Reading raster files
rst <- lapply(list.files(), FUN = stack)
# Extracting individual extents
rst_ext <- lapply(rst, FUN = extent)
# Calculating full extent
xmin_rst <- c(); xmax_rst <- c(); ymin_rst <- c(); ymax_rst <- c();
for (i in 1:length(rst_ext)) {
xmin_rst <- c(xmin_rst, rst_ext[[i]]#xmin)
ymin_rst <- c(ymin_rst, rst_ext[[i]]#ymin)
xmax_rst <- c(xmax_rst, rst_ext[[i]]#xmax)
ymax_rst <- c(ymax_rst, rst_ext[[i]]#ymax)
}
full_extent <- extent(min(xmin_rst), max(xmax_rst),
min(ymin_rst), max(ymax_rst))
# Creating raster from full extent and first rasters' CRS and resolution
bounding_rst <- raster(full_extent,
crs = crs(rst[[1]]),
res = res(rst[[1]]))
# Resampling rasters to match attributes of the bounding raster
rst_resampled <- lapply(X = rst, fun = function(x) {
target_rst <- crop(bounding_rst, x)
resample(x, target_rst, method="bilinear")
})
# Creating mosaic
rst_mosaic <- do.call("mosaic", c(rst_resampled, fun = mean))
That worked out OK, but of course, I didn't want to save all those rasters in my memory since I'd run out of it. I decided to save them in a new folder and re-read them as a stack, then make the mosaic.
# Function to crop, resample and write to a new GeoTIFF
resample_write <- function(x) {
target_rst <- crop(bounding_rst, x)
x <- resample(x, target_rst, method="bilinear")
save_name <- gsub("\\.1",
"_resampled.tif",
names(x)[1]) # Modifying name of 1st band
writeRaster(x,
filename = paste("../testing_resampling/",
save_name, sep = ""),
format = "GTiff")
}
# Running the function
lapply(rst, FUN = resample_write)
# Reading resampled images
setwd("../testing_resampling/")
rst_resampled2 <- lapply(list.files(), FUN = stack)
## Making the mosaic
rst_mosaic2 <- do.call("mosaic", c(rst_resampled2, fun = mean))
This gives the following error:
> rst_mosaic2 <- do.call("mosaic", c(rst_resampled2, fun = mean))
Error in compareRaster(x, extent = FALSE, rowcol = FALSE, orig = TRUE, :
different origin
I was able to get around it by setting the increasing the tolerance argument of mosaic to 0.4 but still don't understand why rst_resampled1 and rst_resampled2 yield different mosaic results.
Comparing them both with compareRaster and cellStats tells me that they're exactly the same.

Resources