Projecting a raster in terra fails - r

I have a single simple raster in EPSG:7532 that I am trying to project to EPSG:4326 but is failing
The source data is a Lidar point clould that I am able to process using the lidR package. The data source is in the link below
https://rockyweb.usgs.gov/vdelivery/Datasets/Staged/Elevation/LPC/Projects/WI_BrownRusk_2020_B20/WI_Brown_2_2020/LAZ/USGS_LPC_WI_BrownRusk_2020_B20_02531702.laz
l1 = readLAS("USGS_LPC_WI_BrownRusk_2020_B20_02531702.laz")
> l1
class : LAS (v1.4 format 6)
memory : 2.5 Gb
extent : 25349, 26849, 170258, 171758 (xmin, xmax, ymin, ymax)
coord. ref. : NAD83(2011) / WISCRS Brown (m) + NAVD88 height - Geoid18 (m)
area : 2.25 km²
points : 35.57 million points
density : 15.79 points/m²
density : 12.89 pulses/m²
convert to a spatRaster:
dsm <- rasterize_canopy(l1, res = 1.0, pitfree(c(0,2,5,10,15), c(0, 1.5)))
> dsm
class : SpatRaster
dimensions : 1500, 1501, 1 (nrow, ncol, nlyr)
resolution : 1, 1 (x, y)
extent : 25349, 26850, 170258, 171758 (xmin, xmax, ymin, ymax)
coord. ref. : NAD83(2011) / WISCRS Brown (m) (EPSG:7532)
source : memory
name : Z
min value : 185.836
max value : 333.709
The point of failure is the attempt to project to geographic format:
dsm_test <- terra::project(dsm, "EPSG:4326", method="bilinear")
> dsm_test <- terra::project(dsm, "EPSG:4326", method="bilinear")
Error: [project] cannot get output boundaries
In addition: Warning messages:
1: In x#ptr$warp(SpatRaster$new(), y, method, mask, FALSE, opt) :
GDAL Error 1: PROJ: vgridshift: could not find required grid(s).
2: In x#ptr$warp(SpatRaster$new(), y, method, mask, FALSE, opt) :
GDAL Error 1: PROJ: pipeline: Pipeline: Bad step definition: proj=vgridshift (File not found or invalid)
3: In x#ptr$warp(SpatRaster$new(), y, method, mask, FALSE, opt) :
GDAL Error 1: Too many points (961 out of 961) failed to transform, unable to compute output bounds.
A similar topic here, but seems different.
https://stackoverflow.com/questions/72404897/what-is-causing-this-raster-reprojection-error

This issue is not resulting from reprojection from EPSG:7532 to EPSG:4326 per se, but seems rather connected to the fact, that your SpatRaster object created via rasterize_canopy() comes with a vertical datum, apparently causing problems downstream:
VERTCRS["NAVD88 height - Geoid18 (m)",
VDATUM["North American Vertical Datum 1988"],
CS[vertical,1],
AXIS["up",up,
LENGTHUNIT["meter",1]],
GEOIDMODEL["GEOID18"],
ID["EPSG",5703]]]
The quick & dirty solution would be to simply override crs definition by EPSG:7532 and dropping references in Z dimension, although this does not feel 100 % right. On the other hand, I'm not sure how terra handles vertical crs information and if it is possible to keep this information at all.
library(lidR)
library(terra)
#> terra 1.6.49
l1 = readLAS("USGS_LPC_WI_BrownRusk_2020_B20_02531702.laz")
#> Warning: There are 53206 points flagged 'withheld'.
dsm <- rasterize_canopy(l1, res = 1.0, pitfree(c(0,2,5,10,15), c(0, 1.5)))
crs(dsm) <- "epsg:7532"
dsm_4326 <- project(dsm, "epsg:4326", method="bilinear")
dsm_4326
#> class : SpatRaster
#> dimensions : 1235, 1727, 1 (nrow, ncol, nlyr)
#> resolution : 1.093727e-05, 1.093727e-05 (x, y)
#> extent : -88.0786, -88.05972, 44.49092, 44.50443 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (EPSG:4326)
#> source(s) : memory
#> name : Z
#> min value : 185.8360
#> max value : 295.1357
From my personal point of view, it would be better to have both crs (xy, z) listed in the SpatRaster summary with reproject() being able to address z-transformations separately (or have e.g. terra::transform()), e.g. when you wanted to just transform your heights but still keep EPSG:7532 as your xy reference system.
coord. ref. xy: NAD83(2011) / WISCRS Brown (m) (EPSG:7532)
coord. ref. z: NAVD88 height - Geoid18 (m) (EPSG:5703)

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

