![]() |
SWMMVis
6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
|
Pure-logic data assembly for Slice BC's longitudinal profile plot: chainage, HGL/EGL time-series, and min/max envelopes. More...
#include <QDateTime>#include <QPointF>#include <QString>#include <QVector>#include <limits>Go to the source code of this file.
Classes | |
| struct | ProfileBuilder::BranchLink |
| One link incident to a path node, described from that node's point of view. More... | |
| struct | ProfileBuilder::NodeStatic |
Time-invariant per-node properties needed by the profile plot. The "rim" elevation is always invertElev + maxDepth — terrain DEMs only override the ground line drawn behind the manhole glyph (see PathStatic::terrainSamples), never the rim itself. More... | |
| struct | ProfileBuilder::LinkStatic |
| Time-invariant per-link properties. Only links present on the chosen path are populated. Indices in PathStatic::links are 0..N-1 where N == PathStatic::nodes.size() - 1, and link[i] joins node[i] → node[i+1] in path-traversal order (which may differ from the underlying model link's intrinsic from/to direction when the router operated in undirected mode). More... | |
| struct | ProfileBuilder::PathStatic |
A fully-resolved profile path: ordered nodes, joining links, and cumulative chainage from nodes[0] to each subsequent node. chainage.size() == nodes.size() and chainage[0] == 0.0. More... | |
| struct | ProfileBuilder::SourceSeries |
Pre-fetched per-source time-series. One instance per SWMMResultsLayer that the user wants to overlay on the plot. More... | |
| struct | ProfileBuilder::SourceDerived |
Output of compute(): per-source HGL/EGL series and per-node envelope min/max. Sized to match the input SourceSeries. More... | |
| struct | ProfileBuilder::Diagnostic |
Returned from validate() to flag malformed inputs without triggering exceptions. Empty error means "OK". More... | |
Namespaces | |
| namespace | ProfileBuilder |
Functions | |
| QVector< double > | ProfileBuilder::computeChainage (const QVector< LinkStatic > &links) |
Computes cumulative chainage from the first node. chainage[0] = 0.0, chainage[i] = chainage[i-1] + links[i-1].length. Returns the populated array — does not mutate path. | |
| double | ProfileBuilder::groundElev (const NodeStatic &n) |
Returns the ground elevation at node i along the path. Equivalent to nodes[i].invertElev + nodes[i].maxDepth. | |
| double | ProfileBuilder::conduitInvertUpstream (const PathStatic &path, int linkIdx) |
Returns the conduit-invert elevation at the upstream end of link i along the path: nodes[i].invertElev + links[i].offset1. | |
| double | ProfileBuilder::conduitInvertDownstream (const PathStatic &path, int linkIdx) |
Symmetric to conduitInvertUpstream for the downstream end: nodes[i+1].invertElev + links[i].offset2. | |
| double | ProfileBuilder::velocityHead (const PathStatic &path, const SourceSeries &src, int nodeIdx, int period, double gravity) |
Velocity-head at node nodeIdx for the given source at period p, using the path-direction convention: head node uses downstream velocity only, tail node uses upstream only, interior nodes average the two incident links. Returns 0.0 if velocity data is missing or the period is out of range. Uses |v|. | |
| double | ProfileBuilder::eglAtPeriod (const PathStatic &path, const SourceSeries &src, int nodeIdx, int period, double gravity) |
Convenience: EGL at node nodeIdx, period p = HGL(nodeIdx, p) + velocityHead(nodeIdx, p, g). | |
| Diagnostic | ProfileBuilder::validate (const PathStatic &path, const SourceSeries &src) |
| Sanity-checks a PathStatic + SourceSeries pair before compute(). Catches: empty path (< 2 nodes), links-count mismatch (must be nodes-1), mismatched series array sizes vs path size, zero report step on a non-empty series, etc. | |
| SourceDerived | ProfileBuilder::compute (const PathStatic &path, const SourceSeries &src, double gravity) |
Builds per-node HGL/EGL time-series and per-node envelope min/max for a single source. Assumes the input has passed validate(). Returns an empty SourceDerived on validation failure. | |
| bool | ProfileBuilder::appendPeriods (const PathStatic &path, const SourceSeries &src, double gravity, SourceDerived &derived) |
Live results: extend a SourceDerived built over the first derived.hglByPeriod.size() periods of src with the periods src has gained since. src must be the full (grown) series. Appends one period-major row per new period and updates the running envelopes; the result is identical to compute() over the whole series (both use accumulatePeriod). Returns false and leaves derived untouched when src does not validate, has fewer periods than derived, or derived is not a compute() of this path. A no-op success when nothing was appended. | |
| void | ProfileBuilder::accumulatePeriod (const PathStatic &path, const SourceSeries &src, int p, double gravity, SourceDerived &out) |
The per-period kernel shared by compute() and appendPeriods(): fills period p's rows of out (which must already be sized and NaN-filled for p) and folds the values into the envelopes. | |
Variables | |
| constexpr double | ProfileBuilder::kGravityFps2 = 32.174 |
Standard gravitational acceleration in the two unit systems SWMM supports. Caller passes whichever applies to its .out file. | |
| constexpr double | ProfileBuilder::kGravityMps2 = 9.80665 |
| constexpr double | ProfileBuilder::kNoBearing = 1.0e9 |
Pure-logic data assembly for Slice BC's longitudinal profile plot: chainage, HGL/EGL time-series, and min/max envelopes.
ProfileBuilder is intentionally decoupled from SWMMModelLayer and the engine output reader so it can be unit-tested without a live model: the caller pre-fetches static topology (NodeStatic / LinkStatic) and full per-source time-series (SourceSeries) and hands them in; the builder derives HGL, EGL, and envelopes.
Rendering conventions assumed by callers (see ProfilePlotWidget):
invertElev + maxDepth (NodeStatic carries both; no DEM is consulted in v1).length, offset1 (upstream invert offset), offset2 (downstream invert offset), and maxDepth (conduit max cross-section depth).HGL + v² / (2·g) because the engine exposes no first-class energy-grade output.