Última actualización: 03 junio 2020
Las zonas de amortiguación son áreas de vegetación ribereña que se dispone en forma de franja a lo largo de la red hidrográfica y que por sus funciones naturales son usadas para reducir contaminación difusa desde zonas agrícolas.
Según el Plan de Acción Santa Lucía - Medidas de segunda generación, se establece la zona buffer de 40 metros a lo largo de los cauces principales y de 25 metros en los tributarios menores.
La distribución espacial de las zonas buffer se puede consultar a continuación.En dónde para una mejor visualización se muestra el buffer de 160 metros para los cauces principales y de 20 metros para los tributarios.
rm(list = ls())
library(mapview)
library(maptools)
utm = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
Buffer_principal = readShapePoly("C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/02_codes_scenarios/shapefiles_filter/ZB_P160.shp",
force_ring = T, proj4string = utm)
Buffer_tributarios = readShapePoly("C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/02_codes_scenarios/shapefiles_filter/ZB_S20.shp",
force_ring = T, proj4string = utm)
subs1 = readRDS("~/R_projects/SWAT_calibration_ETmodis/shapefiles_RDS/subs1.RDS")
mapview(subs1, alpha.regions=0, legend=F,lwd=1.5, zcol="Subbasin") +
mapview(Buffer_tributarios, color="cyan",col.regions="cyan", legend=T) +
mapview(Buffer_principal, color="blue",col.regions="blue", legend=T)
SWAT modela las zonas buffer (Filter Strip) a través del VFSMOD (Muñoz-Carpena, Parsons, and Gilliam 1999), el cual es un modelo empírico que ha sido parametrizado con información de muchos experimentos de campo.
SWAT modela la zona buffer a nivel de HRU a través de 3 parámetros.
A efectos de simplificar el análisis solamente nos concentraremos en el parámetro FILTER_RATIO. Ya que es el parámetro que relaciona el area del HRU y el area del filtro. En otras palabras, este parámetro define el area del HRU que será utilizada para zona buffer.
Los parámetros FILTER_CON y FILTER_CH pueden afectar la efectividad de la zona buffer, son parámetros que dependen en gran medida del relieve y del drenaje. No serán abordados en este trabajo.
Se consideran 6 anchos de zona buffer tanto para los cauces principales como para los tributarios. Los anchos considerados son 5, 10, 20, 40, 80 y 160 metros.
Estos anchos se pueden aplicar por ejemplo:
Se desarrolló un código en R el cual permite calcular el parámetro FILTER_RATIO y el área de la zona buffer en función de los anchos definidos anteriormente. El código se muestra en el Anexo1: Filter_Ratio y requiere un pre-procesamiento en QGIS.
Los valores de FILTER_RATIO para los distintos escenarios se pueden consultar en la siguiente tabla:
filter_ratio <- readRDS("~/R_projects/SWAT_calibration_ETmodis/02_codes_scenarios/03_filter_ratio.RDS")
colnames(filter_ratio) = c("Sub-cuenca", "Buffer principal (m)", "Buffer Tributario (m)", "area zona buffer (km2)", "FILTER_RATIO")
filter_ratio$`Buffer principal (m)` = as.numeric(paste(filter_ratio$`Buffer principal (m)`))
filter_ratio$`Buffer Tributario (m)` = as.numeric(paste(filter_ratio$`Buffer Tributario (m)`))
filter_ratio$`area zona buffer (km2)` = round(filter_ratio$`area zona buffer (km2)`,2)
filter_ratio$FILTER_RATIO = round(filter_ratio$FILTER_RATIO,2)
datatable(filter_ratio, rownames = FALSE, filter="top", options = list(pageLength = 5, scrollX=T), caption = "Parametrización de FILTER_RATIO" )
La implenetación de las Zonas buffer en SWAT debe hacerse modificando y/o creando los archivos .ops y .sub. Estos archivos no pueden modificarse utilizando la versión actual de SWATplusR. La modificación se puede hacer siguiendo el código que se presenta en Anexo2: Modelación de zona buffer.
A efectos de mostrar un ejemplo de la implementación de las zonas buffer se ejecutó el modelo con:
La siguiente imagen muestra la probabilidad de tener una concentración de fósforo menor a el valor dado en el eje “x”. La linea vertical gris indica el valor de concentración máximo permitido en la norma (0.025 mg/l). Se tiene una probabilidad de ~0.65 de estar en la norma para Paso de los Troncos y en el orden de ~0.05 para Paso Pache. Estos resultados confirman lo que se conoce. Muchos ríos de Uruguay no cumplen con la norma. Igualmente se observa que el buffer de 160 metros no es una solución para que el río cumpla con la norma.
base <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_base.RDS")
P160T160 <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_P160T160.RDS")
P40T20 <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_P40T20.RDS")
# se eliminan los días donde el caudal simulado es cero
base = base[base$FLOW_41!=0 & base$FLOW_23!=0,]
P40T20 = P40T20[P40T20$FLOW_41!=0 & P40T20$FLOW_23!=0,]
P160T160 = P160T160[P160T160$FLOW_41!=0 & P160T160$FLOW_23!=0,]
# Concentración de Fósforo
base$conPT_41 = (1000*base$PT_41)/(base$FLOW_41*60*60*24)
base$conPT_23 = (1000*base$PT_23)/(base$FLOW_23*60*60*24)
P40T20$conPT_41 = (1000*P40T20$PT_41)/(P40T20$FLOW_41*60*60*24)
P40T20$conPT_23 = (1000*P40T20$PT_23)/(P40T20$FLOW_23*60*60*24)
P160T160$conPT_41 = (1000*P160T160$PT_41)/(P160T160$FLOW_41*60*60*24)
P160T160$conPT_23 = (1000*P160T160$PT_23)/(P160T160$FLOW_23*60*60*24)
# funciones de probabilidad acumulada
base_PT41 = ecdf(base$conPT_41)
base_PT23 = ecdf(base$conPT_23)
P40T20_PT41 = ecdf(P40T20$conPT_41)
P40T20_PT23 = ecdf(P40T20$conPT_23)
P160T160_PT41 = ecdf(P160T160$conPT_41)
P160T160_PT23 = ecdf(P160T160$conPT_23)
x = seq(0,2, length.out = 10000)
par(mfrow=c(1,2), mar=c(4,4,1,1))
plot(c(0.01,2), c(0.01,1), type="n", xlab = "Concentración (mg/l)", ylab = "Probabilidad",
log="x", las=1, main = "Paso Pache (41)")
lines(x, base_PT41(x))
lines(x, P40T20_PT41(x), col=2)
lines(x, P160T160_PT41(x), col=4)
abline(v=0.025, col=8, lty=2)
plot(c(0.01,2), c(0.01,1), type="n", xlab = "Concentración (mg/l)", ylab = "Probabilidad",
log="x", las=1, main = "Paso de los Troncos (23)")
lines(x, base_PT23(x))
lines(x, P40T20_PT23(x), col=2)
lines(x, P160T160_PT23(x), col=4)
abline(v=0.025, col=8, lty=2)
legend("bottomright", c("Base", "P40T20", "P160T160"), col=c(1,2,4),lty=1)
rm(list = ls())
library(maptools)
library(raster)
library(rgeos)
utm = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
shp_dir = "C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/SL_level5_mensual_backup/shapefiles/"
sub = readShapePoly(paste0(shp_dir,"subs1.shp"),
proj4string = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))
MontNat = readShapePoly("C:/Users/Rafael Navas/Google Drive/SWAT-SubSantaLucia/2-Input data/2-Uso del suelo/LCCS_shapes/LCCS2015/LCCS2015_MultipartToSinglepa_clip_dissolve.shp",
proj4string = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))
MontNat = MontNat[MontNat$LABE_15=="Monte Nativo",]
gIntersection(sub, MontNat, byid = F)
plot(MontNat,col=2,border=2)
plot(gIntersection(sub, MontNat, byid = FALSE), col=4, border=4, add=T)
FR = data.frame(subassin = c(), ZB_principal_km2 = c(), ZB_tributarios_km2 = c(),
area_ZB_km2 = c(), FILTER_RATIO=c())
for(sb in 12:41){
print(sb)
sub_sub = sub[sub$Subbasin==sb,]
if(sb!=12){
MontNat_sub = gIntersection(MontNat,sub_sub, byid = FALSE, unaryUnion_if_byid_false=F)
}else{
MontNat_sub = 0
}
for(Psize in c("05","10","20","40","80","160")){
for(Ssize in c("05","10","20","40","80","160")){
ZB_P = readShapePoly(paste0(shp_dir, "ZB_P",Psize,".shp"),
proj4string = utm)
ZB_S = readShapePoly(paste0(shp_dir, "ZB_S",Ssize,".shp"),
proj4string = utm)
ZB = gUnion(ZB_P, ZB_S,byid = F)
ZB_sub = gIntersection(sub_sub, ZB, byid = FALSE)
if(sb!=12){
MontNat_ZB = gIntersection(MontNat_sub, ZB_sub, byid = FALSE)
area_MontNat = ifelse(is.null(MontNat_ZB), 0, area(MontNat_ZB))
}else{
area_MontNat = 0
}
area_ZB = (area(ZB_sub) - area_MontNat)/1000000
area_sub = area(sub_sub)/1000000
FILTER_RATIO = area_sub/area_ZB
FR_in = data.frame(subassin = sb, ZB_principal_km2 = Psize, ZB_tributarios_km2 = Ssize,
area_ZB_km2 = area_ZB, FILTER_RATIO=FILTER_RATIO)
FR = rbind(FR,FR_in)
print(FR_in)
}
}
}
saveRDS(FR, "C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/02_codes_scenarios/03_filter_ratio.RDS")
Este código modifica y crea los archivos .ops y .sub para modelar la zona buffer. Se cambian únicamente los usos de suelo GRAS, AGRP, AGRC y LECH (711 HRU cambiados de un total de 865).
rm(list=ls())
library(tibble)
library(SWATplusR)
library(stringi)
library(stringr)
# lectura de parámetros optimizados
par_set = readRDS("./resultados/optim20200401_22/best_par_tibble.RDS")
# Creacion de escenarios
FR = readRDS("./02_codes_scenarios/03_filter_ratio.RDS")
model_path = "./SWAT_SL_20200401/"
runrun_path = "./ModelRun_FilterStrip"
# Cuidado aqui se elimina la carpeta runrun_path!!!!!!!!!!!!!!!!
unlink(runrun_path, recursive = TRUE)
dir.create(runrun_path)
# creacion de un nuevo directorio
R.utils::copyDirectory(from=model_path, to=runrun_path)
#Lectura metadata HRU
hru_info <- readRDS("~/R_projects/SWAT_calibration_ETmodis/shapefiles_RDS/hru_info.RDS")
# Seleccion de HRU a aplicar cambios (FILTER_RATIO)
hru2change = hru_info[hru_info$LANDUSE %in% c("GRAS", "AGRC", "AGRP", "LECH"),]
# Alteracion de parametros del Filter Strip
BufferPrin = "40"
BufferTrib = "20"
FilterRatio2sub = FR[FR$ZB_principal_km2==BufferPrin & FR$ZB_tributarios_km2==BufferTrib,]
hru2change$FilterRatio = FilterRatio2sub$FILTER_RATIO[match(hru2change$Subbasin, FilterRatio2sub$subassin)]
# creacion de archivos .ops
for(i in 1:nrow(hru2change)){
MONTH = 1
DAY = 1
IYEAR = 2009
MGT_OP = 4
FILTER_I = 1
FILTER_RATIO = hru2change$FilterRatio[i]
FILTER_CON = 0.5
FILTER_CH = 0
fs_line = paste0(str_pad(MONTH, 3, pad=" "),
str_pad(DAY, 6-3, pad=" "),
str_pad(IYEAR, 15-6, pad=" "),
str_pad(MGT_OP,18-15, pad = " "),
str_pad(FILTER_I,23-18, pad = " "),
str_pad(round(FILTER_RATIO,2),34-23, pad = " "),
str_pad(round(FILTER_CON,5),47-34, pad = " "),
str_pad(round(FILTER_CH,2),54-47, pad = " "))
ops_file = paste0(hru2change$HRUGIS[i],".ops")
ops_out = rbind(".ops generado en R", fs_line)
write.table(ops_out, file=paste0(runrun_path,"/", ops_file), quote = F, col.names = F,
row.names = F)
}
#Modificacion de archivos .sub
sub_files = list.files(runrun_path, pattern = ".sub", full.names = T)
for(i in 1:length(sub_files)){
sub_file = readLines(sub_files[i])
cc = substr(sub_file,1,9) %in% paste(hru2change$HRUGIS)
substr(sub_file[cc], 66, 78) <- paste0(substr(sub_file[cc],1,10),"ops")
write.table(sub_file, file=sub_files[i], quote = F, col.names = F,
row.names = F)
}
# escenario base
base = run_swat2012(project_path = model_path,
output = list(FLOW = define_output(file = "rch",
variable = "FLOW_OUT",
unit = c(23,41)),
PT = define_output(file = "rch",
variable = "TOT_Pkg",
unit = c(23,41)),
NO3 = define_output(file = "rch",
variable = "NO3_OUT",
unit = c(23,41))),
parameter = par_set[1,],
start_date = as.Date("2009-01-01"),
end_date = as.Date("2015-12-31"),
years_skip = 1,
add_parameter = FALSE,
keep_folder = F)
saveRDS(base, "./resultados/ZonaBuffer_optim22/test01_base.RDS")
# ejecucion del modelo
P40T20 = run_swat2012(project_path = runrun_path,
output = list(FLOW = define_output(file = "rch",
variable = "FLOW_OUT",
unit = c(23,41)),
PT = define_output(file = "rch",
variable = "TOT_Pkg",
unit = c(23,41)),
NO3 = define_output(file = "rch",
variable = "NO3_OUT",
unit = c(23,41))),
parameter = par_set[1,],
start_date = as.Date("2009-01-01"),
end_date = as.Date("2015-12-31"),
years_skip = 1,
add_parameter = FALSE,
keep_folder = F)
saveRDS(P40T20, "./resultados/ZonaBuffer_optim22/test01_P40T20.RDS")
# segunda escenario zona buffer de 160 metros
# Alteracion de parametros del Filter Strip
BufferPrin = "160"
BufferTrib = "160"
FilterRatio2sub = FR[FR$ZB_principal_km2==BufferPrin & FR$ZB_tributarios_km2==BufferTrib,]
hru2change$FilterRatio = FilterRatio2sub$FILTER_RATIO[match(hru2change$Subbasin, FilterRatio2sub$subassin)]
# creacion de archivos .ops
for(i in 1:nrow(hru2change)){
MONTH = 1
DAY = 1
IYEAR = 2009
MGT_OP = 4
FILTER_I = 1
FILTER_RATIO = hru2change$FilterRatio[i]
FILTER_CON = 0.5
FILTER_CH = 0
fs_line = paste0(str_pad(MONTH, 3, pad=" "),
str_pad(DAY, 6-3, pad=" "),
str_pad(IYEAR, 15-6, pad=" "),
str_pad(MGT_OP,18-15, pad = " "),
str_pad(FILTER_I,23-18, pad = " "),
str_pad(round(FILTER_RATIO,2),34-23, pad = " "),
str_pad(round(FILTER_CON,5),47-34, pad = " "),
str_pad(round(FILTER_CH,2),54-47, pad = " "))
ops_file = paste0(hru2change$HRUGIS[i],".ops")
ops_out = rbind(".ops generado en R", fs_line)
write.table(ops_out, file=paste0(runrun_path,"/", ops_file), quote = F, col.names = F,
row.names = F)
}
# ejecucion del modelo
P160T160 = run_swat2012(project_path = runrun_path,
output = list(FLOW = define_output(file = "rch",
variable = "FLOW_OUT",
unit = c(23,41)),
PT = define_output(file = "rch",
variable = "TOT_Pkg",
unit = c(23,41)),
NO3 = define_output(file = "rch",
variable = "NO3_OUT",
unit = c(23,41))),
parameter = par_set[1,],
start_date = as.Date("2009-01-01"),
end_date = as.Date("2015-12-31"),
years_skip = 1,
add_parameter = FALSE,
keep_folder = F)
saveRDS(P160T160, "./resultados/ZonaBuffer_optim22/test01_P160T160.RDS")
Muñoz-Carpena, Rafael, John E. Parsons, and J.Wendell Gilliam. 1999. “Modeling Hydrology and Sediment Transport in Vegetative Filter Strips.” Journal of Hydrology 214 (1-4): 111–29. https://doi.org/10.1016/S0022-1694(98)00272-8.
A work by Rafael Navas