Faxina e Processamento de Dados de CO₂ Atmosférico (XCO₂) do OCO-2/NASA

Objetivo

Este script realiza a leitura e pré-processamento de arquivos no formato .nc4 (NetCDF) contendo dados de concentração de dióxido de carbono atmosférico (XCO₂) medidos pelo satélite OCO-2 da NASA. Os dados são filtrados para a região do Brasil e estruturados em um formato tabular para análises posteriores.

Identifica todos os arquivos com extensão .nc4 no diretório data-raw/nc4/ e retorna um vetor com os caminhos completos dos arquivos para leitura posterior.

# Lista com caminho e nomes dos arquivo a serem lidos - xco2
list_of_files <- list.files("data-raw/nc4/",
                            pattern = ".nc4",
                            full.names = TRUE)

Utilizamos o pacote {geobr} para carregar o polígono do território brasileiro e extrai as coordenadas do polígono e converte para uma matriz (formato necessário para a função de filtro espacial). Após isso definimos uma função que verifica se um ponto (longitude, latitude) está dentro do polígono do Brasil por meio da utilização da função point.in.polygon() do pacote {sp} para a operação espacial. A função retorna retorna TRUE/FALSE para cada coordenada.

## buscando o contorno do Brasil
br <- geobr::read_country(showProgress = FALSE)
pol_br <- br$geom |> purrr::pluck(1) |> as.matrix()
def_pol <- function(x, y, pol){
  as.logical(sp::point.in.polygon(point.x = x,
                                  point.y = y,
                                  pol.x = pol[,1],
                                  pol.y = pol[,2]))
}

Criação da Função principal para ler cada arquivo .nc4 e extrair as variáveis essenciais:

+longitude, latitude: Coordenadas geográficas.

+time: Carimbo de tempo da medição.

+xco2: Concentração de CO₂ (partes por milhão - ppm).

+xco2_quality_flag e xco2_incerteza: Indicadores de qualidade e incerteza das medições.

+Fechar a conexão com o arquivo após a leitura (nc_close()).

## função para ler arquivos NCD4
ncdf_reader <- function(file_path){
  nc_file <- ncdf4::nc_open(file_path)
  df <- data.frame(
    "longitude"=ncdf4::ncvar_get(nc_file,varid="longitude"),
    "latitude"=ncdf4::ncvar_get(nc_file,varid="latitude"),
    "time"=ncdf4::ncvar_get(nc_file,varid="time"),
    "xco2"=ncdf4::ncvar_get(nc_file,varid="xco2"),
    "xco2_quality_flag"=ncdf4::ncvar_get(nc_file,varid="xco2_quality_flag"),
    "xco2_incerteza"=ncdf4::ncvar_get(nc_file,varid="xco2_uncertainty"),
    "path" = file_path
  )
  ncdf4::nc_close(nc_file)
  return(df)
}

O código está processando um grande volume de arquivos NetCDF (.nc4) contendo dados de XCO2 e filtrando apenas as medições dentro da área geográfica de interesse do Brasil.

Como os arquivos podem ser muitos (e grandes!), o processo deve ser dividido em etapas para:

1-Evitar sobrecarregar a memória do R (lendo e processando em lotes).

2-Facilitar a depuração (se algo falhar, não se perde todo o progresso).

3-Permitir paralelização futura (cada lote poderia ser processado em núcleos diferentes).

purrr::map_df: Aplica a função ncdf_reader (que definimos antes) em \(1000\) arquivos por vez e combina os resultados em um único data.frame e write_rds salva o resultado em disco no formato .rds (eficiente para objetos do R). Observer que se houver 10.000 arquivos, tentar ler todos de uma vez pode travar o R por falta de memória além de que, se ocorrer um erro, não perderemos o processamento já feito.

dff_1 <- purrr::map_df(list_of_files[1:1000],ncdf_reader)
readr::write_rds(dff_1,"data-raw/dff_1.rds")
dff_2 <- purrr::map_df(list_of_files[1001:2000],ncdf_reader)
readr::write_rds(dff_2,"data-raw/dff_2.rds")
dff_3 <- purrr::map_df(list_of_files[2001:length(list_of_files)],ncdf_reader)
readr::write_rds(dff_3,"data-raw/dff_3.rds")

