rm(list = ls(all = TRUE))
graphics.off()
shell("cls")
library(terra)
## Warning: package 'terra' was built under R version 4.2.2
## terra 1.6.53
library(sf)
## Warning: package 'sf' was built under R version 4.2.2
## Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
# carpeta de rasters
anos <- list.files(
  "C:/Users/PC/Desktop/Artigo2026/imagenesGEE",
  pattern = "\\.tif$",
  full.names = TRUE
)

# cargar rasters
stackanos <- rast(anos)

# extraer años desde el nombre del archivo

nombres <- gsub(
  ".*_(\\d{4})\\.tif",
  "\\1",
  basename(anos)
)

# asignar nombres a las capas
names(stackanos) <- nombres

# cargar shapefile
shp <- st_read(
  "C:/Users/PC/Desktop/Artigo2026/shapes/CORTE.shp"
)
## Reading layer `CORTE' from data source 
##   `C:\Users\PC\Desktop\Artigo2026\shapes\CORTE.shp' using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 1 field
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 494156.1 ymin: 8487465 xmax: 512449 ymax: 8521926
## Projected CRS: SIRGAS 2000 / UTM zone 24S
# reproyectar shape al CRS del raster
shp <- st_transform(shp, crs(stackanos))

# convertir sf -> terra vector
shp_vect <- vect(shp)

# visualizar
plot(stackanos[[1]])
plot(shp_vect, add = TRUE, border = "red")

# crop
anos_crop <- crop(stackanos, shp_vect)

# mask
anos_mask <- mask(anos_crop, shp_vect)

# reproyectar a UTM
# para calculo de áreas

anos_utm <- project(
  anos_mask,
  "EPSG:31984",
  method = "near"
)

# verificar nombres
names(anos_utm)
## [1] "S1_S2_16.tif" "S1_S2_19.tif" "S1_S2_22.tif" "S1_S2_25.tif"
# visualizar
plot(anos_utm)

library(landscapemetrics)
## Warning: package 'landscapemetrics' was built under R version 4.2.2
library(terra)
library(sf)

# Calculo das metricas desejadas (CA)
METRICAS <-calculate_lsm(anos_utm,
                         what = c("lsm_c_ca"),
                         edge_depth = 1, # celulas
                         neighbourhood = 8, # oito celulas nas vizinhancas
                         full_name = TRUE, 
                         verbose = TRUE, 
                         progress = TRUE)
## 
> Progress nlayers:  1 / 4
> Progress nlayers:  2 / 4
> Progress nlayers:  3 / 4
> Progress nlayers:  4 / 4
METRICAS
## # A tibble: 44 × 9
##    layer level class    id metric   value name               type  function_name
##    <int> <chr> <int> <int> <chr>    <dbl> <chr>              <chr> <chr>        
##  1     1 class     0    NA ca       124.  total (class) area area… lsm_c_ca     
##  2     1 class     1    NA ca     14016.  total (class) area area… lsm_c_ca     
##  3     1 class     2    NA ca       417.  total (class) area area… lsm_c_ca     
##  4     1 class     3    NA ca      2345.  total (class) area area… lsm_c_ca     
##  5     1 class     4    NA ca      5630.  total (class) area area… lsm_c_ca     
##  6     1 class     5    NA ca        26.4 total (class) area area… lsm_c_ca     
##  7     1 class     6    NA ca      5116.  total (class) area area… lsm_c_ca     
##  8     1 class     7    NA ca      2785.  total (class) area area… lsm_c_ca     
##  9     1 class     8    NA ca       488.  total (class) area area… lsm_c_ca     
## 10     1 class     9    NA ca      2529.  total (class) area area… lsm_c_ca     
## # ℹ 34 more rows
csv_lsm_class = METRICAS


# crea novas colunas apartir de uma existente
csv_lsm_class["cobertura"]<- csv_lsm_class$class
csv_lsm_class["ano"]<- csv_lsm_class$layer

#renombra columna
csv_lsm_class$ano <- factor(csv_lsm_class$layer, levels = c("1","2","3","4"), 
                            labels=c(2016,2019,2022,2025))
csv_lsm_class$cobertura <- factor(csv_lsm_class$class, 
                                  levels = c('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'), 
                                  labels = c('Urban', 'Forest', 'Beach and Dune', 'Agriculture', 'Water Bodies', 'Shrimp Farming', 'Mangrove', 'Exposed Soil', 'Tidal Flats', 'Restinga', 'Wetlands'))

landcover = csv_lsm_class
#landcover = filter(csv_lsm_class, class != "128" ) # apagar classe 128
tabela = landcover[, c(11, 10, 3, 6)]

