Texas A&M University
Department of Civil Engineering
Instructor: Dr. Francisco Olivera
CVEN689 Applications of GIS to Civil Engineering
Development of SWAT add-ons to calculate HRU parameters for the BASINS project
Huidae Cho
May 3, 2004

Contents

   1   Introduction
   2   SWAT Preprocessor
   3   Methodology
   4   Application
   5   Conclusions
   A   Sources
   A.1   preSWAT.ave
   A.2   swatLoads.ave
   References

Abstract
SWAT is a physically based distributed hydrologic model. It was designed to assess the impact of changes of land characteristics such as land uses and soil classes and has been validated for many years. BASINS is a GIS preprocessor for hydrologic models including HSPF, P-LOAD, and QUAL2E as well as SWAT. Mostly BASINS allows the user to input readily available data from the web and then calculates other required physical parameters for the model. However, BASINS computes these physical parameters only for each subbasin although the smallest subunit of the SWAT watershed model is the Hydrologic Response Unit (HRU). For this reason, the user should calculate parameters and modify many input files manually outside the interface for better results. It is obviously a time consuming and cumbersome process for the user. preSWAT has been developed to automate calculation of parameters per HRU. The current version of BASINS runs on ArcView 3.2 and thus preSWAT has been developed using the Avenue language to be incorporated into the BASINS/SWAT project. Finally, swatLoad summarizes precipitation, runoff flow, sediment loads, nitrogen loads, and phosphorous loads per each land use to easily assess the impact of land use changes. Despite all these efforts, it may be still hopeful in long term for BASINS to compute physical parameters for the smallest subunit in each hydrologic model embedded in it.

1   Introduction  

This project mainly describes how to calculate hydrologic parameters from various geographic data in GIS. Of many hydrologic models, SWAT is chosen because there is a preprocessor for SWAT called BASINS whose Avenue sources are available in the ArcView extension format. BASINS supports many different hydrologic models like HSPF, P-LOAD, QUAL2E, and SWAT; and there are many common procedures for the models. For this reason, some features are not fully implemented for a specific model input. One thing to take into account is that SWAT requires geographic parameters of HRU while BASINS generates only subbasin based parameter input.

The HRU parameters are important to assess the impact of changes of land uses and soil classes, so these input cannot be carelessly lumped to geographic parameters of subbasins which are much different from those of HRUs. The HRU is an intersection of a land use and a soil class within a certain subbasin, so each HRU has a unique combination of subbasin, land use, and soil class. Due to this characteristics of HRU, improving the default input of the BASINS interface that are subbasin-based parameters would be helpful to get better results from SWAT execution and, hopefully, it would save much time to update each .HRU file manually.

2   SWAT Preprocessor  

Since SWAT was introduced, there have been more than one preprocessor developed in order to interface between the model and GIS. SWAT for Windows 98 is a stand-alone interface running on MS-Windows 98/NT for easy development of the SWAT input. SWAT/GRASS is the GRASS GIS interface and ArcView SWAT is the ArcView GIS extension which is now available from the BASINS/SWAT module.

These interfaces are mainly consist of the following components [DiLuzio:2000]:

Watershed Delineation
allows the user to delineate the watershed and to add point discharge sources, reservoirs, and so on.
Land Use and Soil Definition
defines HRUs by specifying thresholds of the land use and the soil.
Editing of the Model Databases
can be used to edit or update the model databases that contain parameters about plant growth, tillage, fertilizers, pesticide, and urban.
Definition of the Weather Stations
adds weather station data.
Input Parameterization and Editing
allows the user to view and edit input data using the edit dialog.
Model Run
executes the SWAT executable.
Read and Map-Chart Results
displays results.
Calibration Tool
provides an interactive tool for easy calibration.

As mentioned above, these interfaces do not deal with HRU parameters, so this project focuses on development of a tool to calculate HRU parameters and to update input data before running SWAT in the BASINS project.

3   Methodology  

preSWAT and swatLoads are programmed in the Avenue language because BASINS itself is an Avenue extension for ArcView 3.x and stable compared to newly developed ArcGIS-SWAT running on ArcGIS 8.x that is still under test.

preSWAT has been developed to recalcuate slopes, slope lengths, and curve numbers for each HRU and to update tables and input files that are created by BASINS modules. This module requires the following themes created by BASINS:

These theme names are not supposed to be changed by the user so that preSWAT can automatically find required themes without user interaction. Another data required is a runoff curve number lookup table that is used to estimate curve numbers. Its format is as follows:
header line
lucode, landuse, detail, curve number for hydro group A (hyd_a), B (hyd_b), C(hyd_c), and D (hyd_d), unused field
repeat
...
Table 1. Format of the runoff curve number lookup table