df1 <- readr::read_rds("data-raw/dff_1.rds")
df1 <- df1 |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df1)

df2 <- readr::read_rds("data-raw/dff_2.rds")
df2 <- df2 |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df2)

df3 <- readr::read_rds("data-raw/dff_3.rds")
df3 <- df3 |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df3)
dff <- rbind(df1,df2,df3)

dff <- dff |>
  dplyr::mutate(
    flag_br = def_pol(longitude, latitude, pol_br)
  )
dplyr::glimpse(dff)

O processamento acima poderá ser realizado com: 1. Abordagem com purrr::map_df + Divisão Automática

library(purrr)
library(dplyr)

# Divide os arquivos em lotes de tamanho fixo (ex.: 1000 por lote)
batch_size <- 1000
file_batches <- split(list_of_files, ceiling(seq_along(list_of_files) / batch_size))

# Processa todos os lotes de uma vez e salva com nomes dinâmicos
file_batches  |> 
  imap(~ {
    df <- map_df(.x, ncdf_reader) 
      filter(
        between(longitude, -80, -32),
        between(latitude, -34, 10)
      )
    saveRDS(df, paste0("data-raw/dff_", .y, ".rds"))  # .y = índice do lote
  })

2. Abordagem com furrr (Paralelização)

library(furrr)  # Versão paralela do purrr
plan(multisession, workers = 4)  # Usa 4 núcleos da CPU

# Processamento paralelo
file_batches  |> 
  future_imap(~ {
    df <- future_map_df(.x, ncdf_reader) |>   # Leitura paralela
      filter(between(longitude, -80, -32), between(latitude, -34, 10))
    saveRDS(df, paste0("data-raw/dff_", .y, ".rds"))
  })

Preparando os polígonos geográficos das regiões brasileiras para análises espaciais, com um tratamento especial para ajustar os contornos.

regiao <- geobr::read_region(showProgress = FALSE)
pol_norte <- regiao$geom |> purrr::pluck(1) |> as.matrix()
pol_nordeste <- regiao$geom |> purrr::pluck(2) |> as.matrix()
pol_sudeste <- regiao$geom |> purrr::pluck(3) |> as.matrix()
pol_sul <- regiao$geom |> purrr::pluck(4) |> as.matrix()
pol_centroeste<- regiao$geom |> purrr::pluck(5) |> as.matrix()

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Recriando o flag_nordeste
dff <- dff |>
  dplyr::mutate(
    flag_br = def_pol(longitude, latitude, pol_br),
    flag_nordeste = def_pol(longitude, latitude, pol_nordeste)
  )
dff <- dff |>
  dplyr::filter(flag_br|flag_nordeste)
data_set <- readr::read_rds("data/nasa-xco2.rds") |>
  # tibble::tibble() |>
  dplyr::filter(
    xco2 > 0,
    xco2_quality_flag == 0) |>
    dplyr::mutate(
      path = stringr::str_remove(path, "data-raw/nc4/|\\.nc4"),
      date = lubridate::as_date(stringr::str_sub(path,12,17)),
      year = lubridate::year(date),
      month = lubridate::month(date),
      day = lubridate::day(date),
      .after = "time"
    )
dplyr::glimpse(data_set)

# # Criando a coluna para os estados.
# # carregando os poligonos e funções

#
# # Leitura do banco de dados
data_set <- readr::read_rds("data/nasa-xco2.rds")
#
# # Classificando pontos
state <- 0
x <- data_set |> dplyr::pull(longitude)
y <- data_set |> dplyr::pull(latitude)
for(i in 1:nrow(data_set)) state[i] <- get_geobr_state(x[i],y[i])
data_set <- data_set |> cbind(state)
# readr::write_rds(data_set,"data/nasa-xco2.rds")

