Sunday, December 29, 2024

SWMM5 Delphi GUI Dpattern.pas Summary

 Below is an overview of Dpattern.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TPatternForm) to create or edit time patterns in SWMM. These time patterns (monthly, daily, or hourly) are typically used to modify inflow or pollutant concentrations on a varying schedule.


1. Purpose and Context

SWMM supports time patterns to represent how certain parameters (e.g., DWF inflow, treatment removal efficiencies, etc.) vary over months, days, or hours. The TPatternForm dialog lets users enter the name and type of a pattern and specify its multiplier values in a grid. These multipliers scale a base value by a time-dependent factor.

A time pattern has:

  • Pattern Type:

    1. Monthly (12 multipliers, one per month)
    2. Daily (7 multipliers, one per day of week)
    3. Hourly (24 multipliers, one per hour of the day)
  • Name: A unique identifier for the pattern.

  • Comment: An optional description (e.g., “Summer irrigation pattern”).


2. Main Form: TPatternForm

2.1 Visual Components

  1. NameEdit (TNumEdit): A field to set or edit the pattern's ID/name.
  2. CommentEdit (TEdit): A single-line text field for an optional comment/description.
  3. PatternTypeCombo (TComboBox): A dropdown to pick the pattern type (Monthly, Daily, Hourly).
  4. GridEdit1 (TGridEditFrame):
    • Houses a TStringGrid to display two columns:
      • Label column (month names, day names, or hour labels).
      • Multiplier column (where the user enters numeric multipliers).
  5. OK/Cancel/Help Buttons.
  6. EditBtn (TBitBtn): Launches a more comprehensive text editor for the comment if desired (via Uedit.EditComment).

2.2 Variables and Constants

  • PatternIndex: The index of the pattern in SWMM’s project data (or -1 if new).
  • MonthlyLabels, DailyLabels, HourlyLabels: Arrays of strings used to label the grid's first column.
  • AM, PM: Additional strings for labeling hours in 12-hour format.

3. Data Flow

3.1 SetData

  1. Takes an Index (the pattern’s position in Project.Lists[PATTERN]) and a TPattern object (aPattern).
  2. If the index >= 0, loads the pattern's name from Project.Lists[PATTERN].Strings[Index] into NameEdit.
  3. Sets PatternTypeCombo.ItemIndex := aPattern.PatternType, which triggers PatternTypeComboClick.
  4. Copies the comment (aPattern.Comment) into CommentEdit.
  5. Copies the multipliers from aPattern.Data[] into the second column of GridEdit1.Grid.

3.2 PatternTypeComboClick

  • Adjusts the GridEdit1.Grid.RowCount and the first column’s labels depending on the selected pattern type:
    • 12 rows for Monthly (Jan…Dec).
    • 7 rows for Daily (Sun…Sat).
    • 24 rows for Hourly (12 AM…11 PM).
  • Ensures any empty multiplier cells are set to "1.0".

3.3 GetData

  1. Outputs the pattern's Name (NameEdit.Text) to the calling variable S.
  2. Writes PatternTypeCombo.ItemIndex to aPattern.PatternType.
  3. Writes CommentEdit.Text to aPattern.Comment.
  4. Reads each row of GridEdit1.Grid.Cells[1, row] into aPattern.Data[row].

3.4 OKBtnClick and ValidateData

  • ValidateData checks:
    1. If NameEdit.Text is non-empty.
    2. If the name is unique (i.e., not used by another pattern).
    3. If all multiplier cells parse as valid floats.
  • If valid, ModalResult := mrOK, otherwise an error message is shown.

