Extracting all individual layers from a Raster Brick File - r

I have stacked 28 layers to a brick in R
brik
class : RasterBrick
dimensions : 720, 1440, 1036800, 28 (nrow, ncol, ncell, nlayers)
resolution : 0.25, 0.25 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
source : C:/Users/Ujjal Baruah/AppData/Local/Temp/Rtmp0GaiPO/raster/r_tmp_2020-01-03_030159_46788_10398.grd
names : Data.Fiel//tNO2Trop.1, Data.Fiel//tNO2Trop.2, Data.Fiel//tNO2Trop.3, Data.Fiel//tNO2Trop.4, Data.Fiel//tNO2Trop.5, Data.Fiel//tNO2Trop.6, Data.Fiel//tNO2Trop.7, Data.Fiel//tNO2Trop.8, Data.Fiel//tNO2Trop.9, Data.Fiel//NO2Trop.10, Data.Fiel//NO2Trop.11, Data.Fiel//NO2Trop.12, Data.Fiel//NO2Trop.13, Data.Fiel//NO2Trop.14, Data.Fiel//NO2Trop.15, ...
Now, i want to save this individual layers in Geotiff using
writeRaster(brik, file.path('/output/filepath/', names(brik)), bylayer=TRUE, format('GTiff'))
Unfortunately, i get just one file instead of multiple layers in geotiff.
Any solution would be appreciated.
Thanks