dff <- readr::read_rds("../data/nasa-xco2.rds")
br |>
  ggplot2::ggplot() +
  ggplot2::geom_sf(fill="white", color="#FEBF57",
                   size=.15, show.legend = FALSE) +
  ggplot2::geom_point(data= dff |>
                        dplyr::sample_n(1000) |>
                        dplyr::filter(flag_br|flag_nordeste) ,
                      ggplot2::aes(x=longitude,y=latitude),
                      shape=3,
                      col="red",
                      alpha=0.2)

Faxina e Processamento de Dados de CH4 Atmosférico (XCH4) Gosat

Buscamos todos arquivos NetCDF (.nc) no diretório e subdiretórios da pasta data-raw e retorna caminhos completos para processamento. Posteriormente a função de leitura, semelhante à anterior abre cada arquivo NetCD, extrai \(7\) variáveis-chave para análise e fecha a conexão após leitura retornando um dataframe padronizado

Variáveis extraídas:

## Lista com caminho e nomes dos arquivo a serem lidos - xco2
list_of_files <- list.files("data-raw/CH4_GOS_OCPR/",
                            pattern = ".nc",
                            full.names = TRUE,
                            all.files = TRUE,
                            recursive = TRUE)

## função para ler arquivos NCD4
ncdf_reader <- function(file_path){
  nc_file <- ncdf4::nc_open(file_path)
  df <- data.frame(
    "longitude"=ncdf4::ncvar_get(nc_file,varid="longitude"),
    "latitude"=ncdf4::ncvar_get(nc_file,varid="latitude"),
    "time"=ncdf4::ncvar_get(nc_file,varid="time"),
    "xch4"=ncdf4::ncvar_get(nc_file,varid="xch4"),
    "xch4_quality_flag"=ncdf4::ncvar_get(nc_file,varid="xch4_quality_flag"),
    "xch4_incerteza"=ncdf4::ncvar_get(nc_file,varid="xch4_uncertainty"),
    "path" = file_path
  )
  ncdf4::nc_close(nc_file)
  return(df)
}

Processamento em Lote dos Dados

Semelhante ao processamento anterior, seleciona apenas dados dentro da “caixa delimitadora” do Brasil e utiliza um filtro rápido antes da análise espacial precisa. Usa o polígono exato do Brasil ({pol_br}) para filtrar pontos costeiros/ilhas e retorma como resultado um dataframe unificado (dff) com apenas medições válidas. Cada lote preserva metadados originais (path do arquivo). A paralelização pode ser usada nesse momento.

dff_1 <- purrr::map_df(list_of_files[1:1000],ncdf_reader)
readr::write_rds(dff_1,"data-raw/dff_1.rds")
dff_2 <- purrr::map_df(list_of_files[1001:2000],ncdf_reader)
readr::write_rds(dff_2,"data-raw/dff_2.rds")
dff_3 <- purrr::map_df(list_of_files[2001:3000],ncdf_reader)
readr::write_rds(dff_3,"data-raw/dff_3.rds")
dff_4 <- purrr::map_df(list_of_files[3001:length(list_of_files)],ncdf_reader)
readr::write_rds(dff_4,"data-raw/dff_4.rds")

df1 <- readr::read_rds("data-raw/dff_1.rds")
df1 <- df1 |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df1)

df2 <- readr::read_rds("data-raw/dff_2.rds") |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df2)

df3 <- readr::read_rds("data-raw/dff_3.rds") |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df3)

df4 <- readr::read_rds("data-raw/dff_4.rds") |>
  dplyr::filter(longitude >= -80 &
                  longitude <= -32,
                latitude >= -34 &
                  latitude <= 10)
dplyr::glimpse(df3)
dff <- rbind(df1,df2,df3,df4)

dff <- dff |>
  dplyr::mutate(
    flag_br = def_pol(longitude, latitude, pol_br)
  )

Extraímos os contornos das \(5\) regiões do Brasil usando {geobr} e posteriormente ajustamos os polígonos para remover pontos a leste da longitude -34° (ilhas oceânicas) e corrigir distorções em áreas costeiras específicas. A saída é objeto pol_br, o polígono do Brasil ajustado e o pol_nordeste, o polígono do Nordeste ajustado.