# export csv com las metricas mapbiomas 6 ---------------------
readr::write_csv(tabela, "C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission/metricas_class.csv")
# ============================================================
# Temporal Evolution of LULC Classes
# APA Tinharé and Boipeba (2016–2025)
# Combined Sentinel-1 + Sentinel-2 Dataset
# ============================================================

setwd("C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission/")
getwd()
## [1] "C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission"
# =========================
# 1. Load libraries
# =========================

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.2
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.5.2      ✔ purrr   1.0.1 
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ tidyr   1.3.1      ✔ stringr 1.5.0 
## ✔ readr   2.1.3      ✔ forcats 0.5.2
## Warning: package 'tidyr' was built under R version 4.2.3
## Warning: package 'readr' was built under R version 4.2.2
## Warning: package 'purrr' was built under R version 4.2.2
## Warning: package 'dplyr' was built under R version 4.2.2
## Warning: package 'stringr' was built under R version 4.2.2
## Warning: package 'forcats' was built under R version 4.2.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ tidyr::extract() masks terra::extract()
## ✖ dplyr::filter()  masks stats::filter()
## ✖ dplyr::lag()     masks stats::lag()
library(readr)
library(ggplot2)

# =========================
# 2. Read CSV file
# =========================

df <- read_csv("metricas_class.csv")
## Rows: 44 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): cobertura
## dbl (3): ano, class, value
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# =========================
# 3. Prepare dataset
# =========================

df <- df %>%
  mutate(
    ano = as.numeric(ano),
    cobertura = as.character(cobertura),
    value = as.numeric(value)
  )

# =========================
# 4. Define class groups
# =========================

natural_classes <- c(
  "Forest",
  "Mangrove",
  "Restinga",
  "Wetlands",
  "Water Bodies",
  "Tidal Flats",
  "Beach and Dune"
)

anthropogenic_classes <- c(
  "Urban",
  "Agriculture",
  "Shrimp Farming",
  "Exposed Soil"
)

# =========================
# 5. Create class group field
# =========================

df_grouped <- df %>%
  mutate(
    group = case_when(
      cobertura %in% natural_classes ~ "Natural classes",
      cobertura %in% anthropogenic_classes ~ "Anthropogenic classes",
      TRUE ~ "Other"
    )
  )

# =========================
# 6. Official LULC color palette
# =========================

lulc_colors <- c(
  "Urban" = "#E31A1C",
  "Forest" = "#0B7D20",
  "Beach and Dune" = "#F4A6D7",
  "Agriculture" = "#F4E04D",
  "Water Bodies" = "#114BBD",
  "Shrimp Farming" = "#7B5CD6",
  "Mangrove" = "#7A9A01",
  "Exposed Soil" = "#A6611A",
  "Tidal Flats" = "#E8D7A5",
  "Restinga" = "#CFE8A9",
  "Wetlands" = "#2DC5C4"
)

# =========================
# 7. Define factor order
# =========================

df_grouped$cobertura <- factor(
  df_grouped$cobertura,
  levels = c(
    "Forest",
    "Mangrove",
    "Restinga",
    "Wetlands",
    "Agriculture",
    "Shrimp Farming",
    "Urban",
    "Exposed Soil",
    "Water Bodies",
    "Tidal Flats",
    "Beach and Dune"
  )
)

# =========================
# 8. Common theme 
# =========================

theme_q1 <- theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(
      face = "bold",
      size = 14,
      hjust = 0
    ),
      text = element_text(family = "Times New Roman"
    ),
    
    axis.title = element_text(
      face = "bold"
    ),

    axis.text = element_text(
      color = "black"
    ),

    strip.text = element_text(
      face = "bold",
      size = 12
    ),

    legend.title = element_text(
      face = "bold"
    ),

    legend.position = "right",

    panel.grid.major = element_line(
      color = "gray90"
    ),

    panel.grid.minor = element_blank(),

    panel.background = element_blank(),

    plot.background = element_blank(),

    legend.background = element_blank(),

    legend.key = element_blank()
  )

# ============================================================
# 9. Figure 8 — Natural classes
# ============================================================

p_natural <- df_grouped %>%
  filter(group == "Natural classes") %>%
  ggplot(aes(
    x = ano,
    y = value,
    color = cobertura,
    group = cobertura
  )) +

  geom_line(linewidth = 1.2) +

  geom_point(size = 3) +

  scale_color_manual(values = lulc_colors) +

  scale_x_continuous(
    breaks = c(2016, 2019, 2022, 2025)
  ) +

  labs(
   # title = "Temporal evolution of natural land-cover classes",
    x = "Year",
    y = "Area (ha)",
    color = "LULC natural classes"
  ) +

  theme_q1

# Visualize plot
p_natural
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family not
## found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family not
## found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

