101 lines
4.3 KiB
R
101 lines
4.3 KiB
R
# ============================================================================
|
|
# SCRIPT 10: Create Per-Field TIFFs (Data Organization & Splitting)
|
|
# ============================================================================
|
|
# PURPOSE:
|
|
# Split full-farm satellite TIFFs into per-field file structure. Supports
|
|
# two phases: legacy data migration and ongoing new downloads. Transforms
|
|
# single large-file architecture into per-field directory structure for
|
|
# clean aggregation in downstream scripts (Script 20, 40, 80/90).
|
|
#
|
|
# INPUT DATA:
|
|
# - Source: laravel_app/storage/app/{project}/merged_tif/ or merged_final_tif/
|
|
# - Format: GeoTIFF (4-band RGB+NIR or 5-band with CI)
|
|
# - Naming: {YYYY-MM-DD}.tif (full farm mosaic)
|
|
#
|
|
# OUTPUT DATA:
|
|
# - Destination: laravel_app/storage/app/{project}/field_tiles/
|
|
# - Format: GeoTIFF (4-band RGB+NIR, same as input)
|
|
# - Structure: field_tiles/{FIELD}/{YYYY-MM-DD}.tif
|
|
# - Naming: Per-field GeoTIFFs organized by field and date
|
|
#
|
|
# USAGE:
|
|
# Rscript 10_create_per_field_tiffs.R [project]
|
|
#
|
|
# Example (Windows PowerShell):
|
|
# & "C:\Program Files\R\R-4.4.3\bin\x64\Rscript.exe" r_app/10_create_per_field_tiffs.R angata
|
|
#
|
|
# PARAMETERS:
|
|
# - project: Project name (character) - angata, chemba, xinavane, esa, simba
|
|
#
|
|
# CLIENT TYPES:
|
|
# - cane_supply (ANGATA): Yes - primary data organization script
|
|
# - agronomic_support (AURA): Yes - supports field-level analysis
|
|
#
|
|
# DEPENDENCIES:
|
|
# - Packages: terra, sf, tidyverse
|
|
# - Utils files: parameters_project.R, 00_common_utils.R, 10_create_per_field_tiffs_utils.R
|
|
# - External data: Field boundaries (pivot.geojson)
|
|
# - Data directories: merged_tif/, field_tiles/ (created if missing)
|
|
#
|
|
# NOTES:
|
|
# - Supports two-phase migration: legacy (merged_final_tif) and ongoing (merged_tif)
|
|
# - Automatically detects and handles field boundaries from pivot.geojson
|
|
# - Geometry validation and repair applied via st_make_valid()
|
|
# - Critical for downstream Scripts 20, 40, and KPI calculations
|
|
# - Creates per-field structure that enables efficient per-field processing
|
|
#
|
|
# RELATED ISSUES:
|
|
# SC-111: Script 10 refactoring and geometry repair
|
|
# SC-112: Utilities restructuring (uses 00_common_utils.R)
|
|
#
|
|
# ============================================================================
|
|
|
|
# Spatial data handling
|
|
library(terra) # For raster operations (reading/writing GeoTIFFs, cropping to field boundaries)
|
|
library(sf) # For spatial operations (reading field boundaries GeoJSON, masking)
|
|
|
|
# ==============================================================================
|
|
# LOAD CENTRALIZED PARAMETERS & PATHS
|
|
# ==============================================================================
|
|
source(here::here("r_app", "parameters_project.R"))
|
|
source(here::here("r_app", "00_common_utils.R"))
|
|
source(here::here("r_app", "10_create_per_field_tiffs_utils.R"))
|
|
|
|
# Get project parameter from command line
|
|
args <- commandArgs(trailingOnly = TRUE)
|
|
if (length(args) == 0) {
|
|
PROJECT <- "angata"
|
|
} else {
|
|
PROJECT <- args[1]
|
|
}
|
|
|
|
# Load centralized path structure (creates all directories automatically)
|
|
paths <- setup_project_directories(PROJECT)
|
|
|
|
safe_log(paste("Project:", PROJECT))
|
|
safe_log(paste("Base path:", paths$laravel_storage_dir))
|
|
safe_log(paste("Data dir:", paths$data_dir))
|
|
|
|
# Load field boundaries using data_dir (not field_boundaries_path)
|
|
# load_field_boundaries() expects a directory and builds the file path internally
|
|
fields_data <- load_field_boundaries(paths$data_dir)
|
|
fields <- fields_data$field_boundaries_sf
|
|
|
|
# Define input and output directories (from centralized paths)
|
|
merged_tif_dir <- paths$merged_tif_folder
|
|
field_tiles_dir <- paths$field_tiles_dir
|
|
field_tiles_ci_dir <- paths$field_tiles_ci_dir
|
|
|
|
# PHASE 1: Process new downloads (always runs)
|
|
# Pass field_tiles_ci_dir so it can skip dates already migrated
|
|
process_result <- process_new_merged_tif(merged_tif_dir, field_tiles_dir, fields, field_tiles_ci_dir)
|
|
|
|
safe_log("\n========================================", "INFO")
|
|
safe_log("FINAL SUMMARY", "INFO")
|
|
safe_log("========================================", "INFO")
|
|
safe_log(paste("Processing: created =", process_result$total_created,
|
|
", skipped =", process_result$total_skipped,
|
|
", errors =", process_result$total_errors), "INFO")
|
|
safe_log("Script 10 complete", "INFO")
|
|
safe_log("========================================\n", "INFO")
|