regiao <- geobr::read_region(showProgress = FALSE)
pol_norte <- regiao$geom |> purrr::pluck(1) |> as.matrix()
pol_nordeste <- regiao$geom |> purrr::pluck(2) |> as.matrix()
pol_sudeste <- regiao$geom |> purrr::pluck(3) |> as.matrix()
pol_sul <- regiao$geom |> purrr::pluck(4) |> as.matrix()
pol_centroeste<- regiao$geom |> purrr::pluck(5) |> as.matrix()

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Recriando o flag_nordeste
dff <- dff |>
  dplyr::mutate(
    flag_br = def_pol(longitude, latitude, pol_br),
    flag_nordeste = def_pol(longitude, latitude, pol_nordeste)
  )

Correções, - mantém apenas pontos dentro do Brasil (flag_br) ou Nordeste (flag_nordeste) removendo valores inválidos. Tratamento de Datas extrai informações temporais do caminho do arquivo:

 - `date`: Data no formato `YYYY-MM-DD`  
 - `year`/`month`/`day`: Componentes separados  

Classificação por Estado pela função get_geobr_state para identificar o estado de cada coordenada resultado armazenado na coluna state.

data_set <- dff |>
  dplyr::filter(flag_br|flag_nordeste) |>
  dplyr::filter(
    xch4 > 0,
    xch4_quality_flag == 0) |>
    dplyr::mutate(
      path = stringr::str_remove(path, "data-raw/CH4_GOS_OCPR/20...|\\.nc"),
      date = lubridate::as_date(stringr::str_sub(path,27,34)),
      year = lubridate::year(date),
      month = lubridate::month(date),
      day = lubridate::day(date),
      .after = "time"
    )
dplyr::glimpse(data_set)

# Criando a coluna para os estados.
# carregando os poligonos e funções


# Classificando pontos
state <- 0
x <- data_set |> dplyr::pull(longitude)
y <- data_set |> dplyr::pull(latitude)
for(i in 1:nrow(data_set)) state[i] <- get_geobr_state(x[i],y[i])
data_set <- data_set |> cbind(state)
dplyr::glimpse(data_set)
# readr::write_rds(data_set,"data/gosat-xch4.rds")

dff <- readr::read_rds("../data/gosat-xch4.rds")
br |>
  ggplot2::ggplot() +
  ggplot2::geom_sf(fill="white", color="#FEBF57",
                   size=.15, show.legend = FALSE) +
  ggplot2::geom_point(data= dff |>
                        dplyr::sample_n(1000) |>
                        dplyr::filter(flag_br|flag_nordeste) ,
                      ggplot2::aes(x=longitude,y=latitude),
                      shape=3,
                      col="red",
                      alpha=0.2)

Faxina e Processamento de Dados de SIF (solar induced fluorescence) OCO-2/NASA.

  1. Conversão de Unidades e Datas

    • Converte XCO₂ para ppm (xco2_moles_mole_1*1e06)
    • Extrai ano/mês/dia do timestamp
  2. Cálculo de SIF
    Combina medidas de fluorescência em 757nm e 771nm numa métrica única

  3. Filtro Geográfico

    • Prepara polígonos das regiões brasileiras
    • Remove pontos oceânicos/distantes
    • Cria flags para Brasil (flag_br) e Nordeste (flag_nordeste)
  4. Visualização Rápida

    • Mapa com amostra de 1.000 pontos sobre o território brasileiro
  5. Classificação por Estado

    • Atribui cada ponto a um estado usando coordenadas
dff <- fco2r::oco2_br |>
  dplyr::mutate(
    xco2 = xco2_moles_mole_1*1e06,
    date = lubridate::ymd_hms(time_yyyymmddhhmmss),
    year = lubridate::year(date),
    month = lubridate::month(date),
    day = lubridate::day(date),
    sif = (
      fluorescence_radiance_757nm_idp_ph_sec_1_m_2_sr_1_um_1*2.6250912*10^(-19)  + 1.5*fluorescence_radiance_771nm_idp_ph_sec_1_m_2_sr_1_um_1* 2.57743*10^(-19))/2)