# Export high-resolution figure
ggsave(
  filename = "Figure_8_Temporal_evolution_natural.png",
  plot = p_natural,
  width = 8,
  height = 5,
  dpi = 700,
  bg = "white"
)
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
# ============================================================
# 10. Figure 9 — Anthropogenic classes
# ============================================================

p_anthropogenic <- df_grouped %>%
  filter(group == "Anthropogenic classes") %>%
  ggplot(aes(
    x = ano,
    y = value,
    color = cobertura,
    group = cobertura
  )) +

  geom_line(linewidth = 1.2) +

  geom_point(size = 3) +

  scale_color_manual(values = lulc_colors) +

  scale_x_continuous(
    breaks = c(2016, 2019, 2022, 2025)
  ) +

  labs(
   # title = "Temporal evolution of anthropogenic land-use classes",
    x = "Year",
    y = "Area (ha)",
    color = "LULC anthropogenic classes"
  ) +

  theme_q1 

# Visualize plot
p_anthropogenic
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

# Export high-resolution figure
ggsave(
  filename = "Figure_9_Temporal_evolution_anthropogenic.png",
  plot = p_anthropogenic,
  width = 8,
  height = 5,
  dpi = 700,
  bg = "white"
)
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
# ============================================================
# 12. Create summary table
# ============================================================

table_lulc <- df %>%
  select(ano, cobertura, value) %>%
  pivot_wider(
    names_from = ano,
    values_from = value
  ) %>%
  mutate(
    Change_2016_2025 = `2025` - `2016`,
    Change_2016_2025_percent =
      ((`2025` - `2016`) / `2016`) * 100
  )

# =========================
# 13. Export summary table
# =========================
readr::write_csv(table_lulc, "Table_LULC_Area_Changes_2016_2025.csv")

write_csv(
  table_lulc,
  "Table_LULC_Area_Changes_2016_2025.csv"
)

# Visualize table
table_lulc
## # A tibble: 11 × 7
##    cobertura `2016` `2019` `2022` `2025` Change_2016_2025 Change_2016_2025_per…¹
##    <chr>      <dbl>  <dbl>  <dbl>  <dbl>            <dbl>                  <dbl>
##  1 Urban     1.24e2 1.63e2 1.57e2 1.32e2             8.05                   6.51
##  2 Forest    1.40e4 1.53e4 1.44e4 1.45e4           498.                     3.55
##  3 Beach an… 4.17e2 6.72e2 1.16e3 1.03e3           617.                   148.  
##  4 Agricult… 2.34e3 1.60e3 2.07e3 1.63e3          -719.                   -30.7 
##  5 Water Bo… 5.63e3 5.61e3 4.95e3 5.08e3          -546.                    -9.70
##  6 Shrimp F… 2.64e1 1.09e1 1.65e1 4.03e1            13.9                   52.6 
##  7 Mangrove  5.12e3 4.96e3 5.18e3 5.19e3            69.5                    1.36
##  8 Exposed … 2.79e3 2.91e3 2.70e3 3.07e3           285.                    10.2 
##  9 Tidal Fl… 4.88e2 9.45e2 1.87e3 1.22e3           733.                   150.  
## 10 Restinga  2.53e3 2.43e3 2.12e3 2.62e3            91.5                    3.62
## 11 Wetlands  2.74e3 1.61e3 1.61e3 1.69e3         -1050.                   -38.3 
## # ℹ abbreviated name: ¹​Change_2016_2025_percent
# ============================================================
# END
# ============================================================
# ============================================================
# Land-Cover Transitions and Change Detection
# APA Tinharé and Boipeba, 2016–2025
# Combined Sentinel-1 SAR + Sentinel-2 MSI Dataset
# ============================================================
setwd("C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission/")
getwd()
## [1] "C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission"
# ============================================================
# 1. Load libraries
# ============================================================

library(terra)
library(dplyr)
library(tidyr)
library(readr)
library(ggplot2)

# ============================================================
# 2. Load classified LULC rasters
# ============================================================

r2016 <- anos_utm[[1]]
r2019 <- anos_utm[[2]]
r2022 <- anos_utm[[3]]
r2025 <- anos_utm[[4]]

# Verify raster values
hasValues(r2016)
## [1] TRUE
hasValues(r2019)
## [1] TRUE
hasValues(r2022)
## [1] TRUE
hasValues(r2025)
## [1] TRUE
# ============================================================
# 3. Align rasters to 2016 reference
# ============================================================

r2019 <- terra::resample(
  r2019,
  r2016,
  method = "near"
)

r2022 <- terra::resample(
  r2022,
  r2016,
  method = "near"
)

r2025 <- terra::resample(
  r2025,
  r2016,
  method = "near"
)

# ============================================================
# 4. Check raster geometry
# ============================================================

