Calculating a CHM with dtm and dsm with different resolutions - r

I have a DTM and DSM with different resolutions.
Here are the summaries of each Raster layer.
> raster_dsm
class : RasterLayer
dimensions : 2001, 2501, 5004501 (nrow, ncol, ncell)
resolution : 0.5, 0.5 (x, y)
extent : -112500.2, -111249.8, 388999.8, 390000.2 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +units=m +no_defs
data source : D:/Test_Raster/DSM/dsm.asc
names : dsm
>raster_dtm
class : RasterLayer
dimensions : 1001, 1251, 1252251 (nrow, ncol, ncell)
resolution : 1, 1 (x, y)
extent : -112500.5, -111249.5, 388999.5, 390000.5 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +units=m +no_defs
data source : D:/Test_Raster/DTM/dtm.asc
names : dtm
As you can see, the resolution of the dtm is 1 m and the resolution of the dsm is 0.5m.
I want to calculate a Crown Heigth Model (CHM).
The easiest way is to
CHM = dsm - dtm
But when I try in R the following error code appear:
Error in compareRaster(e1, e2, extent = FALSE, rowcol = FALSE, crs = TRUE, :
different resolution
Is there a simple way to ignore the resolution? Or must I do a resampling of the data, before further calculation?
In ArcGis you can do this kind of raster calculation easily, because you don't have to resample the data first.
Any suggestions will be appreciated!

Yes, Arc*** will do this for you, but what does it actually do? I think it is better to avoid that kind of ambiguity. In this case you cannot use dis/aggregate because the extents are different. So you need to use resample

Related

Merge (mosaic) of rasters changes resolution

I'm merging two MODIS DSR tiles using a R script that I developed, these are the products:
https://drive.google.com/drive/folders/1RG3JkXlbaotBax-h5lEMT7lEn-ObwWsD?usp=sharing
So, I open both products (tile h15v05 and tile h16v05) from same date (2019180), then I open each SDS and merge them together (00h from h15v05 with 00h from h16v05 and so on...)
Visualisation on Panoply (using the merge option) of the two products:
Purple square is the location of the division line that separates the two tiles.
With my code I obtain a plot with pixels with different resolution (and different min/max values) and I don't understand why:
I suspect that the results obtained are due to:
1- Changing from Sinusoidal CRS to longlat WGS84 CRS;
2- Using resample (method ngb) to work with mosaic.
My code is extensive, but here are some parts of it:
# Open scientific dataset as raster
SDSs <- sds(HDFfile)
SDS <- SDSs[SDSnumber]
crs(SDS) <- crs("+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs")
SDSreprojected <- project(SDS, DesiredCRS)
SDSasRaster <- as(SDSreprojected, "Raster")
# Resample SDS based on a reference SDS (SDS GMT_1200_DSR of a first product), I need to do this to be able to use mosaic
SDSresampled <- resample(SDSasRaster,ResampleReference_Raster,method='ngb')
# Create mosaic of same SDS, but first convert stack to list to use mosaic
ListWith_SameSDS_OfGroupFiles <- as.list(StackWith_SameSDS_OfGroupFiles)
ListWith_SameSDS_OfGroupFiles.mosaicargs <- ListWith_SameSDS_OfGroupFiles
ListWith_SameSDS_OfGroupFiles.mosaicargs$fun <- mean
SDSmosaic <- do.call(mosaic, ListWith_SameSDS_OfGroupFiles.mosaicargs)
# Save SDSs mosaic stack to netCDF
writeRaster(StackWith_AllMosaicSDSs_OfGroupFiles, NetCDFpath, overwrite=TRUE, format="CDF", varname= "DSR", varunit="w/m2", longname="Downward Shortwave Radiation", xname="Longitude", yname="Latitude", zname="TimeGMT", zunit="GMT")
Does anyone have an idea of what could be the cause of this mismatch between results?
print(ResampleReference_Raster)
class : RasterLayer
dimensions : 1441, 897, 1292577 (nrow, ncol, ncell)
resolution : 0.01791556, 0.006942043 (x, y)
extent : -39.16222, -23.09196, 29.99652, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : MCD18A1.A2019180.h15v05.061.2020343034815
values : 227.5543, 970.2346 (min, max)
print(SDSasRaster)
class : RasterLayer
dimensions : 1399, 961, 1344439 (nrow, ncol, ncell)
resolution : 0.01515284, 0.007149989 (x, y)
extent : -26.10815, -11.54627, 29.99717, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : MCD18A1.A2019180.h16v05.061.2020343040755
values : 0, 0 (min, max)
print(SDSmosaic)
class : RasterLayer
dimensions : 1441, 897, 1292577 (nrow, ncol, ncell)
resolution : 0.01791556, 0.006942043 (x, y)
extent : -39.16222, -23.09196, 29.99652, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : layer
values : 0, 62.7663 (min, max)
Also, some of the islands were ignored by the script (bottom right)...
sorry I didn't reply earlier. So I think you're right that this issue is extent to which you are resampling. I think you might be able to get around this by creating a dummy raster that has the extent of the raster you want to resample, but has the resolution of the raster you want to mosaic to.Try:
dummy<-raster(ext = SDSasRaster#extent, resolution=ResampledReference_Raster#res, crs=SDSasRaster#crs)
SDS2<-resample(SDSasRaster, dummy, method="ngb")
Final<-moasic(SDS2, ResampledReference_Raster, fun=mean)

Reprojecting list of raster stacks

I have a big list of raster stacks and I want to reproject and then clip them in R. I have done the same procedure in ArcGIS using batch processing which was significantly faster.
It is not going well in R. Any suggestion to improve the process?
my rstack.lst consist of 19 raster stacks like this:
class : RasterStack
dimensions : 4800, 7200, 34560000, 46 (nrow, ncol, ncell, nlayers)
resolution : 463.3127, 463.3127 (x, y)
extent : 11119505, 14455357, -5559753, -3335852 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs
names : ...
I am using this code:
for (i in 1:length(rstack.lst)){
rstack.lst[[i]] <- projectRaster(rstack.lst[[i]], crs = m.crs) # reproject
rstack.lst[[i]] <- crop(rstack.lst[[i]], brdshp) # crop
rstack.lst[[i]] <- mask(rstack.lst[[i]], brdshp) # mask
print (i)
}
not even one I is printed after two hours!

Identify CRS in raster file

I would like to identify the correct coordinate reference system for the following ASCII raster file:
class : RasterLayer
dimensions : 2160, 4320, 9331200 (nrow, ncol, ncell)
resolution : 0.0833333, 0.0833333 (x, y)
extent : -180, 179.9999, -90, 89.99993 (xmin, xmax, ymin, ymax)
coord. ref. : NA
data source : C:/popc_0AD.asc
names : popc_0AD
I tried to guess the correct projection by setting the CRS to some of the common formats and plotting it, as suggested in related posts. But I am still not sure about the correct setting. As far as I am concerned raster and related packages do not entail any function able to estimate missing CRS information. Do you have any idea what this raster file's CRS could be or how to find out?
The extent suggests coordinates are not projected. This seems to be the extent of Earth in degrees.
Then, you may want to use EPSG 4326, which is also crs="+proj=longlat +datum=WGS84 +no_defs":
library(raster)
r <- raster("0AD_lu/cropland0AD.asc")
projection(r) <- "+proj=longlat +datum=WGS84 +no_defs"
However, it is much better to use dataset correctly built with the coordinates reference system. It is never recommended to guess it... But I know that having clean metadata is not always possible...
You have
r <- raster(nrow=2160, ncol=4320, xmn=-180, xmx=179.9999, ymn=-90, ymx=89.99993, crs=NA)
Sébastien Rochette already pointed out that this is surely lon/lat and that you can set the CRS to relfect that
crs(r) <- "+proj=longlat +datum=WGS84"
It seems to me that the extent is a bit suspect. It looks like it is supposed to be a global raster, but that there has been some loss of precision. If so, you may correct that like this:
extent(r) <- c(-180, 180, -90, 90)
To get
r
#class : RasterLayer
#dimensions : 2160, 4320, 9331200 (nrow, ncol, ncell)
#resolution : 0.08333333, 0.08333333 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0

Crop raster with polygon in R: Error extent does not overlap

I want to crop a raster stack using a polygon shapefile i made in ArcGIS, however I get error that extent does not overlap.
First I create the raster stack:
test1 < stack("C:/mydir/test1.tif")
define projection
myCRS <- test1#crs
then read shapefile
myExtent <- readShapePoly("C:/mydir/loc1.shp", verbose=TRUE, proj4string=myCRS)
Crop
myCrop <- crop(test1, myExtent)
Error in .local(x, y, ...) : extents do not overlap
I have searched for a solution, but i only find that projection can be the problem, however they are definetly both in the same CRS:
> test1$test1.1
class : RasterLayer
band : 1 (of 4 bands)
dimensions : 10980, 10980, 120560400 (nrow, ncol, ncell)
resolution : 10, 10 (x, y)
extent : 6e+05, 709800, 5690220, 5800020 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +ellps=WGS84
+towgs84=0,0,0
data source : C:\mydir\test1.tif
names : test1.1
values : 0, 65535 (min, max)
> myExtent
class : SpatialPolygonsDataFrame
features : 1
extent : 499386.6, 517068.2, 6840730, 6857271 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +ellps=WGS84
+towgs84=0,0,0
variables : 2
names : Shape_Leng, Shape_Area
min values : 67444.6461177, 283926851.657
max values : 67444.6461177, 283926851.657
The message is pretty self explanatory. Your extent do not overlap... here how to check it:
library(raster)
ext.ras <- extent(6e+05, 709800, 5690220, 5800020)
ext.pol <- extent(499386.6, 517068.2, 6840730, 6857271)
plot(ext.ras, xlim = c( 499386.6,709800), ylim= c(5690220,6857271), col="red")
plot(ext.pol, add=T, col="blue")
I've created extent object from data in your question. You see one extent in the top left corner and the other in the bottom right. Have you tried reading both files in QGIS, you could probably easily see it.
If they really are suppose to overlap, than I would suspect the way you read your shapefile. Instead of
myExtent <- readShapePoly("C:/mydir/loc1.shp", verbose=TRUE, proj4string=myCRS)
use :
library(rgdal)
myExtent <- readOGR("C:/mydir","loc1.shp")
myExtent <- spTRansform(myExtent, CRS(proj4string(test1)))

multi band to single band for raster in R

I have the following raster:
class : RasterLayer
dimensions : 1446, 1243, 1797378 (nrow, ncol, ncell)
resolution : 1000, 1000 (x, y)
extent : 4210000, 5453000, 3372000, 4818000 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs
data source : -
names : ALL_2016_year_Raster
values : 0, 36293 (min, max)
It seems like it is a multiband raster but I would like to export it as a single band raster. when I import it, i used raster <- raster(file, band=1) but it does not change anything...
Is there a way to make it single band?

Resources