Only lucode, hyd_a, hyd_b, hyd_c, and hyd_d fields are used and lucode should coincide with the SWAT land use code:
lucode abbreviation description
11 WATR Water
21 URML Urban Medium Density
22 URHD Urban High Density
23 UCOM Urban Commercial
24 UINS Urban Institutional
25 UIDU Urban Industrial
26 UTRN Urban Transportation
31 SWRN South Western Range + Bare Rock
32 SWRN South Western Range + Quarries/Mines
33 SWRN South Western Range
41 FRSD Deciduous Forest
42 FRSE Evergreen Forest
43 FRST Mixed Forest
51 RNGB Range Shrubland
61 ORCD Orchards/Vineyard
71 RNGE Grasslands/Herbaceous
81 PAST Pasture/Hay
82 AGRR Row Crops
83 AGRC Small Grains
85 AGRL Fallow
91 WETF Woody Wetlands
92 WETN Emergent/Herbaceous Wetlands
Table 2. SWAT land use code

Swat-Sol, Swat-Hru, Soil Component Data, Swat-Mgt1, and Swat-Mgt2 tables are also needed to create and manipulate an HRU grid and to populate input databases. These tables are supposed to be generated by the BASINS project before running preSWAT.

Slopes are calculated using the slope and zonal statistics functions in the Avenue objects and averaged over HRUs. Slope lengths are redefined like the following:
slope slope length
< 0.02 400 / 3.28
~ 0.05 300 / 3.28
~ 0.10 200 / 3.28
~ 0.12 120 / 3.28
~ 0.16 80 / 3.28
~ 20.0 60 / 3.28
~ 25.0 50 / 3.28
> 25.0 30 / 3.28
Table 3. Slope and slope length
This classification is based on the source code of the Automatic Delineation menu in BASINS.

Curve numbers are computed using the Soil Component Data and the runoff curve number lookup tables [Olivera:2001]:
CN = pct_a * hyd_a + pct_b * hyd_b + pct_c * hyd_c + pct_d * hyd_d + pct_w * hyd_w(1)
where CN is a curve number; pct_a, pct_b, pct_c, pct_d, and pct_w are fractions of soil A, B, C, D, and water respectively; hyd_a, hyd_b, hyd_c, and hyd_d are curve numbers; and hyd_w is 99 that is a curve number for water.

The curve number of 99 for water is chosen instead of 100 to avoid the domain error of some equations in the SWAT procedures.

4   Application  

The Lake Lewisville watershed is simulated with BASINS/SWAT and its HRU parameters are updated using preSWAT before SWAT executes. All the necessary data to run the SWAT model is easily obtained through BASINS tools like Web Extraction Tool and Data Extraction. Lake Lewisville is a part of the Trinity River basin which is shown in Fig.1.
Figure 1. The Lake Lewisville watershed in the Trinity River basin

BASINS extracts various data from the web. Of these data, the followings are used in this project:

Besides BASINS data extracted by the tools, the DEM and the land use grids are prepared and the NHD stream shapefile is used to burn-in streams as shown in Figs.2 and 3. To delineate the watershed, the inlet from upstream draining area and the outlet from the study area have to be added manually (Fig.3).

Figure 2. Automatic delineation

Figure 3. Land use

Once the watershed is delineated, the land use and the soil are overlaied onto the subbasins to determine HRUs. However, BASINS does not make any HRU related grid and only .HRU files are created using subbasin parameters. At this point, preSWAT is used to generate the HRU grid and update the input files (Figs.4, 5, and 6).

Figure 4. Soil class and preSWAT menu

Figure 5. Calculate HRU parameters

preSWAT requires two tables: runoff curve number (Fig.7) and soil component (Fig.8). These two tables are main factors to estimate HRU curve numbers (Eq.1).

Figure 6. Choose runoff curve number lookup table

Figure 7. Runoff curve number lookup table

Figure 8. Soil component data

Using preSWAT, the HRU grid is created (Fig.9) and its attributes table is calculated per HRU (Fig.10).

Figure 9. HRU

Figure 10. HRU attributes table

swatLoads summarizes the output of SWAT and the two results are compared in Fig.11. The four plots show that the result from HRU parameters is very similar to that of subbasin parameters to some extent.

Figure 11. Comparison of the two results

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
AGRC AGRL AGRR FRSD FRSE FRST PAST RNGB RNGE SWRN UCOM URHD URML WATR WETF WETN
Table 4. Landuse legend of Fig.11

