# ============================================================================== # SmartCane Script 10: Create Per-Field TIFFs # ============================================================================== # # PURPOSE: # Split full-farm satellite TIFFs into per-field file structure across TWO phases: # # PHASE 1 - MIGRATION (Legacy Data): # Input: merged_final_tif/{DATE}.tif (5-band: R,G,B,NIR,CI - with CI calculated) # Output: field_tiles_CI/{FIELD}/{DATE}.tif # Status: One-time reorganization of existing data; will be removed after 2-3 weeks # # PHASE 2 - PROCESSING (New Downloads): # Input: merged_tif/{DATE}.tif (4-band: R,G,B,NIR - raw from Planet API) # Output: field_tiles/{FIELD}/{DATE}.tif # Status: Ongoing for all new downloads; always runs (not conditional) # # INTEGRATION WITH DOWNSTREAM SCRIPTS: # - Script 20 (CI Extraction): # Reads from field_tiles/{FIELD}/{DATE}.tif # Adds CI calculation → outputs to field_tiles_CI/{FIELD}/{DATE}.tif (5-band) # - Script 40 (Mosaic Creation): # Reads from field_tiles_CI/{FIELD}/{DATE}.tif (via per-field weekly aggregation) # Creates weekly_mosaic/{FIELD}/week_{WW}.tif # # ARCHITECTURE: # This script uses field/date folder organization: # field_tiles/ # ├── field_1/ # │ ├── 2024-01-15.tif # │ └── 2024-01-16.tif # └── field_2/ # ├── 2024-01-15.tif # └── 2024-01-16.tif # # Benefits: Upstream scripts iterate per-field → per-date, enabling clean # aggregation for mosaics (Script 40) and KPIs (Script 80/90). # # ============================================================================== library(terra) library(sf) # ============================================================================== # 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")