r-spatialecology/landscapemetrics

Patch ID for multiband Rasters

Cumaribo opened this issue · 4 comments

I love this package.
I have a suggestion. When running get_patches() in a multiband raster/spatRaster the numbers of the individual patch IDs follow do not restart for each subsequent band, but the sequence is maintained over all bands.

I use these tools to identify patches that satisfy certain conditions (eg .area<threshold) for further processing (reclassification).
However, when running calculate_lsm() on a multiband raster, the numeration of the extracted patchIDs restarts in 1 for each layer, requiring some additional manipulation to match the IDs on the output tibbles with the IDs of of the extracted patch rasters.

I think that it would be great to have the option to specify that the enumeration of the patch restarts for each band in the output of get_patches(), and/or that the enumeration of the ids in the output of calculate_lsm() does not restart for each layer, but the sequence is maintained.

Thats certainly a good idea. I would need to have a look at the underlying code how much changes that would require!

However, when running calculate_lsm() on a multiband raster, the numeration of the extracted patchIDs restarts in 1 for each layer, requiring some additional manipulation to match the IDs on the output tibbles with the IDs of of the extracted patch rasters.

@Cumaribo do you have any code to do this additional manipulation? It may help us to add this option to the package.

Hey,

I just had a look at the code and unfortunately we won't be able to implement this. But, it should be fairly easy to just get the IDs outside landscapemetrics yourself (e.g., see attached code).

Will close for now, please re-open if required.

library(landscapemetrics)
library(purrr)
library(terra)

# create multi-band raster
ls_multi <- c(terra::rast(landscape), terra::rast(landscape), terra::rast(landscape))

# get patches
patches_multi <- get_patches(ls_multi)

# create one raster for each layer
patches_stack <- purrr::map(patches_multi, function(i) terra::rast(i) |> sum(na.rm = TRUE))

# get maximum patch ids
id_max <- purrr::map_int(patches_stack, function(i) terra::values(i, mat = FALSE) |> max())

# calculate id increase for each layer
id_add <- id_max * 0:(terra::nlyr(ls_multi) - 1)      

# update ids
(ls_updated <- purrr::map2(patches_stack, id_add, function(i,j) i + j))
#> $layer_1
#> class       : SpatRaster 
#> dimensions  : 30, 30, 1  (nrow, ncol, nlyr)
#> resolution  : 1, 1  (x, y)
#> extent      : 0, 30, 0, 30  (xmin, xmax, ymin, ymax)
#> coord. ref. :  
#> source(s)   : memory
#> name        : sum 
#> min value   :   1 
#> max value   :  28 
#> 
#> $layer_2
#> class       : SpatRaster 
#> dimensions  : 30, 30, 1  (nrow, ncol, nlyr)
#> resolution  : 1, 1  (x, y)
#> extent      : 0, 30, 0, 30  (xmin, xmax, ymin, ymax)
#> coord. ref. :  
#> source(s)   : memory
#> name        : sum 
#> min value   :  29 
#> max value   :  56 
#> 
#> $layer_3
#> class       : SpatRaster 
#> dimensions  : 30, 30, 1  (nrow, ncol, nlyr)
#> resolution  : 1, 1  (x, y)
#> extent      : 0, 30, 0, 30  (xmin, xmax, ymin, ymax)
#> coord. ref. :  
#> source(s)   : memory
#> name        : sum 
#> min value   :  57 
#> max value   :  84

Created on 2023-10-02 with reprex v2.0.2