Se desea conocer en qué zonas del mundo se puede establecer la producción comercial apícola para obtener los mejores rendimientos teniendo en cuenta los rangos de aptitud climática
Revisando información de la UPRA se conocen los rangos optimos de condición climática:
Se desea conocer qué zonas en colombia presentan estas condiciones y conocer otros sitios en el mundo que podrían tener condiciones similares.
Se hace uso de los datos de clima de línea base a nivel global del siguiente enlace, los cuales corresponden al periodo 1970 - 2000, cuya última actualización fue en enero 2020.
https://www.worldclim.org/data/worldclim21.html
Se realiza la carga de datos de precipitación y temperatura media anual en una resolución espacial de 5 minutos.
#Carga de librerías
library(leaflet) # Para la creación de mapas interactivos.
library(sf) # Para trabajar con datos geoespaciales.
library(mapview) # Para la visualización interactiva de mapas.
library(terra) # Para el manejo de datos raster y análisis espacial.
library(leafsync) # Para la sincronización de múltiples mapas interactivos.
library(raster) # Para trabajar con datos espaciales como imagenes
library(rasterVis)
library(sp) # Para trabajar con datos espaciales en formatos vectoriales
library(dplyr) #Para la manipulación y transformación de datos.
library(rnaturalearth) #Para obtener mapas a distintas escalas.
library(rnaturalearthdata)
library(exactextractr)
library(geodata)
#Cargue de datos de precipitación
Prec=list.files("D:/MaestriaCienciaDatos/S2_AnalisisInfoGeografica/M1U2_Exploracion/CasoAccion/DatosClima/Prec/", pattern = ".tif", full.names = TRUE)
precipitacion=raster::stack(Prec)
require(rasterVis)
names(precipitacion)=month.name
levelplot(precipitacion,
par.settings = BuRdTheme,
at = seq(0, 1500, by = 50))
# Calcular la media mensual por capa
monthly_mean <- cellStats(precipitacion, stat = 'mean', na.rm = TRUE)
# Graficar
barplot(monthly_mean,
names.arg = month.name,
las = 2,
col = "skyblue",
main = "Precipitación promedio mensual",
xlab = "Meses", ylab = "Precipitación promedio (mm)")
#Cargue de datos de temperatura
require(rasterVis)
Temp=list.files("D:/MaestriaCienciaDatos/S2_AnalisisInfoGeografica/M1U2_Exploracion/CasoAccion/DatosClima/Temp/", full.names = TRUE)
temperatura=stack(Temp)
names(temperatura)=month.name
levelplot(temperatura,
par.settings = BuRdTheme,
at = seq(-40, 50, by = 5))
# Calcular la media mensual por capa
monthly_meant <- cellStats(temperatura, stat = 'mean', na.rm = TRUE)
# Graficar
barplot(monthly_meant,
names.arg = month.name,
las = 2,
col = "skyblue",
main = "Temperatura promedio mensual",
xlab = "Meses", ylab = "Temperatura promedio (°C)")
Se destaca que la tendencia en la mayor cantidad de países del mundo es mantener una precipítación media baja, cuyos mayores valores se observan en los países ubicados a lo largo de la línea del Ecuador. Los meses con mayor precipitación son Julio y Agosto influenciados particularmente por regiones tropicales como Suramérica, el Sureste de Asia y algunos sectores de África.
En el caso de la temperatura, se destaca una gran variabilidad climática en dónde predominan los valores extremos altos sobre los bajos. Lo cual impacta en gran medida la temperatura promedio mensual, generando valores por debajo de 0°C, se destacan los meses junio, julio y agosto como aquellos con mayor temperatura.
Se filtraron las áreas teniendo en cuenta los rangos óptimos establecidos tanto para la precipitación como para la temperatura en la producción comercial apícola.
#Precipitación media anual: entre 500 y 1800 mm/año
#Precipitación mensual optima: entre 42 y 150 mm
prec_apicola <- precipitacion>42 & precipitacion<150
plot(prec_apicola)
#Temperatura media anual: mayor a 12 grados centígrados
temp_apicola <- temperatura>12
plot(temp_apicola)
prec_bin <- prec_apicola*1
# -------------------------
# Se entiende la celda apta si algún mes del año está en el rango (binario 0/)
prec_agg <- calc(prec_bin, fun = function(x) { as.integer(any(x == 1, na.rm = TRUE)) })
# -------------------------
# Reproyectar a proyección métrica / equal-area para cálculo de área real (si no está ya en metros)
# Verificar si las unidades del raster son metros (crs tiene +units=m) o EPSG proyectado
crs_r <- crs(prec_agg)
# Si el CRS no es métrico, reproyecta; usamos Mollweide (equal area) como ejemplo
is_metric_crs <- grepl("units=m|+units=m|+proj=aea|+proj=moll|EPSG:\\d+", as.character(crs_r), fixed = FALSE)
# (simplista: si no estás seguro, reproyecta de todas formas)
prec_m <- projectRaster(prec_agg, crs = "+proj=moll +units=m", method = "ngb")
# -------------------------
# Preparar países en mismo CRS
paises <- ne_countries(scale = "medium", returnclass = "sf")
paises_m <- st_transform(paises, crs = st_crs(prec_m))
# -------------------------
# Extraer solo países que intersectan la extensión del raster (evita mismatches)
ext_poly <- as(extent(prec_m), "SpatialPolygons")
crs(ext_poly) <- crs(prec_m)
ext_sf <- st_as_sf(ext_poly)
intersect_idx <- st_intersects(paises_m, ext_sf, sparse = FALSE)[,1]
paises_to_extract <- paises_m[intersect_idx, ]
# -------------------------
# Usar exact_extract sobre el raster AGREGADO (ya single-layer)
# Esto devuelve para cada país la SUMA de valores del raster dentro del polígono
ae <- exact_extract(prec_m, paises_to_extract, 'sum', progress = FALSE)
# Convertir a vector (un número por país)
area_count_subset <- sapply(ae, function(x) {
# 'x' puede ser un número, vector, df ... aseguramos sumar
if (is.data.frame(x)) return(sum(as.matrix(x), na.rm = TRUE))
if (is.numeric(x)) return(sum(x, na.rm = TRUE))
if (is.list(x)) { y <- unlist(x); if (is.numeric(y)) return(sum(y, na.rm = TRUE)) }
return(0)
})
# Rellenar vector para todos los países (0 si no intersectaron)
area_count_all <- numeric(nrow(paises_m))
area_count_all[which(intersect_idx)] <- area_count_subset
# -------------------------
# Convertir conteo a área en km²
# * area de celdas aptas en total de meses = area_count_all * area_celda (esto da "meses·area")
area_celda_m2 <- prod(res(prec_m)) # m^2 por celda (res en metros)
area_apta_km2 <- (area_count_all * area_celda_m2) / 1e6
# -------------------------
# Calcular área total país en km2 y proporción
area_total_km2 <- as.numeric(st_area(paises_m)) / 1e6
# Prevenir div/0
area_total_km2[area_total_km2 == 0] <- NA
prop_apta <- area_apta_km2 / area_total_km2
# -------------------------
# Adjuntar y mostrar resultados
paises_m$area_total_km2 <- area_total_km2
paises_m$area_apta_km2 <- area_apta_km2
paises_m$prop_apta <- prop_apta
resultados <- paises_m %>%
st_drop_geometry() %>%
select(admin, area_total_km2, area_apta_km2, prop_apta) %>%
arrange(desc(prop_apta))
knitr::kable(head(resultados, 20), caption = "Top 20 países con precipitación optima")
| admin | area_total_km2 | area_apta_km2 | prop_apta |
|---|---|---|---|
| Saint Barthelemy | 24.57829 | 24.57829 | 1 |
| Andorra | 442.79947 | 442.79949 | 1 |
| Liechtenstein | 138.27521 | 138.27522 | 1 |
| Malawi | 120062.21902 | 120062.22410 | 1 |
| North Macedonia | 25420.81768 | 25420.81869 | 1 |
| Rwanda | 25442.41080 | 25442.41180 | 1 |
| Macao S.A.R | 22.79087 | 22.79088 | 1 |
| Republic of Serbia | 77663.53604 | 77663.53862 | 1 |
| Paraguay | 401803.25237 | 401803.26555 | 1 |
| Lesotho | 30094.79370 | 30094.79464 | 1 |
| eSwatini | 17030.08532 | 17030.08580 | 1 |
| Monaco | 12.44278 | 12.44278 | 1 |
| Slovakia | 48447.50660 | 48447.50784 | 1 |
| Ivory Coast | 323018.43686 | 323018.44409 | 1 |
| Saint Vincent and the Grenadines | 311.78799 | 311.78799 | 1 |
| South Sudan | 625360.44540 | 625360.45469 | 1 |
| Montserrat | 79.96314 | 79.96314 | 1 |
| Zambia | 757286.69822 | 757286.70738 | 1 |
| Moldova | 33191.15272 | 33191.15312 | 1 |
| Bosnia and Herzegovina | 51800.29019 | 51800.29077 | 1 |
temp_bin <- temp_apicola*1
# -------------------------
# Se entiende la celda apta si algún mes del año está en el rango (binario 0/)
temp_agg <- calc(temp_bin, fun = function(x) { as.integer(any(x == 1, na.rm = TRUE)) })
# -------------------------
# Reproyectar a proyección métrica / equal-area para cálculo de área real (si no está ya en metros)
# Verificar si las unidades del raster son metros (crs tiene +units=m) o EPSG proyectado
crs_r <- crs(temp_agg)
# Si el CRS no es métrico, reproyecta; usamos Mollweide (equal area) como ejemplo
is_metric_crs <- grepl("units=m|+units=m|+proj=aea|+proj=moll|EPSG:\\d+", as.character(crs_r), fixed = FALSE)
# (simplista: si no estás seguro, reproyecta de todas formas)
temp_m <- projectRaster(temp_agg, crs = "+proj=moll +units=m", method = "ngb")
# -------------------------
# Preparar países en mismo CRS
paises <- ne_countries(scale = "medium", returnclass = "sf")
paises_m <- st_transform(paises, crs = st_crs(temp_m))
# -------------------------
# Extraer solo países que intersectan la extensión del raster (evita mismatches)
ext_poly <- as(extent(temp_m), "SpatialPolygons")
crs(ext_poly) <- crs(temp_m)
ext_sf <- st_as_sf(ext_poly)
intersect_idx <- st_intersects(paises_m, ext_sf, sparse = FALSE)[,1]
paises_to_extract <- paises_m[intersect_idx, ]
# -------------------------
# Usar exact_extract sobre el raster AGREGADO (ya single-layer)
# Esto devuelve para cada país la SUMA de valores del raster dentro del polígono
ae <- exact_extract(temp_m, paises_to_extract, 'sum', progress = FALSE)
# Convertir a vector (un número por país)
area_count_subset <- sapply(ae, function(x) {
# 'x' puede ser un número, vector, df ... aseguramos sumar
if (is.data.frame(x)) return(sum(as.matrix(x), na.rm = TRUE))
if (is.numeric(x)) return(sum(x, na.rm = TRUE))
if (is.list(x)) { y <- unlist(x); if (is.numeric(y)) return(sum(y, na.rm = TRUE)) }
return(0)
})
# Rellenar vector para todos los países (0 si no intersectaron)
area_count_all <- numeric(nrow(paises_m))
area_count_all[which(intersect_idx)] <- area_count_subset
# -------------------------
# Convertir conteo a área en km²
# * area de celdas aptas en total de meses = area_count_all * area_celda (esto da "meses·area")
area_celda_m2 <- prod(res(temp_m)) # m^2 por celda (res en metros)
area_apta_km2 <- (area_count_all * area_celda_m2) / 1e6
# -------------------------
# Calcular área total país en km2 y proporción
area_total_km2 <- as.numeric(st_area(paises_m)) / 1e6
# Prevenir div/0
area_total_km2[area_total_km2 == 0] <- NA
prop_apta <- area_apta_km2 / area_total_km2
# -------------------------
# Adjuntar y mostrar resultados
paises_m$area_total_km2 <- area_total_km2
paises_m$area_apta_km2 <- area_apta_km2
paises_m$prop_apta <- prop_apta
resultados <- paises_m %>%
st_drop_geometry() %>%
select(admin, area_total_km2, area_apta_km2, prop_apta) %>%
arrange(desc(prop_apta))
knitr::kable(head(resultados, 20), caption = "Top 20 países con temperatura optima")
| admin | area_total_km2 | area_apta_km2 | prop_apta |
|---|---|---|---|
| Saint Barthelemy | 2.457829e+01 | 2.457829e+01 | 1 |
| Malawi | 1.200622e+05 | 1.200622e+05 | 1 |
| Macao S.A.R | 2.279087e+01 | 2.279088e+01 | 1 |
| Republic of Serbia | 7.766354e+04 | 7.766354e+04 | 1 |
| Paraguay | 4.018033e+05 | 4.018033e+05 | 1 |
| Republic of the Congo | 3.476507e+05 | 3.476507e+05 | 1 |
| eSwatini | 1.703009e+04 | 1.703009e+04 | 1 |
| Chad | 1.273841e+06 | 1.273841e+06 | 1 |
| Monaco | 1.244278e+01 | 1.244278e+01 | 1 |
| Ivory Coast | 3.230184e+05 | 3.230184e+05 | 1 |
| Iraq | 4.384353e+05 | 4.384353e+05 | 1 |
| Saint Vincent and the Grenadines | 3.117880e+02 | 3.117880e+02 | 1 |
| South Sudan | 6.253604e+05 | 6.253605e+05 | 1 |
| Montserrat | 7.996314e+01 | 7.996314e+01 | 1 |
| Western Sahara | 9.099750e+04 | 9.099750e+04 | 1 |
| Zambia | 7.572867e+05 | 7.572867e+05 | 1 |
| Moldova | 3.319115e+04 | 3.319115e+04 | 1 |
| Bosnia and Herzegovina | 5.180029e+04 | 5.180029e+04 | 1 |
| San Marino | 6.841198e+01 | 6.841198e+01 | 1 |
| Turkmenistan | 4.716821e+05 | 4.716821e+05 | 1 |
Revisando el top 20 de países con precipitación y temperatura optima se encuentra que el Sahara Occidental y Chad, territorios ubicados en África, cuentan con alto potencial para la la producción comercial apícola.
# --- 1. Obtener el polígono de Sahara Occidental ---
map_units <- ne_download(
scale = "medium",
type = "admin_0_map_units",
category = "cultural",
returnclass = "sf"
)
ws_sf <- map_units %>%
filter(GEOUNIT == "Western Sahara")
ws_sf <- st_transform(ws_sf, crs(precipitacion))
ws_sp <- as(ws_sf, "Spatial") # convertir a formato Spatial (para raster)
# --- 2. Filtrar zonas con precipitación óptima ---
# Suponiendo que 'precipitacion' es tu RasterStack o RasterBrick mensual
prec_apicola <- clamp(precipitacion, lower = 42, upper = 150, useValues = TRUE)
# --- 3. Recortar y enmascarar el raster a Western Sahara ---
prec_apicola_ws <- crop(prec_apicola, ws_sp)
prec_apicola_ws <- mask(prec_apicola_ws, ws_sp)
# --- 4. Graficar el resultado ---
levelplot(prec_apicola_ws,
par.settings = BuRdTheme,
at = seq(42, 150, by = 2),
main = "Zonas con precipitacion optima para apicultura (Sahara Occidental)",
margin = FALSE,
sp.layout = list(list("sp.polygons", ws_sp, col = "black", lwd = 1.5)))
#ws_sf <- st_transform(ws_sf, crs(temperatura))
ws_sp <- as(ws_sf, "Spatial") # convertir a formato Spatial (para raster)
# --- 2. Filtrar zonas con precipitación óptima ---
# Suponiendo que 'precipitacion' es tu RasterStack o RasterBrick mensual
temp_apicola <- clamp(temperatura, lower = 12, useValues = TRUE)
# --- 3. Recortar y enmascarar el raster a Western Sahara ---
temp_apicola_ws <- crop(temp_apicola, ws_sp)
temp_apicola_ws <- mask(temp_apicola_ws, ws_sp)
# --- 4. Graficar el resultado ---
levelplot(temp_apicola_ws,
par.settings = BuRdTheme,
at = seq(12, 50, by = 2),
main = "Zonas con temperatura optima para apicultura (Sahara Occidental)",
margin = FALSE,
sp.layout = list(list("sp.polygons", ws_sp, col = "black", lwd = 1.5)))
# --- 1. Obtener el polígono de Chad ---
Chad_sf <- ne_countries(scale = "medium", country = "Chad", returnclass = "sf")
#Chad_sf <- st_transform(Chad_sf, crs = st_crs(prec_apicola_Chad))
Chad_sp <- as(Chad_sf, "Spatial")
# --- 2. Filtrar zonas con precipitación óptima ---
# Suponiendo que 'precipitacion' es tu RasterStack o RasterBrick mensual
prec_apicola <- mask(precipitacion, precipitacion > 42 & precipitacion < 150)
# --- 3. Recortar y enmascarar el raster a Chad ---
prec_apicola_Chad <- crop(prec_apicola, Chad_sp)
prec_apicola_Chad <- mask(prec_apicola_Chad, Chad_sp)
# --- 4. Graficar el resultado ---
levelplot(prec_apicola_Chad,
par.settings = BuRdTheme,
at = seq(42, 150, by = 2),
main = "Zonas con precipitacion optima para apicultura (Chad)",
margin = FALSE,
sp.layout = list(
list("sp.polygons", Chad_sp, col = "black", lwd = 1.5))
)
# --- Filtrar zonas con precipitación óptima ---
# Suponiendo que 'precipitacion' es tu RasterStack o RasterBrick mensual
temp_apicola <- mask(temperatura, temperatura > 12)
# --- Recortar y enmascarar el raster a Chad ---
temp_apicola_Chad <- crop(temp_apicola, Chad_sp)
temp_apicola_Chad <- mask(temp_apicola_Chad, Chad_sp)
# --- Graficar el resultado ---
levelplot(temp_apicola_Chad,
par.settings = BuRdTheme,
at = seq(12, 50, by = 2),
main = "Zonas con temperatura optima para apicultura (Chad)",
margin = FALSE,
sp.layout = list(
list("sp.polygons", Chad_sp, col = "black", lwd = 1.5))
)
# --- 1. Obtener el polígono de Colombia ---
colombia_sf <- ne_countries(scale = "medium", country = "Colombia", returnclass = "sf")
colombia_sp <- as(colombia_sf, "Spatial") # convertir a formato Spatial (para raster)
# --- 2. Filtrar zonas con precipitación óptima ---
# Suponiendo que 'precipitacion' es tu RasterStack o RasterBrick mensual
prec_apicola <- mask(precipitacion, precipitacion > 42 & precipitacion < 150)
# --- 3. Recortar y enmascarar el raster a Colombia ---
prec_apicola_col <- crop(prec_apicola, colombia_sp)
prec_apicola_col <- mask(prec_apicola_col, colombia_sp)
# --- 4. Graficar el resultado ---
levelplot(prec_apicola_col,
par.settings = BuRdTheme,
at = seq(42, 150, by = 2),
main = "Zonas con precipitacion optima para apicultura (Colombia)")
# --- Filtrar zonas con temperatura óptima ---
temp_apicola <- mask(temperatura, temperatura > 12)
# --- Recortar y enmascarar el raster a Colombia ---
temp_apicola_col <- crop(temp_apicola, colombia_sp)
temp_apicola_col <- mask(temp_apicola_col, colombia_sp)
# --- Graficar el resultado ---
levelplot(temp_apicola_col,
par.settings = BuRdTheme,
at = seq(12, 40, by = 2),
main = "Zonas con temperatura optima para apicultura (Colombia)")
Para unificar el ejercicio se promedian los resultados de temperatura y precipitación en condiciones optimas para la producción comercial apícola. A partir de estos resultados se seleccionan aquellas zonas por encima del 80% con el fin de seleccionar las mejores áreas.
# Promedio anual
prec_optima_apicultura <- sum(prec_apicola) / 12
temp_optima_apicultura <- sum(temp_apicola) / 12
# Recortar a Colombia
optimo_colombia_prec <- crop(prec_optima_apicultura, colombia_sp)
optimo_colombia_temp <- crop(temp_optima_apicultura, colombia_sp)
# Calcular umbrales del 80% del promedio
umbral_prec <- mean(values(optimo_colombia_prec), na.rm = TRUE) * 0.8
umbral_temp <- mean(values(optimo_colombia_temp), na.rm = TRUE) * 0.8
# Asignar NA a celdas no aptas (menores al 80% del promedio)
optimo_colombia_prec[optimo_colombia_prec < umbral_prec] <- NA
optimo_colombia_temp[optimo_colombia_temp < umbral_temp] <- NA
# Enmascarar con el shape de Colombia
optimo_col_prec <- mask(optimo_colombia_prec, colombia_sp)
optimo_col_temp <- mask(optimo_colombia_temp, colombia_sp)
# Crear mapas interactivos
m1 <- mapview(optimo_col_prec, maxpixels = 2332800)
m2 <- mapview(optimo_col_temp, maxpixels = 2332800)
# Sincronizar
m <- leafsync::sync(m1, m2)
m
Inicialmente se establecen las zonas en las que se cumplen las condiciones de precipitación y temperatura, posteriormente se eligen 3 puntos en esas áreas y se extraen las respectivas series temporales.
# --- Combinar zonas óptimas
# Convertir a la misma resolución y extensión
optimo_colombia_prec <- resample(optimo_colombia_prec, optimo_colombia_temp)
# Intersección (solo donde ambas son válidas)
zona_optima <- !is.na(optimo_colombia_prec) & !is.na(optimo_colombia_temp)
# Aplicar máscara a Colombia
zona_optima <- mask(zona_optima, colombia_sp)
# --- Selección de 3 puntos aleatorios dentro de la zona
# Convertir zona_optima (o cualquier RasterLayer) a SpatRaster
zona_optima_spat <- terra::rast(zona_optima)
set.seed(456)
puntos_random <- terra::spatSample(
zona_optima_spat,
size = 3,
method = "random",
as.points = TRUE,
na.rm = TRUE # <- ignora los NA
)
plot(zona_optima_spat)
points(puntos_random, pch = 19, col = "red")
# --- Extraer las series temporales para cada punto
# Convertir puntos a Spatial (clase de raster)
puntos_random_sp <- as(puntos_random, "Spatial")
# Extraer valores
valores_prec <- raster::extract(precipitacion, puntos_random_sp)
valores_temp <- raster::extract(temperatura, puntos_random_sp)
# Crear vector con los nombres de los meses (suponiendo que son 12 capas mensuales)
meses <- 1:nlayers(precipitacion)
# Convertir a data.frame para graficar fácilmente
df_prec <- as.data.frame(t(valores_prec))
df_temp <- as.data.frame(t(valores_temp))
colnames(df_prec) <- paste0("Punto_", 1:ncol(df_prec))
colnames(df_temp) <- paste0("Punto_", 1:ncol(df_temp))
df_prec$Mes <- 1:nrow(df_prec)
df_temp$Mes <- 1:nrow(df_temp)
# ─── Graficar precipitación ───────────────────────────────────────────────
matplot(df_prec$Mes, df_prec[, 1:3], type = "l", lwd = 2, lty = 1,
col = c("blue", "red", "green"),
xlab = "Mes", ylab = "Precipitacion (mm)",
main = "Serie de tiempo de precipitacion")
legend("topright", legend = paste("Punto", 1:3),
col = c("blue", "red", "green"), lwd = 2, bty = "n")
# ─── Graficar temperatura ────────────────────────────────────────────────
matplot(df_temp$Mes, df_temp[, 1:3], type = "l", lwd = 2, lty = 1,
col = c("orange", "purple", "brown"),
xlab = "Mes", ylab = "Temperatura (C)",
main = "Serie de tiempo de temperatura")
legend("topright", legend = paste("Punto", 1:3),
col = c("orange", "purple", "brown"), lwd = 2, bty = "n")
A partir de la distancia euclidiana se generan mapas de similaridad a nivel global para los sitios anteriormente identificados. Valores bajos (azules) representan aquellos con climas más similares al punto. Valores altos (rojos) representan aquellos con climas más diferentes del punto.
library(RColorBrewer)
# ─── 1. Convertir tus capas a RasterBrick si aún no lo están ─────────────
prec_brick <- brick(precipitacion)
temp_brick <- brick(temperatura)
# ─── 2. Extraer series temporales promedio en los 3 puntos ──────────────
valores_prec <- raster::extract(prec_brick, puntos_random_sp)
valores_temp <- raster::extract(temp_brick, puntos_random_sp)
# Calcular el promedio mensual por punto (manteniendo estructura mensual)
valores_clima <- lapply(1:3, function(i) {
c(valores_prec[i, ], valores_temp[i, ])
})
names(valores_clima) <- paste0("Punto_", 1:3)
# ─── 3. Combinar los raster globales de precipitación y temperatura ─────
clima_stack <- stack(prec_brick, temp_brick)
# ─── 4. Calcular distancia euclidiana de cada píxel a cada punto ────────
distancias <- lapply(1:3, function(i) {
punto_ref <- valores_clima[[i]]
raster::calc(clima_stack, fun = function(x) {
if (any(is.na(x))) return(NA)
sqrt(sum((x - punto_ref)^2, na.rm = TRUE))
})
})
# ─── 5. Asignar nombres y combinar en un stack ──────────────────────────
names(distancias) <- paste0("Distancia_Punto_", 1:3)
dist_stack <- stack(distancias)
# ─── 6. Visualizar mapas con escala de colores adecuada ─────────────────
paleta <- rev(brewer.pal(11, "RdYlBu"))
par(mfrow = c(1, 3))
for (i in 1:3) {
plot(dist_stack[[i]],
main = paste(names(dist_stack)[i]),
col = paleta,
zlim = c(0, quantile(dist_stack[[i]][], 0.95, na.rm = TRUE))) # recorte a 95%
}
Promediar los resultados de precipitación para unificar los resultados conllevan la perdida de rigurosidad en la busqueda de los valores optimos. En un próxima aplicación se podría realizar la suma de los valores de precipitación para todos los meses ya que los valores optimos se establecen a partir del valor medio anual.
Se identificó que algunos de los territorios a nivel mundial con precipitación y temperatura optima corresponden a Sahara Occidental y Chad. En el caso de Colombia se cuenta con áreas significativas de aptitud en gran parte del territorio nacional, excluyendo principalmente las zonas de gran altitud por sus bajas temperaturas, así cómo gran parte de la región Caribe debido a insuficiente precipitación.
Los territorios de similaridad climática identificados se ubican en general sobre la misma latitud de los puntos de referencia.
Los mapas de similaridad climática si bien consumen más recursos son muy utiles en caso de querer replicar casos de exito de referencia, delimitando mucho mejor las zonas de interés. Por otro lado, los mapas que consideran extrictamente los valores optimos pueden ser complementados con otras variables y apoyar procesos de planificación agropecuaria.