rasters <- list(
  "2016" = r2016,
  "2019" = r2019,
  "2022" = r2022,
  "2025" = r2025
)

geometry_check <- tibble(
  year = names(rasters),
  nrow = sapply(rasters, nrow),
  ncol = sapply(rasters, ncol),
  xmin = sapply(rasters, function(x) terra::ext(x)[1]),
  xmax = sapply(rasters, function(x) terra::ext(x)[2]),
  ymin = sapply(rasters, function(x) terra::ext(x)[3]),
  ymax = sapply(rasters, function(x) terra::ext(x)[4]),
  xres = sapply(rasters, function(x) terra::res(x)[1]),
  yres = sapply(rasters, function(x) terra::res(x)[2]),
  crs = sapply(rasters, function(x) as.character(terra::crs(x)))
)

print(geometry_check)
## # A tibble: 4 × 10
##   year   nrow  ncol    xmin    xmax     ymin     ymax  xres  yres crs           
##   <chr> <dbl> <dbl>   <dbl>   <dbl>    <dbl>    <dbl> <dbl> <dbl> <chr>         
## 1 2016   3486  1852 494154. 512464. 8487465. 8521928.  9.89  9.89 "PROJCRS[\"SI…
## 2 2019   3486  1852 494154. 512464. 8487465. 8521928.  9.89  9.89 "PROJCRS[\"SI…
## 3 2022   3486  1852 494154. 512464. 8487465. 8521928.  9.89  9.89 "PROJCRS[\"SI…
## 4 2025   3486  1852 494154. 512464. 8487465. 8521928.  9.89  9.89 "PROJCRS[\"SI…
# ============================================================
# 3. Define LULC class labels
# ============================================================

class_labels <- c(
  "0"  = "Urban",
  "1"  = "Forest",
  "2"  = "Beach and Dune",
  "3"  = "Agriculture",
  "4"  = "Water Bodies",
  "5"  = "Shrimp Farming",
  "6"  = "Mangrove",
  "7"  = "Exposed Soil",
  "8"  = "Tidal Flats",
  "9"  = "Restinga",
  "10" = "Wetlands"
)

# ============================================================
# 4. Define LULC color palette
# ============================================================

lulc_colors <- c(
  "Urban" = "#E31A1C",
  "Forest" = "#0B7D20",
  "Beach and Dune" = "#F4A6D7",
  "Agriculture" = "#F4E04D",
  "Water Bodies" = "#114BBD",
  "Shrimp Farming" = "#7B5CD6",
  "Mangrove" = "#7A9A01",
  "Exposed Soil" = "#A6611A",
  "Tidal Flats" = "#E8D7A5",
  "Restinga" = "#CFE8A9",
  "Wetlands" = "#2DC5C4"
)

# ============================================================
# 5. Function to calculate transition matrix
# ============================================================

calculate_transition_matrix <- function(r_from, r_to, year_from, year_to) {
  
  vals <- data.frame(
    from = terra::values(r_from)[, 1],
    to   = terra::values(r_to)[, 1]
  ) %>%
    tidyr::drop_na()
  
  pixel_area_ha <- prod(terra::res(r_from)) / 10000
  
  trans <- vals %>%
    dplyr::group_by(from, to) %>%
    dplyr::summarise(
      pixel_count = dplyr::n(),
      .groups = "drop"
    ) %>%
    dplyr::mutate(
      area_ha = pixel_count * pixel_area_ha,
      from_class = class_labels[as.character(from)],
      to_class = class_labels[as.character(to)],
      transition = paste(from_class, "→", to_class),
      period = paste0(year_from, "-", year_to)
    ) %>%
    dplyr::select(period, from, to, from_class, to_class, transition, pixel_count, area_ha)
  
  trans_wide <- trans %>%
    dplyr::select(from_class, to_class, area_ha) %>%
    tidyr::pivot_wider(
      names_from = to_class,
      values_from = area_ha,
      values_fill = 0
    )
  
  readr::write_csv(trans, paste0("Transition_Long_", year_from, "_", year_to, ".csv"))
  readr::write_csv(trans_wide, paste0("Transition_Matrix_", year_from, "_", year_to, ".csv"))
  
  return(trans)
}

# ============================================================
# 6. Calculate transition matrices
# ============================================================

transition_2016_2019 <- calculate_transition_matrix(r2016, r2019, 2016, 2019)
transition_2019_2022 <- calculate_transition_matrix(r2019, r2022, 2019, 2022)
transition_2022_2025 <- calculate_transition_matrix(r2022, r2025, 2022, 2025)
transition_2016_2025 <- calculate_transition_matrix(r2016, r2025, 2016, 2025)