regiao <- geobr::read_region(showProgress = FALSE)
pol_norte <- regiao$geom |> purrr::pluck(1) |> as.matrix()
pol_nordeste <- regiao$geom |> purrr::pluck(2) |> as.matrix()
pol_sudeste <- regiao$geom |> purrr::pluck(3) |> as.matrix()
pol_sul <- regiao$geom |> purrr::pluck(4) |> as.matrix()
pol_centroeste<- regiao$geom |> purrr::pluck(5) |> as.matrix()

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Retirando alguns pontos
pol_br <- pol_br[pol_br[,1]<=-34,]
pol_br <- pol_br[!((pol_br[,1]>=-38.8 & pol_br[,1]<=-38.6) &
                     (pol_br[,2]>= -19 & pol_br[,2]<= -16)),]

pol_nordeste <- pol_nordeste[pol_nordeste[,1]<=-34,]
pol_nordeste <- pol_nordeste[!((pol_nordeste[,1]>=-38.7 & pol_nordeste[,1]<=-38.6) & pol_nordeste[,2]<= -15),]

# Recriando o flag_nordeste
dff <- dff |>
  dplyr::mutate(
    flag_br = def_pol(longitude, latitude, pol_br),
    flag_nordeste = def_pol(longitude, latitude, pol_nordeste)
  )

br |>
  ggplot2::ggplot() +
  ggplot2::geom_sf(fill="white", color="#FEBF57",
                   size=.15, show.legend = FALSE) +
  ggplot2::geom_point(data= dff |>
                        dplyr::sample_n(1000) |>
                        dplyr::filter(flag_br|flag_nordeste) ,
                      ggplot2::aes(x=longitude,y=latitude),
                      shape=3,
                      col="red",
                      alpha=0.2)

# Classificando pontos
data_set <- dff
state <- 0
x <- data_set |> dplyr::pull(longitude)
y <- data_set |> dplyr::pull(latitude)
for(i in 1:nrow(data_set)) state[i] <- get_geobr_state(x[i],y[i])
data_set <- data_set |> cbind(state)
dplyr::glimpse(data_set)
readr::write_rds(data_set,"../data/oco2-sif.rds")

Faxina de Dados do APPEEARS (MODIS/Vegetação)

O APPEEARS (Application for Extracting and Exploring Analysis Ready Samples) é uma plataforma da NASA desenvolvida pela Land Processes Distributed Active Archive Center (LP DAAC) que facilita o acesso e o pré-processamento de dados de sensoriamento remoto, especialmente da coleção MODIS e outros produtos de observação da Terra.

Objetivo
Este pipeline processa dados ecológicos do MODIS extraídos via APPEEARS, contendo métricas essenciais para monitoramento vegetativo:

Variáveis Processadas:
- ET (Evapotranspiração) - EVI (Enhanced Vegetation Index)
- NDVI (Normalized Difference Vegetation Index)
- FPAR (Fraction of Absorbed Photosynthetically Active Radiation) - LAI (Leaf Area Index)

# Carregar bibliotecas
library(tidyverse)
library(dplyr)

# Lista de arquivos
csv_files_list <- list.files("../data-raw/AppEEARS/", 
                       pattern = ".csv", 
                       full.names = TRUE)

# Empilhar arquivos 
appeears_stack <- purrr::map_dfr(csv_files_list, 
                           readr::read_csv)

Abaixo vamos selecionar camadas de interesses, renomear colunas, extraindo o ano e o mês das datas no formato YYYY-MM-DD, filtrar para nos anos que serão analisados e agrupar por lat e lon. Após o agrupamento é calculado a média das variáveis numéricas por mês e ano.

appeears <- appeears_stack |> 
   dplyr::select(Latitude, Longitude, Date, MOD15A2H_061_Lai_500m, MOD15A2H_061_Fpar_500m, 
         MOD13Q1_061__250m_16_days_EVI, MOD13Q1_061__250m_16_days_NDVI, 
         MOD16A2_061_ET_500m) |>
  dplyr::rename(date = Date,
         lat = Latitude,
         lon = Longitude,
         lai = MOD15A2H_061_Lai_500m,
         fpar = MOD15A2H_061_Fpar_500m,
         evi = MOD13Q1_061__250m_16_days_EVI,
         ndvi = MOD13Q1_061__250m_16_days_NDVI,
         et = MOD16A2_061_ET_500m) |> 
  dplyr::mutate(year = lubridate::year(date),
                month = lubridate::month(date))  |> 
  dplyr::filter(
    year >= 2015 & year <= 2023
  ) |> 
  dplyr::group_by(lat, lon, year, month)  |> 
  dplyr::summarise(
    dplyr::across(c(fpar, lai, evi, ndvi, et), 
           ~ mean(., na.rm = TRUE),
           .names = "media_{.col}"),
    n_observacoes = dplyr::n(),
    .groups = 'drop'
  ) |> 
  dplyr::arrange(lat, lon, year, month)