4. Additional Details

  1. NameEditKeyPress: Blocks [ from being the first character.
  2. EditBtnClick: Opens a comment editor for multiline/extended text.
  3. HelpBtnClick: Launches the SWMM help topic for patterns.
  4. The grid uses two columns: The first for a descriptive label (not editable), and the second for the multiplier.

5. Typical Usage

  1. The user picks an existing pattern from a SWMM interface and chooses Edit (or Add for a new one).
  2. SetData populates TPatternForm with the pattern’s type, name, comment, and multipliers.
  3. The user modifies the type or modifies the multipliers in GridEdit1.
  4. On OK, ValidateData ensures the pattern is valid.
  5. GetData finalizes changes back into SWMM’s Project.Lists[PATTERN][Index].

This approach seamlessly manages the variety of pattern types (monthly, daily, hourly) and ensures the user has a convenient, tabular way to enter multipliers while giving them a textual comment field for extra context.

SWMM5 Delphi GUI Doptions.pas Summary

 Below is an overview of Doptions.pas, a Delphi unit from SWMM 5.2 that defines a dialog (TAnalysisOptionsForm) for editing a project's simulation options. These options dictate how SWMM conducts its rainfall-runoff, RDII, snowmelt, groundwater, flow routing, and water quality calculations.


1. Purpose and Context

In SWMM, project options control everything from the infiltration model and routing method to time-step durations, solver tolerances, and advanced engine settings. The TAnalysisOptionsForm provides multiple tabs (via TPageControl) allowing the user to configure:

  1. Which physical processes are included (rainfall, RDII, snowmelt, groundwater, etc.).
  2. Simulation start and end dates/times.
  3. Reporting time steps.
  4. Routing options (inertial damping, variable time step, force main equations, etc.).
  5. External interface files (e.g., hotstart or interface flows).

When OK is pressed, these choices are written back into SWMM’s Project.Options data structure.


2. Main Form: TAnalysisOptionsForm

2.1 Tabs and Controls

The form includes a TPageControl with 5 TabSheets, each containing groups of controls relevant to particular categories of options:

  1. Simulation Models (TabSheet1)

    • Checkboxes for ignoring or including processes like Rainfall, SnowMelt, Groundwater, FlowRouting, WaterQuality, and RDII.
    • A radio group (InfilModelsGroup) to choose among infiltration models (Horton, Green-Ampt, Curve Number).
    • Another radio group (RoutingMethodsGroup) to pick routing method (Kinematic Wave, DW, or SWMM’s dynamic wave, etc.).
  2. Dates/Times (TabSheet2)

    • Start/Report/End date & time pickers (TDateTimePicker) for simulation period.
    • Street sweeping date pickers (SweepStartPicker, SweepEndPicker) and “Days of No Rain” (DryDaysEdit).
  3. Time Steps (TabSheet3)

    • Controls for Routing time step (RouteStepEdit), Reporting step (RptStepPicker), Dry/Wet weather time step (DryStepPicker, WetStepPicker), etc.
    • SysFlowTolSpinner and LatFlowTolSpinner for system/lat-flow tolerances.
    • Checkboxes like AllowPondingBox and SkipSteadyBox.
    • Optional variable time step (VarTimeStepBox), with a spin edit for maximum time step (%) (VarStepEdit).
  4. Engine/Advanced (TabSheet4)

    • Inertial damping combo (InertialTermsCombo), normal flow limiting combo (NormalFlowCombo), and force main equation combo (ForceMainCombo).
    • Surcharge method (SurchargeCombo), minimum nodal surface area (MinSurfAreaEdit), solver tolerances (HeadTolEdit), max trials, etc.
    • Number of threads (ThreadsEdit and ThreadsButton) to parallelize SWMM’s solver.
  5. Interface Files (TabSheet5)

    • A list box (FileListBox) plus Add, Edit, Delete buttons.
    • These refer to external files that can store or retrieve intermediate states (hotstart, interface flows, etc.).

3. Data Flow

3.1 Loading Options: SetOptions(Page: Integer)

  • Reads from Project.Options and displays:

    • Dates: converts stored strings to TDateTimePicker (StartDatePicker, etc.).
    • Time Steps: stored as “HH:MM:SS” strings, displayed using two pickers (days vs. clock time) via SetStepTime().
    • Check/Radio Boxes: infiltration method, routing method, advanced solver combos, etc.
    • Interface files: populates FileListBox from Project.IfaceFiles.
  • Then it sets PageControl1.TabIndex := Page so the user sees the requested tab first.

3.2 Editing Options

  • User modifies infiltration model, date/time pickers, advanced combos, or adds interface files.
  • Some controls (e.g., infiltration model group) may cause immediate changes in default infiltration parameters if the model changes.

3.3 Saving Options: GetOptions

  • The final user settings are stored back into Project.Options. For example:
    1. Project.Options.Data[START_DATE_INDEX] = the string version of StartDatePicker.Date.
    2. Project.Options.Data[IGNORE_RAINFALL_INDEX] = 'YES' if user unchecked the “Rainfall” box.
    3. DX (time step strings) are reconstructed with GetStepTime(RptDaysPicker, RptStepPicker).
    4. Project.IfaceFiles is cleared and re-filled from FileListBox.
  • Some special logic:
    • If infiltration model changed, reset default infiltration data.
    • If user turned on variable time step (VarTimeStepBox), read the numeric spin for % time step (VarStepEdit).

4. Notable Controls and Methods

4.1 Time Pickers (TDateTimePicker)

  • For simulation start, end, and report times, plus a daily step pickers for “days” portion.
  • The code splits hours from days using helper routines SetStepTime() and GetStepTime() to handle times that can exceed 24 hours.

4.2 VarTimeStepBoxClick

  • Toggles the variable time step feature in dynamic wave routing.
  • When checked, VarStepEdit (spin) and MinTimeStepEdit (float) become enabled.

4.3 Interface Files Section

  • The user can Add (select or define a new file), Edit (change path or type?), or Delete.
  • The form calls an TIfaceFileForm (Diface.pas) to manage details of each file.

4.4 DefaultsLabelLinkClick

  • Sets various “good default” values for advanced solver options (inertial terms, normal flow limiting, force main eqn, etc.).
  • The user can revert to these recommended defaults with one click.

4.5 ThreadsButtonClick

  • Displays a message with the system’s CPU count (MsgDlg(NumberOfCPUs, ...)).
  • The user chooses how many solver threads to use (1..N) in ThreadsEdit.

4.6 Tab-Specific OnChanging / OnChange

  • PageControl1Changing saves the current HasChanged status.
  • PageControl1Change restores it to avoid marking changes if the user only switches tabs.

5. Validation and OK

  • When the user presses OK:

    1. If variable time step was toggled, mark HasChanged.
    2. ModalResult := mrOK.
  • Back in the calling code, GetOptions is invoked to finalize changes in Project.Options.


6. Summary

Doptions.pas is SWMM’s comprehensive interface for configuring simulation settings—from basic infiltration models and simulation times to advanced numeric solver details. By splitting these controls into a TPageControl with multiple tabs, the code neatly organizes what can be a large set of parameters. The form ensures that user edits are validated, stored, and optionally reset to recommended defaults, supporting a flexible yet standardized way to set up a SWMM model run.

SWMM5 Delphi GUI Dnotes.pas Summary

 Below is an overview of Dnotes.pas, a Delphi unit from SWMM 5.2 that defines a dialog (TNotesEditorForm) for editing either:

  1. A project’s Title/Notes text (the lines that appear as descriptive “header” text for the project), or
  2. The Comment property of any individual SWMM object (e.g., a node, link, subcatchment, etc.).

1. Purpose and Context

Many SWMM objects (and the project overall) can store descriptive notes or comments. This dialog provides a text-editing interface so users can:

  • Edit and store multiline comments for a specific object.
  • Modify the SWMM project’s Title/Notes (including an option to treat the title as a header in printed reports).

Because it’s used for two different but related tasks (object comments vs. project notes), some controls (like CheckHeader) may appear only for project-wide notes editing.


2. Main Components: TNotesEditorForm

  1. Memo1 (TMemo):
    • A multiline text box where the user types or views the text.
  2. CheckHeader (TCheckBox):
    • Visible only when editing the project’s Title/Notes.
    • Toggled on/off to indicate whether the project’s Title lines should be used as a report header (TitleAsHeader).
  3. OK and Cancel buttons:
    • Standard dialog acceptance or dismissal.
  4. HasChanged (boolean):
    • Tracks whether the text was modified by the user (or if CheckHeader changed).

3. Data Flow and Methods

3.1 Editing Comments for an Object

  • SetComment(Title, S):

    1. Sets Caption := Title so the dialog’s top bar text might say something like “Comment for Node X”.
    2. Places the existing comment (S) into Memo1.Lines and resets the cursor to the start.
  • GetComment(var S):

    1. Reads all lines from Memo1.Lines and combines them with CR (carriage return, #13) separators into the string S.
    2. Notes if the user typed anything by checking Memo1.Modified.

3.2 Editing the Project Title/Notes

  • SetProjectNotes(Slist):

    1. Makes CheckHeader.Visible := True (so the user can choose if the first line is used as a header in reports).
    2. Copies the multiline text from Slist into Memo1.Lines.
    3. Moves the caret to the start.
  • GetProjectNotes(Slist):

    1. Saves the user’s choice of CheckHeader.Checked into Uglobals.TitleAsHeader.
    2. Copies the lines from Memo1.Lines back into Slist.

3.3 Additional Details

  • FormCreate:
    • CheckHeader.Visible := False; by default, since it’s only shown for project-level notes, not for object comments.
  • CheckHeaderClick:
    • If the user toggles the checkbox, HasChanged := True;
  • The text editor (Memo1) can handle multiple lines. If the user hits OK, the text is committed back to whichever storage is relevant (project notes or object comment).

4. Typical Usage

  1. Editing an object’s comment:

    1. The main application calls SetComment("Link Comment", linkCommentString).
    2. The user modifies text in Memo1.
    3. On OK, GetComment(linkCommentString) is called. The updated text is saved into the link object’s Comment property.
  2. Editing the project’s Title/Notes:

    1. The main application calls SetProjectNotes(NotesList), passing a TStringList of lines.
    2. The user can check/uncheck CheckHeader to specify whether the first line is a “report header.”
    3. On OK, GetProjectNotes(NotesList) is called; the updated lines and header-setting are captured in the project data structures.

Because SWMM uses these free-text fields in many places (reports, user documentation, object definitions), Dnotes.pas is a straightforward but essential piece of the UI for effectively documenting models.

SWMM5 Delphi GUI Dmapexp.pas Summary

 Below is an overview of Dmapexp.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TMapExportForm) to export the current study area map into one of three file formats:

  1. MAP (a plain text format containing map coordinates)
  2. EMF (Enhanced Metafile, a vector-based image format)
  3. DXF (Drawing Exchange Format, often used by CAD applications)

1. Purpose and Context

When a user wants to save or share the spatial layout of a SWMM model’s map (as opposed to the entire SWMM input file), TMapExportForm provides a convenient interface to choose the export format and file location. The user can then:

  • Generate a MAP file, which is an internal SWMM text-based format containing only the graphical layout (node/link coordinates, etc.).
  • Produce an EMF file (vector image) for high-quality printing or embedding in documents.
  • Create a DXF file for importing the geometry into CAD or GIS software.

2. Main Form: TMapExportForm

2.1 Controls

  • Radio Buttons (1) MAP, (2) EMF, (3) DXF:
    Let the user pick which file format to export.

  • RadioGroup1:
    Visible only if DXF is chosen. Provides additional drawing choices (e.g., “Circle” vs. “Square” for node symbols) for how junctions appear in the DXF file.

  • Buttons:

    • OK (Button1): Executes the export.
    • Cancel (Button2): Closes the dialog with no export.
    • Help (Button3): Opens the help topic for exporting.
  • SaveDialog1:
    A standard Windows save-file dialog, controlled at runtime.

2.2 Variables and Constants

const
  MAP_FILE = 0;
  EMF_FILE = 1;
  DXF_FILE = 2;

  FilterTxt: array[MAP_FILE..DXF_FILE] of PChar =
    ('Map files (*.MAP)|*.MAP|All files|*.*',
     'EMF files (*.EMF)|*.EMF|All files|*.*',
     'DXF files (*.DXF)|*.DXF|All files|*.*');

  ExtensionTxt: array[MAP_FILE..DXF_FILE] of PChar =
    ('map','emf','dxf');

  TXT_SAVE_MAP_TITLE = 'Save Map As';
  • These definitions let the code manage SaveDialog1’s filter text and file extension automatically, based on which format is selected.

3. Workflow

  1. User Chooses Format
    By default, RadioButton1 (MAP) is checked. The user can switch to EMF or DXF.

  2. (Optional) Adjust DXF Node Style
    If RadioButton3 (DXF) is checked, RadioGroup1 is revealed, letting the user pick how junctions will be drawn in the DXF.

  3. OK Button

    • The form is hidden.
    • SaveDialog1 is configured with the relevant filter and extension.
    • If the user picks a file name and clicks Save, the form processes the file in the chosen format:
      1. MAP => calls ExportMapFile
      2. EMF => calls MapForm.CopyToMetaFile
      3. DXF => calls Udxf.DXFexport, passing the chosen “junction style” index from RadioGroup1.ItemIndex.
  4. ExportMapFile

    • For a MAP format, the code calls Uexport.ExportMap(S) to retrieve a text representation of the map’s layout in a TStringList (S).
    • Then S.SaveToFile(Fname) writes it out.
  5. Help Button

    • Invokes the help topic for exporting the map (HELP_CONTEXT, 211850).
  6. FormKeyDown

    • If F1 is pressed, calls the Help routine.

4. Key Routines

4.1 ExportMapFile

procedure TMapExportForm.ExportMapFile(const Fname: String);
var
  S: TStringlist;
begin
  S := TStringlist.Create;
  try
    Uexport.ExportMap(S);
    S.SaveToFile(Fname);
  finally
    S.Free;
  end;
end;
  • Leverages the function in Uexport.pas that builds a text-based representation of map coordinates and object placements.
  • This text is saved in a .MAP file, which can be re-imported by SWMM as a partial reference for the map layout.

4.2 MapForm.CopyToMetaFile

  • When exporting to EMF, MapForm.CopyToMetaFile(Filename) captures a vector “screenshot” of the model map.
  • The user can place this .emf into other applications with no loss of resolution.

4.3 Udxf.DXFexport

  • If the user chooses DXF, Udxf.DXFexport(Filename, JuncStyle) writes a standard 2D CAD format file.
  • JuncStyle typically controls how nodes are drawn (circles, squares, etc.) in the resulting DXF.

5. Summary

Dmapexp.pas is a concise unit enabling SWMM to export the model’s map as:

  1. MAP: SWMM’s text layout format (doesn’t include data on subcatchment polygons beyond their vertices, nor does it store hydraulic/hydrologic parameters—only geometry).
  2. EMF: A Windows Enhanced Metafile (vector image).
  3. DXF: A universal CAD format for geometry-based outlines of subcatchments, links, nodes, etc.

By allowing multiple formats, SWMM provides flexibility for both graphical presentation and for transferring geometry to other software tools.

SWMM5 Delphi GUI Dmapdim.pas Summary

 Below is an overview of Dmapdim.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TMapDimensionsForm) used to set (or revise) the dimensions of the project’s study area map. This ensures that all map objects (subcatchments, nodes, links, backdrop images, etc.) appear within a specified coordinate range at the correct scale.


