Determine if two grids match exactly in R - r

I have two rasters and one shape file, all with 100m resolution grids but different extents. The shapefile is slightly smaller extent. I want to make sure they line up exactly so my calculations are correct for each grid cell in future analysis.
Raster 1
day
class : RasterLayer
dimensions : 2367, 2909, 6885603 (nrow, ncol, ncell)
resolution : 0.0008333333, 0.0008333333 (x, y)
extent : -123.6325, -121.2083, 36.8925, 38.865 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
names : DAY_BA
values : 0, 14917 (min, max)
Raster 2
night
class : RasterLayer
dimensions : 2365, 2909, 6879785 (nrow, ncol, ncell)
resolution : 0.0008333333, 0.0008333333 (x, y)
extent : -123.6325, -121.2083, 36.89417, 38.865 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
names : NIGHT_BA
values : 0, 1744 (min, max)
Shapefile
mgrs
class : SpatialPolygonsDataFrame
features : 1186800
extent : -122.6511, -121.594, 37.10124, 38.27151 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
variables : 12
The files are large and loading them and plotting them for visual comparison is yielding nothing interesting.
I tried calculating the distance in meters between the upper and lower extents for each using the functions from https://eurekastatistics.com/calculating-a-distance-matrix-for-geographic-points-using-r/, thinking that increments of 100m would indicate that they are on 100m increment distances from each other, but this did not appear to be the case.
distance.100m <- GeoDistanceInMetresMatrix(df.lims)/100
distance.100m
DayMin DayMax NightMin NightMax MSMin MSMax
DayMin 0.000000 3056.1968 1.906129 3056.1968 903.7839357 2363.0676716
DayMax 3056.196849 0.0000 3054.546060 0.0000 2332.1390496 739.6121652
NightMin 1.906129 3054.5461 0.000000 3054.5461 902.8710503 2361.5160232
NightMax 3056.196849 0.0000 3054.546060 0.0000 2332.1390496 739.6121652
MSMin 903.783936 2332.1390 902.871050 2332.1390 0.0000000 1598.8812655
MSMax 2363.067672 739.6122 2361.516023 739.6122 1598.8812655 0.0000000
Any ideas how to compare that the pixels line up? I want to keep the original values if possible and not resample.

Given that all extent coordinates are the same, except one (ymin), and the resolution is the same, they should line up.
We can first look at the extents
d <- raster(nrow=2367, ncol=2909, ext=extent(c(-123.6325, -121.2083, 36.8925, 38.865)))
n <- raster(nrow=2365, ncol=2909, ext=extent(c(-123.6325, -121.2083, 36.89417, 38.865)))
e <- extent(c(-122.6511, -121.594, 37.10124, 38.27151))
plot(extent(d), col='green', lwd=2)
plot(extent(n), add=TRUE, col="red")
plot(e, add=TRUE, col="blue")
Clearly, the rasters are similar, and the polygons are inside the rasters extent.
We can check the origin of the rasters, to see if they align:
origin(n)
#[1] 3.331042e-05 6.573362e-05
origin(d)
#[1] 3.331042e-05 -7.105427e-14
Not quite, but that is probably because of rounding. If we do
res(n) <- 1/1200
res(d) <- 1/1200
To (probably) get what you really (should) have:
origin(n)
[1] -9.947598e-14 4.263256e-14
origin(d)
[1] -9.947598e-14 -7.105427e-14
As the extent of d is larger, you can do crop it to n, so that things line up
d <- crop(d, n)

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)

Why rasterToPolygons is creating horizontal lines?

I am trying to transform a raster layer to polygons based on its values. My raster looks like this:
> labels_rast
class : RasterLayer
dimensions : 26, 64, 1664 (nrow, ncol, ncell)
resolution : 0.03000146, 0.02999809 (x, y)
extent : 352032, 352033.9, 8551454, 8551455 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs+ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : layer
values : 1, 3 (min, max)
When I apply the rasterToPolygons function (dissolve = TRUE), I get extra polygons (defined by horizontal lines):
How can I avoid the creation of the polygons defined by the horizontal lines?
It works for this very similar case:
library(raster)
r <- raster(nrow=26, ncol=64, xmn=352032, xmx=352033.9, ymn=8551454, ymx=8551455, crs="+proj=utm +zone=18 +south +datum=WGS84 +units=m", vals=3)
r[, 20:40] <- 2
r[1:3, 1:60] <- 1
r[24:26, 5:64] <- 1
x <- rasterToPolygons(r, dissolve=TRUE)
plot(r)
lines(x)
I am guessing that it does not work for you because of floating point imprecision. Would have to see your file to be sure. But, if so, perhaps you can round the extent (or resolution) a little bit.
For example
res(labels_rast) <- 0.03
y <- rasterToPolygons(labels_rast, dissolve=TRUE)

Make raster stack with different extent