# Valores NA na coluna ET (Dados de 2021 a 2024)

# Visualizar dados
dplyr::glimpse(appeears)
# View(appeears)
# Verificacao de pontos Brasil Central

br_country <- geobr::read_country(showProgress = FALSE)

br_country |> 
  ggplot2::ggplot()+
  ggplot2::geom_sf()+
  ggplot2::geom_point(
    data=appeears |> 
      dplyr::filter(ano == 2018), 
      ggplot2::aes(lon,lat)
  )

appeears |> 
  dplyr::filter(ano == 2017) |> 
  ggplot2::ggplot(ggplot2::aes(lon,lat)) +
  ggplot2::geom_point()
# Gerar arquivo com os dados
# readr::write_rds(appeears, '../data/appeears-modis.rds')

NASA-POWER

Criação de um grid de pontos sobre a região Centro-Oeste do Brasil. É utilizado pacotes geográficos como {geobr} e {sf}. Usamdo o pacote {geobr}, que fornece shapefiles (polígonos) oficiais do IBGE.

st_union() une os polígonos dos estados em um único polígono (uma geometria só). Isso evita sobreposição ou múltiplas fronteiras internas.

st_make_grid() cria uma grade (grid) de células retangulares ou quadradas. cellsize = 0.5 define o tamanho das células (aqui: 0.5 graus de latitude/longitude). what = "centers" indica os centros dos quadrados, e não os quadrados em si.

st_as_sf() converte os pontos em um sf (formato espacial).

Esse tipo de grid é útil para:

  • Amostragem espacial;
  • Modelagem de distribuição (e.g., interpolação);
  • Análises ambientais ou climáticas em pontos regulares;
  • Servir como base para extrair dados raster (NDVI, precipitação, etc.).
# Lendo os estados brasileiros pelo pacote geobr
estados_br <- geobr::read_state(year = 2020, 
                                showProgress = FALSE)

# Filtrando estados de interesse (Centro-Oeste)
estados <- estados_br |> 
  dplyr::filter(name_region == 'Centro Oeste')

# Unindo polígono dos estados
pol_estados <- estados |> 
  sf::st_union()

# Criar grid de pontos
grid_pontos <- sf::st_make_grid(pol_estados, 
                            cellsize = 0.5, 
                            what = "centers") |> 
  sf::st_as_sf()

filtro espacial dos pontos do grid, mantendo apenas os que estão dentro da região Centro-Oeste, e depois extrai as coordenadas (latitude e longitude) para visualização com ggplot2.

st_within(grid_pontos, pol_estados, sparse = FALSE) cria uma matriz booleana dizendo quais pontos do grid estão dentro do polígono da região Centro-Oeste.

sparse = FALSE: retorna uma matriz lógica completa (TRUE/FALSE), em vez de uma lista esparsa.

grid_pontos[...]: usa essa matriz lógica para filtrar apenas os pontos "TRUE", ou seja, os que estão dentro do polígono.

st_coordinates() extrai as coordenadas X (longitude) e Y (latitude) dos objetos sf com geometria do tipo ponto.

Pega a matriz coord e transforma em um data.frame com nomes amigáveis: lon (longitude), lat (latitude).

# Filtrar pontos dentro do Centro-Oeste
pontos_filtro <- grid_pontos[sf::st_within(grid_pontos, 
                                       pol_estados, 
                                       sparse = FALSE),]

# Extrair coordenadas de cada ponto no grid
coord <- sf::st_coordinates(pontos_filtro)