Trouble reading a netcdf file and convert it into a SpatRaster

I am struggling to open a NetCDF file and convert it into a raster using R. The
data is supposed to be on a regular grid of 25 km by 25 km. It contains sea
ice concentration in the Arctic.
library(terra)
#> terra 1.5.21
library(ncdf4)
file <- "~/Downloads/data_sat_Phil_changt_grid/SIC_SMMR_month_2015.nc"
I am getting a warning about the extent not found.
r <- rast(file)
#> Error in R_nc4_open: No such file or directory
#> Warning: [rast] GDAL did not find an extent. Cells not equally spaced?
We can see that there is a problem with the coordinates/extent.
r
#> class : SpatRaster
#> dimensions : 448, 304, 12 (nrow, ncol, nlyr)
#> resolution : 0.003289474, 0.002232143 (x, y)
#> extent : 0, 1, 0, 1 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84
#> source : SIC_SMMR_month_2015.nc:sic
#> varname : sic
#> names : sic_1, sic_2, sic_3, sic_4, sic_5, sic_6, ...
I can open the nc file with nc_open() and I see that the coordinates are present.
nc <- nc_open(file)
names(nc$var)
#> [1] "lat" "lon" "sic"
lat <- ncvar_get(nc, "lat")
lon <- ncvar_get(nc, "lon")
dim(lat)
#> [1] 304 448
dim(lon)
#> [1] 304 448
dim(r)
#> [1] 448 304 12
Is it possible to assemble this data (the SIC values and the coordinates) to create a SpatRaster?
The nc file can be downloaded here: https://easyupload.io/pfth0s
Created on 2022-05-20 by the reprex package (v2.0.1)
The data are gridded, but the file does not specify the coordinates, nor the coordinate reference system. The file specifies the lon/lat values associated with the cells, but does not help us much, as these are clearly not on a regular grid. That is easy to see from plot(r)
NAflag(r) = -9999
plot(r,1)
And also from
p = cbind(as.vector(lon), as.vector(lat))
plot(p, cex=.1, xlab="lon", ylab="lat")
So what you need to find out, is which coordinate reference system (crs) is used, clearly some kind of polar crs. And what the extent of the data set is.
From the website you point to, I take it we can use:
crs(r) = "+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs"
ext(r) = c(-3850000, 3750000, -5350000, 5850000)
r
#class : SpatRaster
#dimensions : 448, 304, 12 (nrow, ncol, nlyr)
#resolution : 25000, 25000 (x, y)
#extent : -3850000, 3750000, -5350000, 5850000 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs
#source : SIC_SMMR_month_2015.nc:sic
#varname : sic
#names : sic_1, sic_2, sic_3, sic_4, sic_5, sic_6, ...
The results look good:
g = geodata::gadm("Greenland", level=0, path=".")
gg = project(g, crs(r))
plot(r,1)
lines(gg)
But this is of course not a good way to do such things; the ncdf file should have contained all the metadata required.

Error in shapefile(dataFolder, "file.shp")) : could not find function "shapefile"

I am getting an error, saying could not find the function "shapefile".
I also tried all the possible solutions.
I did the shp, .shx and .dbf files in the same folder and many more but it doesn't work, any help, please?
library(raster)
setwd("filename of the folder ")
S <-shapefile(datafolder,"file.shp"))
then error
Error in shapefile(dataFolder, "file.shp")) : could not find function "shapefile"
Here I show that/how raster::shapefile works.
library(raster)
filename <- system.file("external/lux.shp", package="raster")
filename
#[1] "C:/soft/R/R-4.1.1/library/raster/external/lux.shp"
p <- shapefile(filename)
p
#class : SpatialPolygonsDataFrame
#features : 12
#extent : 5.74414, 6.528252, 49.44781, 50.18162 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#variables : 5
#names : ID_1, NAME_1, ID_2, NAME_2, AREA
#min values : 1, Diekirch, 1, Capellen, 76
#max values : 3, Luxembourg, 12, Wiltz, 312
Your
S <-shapefile(datafolder,"file.shp"))
is not proper R syntax (parenthesis do not match). Perhaps you want
S <- shapefile("file.shp")
or
S <- shapefile(file.path(datafolder,"file.shp"))
in which case you do not need to set the working directory

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)

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)

Resources