# Combine all transition tables
all_transitions <- bind_rows(
  transition_2016_2019,
  transition_2019_2022,
  transition_2022_2025,
  transition_2016_2025
)

write_csv(
  all_transitions,
  "LULC_Transitions_2016_2019_2022_2025.csv"
)

# ============================================================
# 7. Identify major transitions for 2016–2025
# ============================================================

major_transitions_2016_2025 <- transition_2016_2025 %>%
  filter(from_class != to_class) %>%
  arrange(desc(area_ha)) %>%
  slice_head(n = 15)

write_csv(
  major_transitions_2016_2025,
  "Major_Transitions_2016_2025.csv"
)

major_transitions_2016_2025
## # A tibble: 15 × 8
##    period     from    to from_class   to_class    transition pixel_count area_ha
##    <chr>     <dbl> <dbl> <chr>        <chr>       <chr>            <int>   <dbl>
##  1 2016-2025     3     1 Agriculture  Forest      Agricultu…       74623    729.
##  2 2016-2025     4     2 Water Bodies Beach and … Water Bod…       61097    597.
##  3 2016-2025    10     7 Wetlands     Exposed So… Wetlands …       60614    592.
##  4 2016-2025    10     8 Wetlands     Tidal Flats Wetlands …       43974    430.
##  5 2016-2025     3     9 Agriculture  Restinga    Agricultu…       26946    263.
##  6 2016-2025     7     8 Exposed Soil Tidal Flats Exposed S…       26603    260.
##  7 2016-2025     1     9 Forest       Restinga    Forest → …       25797    252.
##  8 2016-2025     9     3 Restinga     Agriculture Restinga …       24801    242.
##  9 2016-2025     7     9 Exposed Soil Restinga    Exposed S…       19627    192.
## 10 2016-2025     9     1 Restinga     Forest      Restinga …       17025    166.
## 11 2016-2025     9     7 Restinga     Exposed So… Restinga …       16641    163.
## 12 2016-2025     7    10 Exposed Soil Wetlands    Exposed S…       15384    150.
## 13 2016-2025    10     6 Wetlands     Mangrove    Wetlands …       15149    148.
## 14 2016-2025     8     7 Tidal Flats  Exposed So… Tidal Fla…       14219    139.
## 15 2016-2025    10     1 Wetlands     Forest      Wetlands …       13602    133.
# ============================================================
# 8. Create transition raster 2016–2025
# ============================================================

# Code structure:
# from_class * 100 + to_class
# Example: Forest(1) to Urban(0) = 100

transition_raster_2016_2025 <- r2016 * 100 + r2025

writeRaster(
  transition_raster_2016_2025,
  "Transition_Raster_2016_2025.tif",
  overwrite = TRUE
)

# ============================================================
# 9. Create persistence vs change raster
# ============================================================

persistence_change <- ifel(r2016 == r2025, 1, 2)

writeRaster(
  persistence_change,
  "Persistence_vs_Change__Raster_2016_2025.tif",
  overwrite = TRUE
)

# 1 = Persistence
# 2 = Change

# ============================================================
# 10. Create simplified major change map
# ============================================================

# Categories:
# 1 = Stable natural vegetation
# 2 = Stable anthropogenic
# 3 = Natural to anthropogenic
# 4 = Anthropogenic to natural
# 5 = Other transitions

natural_ids <- c(1, 2, 4, 6, 8, 9, 10)
anthropogenic_ids <- c(0, 3, 5, 7)

major_change_map <- classify(
  transition_raster_2016_2025,
  rcl = matrix(c(
    -9999, 9999, 5
  ), ncol = 3, byrow = TRUE)
)

major_change_map <- ifel(
  r2016 %in% natural_ids & r2025 %in% natural_ids & r2016 == r2025,
  1,
  major_change_map
)

major_change_map <- ifel(
  r2016 %in% anthropogenic_ids & r2025 %in% anthropogenic_ids & r2016 == r2025,
  2,
  major_change_map
)

major_change_map <- ifel(
  r2016 %in% natural_ids & r2025 %in% anthropogenic_ids,
  3,
  major_change_map
)

major_change_map <- ifel(
  r2016 %in% anthropogenic_ids & r2025 %in% natural_ids,
  4,
  major_change_map
)

writeRaster(
  major_change_map,
  "Major_Change_Map_2016_2025.tif",
  overwrite = TRUE
)

# ============================================================
# 11. Area summary for major change categories
# ============================================================