I am in trouble making raster stack which have slightly different extent. The answer (1st one) given here is useful but did not help in my case. For example, I want to make a raster stack using bio2 raster for Australia and this Australian raster. The second raster comes for Australia only and the first one is global. So I cropped the global bio2 raster to the same extent of Australian raster using crop() function, but the resultant raster extent (i.e., bio2.au) is slightly different (therefore, I cannot make raster using the cropped raster and the Australian raster, awc). Sample code is below:
library(raster)
awc <- raster("path to Australian raster")
bio2.g <- raster("path to Bio2 global raster")
# crop bio2.g to the same extent of awc
bio2.au <- crop(bio2.g, extent(awc))
# make a raster stack
st <- stack(awc, bio2.au)
Error in compareRaster(x) : different extent
I have also tried using quick=TRUE within the stack() function. But in this case the cell values in awc is lost. Note: the size of awc raster is 4gb.
# first make a list of rasters saved in the computer
li <- list.files("path to file", pattern = ".tif$", full.names = TRUE)
st <- stack(li, quick=TRUE)
st[[1]] # no cell values for awc
Your suggestions will be highly appreciated. My ultimate goal is to crop several bioclim rasters to the same extent of Australian raster awc and stack them together so that raster cell values are not lost.
Edit (after comment of #Cobin):
Below is the attribute of each raster
# global raster (bigger raster)
> r
class : RasterLayer
dimensions : 21600, 43200, 933120000 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (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:\Worldclim2_Bioclim\wc2.0_bio_30s_02.tif
names : wc2.0_bio_30s_02
values : 0, 37.06667 (min, max)
# Australian raster (smaller raster)
> r1
class : RasterLayer
dimensions : 43201, 49359, 2132358159 (nrow, ncol, ncell)
resolution : 0.0008333333, 0.0008333333 (x, y)
extent : 112.8921, 154.0246, -44.00042, -7.999583 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : D:\SoilAWC5cm.EV1.tif
names : SoilAWC5cm.EV1
values : 2.997789, 27.86114 (min, max)
# new raster, after crop() function is applied
> r2 <- crop(r,extent(r1))
> r2
class : RasterLayer
dimensions : 4320, 4936, 21323520 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : 112.8917, 154.025, -44, -8 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : C:\Users\Anwar\AppData\Local\Temp\Rtmpmg9fyF\raster\r_tmp_2018-11-23_164300_11308_65747.grd
names : wc2.0_bio_30s_02
values : 1.933333, 18.15833 (min, max)
# rebuild r2 to match r1
> r22 <- raster(vals=values(r2),ext=extent(r1), nrows=dim(r1)[1],ncols=dim(r1)[2])
Error in setValues(r, vals) :
length(values) is not equal to ncell(x), or to 1
I suppose that the extent of two raster are differet though the raster masked by crop function.You
should check the both of awc and bio.au extent base on same reolution, rows and columns. Because I couldn't download data from
hyperlink, I give an example of my own data.
r <- raster('/big_raster')
r1 <- raster('/small_raster')
r2 <- crop(r,extent(r1))
r1
class : RasterLayer
dimensions : 74, 157, 11618 (nrow, ncol, ncell)
resolution : 0.0833333, 0.0833333 (x, y)
extent : 89.2185, 102.3018, 30.96238, 37.12905 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : D:\D\temp\Rtest\modis8km.tif
names : modis8km
values : -32768, 32767 (min, max)
r2
class : RasterLayer
dimensions : 74, 157, 11618 (nrow, ncol, ncell)
resolution : 0.08333333, 0.08333333 (x, y)
extent : 89.25, 102.3333, 31, 37.16667 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : g201401a
values : -32768, 7789 (min, max)
Though r1 and r1 with same resolution and dimension, the extent have tiny offset. It cause stack error.
stack(r1,r2)
Error in compareRaster(x) : different extent
So, you should rebuid the r2 to match r1:
r22 <- raster(vals=values(r2),ext=extent(r1),crs=crs(r1),
nrows=dim(r1)[1],ncols=dim(r1)[2])
Now stack(r22,r1) will be successful.

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)))

Rasterize spatialpolygons in R giving raster with NA values

I am having issues converting this spatialpolygondataframe to a raster. When I do ther conversion, the raster has NA as its values. As shown below:
DL3
[1]
class : SpatialPolygonsDataFrame
features : 126
extent : -15.04001, 46.1036, 3.759985, 31.71804 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +towgs84=0,0,0 +ellps=WGS84
variables : 1
names : LFRP
min values : 14
max values : 335.2
This is how I rasterize it:
##TO CONVERT TO RASTER
FunR<-function(r){
ext<-raster(extent(r))
crs(ext)<-crs(r)
D<-rasterize(r,ext,field=1,update=T)
D}
DL4<-lapply(DL3,FunR)
DL4
[1]
class : RasterLayer
dimensions : 45, 40, 1800 (nrow, ncol, ncell)
resolution : 1.52859, 0.6212901 (x, y)
extent : -15.04001, 46.1036, 3.759985, 31.71804 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +towgs84=0,0,0 +ellps=WGS84
data source : in memory
names : layer
values : NA, NA (min, max)
What can I be doing wrongly? I need help with a method to ensure the values in the dataframe reflect in the raster, please.
The principle works, as illustrated below.
library(raster)
SPP <- shapefile(system.file("external/lux.shp", package="raster"))
r <- raster(SPP, ncol=40, nrow=45)
SPP2 <- rasterize(SPP, r, "ID_1")
As this does not work for you, I assume that your polygons are very small relative to the raster cell size such that none of the cells is covered. Can you try with much smaller grid cells? If indeed the polygons are that small, it might make more sense to use their centroids (coordinates(SPP)) and rasterize these (as points).

Resources