Unfortunately, in this application, there is no real data available and the model itself is simplified due to lack of input data, so it is somewhat difficult to say which one is better. However, as shown in Fig.11, the default BASINS model (subbasin parameters) underestimates loads compared to the HRU result. It may be because geographic parameters are lumped to those of subbasins in the default model, so it loses some data precision and the result can be more averagely spreaded than the result of HRU parameters.

5   Conclusions  

For this project, preSWAT and swatLoads have been developed in order to generate HRU input files for the SWAT model and to summarize the output for each land use. By comparing the result with the default BASINS model which is based on subbasins, its loads are acceptably computed within reasonable ranges and it reflects geographic variety of each HRU better than the subbasin based model. Further, preSWAT reduces time and efforts required to update parameters and input files for those who want to model their watershed more exactly.

Although preSWAT can be incorporated into the BASINS project, it would be much helpful if the BASINS/SWAT module implements the feature of preSWAT and the calculation is done at one time in the consistent interface.

A   Sources  

A.1   preSWAT.ave  

preSWAT.ave

' preSWAT: Preprocessor for BASINS/SWAT
'          updates slope, slope length, and curve number for each HRU.
'  Author: Huidae Cho <geni4u@yahoo.com>
'   Since: Feb. 19, 2004
' $Id: preSWAT.ave,v 1.3 2004/03/17 21:07:22 geni Exp $

theProject = av.getproject
theView = theProject.finddoc("SWAT View")
if (theView = nil) then
  msgbox.error("SWAT View doesn't exist.", "Error")
  exit
end
theThemes = theView.getthemes

action = msgbox.listasstring({"Generate HRU info", "Change CN2 by percent"},
  "Select an action.", "Action")

if (action = nil) then
  exit
elseif (action = "Change CN2 by percent") then
  percent = msgbox.input("CN2 * % (current CN2 = 100%)?",
    "Change CN2 by percent", "")
  if (percent = nil) then exit end
  percent = percent.asnumber
  if (percent <= 0) then exit end

  swatVtab = theProject.finddoc("Swat-Mgt1").getvtab
  swatVtab.seteditable(true)
  swatSbField = swatVtab.findfield("Subbasin")
  swatLuField = swatVtab.findfield("Landuse")
  swatSoField = swatVtab.findfield("Soil")
  swatCnField = swatVtab.findfield("Cn2")
  for each i in swatVtab
    cn2 = swatVtab.returnvalue(swatCnField, i) * (percent / 100)
'    if (cn2 <= 0) then cn2 = 1 end
'    if (cn2 >= 100) then cn2 = 99 end
    swatVtab.setvalue(swatCnField, i, cn2)
  end
  swatVtab.seteditable(false)
  swatHrField = swatVtab.findfield("Hru")
  swatStField = swatVtab.findfield("Strec2")
  swatEnField = swatVtab.findfield("Endrec2")
  swatVtab2 = theProject.finddoc("Swat-Mgt2").getvtab
  for each i in swatVtab
    l = list.make
    s = swatVtab.returnvalue(swatStField, i)
    e = swatVtab.returnvalue(swatEnField, i)
    for each j in s..e
      l.add(j)
    end
    av.run("Swat1_PrintMgt", {swatVtab.returnvalue(swatSbField, i),
      swatVtab.returnvalue(swatHrField, i),
      swatVtab.returnvalue(swatLuField, i),
      swatVtab.returnvalue(swatSoField, i), swatVtab, swatVtab2, i, l})
    l.empty
  end
  
  system.beep
  msgbox.info("Finished preSWAT!", "preSWAT")
  exit
end

' Choose subbasin, landuse, and soil themes.
subbasin = theView.findtheme("Subbasins")
landuse = theView.findtheme("SwatLandUseClass")
soil = theView.findtheme("SoilClass")
dem = theView.findtheme("Dem")

myList = list.make

if (subbasin = nil) then
  ' Get a list of feature themes.
  for each i in theThemes
    if (i.is(FTHEME)) then myList.add(i) end
  end
  subbasin = msgbox.choice(myList, "Choose a subbasin feature.",
    "Subbasin feature")
end
if (subbasin = nil) then exit end

if ((landuse = nil) or (soil = nil) or (dem = nil)) then
  myList.empty
  ' Get a list of grid themes.
  for each i in theThemes
    if (i.is(GTHEME)) then myList.add(i) end
  end
end

if (landuse = nil) then
  landuse = msgbox.choice(myList, "Choose a landuse grid.", "Landuse grid")
end
if (landuse = nil) then exit end
landuseGrid = landuse.getgrid

if (soil = nil) then
  soil = msgbox.choice(myList, "Choose a soil grid.", "Soil grid")