1. Purpose and Context

SWMM maintains coordinate extents (min/max xx and yy) for the study area map. These coordinates:

  1. Determine how the map is displayed in the user interface (how zoomed in/out it appears initially).
  2. Provide a basis for calculating scaled distances or areas, particularly if the user chooses map units of feet/meters or degrees.

The TMapDimensionsForm dialog lets users:

  • Manually enter the map’s lower-left and upper-right corners (LLX,LLY,URX,URY)(\text{LLX}, \text{LLY}, \text{URX}, \text{URY}).
  • Automatically compute them by scanning all existing model objects plus any backdrop image extents.
  • Choose whether the map is in length units (feet/meters) or geographic units (degrees).

2. Key Form Elements

  1. GroupBoxes

    • One for entering or automatically setting the coordinate extents (the lower-left and upper-right points).
    • Another for choosing the MapUnits radio group (feet/meters vs. degrees).
  2. Edit Controls:

    • LLXEdit, LLYEdit: Lower-left xx and yy.
    • URXEdit, URYEdit: Upper-right xx and yy.
      Each is a TNumEdit control, ensuring numeric input.
  3. RadioGroup (MapUnits):

    • muFeet, muMeters, or muDegrees.
    • Adjusting it changes how SWMM interprets the map coordinate scale.
  4. AutoLengths CheckBox:

    • If checked, triggers an update of stored element lengths (e.g., conduit lengths) after changing the map’s scale.
  5. Buttons

    • OK: Validates the user’s input.
    • Cancel: Closes the dialog without changes.
    • Help: Opens context-sensitive help.
    • Auto: Retrieves the minimum bounding rectangle from all model objects and the backdrop image, if present.

3. Typical Workflow

  1. User opens the Map Dimensions dialog.
  2. SetData(Dimensions: TMapDimensions) is called to load the current coordinate extents into the form controls:
    • If the user has a previous scale, that data is displayed.
  3. The user can either:
    • Type in new LLX/LLY/URX/URY values, or
    • Click Auto to let SWMM compute bounding coordinates from the map’s existing objects (subcatchments, nodes, links, backdrop).
  4. The user optionally checks AutoLengths if they want conduit and subcatchment area calculations automatically updated in light of the new coordinates.
  5. On OK, the form calls:
    • GetData(Dimensions) to store user changes back into a TMapDimensions record.
    • Validates that no blank or equal min/max values exist. If invalid, an error message appears.
    • If valid, the map is re-scaled accordingly.

4. Implementation Details

4.1 SetData(Dimensions: TMapDimensions)

  • Copies the four numeric fields (LLX, LLY, URX, URY) into the TNumEdits.
  • Sets the MapUnits radio group from Dimensions.Units.
  • AutoLengths.Visible is set based on Dimensions.AutoLength. (In SWMM 5.2, this might relate to whether the user wants SWMM to re-compute lengths or not.)

4.2 GetData(Dimensions: TMapDimensions)

  • Reads back the user’s numeric entries into Dimensions.LowerLeft.X, .Y, and Dimensions.UpperRight.X, .Y.
  • Updates Dimensions.Units from the MapUnits.ItemIndex.
  • If AutoLengths.Checked, calls a function to update all length calculations (via Uupdate.UpdateAllLengths).

4.3 BtnAutoClick

  • Calls Ucoords.GetCoordExtents(...) to find the bounding rectangle of all model objects.
  • Also merges in any backdrop image’s bounding rectangle.
  • If the resulting rectangle is valid, populates the TNumEdits. Otherwise, reverts to default dimensions from DefMapDimensions.

4.4 BtnOKClick

  • Ensures the numeric fields aren’t empty and that LLXURX\text{LLX} \neq \text{URX} and LLYURY\text{LLY} \neq \text{URY}.
  • If checks pass, sets ModalResult := mrOK.

5. Summary

Dmapdim.pas provides a simple but essential dialog to define or adjust the coordinate system bounding box for a SWMM project’s map. By specifying the lower-left and upper-right corners—and optionally the map units (feet, meters, or degrees)—the user ensures the project’s geometry is scaled properly for:

  1. Visual display in the SWMM user interface.
  2. Correct length/area computations for subcatchments and links.

Additionally, the Auto feature quickly sets the bounding box to encompass all existing objects on the map plus any loaded backdrop image, saving users the effort of manually setting map extents.

SWMM5 Delphi GUI Dmap.pas Summary

 Below is an overview of Dmap.pas, a Delphi unit from SWMM 5.2 that defines a dialog (TMapOptionsForm) for configuring map display options in the SWMM user interface. This dialog allows the user to customize how subcatchments, nodes, links, labels, arrows, and other map elements are rendered.


1. Purpose and Context

When viewing a SWMM model, users may want to change how the map looks—for example, adjusting node sizes, link widths, subcatchment fill style, or label transparency. The TMapOptionsForm provides these customization options, which SWMM later uses when drawing the main project map.


2. Main Form: TMapOptionsForm

2.1 Key Visual Components

  1. ListBox1 on the left:

    • Lists different categories of map display options (e.g., Subcatchments, Nodes, Links, Labels, etc.).
    • When the user selects an item from this list, the corresponding page in Notebook1 is shown.
  2. Notebook1 (with multiple pages):

    • Each page corresponds to a category of map display options:
      • Page 0: Subcatchment appearance (e.g., fill style, line style).
      • Page 1: Node appearance (node size, border, shape).
      • Page 2: Link appearance (link width, border).
      • Page 3: Label/notation settings (font size, transparency).
      • Page 4: Arrow appearance.
      • … and so on.
    • Contains various controls (checkboxes, radio groups, up-down numeric edits, etc.) for adjusting each display option.
  3. ColorListBox1:

    • Lets the user pick a background color for the map from a custom list of colors.
  4. Button Panel:

    • OK, Cancel, Help.

3. Map Settings in TMapOptions

A TMapOptions record (from Umap.pas) typically holds many boolean and integer fields that control how the map is drawn. For example:

  • ShowSubcatchLinks: Whether lines from subcatchment centroids to nodes are shown.
  • SubcatchFillStyle: Brush style (solid, clear, diagonal, etc.) for subcatchments.
  • SubcatchSize and SubcatchLineSize: The size of subcatchment symbols and boundary lines.
  • NodeSize: Node symbol size.
  • ShowNodesBySize / ShowNodeBorder: Whether node sizes and borders are displayed.
  • LinkSize: Link line width, etc.
  • LabelsTranspar: Whether labels have a transparent background.
  • NotationSize: Font size for object labels (IDs/values).
  • ColorIndex: An index for the background color choice.

The form reads and writes these fields through SetOptions and GetOptions.


4. Event Handlers and Workflow

4.1 FormCreate

  • Initializes the left-side ListBox1 so each item (option category) displays at an appropriate height.
  • Sets ListBox1.ItemIndex := 0 and calls ListBox1Click to show the first page in Notebook1.