major_change_values <- as.data.frame(
  freq(major_change_map)
) %>%
  rename(category_id = value, pixel_count = count) %>%
  mutate(
    area_ha = pixel_count * (prod(res(major_change_map)) / 10000),
    category = case_when(
      category_id == 1 ~ "Stable natural vegetation",
      category_id == 2 ~ "Stable anthropogenic areas",
      category_id == 3 ~ "Natural to anthropogenic transition",
      category_id == 4 ~ "Anthropogenic to natural transition",
      category_id == 5 ~ "Other transitions",
      TRUE ~ "No data"
    )
  ) %>%
  select(category_id, category, pixel_count, area_ha)

write_csv(
  major_change_values,
  "Major_Change_Area_Summary_2016_2025.csv"
)

major_change_values
##   category_id                            category pixel_count   area_ha
## 1           1           Stable natural vegetation     2754885 26925.858
## 2           2          Stable anthropogenic areas      342997  3352.404
## 3           3 Natural to anthropogenic transition      141836  1386.285
## 4           4 Anthropogenic to natural transition      184010  1798.488
## 5           5                   Other transitions      281694  2753.238
# ============================================================
# END
# ============================================================
# ============================================================
# Sankey / Alluvial Diagram for LULC Transitions
# APA Tinharé and Boipeba, 2016–2025
# Areas in hectares
# ============================================================
setwd("C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission/")
getwd()
## [1] "C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission"
library(terra)
library(dplyr)
library(tidyr)
library(ggplot2)
library(ggalluvial)
library(readr)

# ============================================================
# 1. Use rasters from anos_utm
# ============================================================

# Check layer names
names(anos_utm)
## [1] "S1_S2_16.tif" "S1_S2_19.tif" "S1_S2_22.tif" "S1_S2_25.tif"
# Select layers
r2016 <- anos_utm[[1]]
r2025 <- anos_utm[[4]]

# Align 2025 to 2016
r2025 <- terra::resample(
  r2025,
  r2016,
  method = "near"
)

# ============================================================
# 2. Class labels
# ============================================================

class_labels <- c(
  "0"  = "Urban",
  "1"  = "Forest",
  "2"  = "Beach and Dune",
  "3"  = "Agriculture",
  "4"  = "Water Bodies",
  "5"  = "Shrimp Farming",
  "6"  = "Mangrove",
  "7"  = "Exposed Soil",
  "8"  = "Tidal Flats",
  "9"  = "Restinga",
  "10" = "Wetlands"
)

# ============================================================
# 3. Extract values safely
# ============================================================

v2016 <- terra::values(r2016, mat = FALSE)
v2025 <- terra::values(r2025, mat = FALSE)

vals <- data.frame(
  from = as.numeric(v2016),
  to = as.numeric(v2025)
) %>%
  filter(!is.na(from), !is.na(to))

# ============================================================
# 4. Pixel area in hectares
# ============================================================

pixel_area_ha <- prod(terra::res(r2016)) / 10000

# ============================================================
# 5. Create transition table
# ============================================================

transitions <- vals %>%
  count(from, to, name = "pixel_count") %>%
  mutate(
    area_ha = pixel_count * pixel_area_ha,
    from_class = class_labels[as.character(from)],
    to_class = class_labels[as.character(to)],
    transition = paste(from_class, "→", to_class)
  ) %>%
  filter(!is.na(from_class), !is.na(to_class)) %>%
  arrange(desc(area_ha))

write_csv(
  transitions,
  "Sankey_Transitions_2016_2025.csv"
)

# ============================================================
# 6. Filter small flows
# ============================================================

transitions_plot <- transitions %>%
  filter(area_ha >= 50)

# ============================================================
# 7. Color palette
# ============================================================

lulc_colors <- c(
  "Urban" = "#E31A1C",
  "Forest" = "#0B7D20",
  "Beach and Dune" = "#F4A6D7",
  "Agriculture" = "#F4E04D",
  "Water Bodies" = "#114BBD",
  "Shrimp Farming" = "#7B5CD6",
  "Mangrove" = "#7A9A01",
  "Exposed Soil" = "#A6611A",
  "Tidal Flats" = "#E8D7A5",
  "Restinga" = "#CFE8A9",
  "Wetlands" = "#2DC5C4"
)

class_order <- c(
  "Urban",
  "Forest",
  "Beach and Dune",
  "Agriculture",
  "Water Bodies",
  "Shrimp Farming",
  "Mangrove",
  "Exposed Soil",
  "Tidal Flats",
  "Restinga",
  "Wetlands"
)

# ============================================================
# 8. Areas by class for labels
# ============================================================

area_2016 <- transitions %>%
  group_by(from_class) %>%
  summarise(area_ha_2016 = sum(area_ha), .groups = "drop") %>%
  mutate(
    from_class = factor(from_class, levels = class_order),
    label_2016 = paste0(from_class, "\n", round(area_ha_2016, 1), " ha")
  ) %>%
  arrange(from_class)