end
if (soil = nil) then exit end
soilGrid = soil.getgrid

if (dem = nil) then
  ' Choose a DEM grid.
  dem = msgbox.choice(myList, "Choose a DEM grid.", "DEM grid")
end
if (dem = nil) then exit end

myList.empty

' Choose a rcn lookup tables.
rcnLookupFile = filedialog.show("*.txt", "Text",
  "Runoff curve number lookup table")
if (rcnLookupFile = nil) then exit end

' Get analysis environment.
cellsize = landuseGrid.getcellsize
extent = landuseGrid.getextent

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Commented out because it's useless after Write Soil Data.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Update hydgrp for water in the Swat-Sol table.
''av.showmsg("Updating SOL parameters...")
''dbfFile = "$BASINSSWATOUT/tablesin/sol.dbf".asfilename.getfullname.asfilename
''swatVtab = vtab.make(dbfFile, false, false)
'swatVtab = theProject.finddoc("Swat-Sol").getvtab
'swatVtab.seteditable(true)
'swatHgField = swatVtab.findfield("Hydgrp")
'for each i in swatVtab
'  if (swatVtab.returnvalue(swatHgField, i) = "") then
'    swatVtab.setvalue(swatHgField, i, "D")
'  end
'end
'swatVtab.seteditable(false)
'for each i in swatVtab
'  av.run("Swat1_PrintSol", {i, swatVtab})
'end

' Create a subbasin grid.
oldTheme = theView.findtheme("Subbasin")
if (oldTheme <> nil) then
  theView.deletetheme(oldTheme)
end
subbasinFtab = subbasin.getftab
subbasinGrid = grid.makefromftab(subbasinFtab, theView.getprojection,
  subbasinFtab.findfield("Subbasin"), {cellsize, extent})
subbasin = gtheme.make(subbasinGrid)
subbasin.setname("Subbasin")
theView.addtheme(subbasin)
subbasin.setvisible(true)

' Create a slope grid.
oldTheme = theView.findtheme("Slope")
if (oldTheme <> nil) then
  theView.deletetheme(oldTheme)
end
slopeGrid = dem.getgrid.extractbymask(subbasinGrid).slope(nil, true)/100
slope = gtheme.make(slopeGrid)
slope.setname("Slope")
theView.addtheme(slope)
slope.setvisible(true)

' Create an hru grid.
oldTheme = theView.findtheme("HRU")
if (oldTheme <> nil) then
  theView.deletetheme(oldTheme)
end
hruGrid = subbasinGrid.combine({landuseGrid, soilGrid})
hru = gtheme.make(hruGrid)
hru.setname("HRU")
theView.addtheme(hru)
hru.setvisible(true)