4.2 SetOptions(Options: TMapOptions)

  • Called by the main application to load the current map settings into the form’s controls.
  • For example:
    • SubcatchLink.Checked := Options.ShowSubcatchLinks;
    • SubcatchSymbol.Spinner.Position := Options.SubcatchSize;
    • NodeSpin.Spinner.Position := Options.NodeSize;
    • NodesBySize.Checked := Options.ShowNodesBySize;
    • … etc. …
  • Finally, calls routines to resize sample shapes (ResizeNodeShape, ResizeLinkShape) and sets HasChanged := False.

4.3 User Adjustments

  • The user selects categories from ListBox1.
  • They toggle checkboxes (e.g., NodeBorder), use spin boxes for sizes (NodeSpin, LinkSpin), or pick fill styles from a TRadioGroup (SubcatchFill).
  • The form draws a small preview shape (NodeShape or LinkShape) scaled according to the user’s input.

4.4 NodeSpinChange / ResizeNodeShape

  • When the user changes node size, the code updates the shape (NodeShape) to reflect the new dimension. This is purely a preview—final changes are only applied to the SWMM map once the user clicks OK.

4.5 GetOptions(Options: TMapOptions)

  • Called after the user presses OK:
    1. Reads each control’s value back into the corresponding Options field.
    2. Compares with old values to set HasChanged := True if something changed.
    3. Example: Options.NodeSize := NodeSpin.Spinner.Position; Options.ShowNodeSymbols := NodeSymbols.Checked; etc.

4.6 BtnHelpClick

  • Displays context-sensitive help, with different Help IDs for each Notebook1 page.

5. Notable Details

  1. ColorListBox1GetColors:

    • A specialized event populating ColorListBox1 with a custom set of colors (White, Yellow, Blue, Panel, Black, etc.).
    • The user’s selection sets Options.ColorIndex.
  2. NodeBorder / NodeSymbols

    • Checkboxes that toggle whether node shapes have a border or if node symbols are shown at all.
    • The shape’s pen color changes dynamically (red for no border, black for border).
  3. Zoom Fields (e.g., ZoomForLabels, ZoomForSymbols):

    • Control at what zoom level these elements become visible.
    • For instance, if LabelZoom is 10, then labels only appear if the map is zoomed in beyond a certain threshold.
  4. ListBox1DrawItem:

    • An override that custom-draws each item in the category list, centering the text vertically.

6. Summary

Dmap.pas provides a multi-tabbed Map Options dialog, letting users customize subcatchment fill, node/link size, color, labeling transparency, arrows, background color, and more. Through SetOptions and GetOptions, it synchronizes these choices with the global TMapOptions structure, which the SWMM UI then uses to redraw the map with the user’s preferred appearance.

SWMM5 Delphi GUI Dloads.pas Summary

 Below is an overview of Dloads.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TInitLoadingsForm) for editing initial pollutant loadings on a subcatchment. In SWMM, you can specify an initial buildup (mass per area) of each pollutant on a subcatchment at the start of a simulation. This form makes it easy to set these initial loads for all pollutants at once.


1. Purpose and Context

When setting up a subcatchment in SWMM, you might have initial pollutant buildup (e.g., sediments, nutrients) already present on the land surface. These initial loads affect the first-flush pollutant washoff. The TInitLoadingsForm dialog allows you to enter these loads for each pollutant in one place.


2. Main Components: TInitLoadingsForm

  1. Property Editor (PropEdit1)

    • A specialized grid-like control that displays the pollutant names and their respective initial loads side by side.
    • The first column shows pollutant names, the second shows initial buildup values.
    • Each property row has an esEdit style, meaning the user can type in a numeric value.
  2. TStringList (PropList)

    • Stores the numeric values (mass per area) for each pollutant.
    • These correspond to the rows of the PropEdit1 control.
  3. TPropRecord array (PropRecd)

    • An array of metadata describing each pollutant row (e.g., name, editing style, input mask).
    • SWMM uses these records to define how each row is displayed and validated in the property editor.
  4. Buttons: OK, Cancel, Help

    • OKBtn: Validates the numeric inputs (via PropEdit1.IsValid) and, if valid, returns with mrOK.
    • HelpBtn: Opens context-sensitive help.
    • CancelBtn: Closes the form without saving new changes.
  5. HintPanel / HintLabel

    • Displays a short message (e.g., “Enter initial buildup of pollutants on subcatchment X”).

3. Data Flow

3.1 SetData(aSubcatch: TSubcatch)

  • Called from outside (e.g., some main form or property editor) to load existing data into this form:
    1. Sets HintLabel.Caption to show which subcatchment is being edited.
    2. For each pollutant in Project.Lists[POLLUTANT], retrieves any existing initial loading from aSubcatch.Loadings.
    3. Stores these values in PropList, matching row order with PropRecd.
    4. As a result, PropEdit1 is populated with pollutant names (from PropRecd[]) and their values (from PropList).

3.2 FormShow

  • PropEdit1.SetProps(PropRecd, PropList) places the rows (one per pollutant) into the property editor.
  • Calls PropEdit1.Edit to set up the editing session.

3.3 User Edits

  • The user types numeric values in the second column for each pollutant.
  • If the user wants to discard changes, they press Cancel.
  • If they accept, they press OK.

3.4 OKBtnClick

  • Calls PropEdit1.IsValid to validate that each row has valid numeric input.
  • If invalid, ModalResult := mrNone keeps the form open, otherwise mrOK closes the form.

3.5 GetData(aSubcatch: TSubcatch; var Count: Integer)

  • Called externally after OK to store user inputs back into the subcatchment:
    1. Clear any existing aSubcatch.Loadings.
    2. For each pollutant row, parse the string as a floating number.
    3. If it’s greater than 0, store it in aSubcatch.Loadings with pollutant=loading.
    4. Keep track of how many nonzero loadings were found in Count.

4. Key Implementation Details

  • Unit System:
    • If SWMM is in US units, the column heading is “Initial Buildup (lbs/ac)”.
    • If in SI units, it’s “Initial Buildup (kg/ha)”.
  • Validation:
    • PropRecd[i].Mask := emPosNumber means the form only allows numeric input with optional decimal points.
    • Anything else triggers an error message if the user tries to press OK.
  • HasChanged:
    • Set to True if the user makes changes, tracked through PropEdit1.Modified.
    • This helps the main application know if anything in the subcatchment changed after leaving the dialog.

5. Summary

Dloads.pas provides a straightforward, tabular approach to initial pollutant loadings in SWMM 5.2:

  1. PropEdit displays each pollutant and a single numeric field for its initial buildup.
  2. SetData loads existing loadings from the subcatchment’s Loadings property.
  3. GetData writes the user’s final changes back to that subcatchment.
  4. The form ensures all inputs are valid numeric values before closing.

This dialog thus streamlines the process of setting or modifying the starting level of pollutant buildup on each subcatchment, which can be an important factor in first-flush pollutant washoff calculations during the simulation.

SWMM5 Delphi GUI Dlidusage.pas Summary

 Below is an overview of Dlidusage.pas, a Delphi unit from SWMM 5.2 that defines a dialog (TLidUsageDlg) for specifying how a particular LID control is used in a given subcatchment. Unlike the LID control itself (defined in Dlid.pas), which stores the design of the LID, this dialog focuses on deployment details—how many units, what fraction of the subcatchment’s area they occupy, what area of impervious/pervious surfaces they treat, any separate underdrain outlet, and an optional report file.


1. Purpose and Context

When a user is setting up LID usage for a subcatchment, they need to specify:

  1. Which LID control is being used.
  2. How many replicate units (e.g., 5 rain barrels or 3 infiltration trenches).
  3. Each unit’s surface area and width, plus the fraction of the subcatchment’s impervious/pervious surfaces it intercepts.
  4. Whether outflow from the LID’s underdrain is routed to the outlet or to the pervious area of the subcatchment.
  5. An optional report file to log performance of the LID usage.
  6. An optional drain outlet (a node ID), if outflow is routed to a different location.

The TLidUsageDlg collects these parameters from the user and returns them to the calling form (Dlidgroup.pas). The user can then have multiple LID usage rows within a single subcatchment.


2. Key Form Elements

  1. ComboBox1: A dropdown listing existing LID control names (from the project’s Project.Lists[LID]). The user picks which LID control to deploy.
  2. NumUnitsUpDn / NumUnitsEdit: The number of replicate LID units to place in the subcatchment.
  3. UnitAreaEdit and UnitWidthEdit: The area (per unit) and overall width of each LID strip.
  4. InitSatEdit: The initial percent saturation of the LID’s soil or storage zone at the start of the simulation.
  5. FromImpervEdit / FromPervEdit: The percentage of impervious or pervious area that drains to this LID usage.
  6. DrainOutletCheckBox: Indicates if the LID’s underdrain flow is routed to the subcatchment outlet (checked = “1”) or to the subcatchment’s pervious area (unchecked = “0”).
  7. DrainOutletEdit: An optional node name if outflow is routed somewhere else.
  8. RptFileEdit (plus BrowseBtn and ClearBtn): An optional text file where the LID usage performance is reported.
  9. FullAreaCheckBox: If checked, indicates that the LID usage occupies the entire subcatchment area (so that “% of subcatchment” = 100).
  10. Notebook1 with multiple pages: Displays a small illustration of the chosen LID type (Rain Barrel, Vegetative Swale, Biocell, etc.), helping the user see which LID design they’ve selected.

