validate_fire_maps: Validate burned area maps against reference polygons

View source: R/7_validate_fire_maps.R

validate_fire_mapsR Documentation

Validate burned area maps against reference polygons

Description

The 'validate_fire_maps()' function evaluates the spatial accuracy of burned area detection shapefiles by comparing them against independent reference fire polygons (e.g., from Focclim or national databases).

It calculates both **pixel-based metrics** and **area-based metrics**, unless a specific mode is selected. Reference polygons are masked to retain only burnable areas based on a CORINE-derived raster and filtered by a minimum area threshold if specified.

**Important**: If 'min_area_reference_ha' is changed, you must set 'force_reprocess_ref = TRUE' to recalculate the masked reference polygons.

Arguments

input_shapefile

Character vector. One or more paths to shapefiles containing the burned polygons to validate.

ref_shapefile

Character. Path to the shapefile with reference burned area polygons.

mask_shapefile

Character. Path to the shapefile defining the study area boundary.

burnable_raster

Character. Path to the raster file indicating burnable areas (binary or categorical).

year_target

Numeric. Target year for filtering reference polygons.

validation_dir

Character. Output directory to save validation results.

binary_burnable

Logical. TRUE if the burnable raster is binary (1 = burnable, 0 = non-burnable). Default is TRUE.

burnable_classes

Optional numeric vector of raster values considered burnable if 'binary_burnable = FALSE'.

class_shape

Optional character. Path to a shapefile containing class information (e.g., CORINE or ecoregions) used for class-wise error breakdown.

class_field

Optional character. Name of the field in 'class_shape' to group omission and commission errors by class (e.g., "CORINE", "eco_name", "cor_eco").

buffer

Numeric. Optional buffer distance (in meters) applied around reference polygons for pixel-based validation. Default is 0.

threshold_completely_detected

Numeric. Minimum percentage (e.g., 90) of a reference polygon area that must be intersected to be considered completely detected. Default is 90.

min_area_reference_ha

Numeric. Minimum area (in hectares) to retain reference polygons after masking. Default is NULL (no filtering).

use_gdal

Logical. Whether to use external GDAL (via Python) for polygonizing rasters (faster for large datasets). Default is TRUE.

python_exe

Character. Path to the Python executable used for GDAL polygonization.

gdal_polygonize_script

Character. Path to the 'gdal_polygonize.py' script.

force_reprocess_ref

Logical. If TRUE, forces recalculation of masked reference polygons even if cached versions exist. Default is FALSE.

metrics_type

Character. Type of metrics to compute. One of '"all"' (default), '"pixel"', or '"area"'.

Details

## Pixel-based metrics (when 'metrics_type = "pixel"' or '"all"'): - **True Positives (TP)**: Pixels correctly detected as burned. - **False Positives (FP)**: Pixels wrongly detected as burned. - **False Negatives (FN)**: Burned pixels missed by the detection. - **True Negatives (TN)**: Pixels correctly identified as unburned.

Derived indicators: - **Precision** = TP / (TP + FP) - **Recall** = TP / (TP + FN) - **F1 Score** = 2 * (Precision * Recall) / (Precision + Recall) - **Intersection over Union (IoU)** = TP / (TP + FP + FN) - **Error Rate** = (FP + FN) / (TP + FP + FN + TN)

## Area-based metrics (when 'metrics_type = "area"' or '"all"'): - **N_Reference_Polygons**: Number of reference polygons after masking and filtering. - **N_Completely_Detected**: Count of reference polygons where detected area ? 'threshold_completely_detected'. - **N_Detected_Polygons**: Reference polygons partially or fully detected (>0 - **N_Not_Detected**: Reference polygons without any detected overlap. - **Perc_Detected_Polygons**: Share of reference polygons detected. - **Area_Reference_ha**: Total area of reference polygons (ha). - **Area_Detected_ha**: Total area of detected burned polygons (ha). - **Area_Intersection_ha**: Area of intersection between detection and reference polygons (ha). - **Area_Reference_NotDetected_ha**: Area of reference polygons not intersected (ha). - **Perc_Reference_Area_NotDetected**: Share of reference area missed ( - **Recall_Area_percent** = (Area_Intersection_ha / Area_Reference_ha) * 100 - **Precision_Area_percent** = (Area_Intersection_ha / Area_Detected_ha) * 100

## Class-wise error breakdown: If 'class_shape' and 'class_field' are provided and valid: - 'ref_not_detected' and 'det_not_matched' polygons are joined to 'class_shape'. - Output CSV files: - 'omission_by_<class_field>_<input>.csv' - 'commission_by_<class_field>_<input>.csv'

## Output files: - 'metrics_summary_<year>.csv' and/or 'polygon_summary_<year>.csv' - Shapefiles of undetected and unmatched polygons - Class-wise omission/commission CSVs (if class information is provided)

Value

A list with:

metrics

A data.table of pixel-based accuracy metrics, or NULL if 'metrics_type' excludes them.

polygon_summary

A data.table of area-based metrics, or NULL if 'metrics_type' excludes them.

Note

Examples require large external raster files (hosted on Zenodo) and depend on external software (Python, GDAL). Therefore, they are wrapped in dontrun to avoid errors during R CMD check and to ensure portability.

Examples

## Not run: 
validate_fire_maps(
  input_shapefile = list.files("shapefiles", pattern = "\\.shp$", full.names = TRUE),
  ref_shapefile = "ref_polygons_2022.shp",
  mask_shapefile = "mask_region.shp",
  burnable_raster = "burnable.tif",
  year_target = 2022,
  validation_dir = "validation_results",
  binary_burnable = TRUE,
  min_area_reference_ha = 1,
  buffer = 30,
  threshold_completely_detected = 90,
  use_gdal = TRUE,
  python_exe = "C:/Python/python.exe",
  gdal_polygonize_script = "C:/Python/Scripts/gdal_polygonize.py",
  force_reprocess_ref = TRUE,
  metrics_type = "all",
  class_shape = "corine_eco_regions.shp",
  class_field = "cor_eco"
)

## End(Not run)


OtsuFire documentation built on June 13, 2025, 3:01 a.m.