0

I have a spline interpolation function that I used for interpolating a RasterStack of 31 NDVI layers for the month of June 2018. The function needs to include the requirement of only generating pixel values inside a NDVI interval (-1 to +1).

My problem is that the RasterBrick resulted have pixel values outside the (-1 to +1) interval. How can I fix that?

So, to give a background of my goal:

I want to create a NDVI time series for June of 2018 with no time gaps. I have 5 NDVI raster images for the month:

  • 2018-05-09
  • 2018-05-14
  • 2018-05-19
  • 2018-05-24
  • 2018-05-29

And the rest of the days I want to create empty rasters with NA pixel values to have then 31 raster images to stack them and then apply the spline function. Here are my steps:

STEP 1

I created an empty raster with NA values for all the missing days of the month, here is an example of one date:

#creating empty raster for the missing dates JUNE2018
#define raster layer
NDVI_20180501 <- raster(ncol=7925, nrow=7218, xmn=602770, xmx=682020, ymn=6590220, ymx=6662400, crs=CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"))
#set all pixel values to NA
NDVI_20180501[] <- NA
#save the raster (write to disk) as .tif file
writeRaster(NDVI_20180501, "NDVI_20180501.tif", format="GTiff", overwrite=TRUE)

STEP 2

Then I stack all the empty raster with the NDVI rasters:

#list of raster files
file_list <- list.files(pattern = "\\.tif$")

#Stack all rasters
rstack_ndvi_062018 <- stack(file_list)

STEP 3

Then thats the part that I believe lies the problem, I wrote the spline function inspired by this answer https://stackoverflow.com/a/37846446/21455915 but altering so the spline interpolation would generate values that are inside the NDVI interval (from -1 to +1):

f2 <- function(x) {
  z <- which(is.na(x))
  nz <- length(z)
  nx <- length(x)
  if (nz > 0 & nz < nx) { 
    # Find the min and max values within the -1 to +1 range
    min_val <- min(x[x >= -1 & x <= 1])
    max_val <- max(x[x >= -1 & x <= 1])
    
    # If there are no values within the range, set the range to -1 to +1
    if (is.na(min_val) | is.na(max_val)) {
      min_val <- -1
      max_val <- 1
    }
    
    # Interpolate the missing values using the spline function
    x[z] <- spline(x=1:nx, y=pmin(pmax(x, min_val), max_val), xout=z, method="natural")$y
  }
  x
}

STEP 4

Used calc() to apply the above spline function into the RasterStack created on STEP 2:

nogap_rstack_ndvi_062018_f2 <- calc(rstack_ndvi_062018, f2)

But when observing the result by:

nogap_rstack_ndvi_062018_f2

You can see that the pixel values for the interpolated layers are outside the -1 to +1 interval:

class : RasterBrick dimensions : 7218, 7925, 57202650, 31 (nrow, ncol, ncell, nlayers) resolution : 10, 10 (x, y) extent : 602770, 682020, 6590220, 6662400 (xmin, xmax, ymin, ymax) crs : +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs source : r_tmp_2023-03-23_170523_8596_34248.grd names : layer.1, layer.2, layer.3, layer.4, layer.5, layer.6, layer.7, layer.8, layer.9, layer.10, layer.11, layer.12, layer.13, layer.14, layer.15, ... min values : -3.8575468, -3.5863018, -3.3150567, -3.0438116, -2.7725666, -2.5148830, -2.3982520, -2.2816209, -2.1649899, -2.0483589, -1.9317279, -1.8150969, -1.6984659, -1.5818349, -1.4652039, ... max values : 4.568034, 4.293518, 4.019002, 3.744486, 3.469970, 3.195453, 2.920937, 2.646421, 2.371905, 2.097389, 1.828929, 1.733057, 1.637185, 1.541313, 1.445441 , ...

How can I fix this?

And thanks for helping!

  • You could try to use a model other than a spline to fill the gaps. A possibility is a general additive model with shape constraints as implemented in the `scam` package. – Rainfall.NZ Mar 23 '23 at 22:58

0 Answers0