3. Data Flow

3.1 SetData(Data: array of String)

When called from Dlidgroup.pas, an array of strings defines the usage parameters to load:

Index | Meaning
-----------------------------------------------------
0     | LID Control Name
1     | Number of units
2     | Unit area
3     | Unit width
4     | % initially saturated
5     | % from impervious area
6     | Outflow routing (0=outlet, 1=pervious)
7     | Full report file path
8     | (Unused or path name repeated)
9     | Underdrain outlet node
10    | % from pervious area

SetData populates the controls (e.g., ComboBox1.ItemIndex, NumUnitsUpDn.Position, UnitAreaEdit.Text, etc.). It also sets an internal RptFileName to track the actual path to the LID’s optional report file.

Finally, DisplayLidImage loads an appropriate page into Notebook1 based on the LID’s ProcessType.

3.2 GetData(var Data: array of String)

Once the user presses OK, the code compiles the user’s final entries back into a string array:

  • Data[0] = chosen LID control name
  • Data[1] = number of units
  • … etc. …
  • Data[6] = “1” if DrainOutletCheckBox is checked, otherwise “0”
  • Data[7] = the stored path in RptFileName
  • Data[9] = DrainOutletEdit.Text
  • Data[10] = % from pervious area

4. Event Handlers and Validation

4.1 OkBtnClick

  • Verifies that ComboBox1 is not blank.
  • Computes the total % of subcatchment area occupied by this LID usage. If it’s greater than 100, shows an error.
  • If checks pass, sets ModalResult := mrOK.

4.2 BrowseBtnClick / ClearBtnClick

  • Manages the optional report file path.
  • BrowseBtnClick opens a TSaveDialog to pick a file location, storing it in RptFileName.
  • ClearBtnClick resets RptFileName to empty.

4.3 FullAreaCheckBoxClick

  • If checked, sets “LID area = entire subcatchment” logic by:
    • Disabling UnitAreaEdit
    • Setting PcntAreaLabel.Caption = "100.0"
    • Automatically computes each replicate unit’s area if there are multiple units.

4.4 NumUnitsEditChange / UnitAreaEditChange

  • Recalculates the “% of subcatchment area” shown in PcntAreaLabel. This uses a function in Ulid (e.g., Ulid.GetPcntArea(…)) that presumably references the subcatchment’s total area.

4.5 DisplayLidImage

  • Looks up the chosen LID’s ProcessType from the project’s Project.Lists[LID].
  • Switches Notebook1.ActivePage to an appropriate image page (e.g., “PermPavePage” for permeable pavement, “VegSwalePage” for a vegetative swale, etc.).

5. Summary of Operation

  1. Initialization: SetData loads the usage’s initial values (which might be blank if new).
  2. User Editing: The user picks from the list of LID controls, sets number of units, fraction from impervious/pervious, etc. They can select a specific file for a performance report and optionally direct the LID’s underdrain outflow to the pervious area or a specified node.
  3. Validation: On pressing OK, the dialog ensures no invalid conditions (e.g., area > 100%).
  4. Saving: GetData prepares the final usage properties for the caller (Dlidgroup.pas), which stores them in the subcatchment’s LID usage list.

This structure ensures that all relevant details about how an LID control is deployed in a subcatchment are collected and validated, keeping the design (from Dlid.pas) distinct from the usage details here in Dlidusage.pas.

SWMM5 Delphi GUI Dlidgroup.pas Summary

 Below is an overview of Dlidgroup.pas, a Delphi unit from SWMM 5.2 that provides a form (TLidGroupDlg) to add, edit, and remove LID units (i.e., LID usage entries) within a particular subcatchment. Each subcatchment can have multiple LID units installed, each of which references a particular LID control (defined in Dlid.pas) and contains additional usage data (area, percent from impervious/pervious, etc.).


1. Purpose and Context

This dialog manages a list of LID usage entries for a chosen subcatchment. For instance, a subcatchment might have:

  • 10% area as Bioretention Cells
  • 5% area as Rain Barrels treating 50% of the impervious area
  • etc.

The form displays these entries in a TStringGrid and lets the user:

  1. Add a new LID usage entry.
  2. Edit the properties of an existing entry.
  3. Delete an entry.

Once confirmed, the updated list is stored in the subcatchment’s TSubcatch.LIDs string list.


2. Main Form: TLidGroupDlg

2.1 UI Elements

  1. StringGrid1

    • Each row (except row 0) corresponds to one LID usage.
    • Row 0 is the header row.
    • For each LID usage row, columns 0..5 display:
      1. Control Name
      2. LID Type (in short form, e.g. “RG” for Rain Garden)
      3. % of Area
      4. % From Imperv
      5. % From Perv
      6. Report File (file name portion)
    • The “true” parameter values (like area fraction, report file path, etc.) are actually stored in invisible columns (beyond column 5).
  2. Add / Edit / Delete Buttons

  3. OK, Cancel, Help Buttons

2.2 Relationship to TLidUsageDlg (Dlidusage.pas)

When the user adds or edits an LID entry, TLidUsageDlg (from Dlidusage.pas) is invoked. That dialog form gathers or edits the usage data (e.g., area fraction, underdrain parameters, optional report file, etc.) for a single LID usage entry.


3. Data Flow

3.1 SetData(theSubcatch)

  • Called externally to initialize the form with the LID usage data for a subcatchment:
    1. The subcatchment’s ID is displayed in the form caption.
    2. Retrieves the subcatchment’s Lids (a TStringList), which may contain multiple lines, each referencing a TLidUnit object.
    3. For each existing LID usage, create/add a row in the StringGrid1.
    4. If there are any entries, enable the Edit and Delete buttons.

3.2 GetData(theSubcatch)

  • After the user presses OK, data from StringGrid1 are read back into the subcatchment’s LIDs list:
    1. Clear (free) any existing LIDs from the subcatchment.
    2. For each row with a non-empty “Control Name”, create a new TLidUnit object.
    3. Copy the data from each grid column into TLidUnit.Data[].
    4. Append the new TLidUnit object to the subcatchment’s LIDs list.

4. Core Event Handlers

4.1 BtnAddClick

  1. Creates and shows a TLidUsageDlg.
  2. If the user clicks OK, the form returns the new LID usage data.
  3. A new row is appended to StringGrid1 containing these data.
  4. HasChanged := True; enable Edit/Delete buttons if needed.

4.2 BtnEditClick

  1. Looks up the row in StringGrid1 the user selected.
  2. Extracts the existing usage data from the row’s cells.
  3. Calls TLidUsageDlg.SetData to populate that form with the usage’s existing properties.
  4. If the user changes something and presses OK, the row in the grid is updated with the revised usage.
  5. HasChanged := True if changes occurred.

4.3 BtnDeleteClick

  • Removes the currently selected row from StringGrid1.
  • If no more usage rows remain, disable Edit/Delete.
  • HasChanged := True.

4.4 OkBtnClick

  • Summarizes the total subcatch area assigned to LIDs (% of Area), and the total fractions of impervious/pervious area each LID treats.
  • If any total exceeds 100%, displays an error message. Otherwise, closes with mrOK.
  • The caller then uses GetData to store these usage entries in the subcatchment object.

4.5 StringGrid1KeyDown

  • Insert => same as BtnAddClick.
  • Enter => same as BtnEditClick.
  • Delete => same as BtnDeleteClick.

4.6 FillGridRow(I, Data)

  • Fills row I in StringGrid1 with the provided Data array from a TLidUnit.
  • The first two cells (columns 0..1) display the LID name and a short LID Type description.
  • The next columns show derived or truncated items like “% of Area,” “% From Imperv,” etc.
  • The real parameters remain in the invisible columns for retrieval later.

5. Summary

Dlidgroup.pas coordinates the usage of LID controls in a subcatchment by:

  1. Displaying a grid of LID usage entries.
  2. Letting the user add/edit each usage entry’s details via Dlidusage.pas.
  3. Preventing invalid totals (over 100% of subcatch area).
  4. Storing updated usage data back into the SWMM project data structures.

This design streamlines how multiple LID units are set up in a single subcatchment, ensuring consistency and clarity in the assignment of LID controls (like permeable pavement, bioretention, etc.) to the model.