# Gerando df com latitude e longitude
df_coords <- data.frame(lon = coord[,1], lat = coord[,2])

# Conferindo pontos
ggplot2::ggplot() +
    ggplot2::geom_sf(data = pol_estados, fill = "black", color = "black") +
    ggplot2::geom_point(data = df_coords, ggplot2::aes(x = lon, y = lat), color = "red", size = 1.5) + 
    ggplot2::theme_bw()

agora vamos baixar dados climáticos para cada ponto do grid

try() serve para tentar rodar um código que pode gerar erro, mas sem parar o script.

power_data_download() é uma função do pacote {nasapower}, que baixa dados meteorológicos da NASA POWER API.

inherits(dw, "try-error"): verifica se a tentativa anterior gerou erro.

O ! (negação) faz com que, se não houver erro, o laço repeat seja interrompido com break.

Portanto para cada ponto (i) da grade de coordenadas:

1-Tenta baixar os dados meteorológicos;

2-Se der erro, tenta de novo (infinitamente, até funcionar);

3-Se funcionar, sai do repeat e passa para o próximo ponto.
# Baixar dados nasa power
for (i in 1:nrow(df_coords)) {
  repeat {
    dw <- try(
      nasapower::power_data_download(df_coords$lon[i], df_coords$lat[i],
                          startdate = '2015-01-01',
                          enddate = '2024-01-01')
    )
    if (!(inherits(dw, "try-error")))
      break
  }
}

Agora vamos ler todos os .csv gerados pelo loop anterior (um por ponto), juntar tudo num único data frame, limpar os nomes das colunas e salvar como .rds.

# Criar banco de dados com os arquivos baixados
files_names <- list.files("../data-raw/nasa-power/", 
                          full.names = TRUE,
                          pattern = ".csv")

df_final <- purrr::map_dfr(files_names, read.csv)

# Salvar o banco de dados final
readr::write_rds(df_final |> 
                   janitor::clean_names(), 
                 '../data/nasa-power.rds')

Faxina dos dados de desmatamento do prodes

Carregando bibliotecas

library(tidyverse)
library(terra)
library(geobr)
library(dplyr)
library(sf)
library(tmap)  # ou ggplot2

Carregando raster (.tiff)

raster <- rast("../data-raw/desmat-prodes/prodes_brasil_2023.tif")
str(raster)
estados_estudados <- c("MT","MS","GO","DF")
municipality <- read_municipality(showProgress = FALSE)
raster::plot(raster)
categotia <- 15:22
cod_muni <- 1:nrow(estado_x_mun_y)
comb <- expand.grid(categotia,cod_muni, sep = " ")
codigo <- paste(comb$Var1, comb$Var2)
get_my_coord <- function(x){
  x_cat <- str_split(x," ",simplify = TRUE)[1,1] |> as.numeric()
  y_muni <- str_split(x," ",simplify = TRUE)[1,2] |> as.numeric()
  estado_x_mun_y <- municipality |> 
    filter(abbrev_state %in% estados_estudados) |> 
    slice(y_muni)
  muni_y <- st_transform(estado_x_mun_y, crs(raster))
  raster_muni_y <- crop(raster, muni_y, mask = TRUE)
  raster_2020 <- raster_muni_y == x_cat
  raster_2020[raster_2020 == 1] <- x_cat # ENTENDER O QUE OCORRE
  idx <- which(raster_muni_y[] == x_cat)
  coords <- xyFromCell(raster_muni_y, idx)  
  df <- as.data.frame(coords) |>
    add_column(categorie = x_cat,
               muni = muni_y$name_muni,
               state = muni_y$abbrev_state) 
    write_rds(df, paste0("../data-raw/prodes-bad-alloc/",
                   muni_y$name_muni,"-",
                   muni_y$abbrev_state,"-",
                   x,".rds"
                   ))
    }
# invisible(map(codigo,get_my_coord))
lista <- list.files("../data-raw/prodes-bad-alloc/",
           full.names=TRUE)
prodes <- purrr::map_df(lista,readr::read_rds)
glimpse(prodes)
write_rds(prodes,"../data/prodes-deforestation.rds")