0

I have a raster that tells me fraction burnt area in a cell

class       : SpatRaster 
dimensions  : 128, 256, 1  (nrow, ncol, nlyr)
resolution  : 1.40625, 1.400437  (x, y)
extent      : -180.7031, 179.2969, -89.62795, 89.62795  (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326) 
source      : BurntArea.tif 
name        : BurntArea 
min value   :       0.0000000 
max value   :       0.8538834

I have another raster which is a fine resolution and a binary 1 and 0. 1 implies that pixel is burnable and 0 implies it is unburnable

class       : SpatRaster 
dimensions  : 64800, 129600, 1  (nrow, ncol, nlyr)
resolution  : 0.002777778, 0.002777778  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326) 
source      : binary_raster 
name        : binary_raster 
min value   :       0 
max value   :       1

I want to disaggregate burnt area to the binary layer to only those cells which are burnable i.e. have a value of 1. When disaggregating burnt area to the binary layer 1, I need to distribute it equally to all cells equal to 1. I am thinking the best way to do this is:

  1. Do a zonal stats first to calculate number of burnable pixels (binarylayer = 1) in each coarse burnt area cell

    count_brpixel <- terra::zonal(binary_raster, BurntArea, fun = "sum", as.raster = T)
    
  2. Divide the burnt area by total number of burnable pixels such that I get burnt area per burnable pixel

    burnt_per_pixel <- BurntArea/count_brpixel
    
  3. Disaggregate burnt_per_pixel at the same resolution as the binary_raster

    res_drop <- res(binary_raster)[1]/res(BurntArea)[1]
    burnt_per_pixel_disagg <- terra::disagg(burnt_per_pixel, fact = res_drop)
    
  4. Multiply burnt_per_pixel_disagg with binary raster.

    final_file <- burnt_per_pixel_disagg * binary_raster
    

The final_file contains the burntarea in a high resolution

I am actually stuck on step (1) where I get the Error: [zonal] extents do not match. At this point, I don't even know if the rest of steps will generate any error or whether this is right way to go about this. Any help is appreciated.

89_Simple
  • 3,393
  • 3
  • 39
  • 94
  • For the first hurdle (1), make an empty rast with resolution of binary and extent of burnt (and crs) as binary2 - see ?rast signature 'missing', and `aligned_I_can_use_binary <- terra::resample(binary, binary2)`, use the resulting in your terra::focal. What data are you using? – Chris Aug 28 '23 at 22:43
  • For the burnt area, I am using the CMIP6 GCM data. For binary 0/1 mask, it is a derived raster from 300m Copernicus LULC but each LULC is classified as either burnable or unburnable – 89_Simple Aug 29 '23 at 08:41
  • And date of data downloaded, approximately? – Chris Aug 29 '23 at 12:43
  • A week back I downloaded it – 89_Simple Aug 29 '23 at 17:14
  • For Copernicus, I calculated it myself i.e. derived the binary layer myself – 89_Simple Aug 29 '23 at 17:15
  • The answers to this question, over at the GIS platform, might do the trick with little need for adaptation: https://gis.stackexchange.com/questions/423291/how-can-i-both-resample-and-aggregate-a-raster-using-terra – I_O Sep 01 '23 at 20:28

1 Answers1

-3

Your task involves spatial downscaling of raster data, which is a common problem in remote sensing and geographical information systems (GIS). The error you're seeing—[zonal] extents do not match—is likely because the extents (i.e., the geographical boundaries) of your BurntArea raster and binary_raster don't match exactly, which is a requirement for the terra::zonal function to work.

Here's how you can solve this:

Step 1: Align the Rasters First, crop and/or resample one raster so that its extent matches that of the other raster. You can use terra::crop and terra::resample for this.

# Crop the binary raster to match the extent of the BurntArea raster
binary_raster_cropped <- terra::crop(binary_raster, terra::ext(BurntArea))

# Or, crop the BurntArea raster to match the extent of the binary raster
# BurntArea_cropped <- terra::crop(BurntArea, terra::ext(binary_raster))

Step 2: Zonal Statistics After cropping, you should be able to use terra::zonal to get the sum of burnable pixels within each coarse burnt area cell.

count_brpixel <- terra::zonal(binary_raster_cropped, BurntArea, fun = "sum", as.raster = T)

Step 3: Calculate burnt area per pixel Divide the burnt area by the total number of burnable pixels.

burnt_per_pixel <- BurntArea / count_brpixel

Step 4: Disaggregate Disaggregate the raster to match the resolution of the binary_raster.

res_drop <- res(binary_raster)[1] / res(BurntArea)[1]
burnt_per_pixel_disagg <- terra::disagg(burnt_per_pixel, fact = res_drop)

Step 5: Final Calculation Multiply the disaggregated raster with the binary raster.

final_file <- burnt_per_pixel_disagg * binary_raster_cropped

This will produce a high-resolution raster where values are distributed equally to cells that are burnable (binary_raster = 1).

This should solve your problem, but please make sure to double-check whether the geographical alignment and projections are correctly handled. Incorrect geographical extents and projections can result in misleading results.

DevGuy
  • 123
  • 1
  • 3
  • 10