SWMM5 Delphi GUI Dlid.pas Summary

 Below is an overview of Dlid.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TLidControlDlg) to create or edit an LID Control definition. SWMM uses Low Impact Development (LID) controls—such as bioretention cells, rain barrels, permeable pavement, etc.—to model best management practices in a watershed.


1. Purpose and Context

Each LID Control in SWMM represents a reusable design template that can be assigned to multiple subcatchments. This dialog enables the user to:

  1. Specify the LID type (e.g., Rain Garden, Green Roof, Permeable Pavement, etc.)
  2. Provide layer properties (surface layer, pavement layer, soil layer, storage layer, drain layer, etc.)
  3. Handle pollutant removals in the underdrain outflow.

These controls reflect how infiltration, storage, and outflow are handled for a particular type of LID.


2. Main Form: TLidControlDlg

2.1 Key Controls

  1. NameEdit: The name of the LID control (must be unique among LID controls).
  2. TypeCombo: A dropdown listing the LID process types (Bio Cell, Rain Garden, Green Roof, etc.).
  3. PageControl1 with multiple TTabSheet pages, each containing TNumEdit controls for layer properties:
    • TabSheet1: Surface layer (e.g., Berm Height, Surface Storage, Vegetative cover, etc.)
    • TabSheet2: Pavement layer (thickness, void ratio, impervious surfaces)
    • TabSheet3: Soil layer (thickness, porosity, infiltration rates, etc.)
    • TabSheet4: Storage layer (thickness, void ratio, infiltration, optional “rain barrel” coverage)
    • TabSheet5: Drain layer (flow coefficient, offset, underdrain capacity)
    • TabSheet6: Drainage mat (for Green Roofs)
    • TabSheet7: Roof Disconnection (downspout parameters)
    • TabSheet8: Pollutant Removals (optional percent removals for underdrain outflow)
  4. RemovalsEditor: A TValueListEditor containing a row for each pollutant, storing underdrain removal efficiency.
  5. CoveredCheckBox: An option for a covered rain barrel.
  6. OK, Cancel, and Help buttons.

3. Data Structures

3.1 TLid Object

A single TLid object has:

  • ProcessType: integer matching the selected item in TypeCombo.
  • SurfaceLayer: array of up to 5 strings.
  • PavementLayer: array of up to 7 strings.
  • SoilLayer: array of up to 7 strings.
  • StorageLayer: array of up to 5 strings (four numeric + “YES/NO” for rain barrel coverage).
  • DrainLayer: array of up to 7 strings (6 numeric + 1 reference to a control curve).
  • DrainMatLayer: array of 3 strings (for Green Roof drainage mat).
  • DrainRemovals: string list of Key=Value entries for each pollutant’s removal efficiency.

Note: Many fields are stored as strings so that SWMM can parse them at runtime without losing formatting or the user’s numeric precision.


4. Form Lifecycle

4.1 SetData(Index, aLID)

  • Called to initialize the dialog:
    • If Index >= 0, fetch the LID’s name from Project.Lists[LID].Strings[Index] and place it in NameEdit.
    • Set TypeCombo.ItemIndex := aLID.ProcessType.
    • Fill each relevant TNumEdit (e.g., SurfaceEdit1..SurfaceEdit5, PavementEdit1..PavementEdit7, etc.) from aLID.SurfaceLayer[], aLID.PavementLayer[], etc.
    • Assign the underdrain pollutant removals into RemovalsEditor.
    • Update which tab sheets (TabSheet1..TabSheet8) are visible or hidden based on the chosen LID type (via TypeComboClick).
    • Mark Modified := False.

4.2 TypeComboClick

  • Adjusts TabSheet visibility based on the selected LID type. For example:
    • Rain Barrel hides the surface layer tab, makes the storage tab more specialized, etc.
    • Green Roof hides the storage tab, shows the drain mat tab.
    • Roof Disconnection shows a simpler layout, no drain or storage tab.
    • Vegetative Swale hides the storage/drain tabs, modifies surface label usage.
  • Also updates the icon in LIDImage to reflect the chosen type.

4.3 User Interaction

  1. The user edits layer parameters in the TNumEdits across multiple tabs.
  2. Optionally checks the CoveredCheckBox for a Rain Barrel.
  3. Edits pollutant removal percentages in RemovalsEditor.
  4. Switches LID type from the drop-down, which triggers re-configuration of visible tabs.

4.4 Validation

OkBtnClick:

  1. Checks that NameEdit is non-empty and not duplicated.
  2. Runs LayerDepthsValid to ensure certain layer thickness fields (soil, pavement, storage, drainage mat) are > 0 if required by the chosen LID type.
  3. If invalid, displays an error message, sets focus to the offending field, and does not close.
  4. Otherwise, sets ModalResult := mrOK.

4.5 GetData

  • Called after OK is pressed and validation passes, to store the final results into the TLid object:
    • LID name is read from NameEdit.Text.
    • ProcessType from TypeCombo.ItemIndex.
    • The numeric TNumEdits from each layer tab are written back into e.g. aLID.SurfaceLayer[i-1], aLID.PavementLayer[i-1], etc.
    • The pollutant removal Key=Value pairs from RemovalsEditor.Strings go into aLID.DrainRemovals.
    • The “Covered” rain barrel option is saved as aLID.StorageLayer[4] := 'YES' or 'NO'.

5. Notable Procedures

5.1 LayerDepthsValid

  • Checks that certain layer thickness TNumEdits are greater than zero, depending on LID type:
    • Biocell/Rain Garden/Green Roof => soil layer must be > 0.
    • Permeable Pavement => pavement layer must be > 0.
    • If infiltration trench => storage layer must be > 0.
    • Green Roof => drainage mat must be > 0.
    • Vegetative Swale => berm height must be > 0.

If any are 0, it shows an error message and makes the form remain open.

5.2 RemovalsEditorValidate

  • Ensures the user’s entered removal fraction is numeric and in [0..100].
  • If invalid, it reverts to the prior value.

5.3 NumEditExit

  • For certain fraction-based fields (e.g., infiltration fraction), ensures it’s < 1.0. If not, prompts an error.

6. Summary

Dlid.pas provides a multi-tabbed dialog to define or edit a Low Impact Development template, specifying layering and outflow pollutant removals. The LID control can then be reused in subcatchments. By splitting parameters across separate tabs (Surface, Pavement, Soil, Storage, Drain, etc.), the form makes it clearer to configure the LID’s layered structure and internal drainage properties. Validation ensures consistent entries for thickness, name uniqueness, and pollutant removal rates.

SWMM5 Delphi GUI Dlegend.pas Summary

 Below is an overview of Dlegend.pas, a Delphi unit from SWMM 5.2 that provides a form (TLegendForm) for editing a map legend. The legend is used to display intervals (ranges) of a particular hydraulic/hydrologic variable in color-coded form on the SWMM map.


1. Purpose and Context

This unit creates a Legend Editor dialog that allows the user to:

  1. Define up to 5 intervals for a selected map variable (e.g., subcatchment runoff, node depth, or link flow).
  2. Assign a color to each interval.
  3. Optionally auto-generate intervals from the current min/max of the selected variable.
  4. Pick a color ramp from predefined gradient schemes or manually choose individual colors.
  5. Decide whether the legend appears with or without a frame on the map.

Because only 5 intervals are supported, the code references a constant MAXINTERVALS = 5 (though it’s effectively 5 minus 1 for distinct interval boundaries, plus one color for the top range).


2. Main Form Elements: TLegendForm

2.1 Color Boxes (Shapes)

  • Box0Box4: five TShape components that represent the color assigned to each interval boundary and the final interval.
  • A Hiliter shape that can highlight whichever color box the user clicks.

2.2 Interval Edit Controls

  • Edit1Edit5: five TEdit fields in which the user can type numeric values that define the boundaries between intervals (e.g., 0, 2, 5, 10 …).

2.3 Other Controls and Buttons

  • BtnAutoScale: automatically set interval boundaries based on the current min/max values of the selected map variable.
  • BtnColorRamp: open a “Color Ramp” dialog (from Dcolramp.pas) to pick from a predefined set of color gradients.
  • BtnReverse: reverse the order of the colors currently shown.
  • CheckFramed: toggles whether the legend is displayed in a framed box.
  • Standard OK, Cancel, and Help buttons.

3. Workflow and Data Flow

3.1 Input Data

SetData(...) is called externally to initialize the form:

  1. VarName and VarUnits: text labels for the map variable being legended (e.g., “Depth,” “inches”).
  2. Digits: number of decimal digits to display.
  3. TimePeriod: which time period (e.g., simulation timestep) this legend applies to (for min/max retrieval).
  4. Legend: a TMapLegend record that holds:
    • Intervals[]: up to 5 interval boundary values.
    • Nintervals: how many intervals are actually in use.
    • Ltype: which object category (subcatchments, nodes, or links) the legend is for.
  5. An array of TColor for each color box.
  6. A boolean that indicates whether the legend is framed (CheckFramed.Checked).