' Add a slope and a curve number fields to the hru table.
hruVtab = hru.getvtab
hruVtab.seteditable(true)
hruVtab.addfields({
  field.make("Subbasin", #FIELD_SHORT, 2, 0),
  field.make("Landuse", #FIELD_CHAR, 4, 0),
  field.make("Soil", #FIELD_CHAR, 5, 0),
  field.make("Slope", #FIELD_FLOAT, 10, 5),
  field.make("Slsubbsn", #FIELD_FLOAT, 10, 5),
  field.make("CurveNumber", #FIELD_FLOAT, 10, 5)
})

' Populate the subbasin field of the hru table.
hruField = hruVtab.findfield("Subbasin")
aField = hruVtab.findfield(subbasinGrid.getsrcname.asstring)
for each i in 0..(hruVtab.getnumrecords-1)
  hruVtab.setvalue(hruField, i, hruVtab.returnvalue(aField, i))
end

' Populate the landuse field of the hru table.
aDic = dictionary.make(200)
aDic.add(11, "WATR")
aDic.add(21, "URML")
aDic.add(22, "URHD")
aDic.add(23, "UCOM")
aDic.add(24, "UINS")
aDic.add(25, "UIDU")
aDic.add(26, "UTRN")
aDic.add(31, "SWRN")
aDic.add(32, "SWRN")
aDic.add(33, "SWRN")
aDic.add(41, "FRSD")
aDic.add(42, "FRSE")
aDic.add(43, "FRST")
aDic.add(51, "RNGB")
aDic.add(61, "ORCD")
aDic.add(71, "RNGE")
aDic.add(81, "PAST")
aDic.add(82, "AGRC")
aDic.add(83, "AGRL")
aDic.add(85, "AGRR")
aDic.add(91, "WETF")
aDic.add(92, "WETN")

hruField = hruVtab.findfield("Landuse")
aField = hruVtab.findfield(landuseGrid.getsrcname.asstring)
for each i in hruVtab
  hruVtab.setvalue(hruField, i, aDic.get(hruVtab.returnvalue(aField, i)))
end
aDic.empty

' Populate the soil field of the hru table.
aDic = dictionary.make(200)
aDic.add("01", "AL")
aDic.add("02", "AK")
aDic.add("04", "AZ")
aDic.add("05", "AR")
aDic.add("06", "CA")
aDic.add("08", "CO")
aDic.add("09", "CT")
aDic.add("10", "DE")
aDic.add("11", "DC")
aDic.add("12", "FL")
aDic.add("13", "GA")
aDic.add("16", "ID")
aDic.add("17", "IL")
aDic.add("18", "IN")
aDic.add("19", "IA")
aDic.add("20", "KS")
aDic.add("21", "KY")
aDic.add("22", "LA")
aDic.add("23", "ME")
aDic.add("24", "MD")
aDic.add("25", "MA")
aDic.add("26", "MI")
aDic.add("27", "MN")
aDic.add("28", "MS")
aDic.add("29", "MO")
aDic.add("30", "MT")
aDic.add("31", "NE")
aDic.add("32", "NV")
aDic.add("33", "NH")
aDic.add("34", "NJ")
aDic.add("35", "NM")
aDic.add("36", "NY")
aDic.add("37", "NC")
aDic.add("38", "ND")
aDic.add("39", "OH")
aDic.add("40", "OK")
aDic.add("41", "OR")
aDic.add("42", "PA")
aDic.add("44", "RI")
aDic.add("45", "SC")
aDic.add("46", "SD")
aDic.add("47", "TN")
aDic.add("48", "TX")
aDic.add("49", "UT")
aDic.add("50", "VT")
aDic.add("51", "VA")
aDic.add("53", "WA")
aDic.add("54", "WV")
aDic.add("55", "WI")
aDic.add("56", "WY")
aDic.add("60", "AS")
aDic.add("64", "FM")
aDic.add("66", "GU")
aDic.add("68", "MH")
aDic.add("69", "MP")
aDic.add("70", "PW")
aDic.add("72", "PR")
aDic.add("74", "UM")
aDic.add("78", "VI")

mDic = dictionary.make(200)
bDic = dictionary.make(200)
soilVtab = soil.getvtab
aField = soilVtab.findfield("Value")
stField = soilVtab.findfield("Stmuid")
for each i in soilVtab
  stmuid = soilVtab.returnvalue(stField, i)
  muid = aDic.get(stmuid.left(2)) + stmuid.middle(2,3)
  mDic.add(stmuid, muid)
  bDic.add(soilVtab.returnvalue(aField, i), muid)
end
aDic.empty

hruField = hruVtab.findfield("Soil")
aField = hruVtab.findfield(soilGrid.getsrcname.asstring)
for each i in hruVtab
  hruVtab.setvalue(hruField, i, bDic.get(hruVtab.returnvalue(aField, i)))
end
bDic.empty

' Calculate mean slopes for hru's.
aFile = theProject.getworkdir.maketmp("hru_slope", "dbf")
aVtab = slopeGrid.zonalstatstable(hruGrid, theView.getprojection,
  hruVtab.findfield("Value"), false, aFile)

' Populate the slope and slsubbsn fields of the hru table.
hruSlField = hruVtab.findfield("Slope")
hruSsField = hruVtab.findfield("Slsubbsn")
aField = aVtab.findfield("Mean")
for each i in aVtab
  s = aVtab.returnvalue(aField, i)
  hruVtab.setvalue(hruSlField, i, s)

  ' from BASINS/etc/extensions/delineate/b3wd_autodelin.avx
  if (s < 0.02) then
    sl = 400 / 3.28
  elseif (s < 0.05) then
    sl = 300 / 3.28
  elseif (s < 0.10) then
    sl = 200 / 3.28
  elseif (s < 0.12) then
    sl = 120 / 3.28
  elseif (s < 0.16) then
    sl = 80 / 3.28
  elseif (s < 20.0) then
    sl = 60 / 3.28
  elseif (s < 25.0) then
    sl = 50 / 3.28
  else
    sl = 30 / 3.28
  end
  hruVtab.setvalue(hruSsField, i, sl)
end

' Remove unnecessary fields.
hruVtab.removefields({
  hruVtab.findfield(subbasinGrid.getsrcname.asstring),
  hruVtab.findfield(landuseGrid.getsrcname.asstring),
  hruVtab.findfield(soilGrid.getsrcname.asstring)
})

' Update the Swat-Hru table.
'av.showmsg("Updating HRU parameters...")
aDic = dictionary.make(200)
bDic = dictionary.make(200)
hruSbField = hruVtab.findfield("Subbasin")
hruLuField = hruVtab.findfield("Landuse")
hruSoField = hruVtab.findfield("Soil")
hruSlField = hruVtab.findfield("Slope")
hruSsField = hruVtab.findfield("Slsubbsn")
for each i in hruVtab
  hruStr = hruVtab.returnvalue(hruSbField, i).asstring + "-" +
    hruVtab.returnvalue(hruLuField, i) + "-" +
    hruVtab.returnvalue(hruSoField, i)
  aDic.add(hruStr, hruVtab.returnvalue(hruSlField, i))
  bDic.add(hruStr, hruVtab.returnvalue(hruSsField, i))
end

'dbfFile = "$BASINSSWATOUT/tablesin/hru.dbf".asfilename.getfullname.asfilename
'swatVtab = vtab.make(dbfFile, false, false)
swatVtab = theProject.finddoc("Swat-Hru").getvtab
swatVtab.seteditable(true)
swatSbField = swatVtab.findfield("Subbasin")
swatLuField = swatVtab.findfield("Landuse")
swatSoField = swatVtab.findfield("Soil")
swatSsField = swatVtab.findfield("Slsubbsn")
swatSlField = swatVtab.findfield("Slope")
for each i in swatVtab
  hruStr = swatVtab.returnvalue(swatSbField, i).asstring + "-" +
      swatVtab.returnvalue(swatLuField, i) + "-" +
      swatVtab.returnvalue(swatSoField, i)
  swatVtab.setvalue(swatSsField, i, bDic.get(hruStr))
  swatVtab.setvalue(swatSlField, i, aDic.get(hruStr))
end
swatVtab.seteditable(false)
aDic.empty
bDic.empty
for each i in swatVtab
  av.run("Swat1_PrintHru", {i, swatVtab})
end

' Create a rcn dictionary.
aVtab = vtab.make(rcnLookupFile, false, false)
lField = aVtab.getfields.get(1)
aField = aVtab.getfields.get(3)
bField = aVtab.getfields.get(4)
cField = aVtab.getfields.get(5)
dField = aVtab.getfields.get(6)
rcnDic = dictionary.make(200)
for each i in aVtab
  rcnDic.add(aVtab.returnvalue(lField, i).left(4),
    {aVtab.returnvalue(aField, i), aVtab.returnvalue(bField, i),
     aVtab.returnvalue(cField ,i), aVtab.returnvalue(dField, i), 99})
end

' Create a soil component percentage dictionary.
compLookupVtab = theProject.finddoc("Soil Component Data").getvtab
cmuidField = compLookupVtab.findfield("Muid")
chgrpField = compLookupVtab.findfield("Hydgrp")
ccpctField = compLookupVtab.findfield("Comppct")
cnameField = compLookupVtab.findfield("Compname")

compBit = compLookupVtab.getselection
compDic = dictionary.make(200)

for each i in soilVtab
  muid = mDic.get(soilVtab.returnvalue(stField, i))
  compLookupVtab.query("[Muid] = """ + muid + """", compBit, #VTAB_SELTYPE_NEW)

  pctA = 0
  pctB = 0
  pctC = 0
  pctD = 0
  pctW = 0

  for each j in compLookupVtab.getselection
    hgrp = compLookupVtab.returnvalue(chgrpField, j)
    cpct = compLookupVtab.returnvalue(ccpctField, j).asnumber
    name = compLookupVtab.returnvalue(cnameField, j)
    if (name = "WATER") then
      pctW = pctW + cpct
    else
      if (hgrp = "A") then
        pctA = pctA + cpct
      elseif (hgrp = "B") then
        pctB = pctB + cpct
      elseif (hgrp = "C") then
        pctC = pctC + cpct
      elseif ((hgrp = "D") or (hgrp.count > 1)) then
        pctD = pctD + cpct
      end
    end
  end

  compDic.add(muid, {pctA, pctB, pctC, pctD, pctW})
end
compBit.clearall
mDic.empty

' Populate the curve number field of the hru table.
hruField = hruVtab.findfield("CurveNumber")
for each i in hruVtab
  rcn = rcnDic.get(hruVtab.returnvalue(hruLuField, i))
  comp = compDic.get(hruVtab.returnvalue(hruSoField, i))
  num = 0
  denom = 0
  for each j in 0..4
    r = rcn.get(j)
    c = comp.get(j)
    num = num + (r * c)
    denom = denom + c
  end
  hruVtab.setvalue(hruField, i, num/denom)
end
hruVtab.seteditable(false)
rcnDic.empty
compDic.empty

' Update the Swat-Mgt1 table.
'av.showmsg("Updating MGT parameters...")
aDic = dictionary.make(200)
hruSbField = hruVtab.findfield("Subbasin")
hruLuField = hruVtab.findfield("Landuse")
hruSoField = hruVtab.findfield("Soil")
hruCnField = hruVtab.findfield("CurveNumber")
for each i in hruVtab
  aDic.add(hruVtab.returnvalue(hruSbField, i).asstring + "-" +
    hruVtab.returnvalue(hruLuField, i) + "-" +
    hruVtab.returnvalue(hruSoField, i), hruVtab.returnvalue(hruCnField, i))
end

'dbfFile = "$BASINSSWATOUT/tablesin/mgt1.dbf".asfilename.getfullname.asfilename
'swatVtab = vtab.make(dbfFile, false, false)
swatVtab = theProject.finddoc("Swat-Mgt1").getvtab
swatVtab.seteditable(true)
swatSbField = swatVtab.findfield("Subbasin")
swatLuField = swatVtab.findfield("Landuse")
swatSoField = swatVtab.findfield("Soil")
swatCnField = swatVtab.findfield("Cn2")
for each i in swatVtab
  swatVtab.setvalue(swatCnField, i,
    aDic.get(swatVtab.returnvalue(swatSbField, i).asstring + "-" +
      swatVtab.returnvalue(swatLuField, i) + "-" +
      swatVtab.returnvalue(swatSoField, i)))
end
swatVtab.seteditable(false)
aDic.empty
swatHrField = swatVtab.findfield("Hru")
swatStField = swatVtab.findfield("Strec2")
swatEnField = swatVtab.findfield("Endrec2")
swatVtab2 = theProject.finddoc("Swat-Mgt2").getvtab
for each i in swatVtab
  l = list.make
  s = swatVtab.returnvalue(swatStField, i)
  e = swatVtab.returnvalue(swatEnField, i)
  for each j in s..e
    l.add(j)
  end
  av.run("Swat1_PrintMgt", {swatVtab.returnvalue(swatSbField, i),
    swatVtab.returnvalue(swatHrField, i), swatVtab.returnvalue(swatLuField, i),
    swatVtab.returnvalue(swatSoField, i), swatVtab, swatVtab2, i, l})
  l.empty
end

system.beep
msgbox.info("Finished preSWAT!", "preSWAT")

A.2   swatLoads.ave  

swatLoads.ave

' swatLoads: Sediment, N, and P loads summarizer for the lake Lewisville Project
'    Author: Huidae Cho
'     Since: Feb. 19, 2004
' $Id: swatLoads.ave,v 1.2 2004/03/17 21:07:22 geni Exp $

theProject = av.getproject
theView = theProject.finddoc("SWAT View")
if (theView = nil) then
  msgbox.error("SWAT View doesn't exist.", "Error")
  exit
end
theThemes = theView.getthemes

lu = theView.findtheme("SwatLandUseClass")
if (lu = nil) then
  myList = list.make
  for each i in theThemes
    if (i.is(GTHEME)) then myList.add(i) end
  end
  lu = msgbox.choice(myList, "Choose a landuse grid.", "Landuse grid")
  myList.empty
end
if (lu = nil) then exit end

stblYear = msgbox.input("How many years for stabilization?", "Stabilization",
  "2")
if (stblYear = nil) then exit end
stblYear = stblYear.asnumber
if (stblYear < 0) then exit end

loadsFile = filedialog.put("loads.dbf".asfilename, "*.dbf", "Loads file")
if (loadsFile = nil) then exit end

luVtab = lu.getvtab
luField = luVtab.findfield("LandUseSwat")

sbsVtab = theProject.finddoc("Swat-Sbs").getvtab
areaField = sbsVtab.findfield("Area")
precipField = sbsVtab.findfield("Precip")
surqField = sbsVtab.findfield("Surq")
syldField = sbsVtab.findfield("Syld")
orgnField = sbsVtab.findfield("Orgn")
nsurqField = sbsVtab.findfield("Nsurq")
nlatqField = sbsVtab.findfield("Nlatq")
no3lField = sbsVtab.findfield("NO3l")
no3gwField = sbsVtab.findfield("NO3gw")
orgpField = sbsVtab.findfield("Orgp")
sedpField = sbsVtab.findfield("Sedp")
solpField = sbsVtab.findfield("Solp")
p_gwField = sbsVtab.findfield("P_Gw")

loadsVtab = vtab.makenew(loadsFile, dBASE)
loadsVtab.addfields({
  field.make("Landuse", #FIELD_CHAR, 4, 0),
  field.make("Area", #FIELD_FLOAT, 7, 2),
  field.make("Prec", #FIELD_FLOAT, 7, 2),
  field.make("Flow", #FIELD_FLOAT, 7, 2),
  field.make("Sedi", #FIELD_FLOAT, 7, 2),
  field.make("N", #FIELD_FLOAT, 7, 2),
  field.make("P", #FIELD_FLOAT, 7, 2)
})
lLuField = loadsVtab.findfield("Landuse")
lArField = loadsVtab.findfield("Area")
lPrField = loadsVtab.findfield("Prec")
lFlField = loadsVtab.findfield("Flow")
lSeField = loadsVtab.findfield("Sedi")
lNField = loadsVtab.findfield("N")
lPField = loadsVtab.findfield("P")

aBit = sbsVtab.getselection

' years for stabilization
aField = sbsVtab.findfield("Date")
firstYear = sbsVtab.returnvalue(aField, 0).asnumber + stblYear
sbsVtab.query("([Date] <> ""Aver"")", aBit, #VTAB_SELTYPE_NEW)
nYears = sbsVtab.returnvalue(aField, sbsVtab.getnumselrecords-1).asnumber -
  firstYear + 1
firstYear = firstYear.asstring

onceSWRN = false

for each i in luVtab
  lu = luVtab.returnvalue(luField, i)
  if (lu = "SWRN") then
    if (onceSWRN) then
      continue
    end
    onceSWRN = true
  end
  sbsVtab.query("([Date] <> ""Aver"") and ([Date] >= """+firstYear+""") and" +
    "([Landuse] = """+lu+""")", aBit, #VTAB_SELTYPE_NEW)
  luArea = 0
  luPrec = 0
  luFlow = 0
  luSedi = 0
  luN = 0
  luP = 0
  for each j in sbsVtab.getselection
    area = sbsVtab.returnvalue(areaField, j)
    precip = sbsVtab.returnvalue(precipField, j)
    surq = sbsVtab.returnvalue(surqField, j)
    syld = sbsVtab.returnvalue(syldField, j)
    orgn = sbsVtab.returnvalue(orgnField, j)
    nsurq = sbsVtab.returnvalue(nsurqField, j)
    nlatq = sbsVtab.returnvalue(nlatqField, j)
    no3l = sbsVtab.returnvalue(no3lField, j)
    no3gw = sbsVtab.returnvalue(no3gwField, j)
    orgp = sbsVtab.returnvalue(orgpField, j)
    sedp = sbsVtab.returnvalue(sedpField, j)
    solp = sbsVtab.returnvalue(solpField, j)
    p_gw = sbsVtab.returnvalue(p_gwField, j)

    luArea = luArea + area
    luPrec = luPrec + (precip * area)
    luFlow = luFlow + (surq * area)
    ' ?/ha * 100ha/km^2 = ?/km^2
    luSedi = luSedi + (syld * area * 100)
    luN = luN + ((orgn + nsurq + nlatq + no3l + no3gw) * area * 100)
    luP = luP + ((orgp + sedp + solp + p_gw) * area * 100)
  end
  if (luArea <= 0) then
    continue
  end
 
  luPrec = luPrec / luArea
  luFlow = luFlow / luArea
  luSedi = luSedi / luArea
  luN = luN / luArea
  luP = luP / luArea
  luArea = luArea / nYears

  k = loadsVtab.addrecord
  loadsVtab.setvalue(lLuField, k, lu)
  loadsVtab.setvalue(lArField, k, luArea)
  loadsVtab.setvalue(lPrField, k, luPrec)
  loadsVtab.setvalue(lFlField, k, luFlow)
  loadsVtab.setvalue(lSeField, k, luSedi)
  loadsVtab.setvalue(lNField, k, luN)
  loadsVtab.setvalue(lPField, k, luP)
end
aBit.clearall
loadsVtab.seteditable(false)

system.beep
msgbox.info("Finished swatLoads!", "swatLoads")

References  

[DiLuzio:2000]   M. Di Luzio, R. Srinivasan, and J.G. Arnold. AVSWAT: An ArcView GIS Extension as a Tool for the Watershed Control of Point and Non-Point Sources. In Proceedings of 2000 ESRI International User Conference. June 26-30, 2000. San Diego.

[Olivera:2001]   F. Olivera. Soils and Land Use. http://ceprofs.tamu.edu/folivera/GIS-CE/Exercises/SoilsAndLandUse/WebFiles/landsoil.htm. November 2001.