writeRaster seems to strip off the dot-number before creating a raster file. Hence it tries to write your layers all to Data.Fiel//tNO2Trop.tif.
> writeRaster(r, "./test.2", format="GTiff")
> dir(".")
[1] "test.tif"
(Note for some reason your code has format("GTiff") for format="GTiff". This works by the fluke that format is a function and returns the string "GTiff" and writeRaster is expecting the format string here)
I don't know why and I don't know if this is documented or a bug. You can work round by using dashes instead of dots:
> writeRaster(r, "./test-2", format="GTiff")
> dir(".")
[1] "test-2.tif" "test.tif"
and if dots are important to you then do a file.rename afterwards.
Edit: If you add the .tif to the file names then all is well:
> writeRaster(s, names(s), bylayer=TRUE, format="GTiff")
Error in .getGDALtransient(x, filename = filename, options = options, :
filename exists; use overwrite=TRUE
fails on the second layer because dot-number is stripped:
> dir()
[1] "layer.tif"
add .tif to the names:
> writeRaster(s, paste0(names(s),".tif"), bylayer=TRUE, format="GTiff")
shazam:
> dir()
[1] "layer.1.tif" "layer.2.tif" "layer.3.tif" "layer.tif"

Related

Save raster to USGS DEM Format in R

Similar to this question:
I would like to know how to do the reverse and save an .img raster image into a USGS DEM format.
Based on GDAL docs, it seems like it would be possible but when I run rgdal::getGDALDriverNames() in R I get the following:
name long_name create copy isRaster
139 USGSDEM USGS Optional ASCII DEM (and CDED) FALSE TRUE TRUE
which seems to imply that it won't create these files?
I was hoping to do something like:
library(raster)
# read
img <- raster("Raster_100ft_2022_10_18.img")
# convert to DEM
writeRaster(img, 'test.dem')
But raster doesn't seem to recognize that output format.
Is there some other method to save as USGS DEM files?
Thanks
For me it works with terra. If that's proper "USGSDEM" file, that's another question. From gdal reference it should save the file as well: https://gdal.org/drivers/raster/usgsdem.html
f <- system.file("ex/elev.tif", package="terra")
r <- terra::rast(f)
terra::writeRaster(r, filename = "test.dem", filetype = "USGSDEM", overwrite = TRUE)
raster::raster("test.dem")
#> class : RasterLayer
#> dimensions : 90, 95, 8550 (nrow, ncol, ncell)
#> resolution : 0.008333333, 0.008333333 (x, y)
#> extent : 5.741667, 6.533333, 49.44167, 50.19167 (xmin, xmax, ymin, ymax)
#> crs : +proj=longlat +datum=WGS84 +no_defs
#> source : test.dem
#> names : elevation
#> values : 141, 547 (min, max)
Created on 2022-10-20 with reprex v2.0.2

Extent and crs of rasters not written by writeCDF

When writing rasters in netCDF files, I always get the warning message: "[rast] unknown extent". Indeed, the extent is not written in the external file. Neither is the crs.
library(terra)
#terra version 1.0.2
r <- rast(ncol=2, nrow=2, vals=c(5.3, 7.1, 3, 1.2))
crs(r)<-"epsg:27572"
ext(r)
#SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
t<-writeCDF(r,"test.ncdf",overwrite=TRUE)
#Warning message:
#[rast] unknown extent
ext(t) # extension is not correct
#SpatExtent : 0, 1, 0, 1 (xmin, xmax, ymin, ymax)
crs(t) # crs is not correct
#[1] "GEOGCRS[\"unknown\",\n DATUM[\"World Geodetic System 1984\",\n ...
Perhaps there is a peculiar syntax to use here. I explored ?writeCDF, but could not find any clue.
This points at an issue with GDAL --- depending on whether you think that .ncdf is a common filename extension for netCDF files.
library(terra)
#terra version 1.0.3
r <- rast(ncol=2, nrow=2, vals=c(5.3, 7.1, 3, 1.2))
Note the different file extensions, .nc, .cdf, .ncdf or missing.
# ok
x <- writeCDF(r, "test1.nc", overwrite=TRUE)
y <- writeCDF(r, "test2.cdf", overwrite=TRUE)
# not ok
z <- writeCDF(r, "test3.ncdf", overwrite=TRUE)
#Warning message:
#[rast] unknown extent
a <- writeCDF(r, "test4", overwrite=TRUE)
#Warning message:
#[rast] unknown extent
GDALinfo shows:
describe("test1.nc")[1]
#[1] "Driver: netCDF/Network Common Data Format"
describe("test3.ncdf")[1]
#[1] "Driver: HDF5Image/HDF5 Dataset"
It looks like GDAL first tries the netCDF driver when the extension is .nc or .cdf, but that it first tries the HDF5 driver when it is .ncdf or missing --- and since this does not fail (the warning comes from terra, not from GDAL), that is what it uses.
This is the GDAL version on windows.
gdal()
#[1] "3.0.4"
I see the same behavior with GDAL 2.2.3 on linux and 3.2.0 on mac.
You can work around that by not using .ncdf or by specifying the driver when opening the file:
rast('NETCDF:"test3.ncdf"')
#class : SpatRaster
#dimensions : 2, 2, 1 (nrow, ncol, nlyr)
#resolution : 180, 90 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs
#source : NETCDF:test1.ncdf
#varname : test1
#name : test1
I do not think there is anything wrong with the CRS (it is the same as crs(r)). However, I should note that terra writes the proj4 and wkt strings to a ncdf file, and does not follow the ncdf standard in that respect.
(You are asking a question about a method that is only available in the development version of terra. I appreciated that very much, but raising an issue on the terra github site would be more appropriate in this case. I will make writeCDF give a warning when the file extension is not .nc or .cdf)

Extraction of data from multiple netcdf files at five coordinates files and writing them to five separate csv files

I have 365 .nc files located in a folder containing daily soil moisture information. I want to extract data at five-coordinate locations for the whole year and write them into five separate csv files. My code is attached below. However, I am getting this error after the line:
s <- stack(ff)
>Error in if (is.na(get("has_proj_def.dat", envir = .RGDAL_CACHE))) { : argument is of length zero In addition: Warning message: In .varName(nc, varname, warn = warn) : varname used is: sm If that is not correct, you can set it to one of: sm, sm_noise, flag, sensor
No idea how to proceed further.
library(raster)
library(ncdf4)
ptf <- "D://SMOS_ECV_SM//SMOS_ECV_SM//ECV_SM_Data_1978_2010//1978"
ff <- list.files(path=ptf, pattern="[.]nc$", full.names=TRUE)
s <- stack(ff)
points <- rbind(c(0,1), c(100,120), c(80,5), c(85,4), c(82,4))
v <- extract(s, points)
for (i in 1:ncol(v)) {
write.csv(v[,i,drop=FALSE], paste0("file", i, ".csv"))
}
library(raster)
#Loading required package: sp
f <- list.files("try", full=T)
First try for a single file
r <- raster(f[1])
#Loading required namespace: ncdf4
#Warning message:
#In .varName(nc, varname, warn = warn) : varname used is: sm
#If that is not correct, you can set it to one of: sm, sm_noise, flag, sensor
To get rid of the warning:
r <- raster(f[1], varname="sm")
Now for all files
s <- stack(f, varname="sm")
s
#class : RasterStack
#dimensions : 720, 1440, 1036800, 2 (nrow, ncol, ncell, nlayers)
#resolution : 0.25, 0.25 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#names : Soil.Moisture.1, Soil.Moisture.2
Extract values
points <- rbind(c(-96.7, 47), c(34.55, 54.85))
v <- extract(s, points)
v
# Soil.Moisture.1 Soil.Moisture.2
#[1,] 0.3254 0.3018
#[2,] 0.3386 0.3386

stack and brick function error despite all of the rasters have been

Good day everyone..
I have 13 bioclimatic variables (in .tiff format) that I will used to perform sdm by using dismo package.
I followed the tutorial written by Robert J. Hijmans and Jane Elith.
However, when I tried to stack all of the variables, I got the following error
Error in .local(.Object, ...) :
Error in .rasterObjectFromFile(x, band = band, objecttype = "RasterLayer", :
Cannot create a RasterLayer object from this file.
All of my file's coordinate system, extent, and cell size have been adjusted so they are all the same..
when I tried to used the alternative brick function, I got the following error :
Error in .rasterObjectFromFile(x, objecttype = "RasterBrick", ...) :
Cannot create a RasterLayer object from this file.
In addition: There were 12 warnings (use warnings() to see them)
I used the warning() message but it was empty..
do any of you have any hints regarding what may be the cause of such errors?
i've tried to google it, but unfortunately, no answer can solve it.
Thank you in advance..
Here presented is the fraction of the transcript
#setting the workspace
setwd("D:/Riset/MaxentSelaginella/newpaperproject_part2/MakalahVI/Workspace_R")
#Loading Libraries
library("sp")
library("raster")
library("maptools")
library("rgdal")
library("dismo")
library("rJava")
#open the csv file
obs.data <- read.csv(file = "data3/Selaginella_plana.csv", sep = ",")
#open Environmental Data
files <- list.files(path = "data3/tif/", pattern = ".tif", full.names=TRUE)
#stacking all the files
predictors <- brick(files)
I guess you need to use stack instead of brick. As per brick help, in fact:
A RasterBrick is a multi-layer raster object. They are typically created from
a multi-layer (band) file; but they can also exist entirely in memory.
They are similar to a RasterStack (that can be created with stack), but processing
time should be shorter when using a RasterBrick. Yet they are less flexible as they can only point to a single file.
So, if we try to “stack” multiple files:
library(raster)
r <- raster(ncols = 100, nrows = 100, vals = 1:10000)
rfile1 <- tempfile(fileext = ".tif")
writeRaster(r, filename = rfile1)
rfile2 <- tempfile(fileext = ".tif")
writeRaster(r, filename = rfile2)
files_to_stack <- c(rfile1, rfile2)
This fails:
brick(files_to_stack)
#> Warning in if (x == "" | x == ".") {: the condition has length > 1 and only
#> the first element will be used
#> Warning in if (!start %in% c("htt", "ftp")) {: the condition has length > 1
#> and only the first element will be used
#> Warning in if (fileext %in% c(".GRD", ".GRI")) {: the condition has length
#> > 1 and only the first element will be used
#> Warning in if (!file.exists(x)) {: the condition has length > 1 and only
#> the first element will be used
.....
#> Error in .rasterObjectFromFile(x, objecttype = "RasterBrick", ...): Cannot create a RasterLayer object from this file.
While this works:
stack(files_to_stack)
#> class : RasterStack
#> dimensions : 100, 100, 10000, 2 (nrow, ncol, ncell, nlayers)
#> resolution : 3.6, 1.8 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#> names : file46e41bcd78e3, file46e43ea75bad
#> min values : 1, 1
#> max values : 10000, 10000
If you want to have a brick to get some gain in “efficiency” in further
processing, you can save the different "layers" as a multiband tiff, and then open using brick:
rfile_multi <- tempfile(fileext = ".tif")
writeRaster(stack(files_to_stack), filename = rfile_multi)
brick(rfile_multi)
#> class : RasterBrick
#> dimensions : 100, 100, 10000, 2 (nrow, ncol, ncell, nlayers)
#> resolution : 3.6, 1.8 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#> data source : D:\RTemp\RtmpacXztJ\file4808784f268c.tif
#> names : file4808784f268c.1, file4808784f268c.2
#> min values : 1, 1
#> max values : 10000, 10000
Created on 2018-11-10 by the reprex package (v0.2.1)

Save multi layer RasterBrick to harddisk

I have a multilayer RasterBrick representing a topographic map that I want to save to the harddisk as grd or tif format, so that others can work with later.
This is the RasterBrick:
class : RasterBrick
dimensions : 2400, 4200, 10080000, 3 (nrow, ncol, ncell, nlayers)
resolution : 100, 100 (x, y)
extent : 480000, 9e+05, 62000, 302000 (xmin, xmax, ymin, ymax)
coord. ref. : NA
data source : in memory
names : layer.1, layer.2, layer.3
min values : 2.8725, 2.8725, 2.8725
max values : 254.5175, 254.5175, 254.5175
I tried to save it with this command:
outfile <- writeRaster(brick, filename='grid.tif', format="GTiff", overwrite=TRUE)
and this:
outfile <- writeRaster(m, filename='grid.grd', format="raster", overwrite=TRUE)
But the tif file is corrupt and the grd object only contains one layer and is not recognized as multi layer RasterBrick when I read it back in using raster().
The aim is to use the topographic map as background for thematic maps.
Try this:
outfile <- writeRaster(brick, filename='grid.tif', format="GTiff", overwrite=TRUE,options=c("INTERLEAVE=BAND","COMPRESS=LZW"))

Resources