Inside SetData, the code:

  • Sets up the color boxes (Box0Box4) to use the provided colors.
  • Fills each Edit# with the corresponding numeric boundary from Legend.Intervals[] (or blank if MISSING).
  • Records the relevant legend variable info in local fields (LegendType, LegendVarIndex, etc.).

3.2 Editing the Legend

The user can:

  1. Manually edit the numeric boundary in each Edit# to define intervals.
  2. Click a color box (BoxMouseDown) to change its color via the standard ColorDialog1.
  3. Use BtnAutoScale to compute intervals from the project’s min/max of the selected variable at the chosen time step.
  4. Use BtnColorRamp to pick a standard color gradient, which updates the shape colors.
  5. Use BtnReverse to invert the current color sequence.

3.3 Validation and OK/Cancel

  • BtnOKClick calls ValidateInput:
    1. Ensures each non-blank Edit# is a valid float.
    2. Checks that the user doesn’t leave all intervals blank.
    3. Sets Modified := True if something changed.
  • If validation fails, the form remains open. Otherwise, it closes with mrOK.

3.4 Saving the Legend

GetData is called after the user presses OK to retrieve:

  1. Interval Values: The form merges any blank entries, thus “compressing” the intervals so that only non-blank ones remain.
  2. Colors: The color for each non-blank interval boundary is taken from the color box above it, and the final color from the last box.
  3. Framed: whether CheckFramed was checked.

Those updates are stored in the Legend record and the color array, which the calling code can use to redraw the map legend.


4. Notable Procedures

4.1 BtnAutoScaleClick

  • Retrieves the min and max of the selected variable (depending on LegendType—subcatchment, node, or link) from the Uoutput routines.
  • Divides the range into equal increments if feasible, placing the resulting values into Edit1..Edit5.
  • If the range is invalid (Xmax = MISSING), a warning is displayed.

4.2 BtnColorRampClick

  • Displays TColorRampForm (from Dcolramp.pas), allowing a user to pick from a set of built-in color schemes (e.g., rainbow, heatmap, etc.).
  • Copies the chosen ramp colors into Box0..Box4.

4.3 BtnReverseClick

  • Reverses the order of the colors in the boxes (box0 ↔ box4, box1 ↔ box3, etc.).

4.4 BoxMouseDown

  • When the user clicks on a shape (e.g., Box3), the code visually highlights it (Hiliter) and opens a ColorDialog.
  • On choosing a new color, that color is assigned to the shape’s Brush.Color.

5. Summary

  • Dlegend.pas provides a compact “Legend Editor” form that handles up to 5 intervals and color boxes for a SWMM map variable.
  • Users can manually define or auto-generate intervals, choose a color ramp, or pick each color individually.
  • The final result is stored in a TMapLegend record and a color array, allowing the map to be rendered with a custom legend that suits the user’s data range and color preferences.

This feature helps visualize results effectively, making it simpler to interpret and diagnose modeling outcomes within SWMM.

SWMM5 Delphi GUI Dlanduse.pas Summary

 Below is an overview of Dlanduse.pas, a Delphi unit from SWMM 5.2 that provides a dialog (TLanduseForm) for creating or editing Land Use objects. A land use can have:

  • General Properties (e.g., name, street sweeping interval)
  • Buildup properties (how pollutants accumulate)
  • Washoff properties (how pollutants wash off with runoff)

1. Purpose and Context

In SWMM, Land Use objects define how pollutants build up over time and wash off during a rainfall event. This helps simulate nonpoint source pollution loading in subcatchments. The TLanduseForm allows users to specify:

  1. General: Land use name, description, street sweeping data.
  2. Buildup: How pollutants accumulate on the land surface over time.
  3. Washoff: How pollutants are washed off by runoff or how an Event Mean Concentration (EMC) is defined.

2. Key Form Elements

2.1 Controls

  • TabControl1: Has three tabs:
    1. General (land use name, description, street cleaning)
    2. Buildup (power, exponential, saturation, or external time series)
    3. Washoff (exponential, rating curve, or EMC)
  • TPropEdit (PropEditor) on each tab to edit properties in a name/value table.
  • BuildupGrid & WashoffGrid: Hidden string grids that store pollutant-specific data for Buildup/Washoff.
  • PollutCombo: Drop-down list of pollutants for the Buildup and Washoff tabs.
  • GeneralProps: A TStringlist that holds the general land use properties.
  • OKBtn, CancelBtn, HelpBtn: Standard dialog buttons.

2.2 Property Records

Three sets of TPropRecord arrays define how each tab's properties appear in the PropEditor:

  1. DefGeneralProps (name, description, street sweeping).
  2. DefBuildupProps1 and DefBuildupProps2 (for different buildup “Function” types; EXT has different fields).
  3. DefWashoffProps (exponential, rating curve, EMC).

These records specify each property’s display label, editing style (e.g., esEdit, esComboList, esButton), valid input mask (e.g., numeric only), and other characteristics.


3. Data Structures in SWMM

3.1 TLanduse

  • Holds an array (Data[]) for general properties such as:
    • Data[COMMENT_INDEX] = Description
    • Data[LANDUSE_CLEANING_INDEX] = Street sweeping interval
    • Data[LANDUSE_AVAILABLE_INDEX] = Fraction of buildup available for sweeping
    • Data[LANDUSE_LASTCLEAN_INDEX] = Days since last sweeping
  • Contains a list of TNonpointSource objects (one per pollutant), each with:
    • BuildupData[] (array of up to five strings).
    • WashoffData[] (another array of up to five strings).

3.2 TNonpointSource

  • Manages buildup/washoff properties for one pollutant under a land use.
  • Buildup properties: function type, coefficients, normalizer, etc.
  • Washoff properties: function type, coefficients, exponent, BMP efficiency, etc.

4. Workflow and Event Handling

4.1 FormCreate

  • Creates a string list (GeneralProps) for general properties.
  • Instantiates the PropEditor, setting column titles, read-only color, event handlers (OnButtonClick, OnValidate, OnRowSelect), etc.

4.2 SetData(I: Integer)

Called to load an existing land use (index I) or start a new one:

  1. GeneralProps receives default or existing values:
    • Name, Description, Sweeping Interval, etc.
  2. BuildupGrid / WashoffGrid are sized to have one row per pollutant. Each row stores the buildup/washoff parameters for that pollutant.
  3. If I >= 0, it reads the existing land use object Project.Lists[LANDUSE].Objects[I]:
    • Copies general properties into GeneralProps.
    • Reads each pollutant’s TNonpointSource into BuildupGrid and WashoffGrid rows.

4.3 TabControl1Change

When the user switches tabs:

  • Tab 0 (General): Display DefGeneralProps in PropEditor, with data from GeneralProps.
  • Tab 1 (Buildup) or Tab 2 (Washoff): Show PollutCombo (if there are pollutants).
    • If the tab is Buildup, then either use BuildupProps1 or BuildupProps2 depending on whether the selected function is EXT. The data come from the current row of BuildupGrid (matching the selected pollutant).
    • If the tab is Washoff, display DefWashoffProps, with data from WashoffGrid.

4.4 PollutComboClick

  • The user changes the active pollutant in PollutCombo.
  • The form loads that pollutant’s buildup or washoff row in PropEditor.
  • This allows switching between pollutants’ parameters without leaving the tab.

4.5 OKBtnClick

  • Validates the land use name to ensure it isn’t blank or duplicated.
  • If valid, calls GetData to write the edited properties back to the SWMM data structures.
  • Closes the form with ModalResult := mrOK.

4.6 GetData(I: Integer)

  • Retrieves name, description, street sweeping info from GeneralProps.
  • Either updates an existing TLanduse or creates a new one if I < 0.
  • Clears any existing NonpointSource objects on that TLanduse, then for each pollutant row in BuildupGrid / WashoffGrid:
    • Creates a new TNonpointSource with those properties.
    • Adds it to the land use’s list of nonpoint sources.

4.7 Other Events

  • OnValidate (ValidateData) triggers whenever a user changes a property value in PropEditor. It sets HasChanged := True and checks if the user changed the Buildup “Function” to or from “EXT,” then reloads the correct property set.
  • OnButtonClick (EditComment): opens a text editor dialog for the land use “Description” property (the second field in GeneralProps).

5. Summary of Operation

  1. Initialization: The form is created, and SetData is called with the index of a land use in the project (or -1 if new).
  2. Editing: The user picks among tabs:
    • General: Edits name, description, sweeping parameters.
    • Buildup: Switches pollutants in PollutCombo, edits buildup parameters in PropEditor.
    • Washoff: Similarly, edits washoff properties per pollutant.
  3. Validation and Save: On OK, the code checks for a valid (non-duplicate) name, then calls GetData to write changes back to the SWMM project data structures.
  4. Result: The project now has updated land use definitions that specify how each pollutant accumulates and washes off for each land use category.