area_2025 <- transitions %>%
  group_by(to_class) %>%
  summarise(area_ha_2025 = sum(area_ha), .groups = "drop") %>%
  mutate(
    to_class = factor(to_class, levels = class_order),
    label_2025 = paste0(to_class, "\n", round(area_ha_2025, 1), " ha")
  ) %>%
  arrange(to_class)

transitions_plot <- transitions_plot %>%
  mutate(
    from_class = factor(from_class, levels = class_order),
    to_class = factor(to_class, levels = class_order)
  ) %>%
  left_join(area_2016, by = "from_class") %>%
  left_join(area_2025, by = "to_class") %>%
  mutate(
    from_label = factor(label_2016, levels = area_2016$label_2016),
    to_label = factor(label_2025, levels = area_2025$label_2025)
  )

# ============================================================
# 9. Sankey / Alluvial diagram
# ============================================================

p_sankey <- ggplot(
  transitions_plot,
  aes(
    axis1 = from_label,
    axis2 = to_label,
    y = area_ha
  )
) +
  geom_alluvium(
    aes(fill = from_class),
    width = 0.18,
    alpha = 0.75
  ) +
  geom_stratum(
    width = 0.25,
    fill = "grey95",
    color = "grey40"
  ) +
  geom_text(
    stat = "stratum",
    aes(label = after_stat(stratum)),
    size = 3.0,
    family = "Times New Roman"
  ) +
  scale_x_discrete(
    limits = c("2016", "2025"),
    expand = c(0.08, 0.08)
  ) +
  scale_fill_manual(
    values = lulc_colors,
    name = "LULC class"
  ) +
  labs(
  #  title = "Land-use and land-cover transition pathways",
   # subtitle = "APA of Tinharé and Boipeba, 2016–2025",
    x = NULL,
    y = "Area (ha)"
  ) +
  theme_minimal(
    base_size = 13,
    base_family = "Times New Roman"
  ) +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    plot.subtitle = element_text(size = 12),
    axis.title.y = element_text(face = "bold"),
    axis.text.y = element_text(color = "black"),
    axis.text.x = element_text(face = "bold", size = 12),
    legend.position = "right",
    panel.grid.minor = element_blank()
  )

p_sankey
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family not
## found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

# ============================================================
# 10. Export figure
# ============================================================

ggsave(
  filename = "Figure_11_Sankey_diagram.png",
  plot = p_sankey,
  width = 11,
  height = 9,
  dpi = 700,
  bg = "white"
)
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database

## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
# ============================================================
# END
# ============================================================
##############################
# 1. LOAD LIBRARIES
##############################
library(tidyverse)
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.2.3
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
library(ggplot2)
library(RColorBrewer)
library(rstatix)
## Warning: package 'rstatix' was built under R version 4.2.3
## 
## Attaching package: 'rstatix'
## The following object is masked from 'package:stats':
## 
##     filter
library(boot)
## Warning: package 'boot' was built under R version 4.2.2
library(readxl)
## Warning: package 'readxl' was built under R version 4.2.3
# mudar diretorio
setwd("C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission/")
getwd()
## [1] "C:/Users/PC/Desktop/Artigo2026/Manuscript_Submission"
##############################
# 2. LOAD AND CLEAN DATA
##############################
# Cargar datos

data <- read_excel("accuracy_data_v2.xlsx")
data
## # A tibble: 44 × 11
##    Class_ID F1_Combined F1_S2 F1_SAR PA_Combined PA_S2 PA_SAR UA_Combined UA_S2
##       <dbl>       <dbl> <dbl>  <dbl>       <dbl> <dbl>  <dbl>       <dbl> <dbl>
##  1        0       0.990 0.99  0.713        1     0.99  0.604        0.980 0.99 
##  2        1       0.999 1.000 0.693        1     1     0.740        0.999 0.999
##  3        2       1     0.991 0.644        1     0.982 0.982        1     1    
##  4        3       0.986 0.952 0.0595       1     0.980 0.0490       0.971 0.926
##  5        4       1     1.000 0.927        1     1     0.891        1     1.000
##  6        5       1     1     0.208        1     1     0.544        1     1    
##  7        6       0.998 0.999 0.286        0.997 1     0.251        1     0.999
##  8        7       0.952 0.950 0.724        0.912 0.922 0.639        0.996 0.980
##  9        8       0.948 0.895 0.161        0.922 0.836 0.148        0.975 0.964
## 10        9       1     0.994 0.617        1     0.994 0.674        1     0.994
## # ℹ 34 more rows
## # ℹ 2 more variables: UA_SAR <dbl>, Year <dbl>
# Convertir comas decimales a punto (si aplica)
data <- data %>%
  mutate(across(-c(Class_ID, Year), ~as.numeric(gsub(",", ".", .))))


