SmartCane/r_app/10_create_per_field_tiffs.R

89 lines
3.6 KiB
R

# ==============================================================================
# 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")