By splitting parameters into General, Buildup, and Washoff tabs, Dlanduse.pas provides a clear, tab-based editor for land use configurations—integral to modeling stormwater quality in SWMM.

SWMM5 Delphi GUI Dlabel.pas Summary

 Below is an overview of Dlabel.pas, a Delphi unit from SWMM 5.2 that provides a simple form (TLabelForm) for adding text labels to the study area map.


1. Purpose and Context

In SWMM, the user can place custom text labels onto the map to annotate features or provide additional information. The TLabelForm in this unit is a frameless modal dialog that allows the user to type a label, which is then placed at a specified map location.


2. The Form: TLabelForm

Key points:

  1. TEdit (Edit1): A single-line edit box where the user can type the text of the label.
  2. Dialog Behavior:
    • The form is frameless, so it does not have a typical caption bar or system menu.
    • It behaves like a modal dialog (the user must dismiss it before returning to the main application).

2.1 Form Layout

  • In FormCreate, the code sets the Edit1 control’s left and top to 0, and then resizes the form’s ClientWidth and ClientHeight to match the edit control’s dimensions.
  • As a result, the dialog basically appears just as a text box without surrounding borders.

2.2 Closing the Form

  • FormClose: sets Action := caFree so that when the user closes the dialog, it is destroyed and removed from memory.

2.3 Key Handlers

  • Edit1KeyPress:
    • Enter (#13): causes ModalResult := mrOK, effectively closing the dialog and returning an “OK” result.
    • Escape (#27): causes ModalResult := mrCancel, canceling the label creation.

This means the user can press Enter to confirm the typed label or Escape to cancel.


3. Summary of Operation

  1. Initialization:

    • The form and its single TEdit control are created, sized to match the TEdit’s width and height.
    • The form has no border or caption to give a minimalist text-entry appearance.
  2. User Interaction:

    • The user enters text in the TEdit box.
    • Pressing Enter closes the form with OK; pressing Escape closes it with Cancel.
  3. Result:

    • When returning with OK, the calling code can retrieve the text from Edit1.Text to place a new label on the map.
    • If Cancel, no label is created.

Thus, Dlabel.pas provides a lightweight, no-frills interface for placing user-defined text labels on the SWMM map.

SWMM5 Delphi GUI Dinletusage.pas Summary

 Below is an overview of Dinletusage.pas, a Delphi unit from SWMM 5.2 that provides a form (TInletUsageForm) to manage how a street Inlet is assigned to a conduit (link), and which node receives the intercepted flow. It allows users to choose an inlet design (created in Dinlet.pas) and specify usage properties (e.g., number of inlets, flow restriction, etc.).


1. Purpose and Context

In SWMM 5.2, each conduit (link) can optionally have an inlet assigned that intercepts gutter or overland flow. The Dinletusage form:

  1. Lets the user pick which inlet design to apply (from among those listed in the project's inlets).
  2. Defines the receiver node (a node where the inlet’s captured flow is routed).
  3. Sets additional properties specific to the application of that inlet (e.g., “percent clogged,” “flow restriction,” “depression geometry,” etc.).

This allows SWMM to model partial street flow interception along a conduit, sending the intercepted flow to a specified node in the drainage network.


2. Key Classes and Data

2.1 TInletUsageForm

  • The main form with:
    • A TPropEdit control (PropEdit1) that displays property names/values in a grid-like format.
    • A string list (PropList) that holds the textual property values corresponding to the TInletUsage object associated with the conduit.
    • Image, buttons (OkBtn, CancelBtn, HelpBtn), panels, and a label for hints.

2.2 TInletUsage Object

  • Each conduit may contain a TInletUsage reference (TheLink.Inlet) that stores:
    • Inlet: a reference to a TInlet design (see Dinlet.pas).
    • InletNode: the node that receives the captured flow.
    • Data[]: an array of strings holding numerical or text properties (number of inlets, % clogged, etc.).

2.3 Constants and Structures

  • PropNames[]: The names of the properties displayed in the property editor, e.g.:

    1. “Inlet Structure”
    2. “Capture Node”
    3. “Number of Inlets”
    4. “Percent Clogged”
    5. “Flow Restriction”
    6. “Depression Height”
    7. “Depression Width”
    8. “Inlet Placement”
  • PropHints[]: Tooltips describing each property.

  • PropEdit1 (a TPropEdit) is configured so each row in the property grid corresponds to one item in PropNames[].

  • DefaultProps: A multiline string that initializes property defaults if an inlet usage doesn’t exist yet.


3. Form Lifecycle

3.1 FormCreate

  1. Sets up the property editor (PropEdit1) with column headings (e.g., “Property,” “Value”) and styling.
  2. Creates a TStringList (PropList) that will store property values.
  3. Initializes each TPropRecord in InletProps[], specifying:
    • Display name (from PropNames[]).
    • Style (e.g., esComboList, esEdit, etc.).
    • Allowed numeric or text masks.

3.2 SetData

SetData(Index: Integer; InletDesigns: String);

  • Called externally to populate the form with data for a particular conduit (Index) and the list of available inlet designs (InletDesigns).
  • Looks up the conduit object (TheLink) in Project.Lists[CONDUIT].
  • If the conduit has no inlet usage yet, sets PropList to default property strings. Otherwise loads property values from the existing TInletUsage object (TheUsedInlet).
  • Updates the property record for “Inlet Structure” to list available inlet designs.
  • Sets the form’s caption to “Inlet for Conduit [link ID]”.

3.3 FormShow

  • Positions the form near the standard property editor form (PropEditForm.Left, PropEditForm.Top).
  • Calls PropEdit1.SetProps(InletProps, PropList) so the property editor displays the property records with the current values from PropList.
  • Then calls PropEdit1.Edit to enter editing mode.

3.4 User Interaction

  • The user edits values in the property grid:

    • “Inlet Structure” (pick from combo box).
    • “Capture Node” (typed in or assigned via SetReceiverNode).
    • “Number of Inlets,” “Percent Clogged,” etc.
    • “Inlet Placement” (ON_GRADE, ON_SAG, or AUTOMATIC).
  • The user may also close the form with OK (save changes) or Cancel.

3.5 FormClose and OkBtnClick

  • OkBtnClick checks for:
    1. A valid inlet name (if provided).
    2. A valid capture node ID.
    • If invalid, it shows an error dialog. Otherwise, it updates the underlying conduit’s inlet usage with GetData.
  • FormClose updates the main interface (Browser, Map, etc.) to reflect any changes.

4. Data Synchronization

4.1 GetData(aNode: TNode): String

After the user clicks OK, the code calls GetData to:

  1. Ensure the “Inlet Structure” field is not empty.
  2. If empty and the conduit had an inlet usage object, it frees it and sets TheLink.Inlet to nil.
  3. Otherwise, if an inlet usage object doesn’t exist yet, it creates a new TInletUsage.
  4. Looks up the chosen inlet design from Project.Lists[INLET] and assigns it to TheUsedInlet.Inlet.
  5. Sets TheUsedInlet.InletNode to the node object passed in.
  6. Copies the property values from PropList into TheUsedInlet.Data[].
  7. Triggers a map redraw if needed (e.g., if a new inlet was added or removed).

The function returns 'YES' if an inlet was assigned, or 'NO' if it was cleared.

4.2 SetReceiverNode(ObjType: Integer; ObjIndex: Integer)

  • Called when the user picks a node from somewhere else in the GUI (like on the map).
  • Updates the Capture Node property in PropList and marks the form as modified.

5. Summary of Operation

  1. Loading: SetData is called to display existing inlet usage for a chosen conduit (or defaults if no inlet is assigned).
  2. Editing: The user changes property values in PropEdit1, possibly assigning a new inlet structure or capture node.
  3. Validation: OkBtnClick ensures the capture node is valid and finalizes the property editor.
  4. Saving: GetData writes back to the underlying TInletUsage object, linking it to both an inlet design and a receiver node. The project is then updated accordingly.
  5. Map Refresh: The map and browser are refreshed to display inlet usage status for the conduit.

Overall, Dinletusage.pas provides a concise, property-grid-based approach to assigning an inlet design to a conduit and specifying to which node (if any) the intercepted flow is diverted. This allows more fine-grained modeling of surface inlets and how they connect back into the larger drainage network.

InfoSWMM: A 2030 AI-Assisted Study Guide

  InfoSWMM: A 2030 AI-Assisted Study Guide delete   InfoSWMM: A 2030 AI-Assisted Study Guide A comprehensive study guide for someone in 2030...