data <- read_excel("accuracy_data_v2.xlsx") %>%
  mutate(
    Class_ID = factor(
      recode(Class_ID,
             "0" = "Urban",
             "1" = "Forest",
             "2" = "Beach and Dune",
             "3" = "Agriculture",
             "4" = "Water Bodies",
             "5" = "Shrimp Farming",
             "6" = "Mangrove",
             "7" = "Exposed Soil",
             "8" = "Tidal Flats",
             "9" = "Restinga",
             "10" = "Wetlands"
      ),
      levels = c(
        "Urban","Forest","Beach and Dune","Agriculture","Water Bodies",
        "Shrimp Farming","Mangrove","Exposed Soil","Tidal Flats",
        "Restinga","Wetlands"
      )
    )
  )

##############################
# 3. RESHAPE DATA (TIDY FORMAT)
##############################
data_long <- data %>%
  pivot_longer(
    cols = -c(Class_ID, Year),
    names_to = "Metric",
    values_to = "Value"
  ) %>%
  separate(Metric, into = c("Metric", "Sensor"), sep = "_")

##############################
# 4. SUMMARY STATISTICS (MEAN, SD, SE)
##############################
summary_stats <- data_long %>%
  group_by(Year, Sensor, Metric) %>%
  summarise(
    mean = mean(Value, na.rm = TRUE),
    sd = sd(Value, na.rm = TRUE),
    n = n(),
    se = sd / sqrt(n),
    .groups = "drop"
  )

##############################
# 6. BARPLOT (MEAN ± SE)
##############################
f1_summary <- summary_stats %>%
  filter(Metric == "F1")

bar_plot2 <- ggplot(f1_summary, aes(x = factor(Year), y = mean, fill = Sensor)) +
  geom_bar(stat = "identity", position = position_dodge(0.7), width = 0.6, color = "black") +
  geom_errorbar(
    aes(ymin = mean - se, ymax = mean + se),
    position = position_dodge(0.7),
    width = 0.2
  ) +
  scale_fill_manual(values = c(
    "SAR" = "#D4E6F1",
    "S2" = "#D5F5E3",
    "Combined" = "#FDEBD0"
  )) +
  theme_classic(base_size = 14) +
  theme(
    axis.text = element_text(color = "black"),
    axis.title = element_text(face = "bold"),
    legend.title = element_text(face = "bold"),
    legend.position = "top",
    plot.title = element_text(face = "bold", hjust = 0.5)
  ) +
  
  # Etiquetas del gráfico
  labs(
    x = "Year",
    y = "Mean F1-score",
    fill = "Sensor"
  ) +
  theme(
    legend.position = "top"
  )
bar_plot2

##############################
# 8. STATISTICAL TESTS
##############################

# 8.1 Friedman Test
f1_data <- data_long %>%
  filter(Metric == "F1")

friedman_results <- f1_data %>%
  group_by(Year) %>%
  friedman_test(Value ~ Sensor | Class_ID)

# 8.2 Effect Size (Kendall’s W)
friedman_effect <- f1_data %>%
  group_by(Year) %>%
  friedman_effsize(Value ~ Sensor | Class_ID)

# 8.3 Pairwise Wilcoxon Test
pairwise_results <- f1_data %>%
  group_by(Year) %>%
  pairwise_wilcox_test(
    Value ~ Sensor,
    paired = TRUE,
    p.adjust.method = "bonferroni"
  )



##############################
# 9. BOOTSTRAP CONFIDENCE INTERVALS
##############################

# Función bootstrap
boot_mean <- function(data, indices) {
  d <- data[indices]
  return(mean(d, na.rm = TRUE))
}

# Aplicar bootstrap
bootstrap_results <- f1_data %>%
  group_by(Year, Sensor) %>%
  summarise(
    boot = list(boot(Value, statistic = boot_mean, R = 1000)),
    .groups = "drop"
  )

# Extraer CI 95%
bootstrap_ci <- bootstrap_results %>%
  mutate(
    ci = map(boot, ~boot.ci(.x, type = "perc")$percent[4:5])
  ) %>%
  unnest_wider(ci, names_sep = "_") %>%
  rename(
    CI_low = ci_1,
    CI_high = ci_2
  ) %>%
  select(Year, Sensor, CI_low, CI_high)

##############################
# 10. FINAL TABLE 
##############################
final_table <- summary_stats %>%
  filter(Metric == "F1") %>%
  left_join(bootstrap_ci, by = c("Year", "Sensor"))

##############################
# 11. EXPORT FIGURES 
##############################

ggsave("Figure_6_Mean_F1score_barplot2.tiff", bar_plot2, width = 8, height = 5, dpi = 700)


##############################
# END OF SCRIPT
##############################