Sunday, December 29, 2024

SWMM5 Delphi GUI Ucoords.pas Summary

 Extended and Expanded Summary of Ucoords.pas

This Delphi unit, Ucoords.pas, is part of the EPA SWMM project. It provides functionality to:

  1. Compute the bounding (min/max) coordinates of all geometry in the model.
  2. Transform (i.e., rescale and shift) all map object coordinates from one bounding rectangle to another.

1. Overview of Key Procedures

There are two main procedures in this unit:

  1. GetCoordExtents(var X1, Y1, X2, Y2: Extended)
    Determines the minimal bounding rectangle that encloses all map objects in the project. The bounding rectangle is described by the coordinates (X1,Y1)(X_1, Y_1) (bottom-left corner) and (X2,Y2)(X_2, Y_2) (top-right corner).

  2. TransformCoords(LL1, UR1, LL2, UR2: TExtendedPoint)
    Applies a linear coordinate transform to all map objects. The transform is from an old bounding rectangle (LL1,UR1)(LL1, UR1) to a new bounding rectangle (LL2,UR2)(LL2, UR2).

Data Types & Structures

  • Extended: A floating-point type used for coordinates.
  • TExtendedPoint: A record containing X and Y fields of type Extended.
  • Project: A global data structure containing lists of objects for all object categories (e.g., subcatchments, nodes, links, labels, etc.).
  • PVertex: A pointer to a linked list node used to store polygon or polyline coordinates of subcatchments and links.

2. The GetCoordExtents Procedure

procedure GetCoordExtents(var X1: Extended; var Y1: Extended;
                          var X2: Extended; var Y2: Extended);

Purpose:
Finds the minimum and maximum X and Y coordinates over all relevant objects in the SWMM project.

Key Steps:

  1. Initialize bounding values

    • X1 := -MISSING; X2 := MISSING;
    • Y1 := -MISSING; Y2 := MISSING;

    Note that MISSING is a special constant used to designate "no coordinate". -MISSING is effectively negative infinity, and MISSING is positive infinity for the logic.

  2. Loop Over Object Categories (I from 0 to MAXCLASS)

    • For each category, the procedure checks if it is a "visual" object type that stores coordinates (e.g., subcatchments, nodes, rain gages, etc.).
    • If so, gather X and Y values into the bounding extents.

    Specifically:

    • Rain gages (I = RAINGAGE): Each gage has a single (X, Y) location.
    • Nodes (Project.IsNode(I)): Each node also has a single (X, Y).
    • Subcatchments (Project.IsSubcatch(I)): Each subcatch can have a polygon of vertices. The code loops through these vertex lists to find min and max X, Y.
  3. Expand Extents Slightly
    If final bounding box is degenerate in X or Y (same min and max), it adjusts it by some small fraction so that the bounding area is non-zero. Specifically, it expands the bounding box by 5% of the range in each dimension.

  4. Returning:

    • On exit, X1, Y1 will be the minimum coordinate in each dimension.
    • X2, Y2 will be the maximum coordinate in each dimension.

In summary, you get a bounding rectangle that encloses all geometry with a small margin added.


3. The TransformCoords Procedure

procedure TransformCoords(LL1, UR1, LL2, UR2: TExtendedPoint);

Purpose:
Transforms all map coordinates from bounding box (LL1, UR1) to box (LL2, UR2).

Where:

  • LL1, UR1 = old lower-left & upper-right corners
  • LL2, UR2 = new lower-left & upper-right corners

Key Steps:

  1. Compute the Scale Factors

    • Xscale := (UR2.X - LL2.X) / (UR1.X - LL1.X)
    • Yscale := (UR2.Y - LL2.Y) / (UR1.Y - LL1.Y)

    This effectively means that any coordinate X in [LL1.X, UR1.X] is mapped into [LL2.X, UR2.X] linearly.

  2. Define Local Transform Helper Functions

    • Xtransform(X: Extended): Extended
    • Ytransform(Y: Extended): Extended

    If X or Y is MISSING, it remains MISSING; otherwise it’s a direct linear scaling from the old domain to the new domain.

  3. Loop Over All SWMM Objects

    • Rain gage => transform (X, Y)
    • Subcatchment => transform (X, Y) centroid and each vertex in its polygon.
    • Node => transform (X, Y) for each node.
    • Link => transform each vertex in the link’s polyline Vlist.
    • Map label => transform (X, Y) location.

All geometry is thus re-scaled and shifted so that the old bounding box is effectively mapped onto the new bounding box.


4. Implementation Details

  1. Global Variables:
    • Xscale, Yscale: Computed once in TransformCoords to store the scale factors.
  2. Local Helper:
    • AdjustExtents inside GetCoordExtents is used to handle degenerate bounding boxes by expanding them a bit.
  3. Project:
    The Project has lists of different object types—some are in memory as TNode, TLink, TSubcatch, TRainGage, TMapLabel, etc.
  4. MISSING:
    A sentinel constant used to represent nonexistent or undefined coordinates.
  5. Map:
    • Rain gages store a single (X, Y) coordinate.
    • Subcatchments store a centroid plus a polygon (Vlist).
    • Nodes store a single (X, Y).
    • Links store a set of polyline vertices.
    • Labels store a single (X, Y).

5. Error Handling & Edge Cases

  • GetCoordExtents checks whether all coordinates might remain at default values (X1 = -MISSING or X2 = MISSING) if no geometry is present.
  • If X1 = X2 or Y1 = Y2 after reading geometry, they get expanded by 5% or by ±5 units if the bounding coordinate is 0.
  • TransformCoords does nothing if old bounding box (UR1.X - LL1.X) or (UR1.Y - LL1.Y) is zero (to avoid division by zero).

6. Summary

In short, the unit Ucoords.pas provides two main functionalities for managing geometry in an EPA SWMM project:

  1. GetCoordExtents collects the min and max X,Y coordinates from all map objects (rain gages, subcatchments, nodes, links, map labels), returning a bounding rectangle that encloses all geometry.

  2. TransformCoords linearly rescales every coordinate from an old bounding rectangle to a new one. This is especially useful when you want to reposition or re-scale the entire model map (e.g., after reading a background image or changing projection units).

These routines are typically called by the main user interface or other geometry-handling routines whenever a bounding view is required or map coordinates need re-scaling.

No comments:

A comprehensive explanation of how minimum travel distance relates to link length in InfoSewer

In hydraulic modeling of sewer networks, the minimum travel distance is a fundamental parameter that affects how accurately the model can si...