![]() |
SWMMVis
6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
|
The central map display widget — QGIS-style hybrid rendering. More...
#include <mapcanvas.h>
Public Types | |
| enum | DirtyChannel { NoChannel = 0x0 , Raster = 0x1 , Scene = 0x2 , Overlay = 0x4 , Extent = 0x8 } |
| Independent redraw channels — see Phase 0.9 in the GUI implementation plan. Each channel has a separate debounce timer so cheap updates don't pay for expensive ones. More... | |
Public Slots | |
| void | flashSelection () |
| Flash + beacon the CURRENT selection. | |
| void | clearSelectionBeacon () |
| Drops a standing beacon (a new selection has superseded it). | |
Signals | |
| void | extentChanged (const MapExtent &extent) |
| void | scaleChanged (double scale) |
| void | canvasSRSChanged (SpatialReferenceSystem *srs) |
| void | layerAdded (OpenSWMMVisLayer *layer) |
| void | layerRemoved (OpenSWMMVisLayer *layer) |
| void | layerOrderChanged () |
| void | sublayerOrderChanged (OpenSWMMVisLayer *host) |
| void | activeToolChanged (OpenSWMMVisMapTool *tool) |
| void | cursorPositionChanged (double mapX, double mapY) |
| void | showScaleBarChanged (bool show) |
| void | showCoordinatesChanged (bool show) |
| void | maxUndoCountChanged (int count) |
| void | backgroundColorChanged (const QColor &color) |
Public Member Functions | |
| MapCanvas (QWidget *parent=nullptr) | |
| ~MapCanvas () override | |
| OpenSWMMVisScene * | mapScene () const |
| OpenSWMMVisGraphicsView * | overlayView () const |
| SpatialReferenceSystem * | canvasSRS () const |
| void | setCanvasSRS (SpatialReferenceSystem *srs, bool ownsSRS=false) |
| bool | setCanvasSRSByCode (const QString &authName, int code) |
| MapExtent | extent () const |
| void | setExtent (const MapExtent &extent, bool pushUndo=true) |
| void | zoomToFullExtent () |
| void | zoomIn (double factor=2.0) |
| void | zoomOut (double factor=2.0) |
| void | pan (double dx, double dy) |
| double | scale () const |
| double | scaleDenominator () const |
| Current scale as a 1:N denominator, DPI-aware and CRS-aware. | |
| void | setScaleDenominator (double denom) |
Zoom the view to exactly the given 1:N scale, preserving the current centre point and canvas aspect ratio. CRS-aware: the physical metres-per-pixel implied by denom is converted back to map units using the canvas SRS (cosine-latitude for geographic, linearUnitsToMetres for projected). | |
| void | translateViewBy (int dx, int dy) |
| Smooth-pan the view by (dx, dy) screen pixels without updating m_extent or triggering tile reloads. Call endPan() on release. | |
| void | zoomAroundCursor (double factor, const QPoint &viewportPos) |
Zoom the view by factor anchored at viewportPos, then sync m_extent and schedule a tile refresh. | |
| void | syncExtentFromView () |
| Recompute m_extent from the current overlay view transform. Call after translateViewBy() or direct transform manipulation. | |
| const QList< OpenSWMMVisLayer * > & | layers () const |
| void | addLayer (OpenSWMMVisLayer *layer, bool pushUndo=true) |
| void | insertLayer (int position, OpenSWMMVisLayer *layer, bool pushUndo=true) |
| OpenSWMMVisLayer * | takeLayer (int index, bool pushUndo=true) |
| void | moveLayer (int fromIndex, int toIndex, bool pushUndo=true) |
| void | reorderLayers (const QList< OpenSWMMVisLayer * > &newOrder, bool pushUndo=true) |
Atomically reorder the entire layer stack to match newOrder. | |
| int | layerCount () const |
| OpenSWMMVisLayer * | layerAt (int index) const |
| MapExtent | fullExtent () const |
| QVector< int > | layerGroupOrder () const |
| void | setLayerGroupOrder (const QVector< int > &order) |
| void | setPendingLayerOrder (const QStringList &keysBottomToTop) |
| QStringList | pendingLayerOrder () const |
| int | groupedInsertPosition (const OpenSWMMVisLayer *layer) const |
| bool | moveSublayer (OpenSWMMVisLayer *host, int from, int to, bool pushUndo=true) |
| MapExtent | extentInCanvasCRS (const OpenSWMMVisLayer *layer, const MapExtent &nativeExtent) const |
Reproject nativeExtent from layer's CRS into canvas CRS by transforming its four corners. Returns the unmodified extent when the CRSes match or when either SRS is unavailable. | |
| MapExtent | layerExtentInCanvasCRS (const OpenSWMMVisLayer *layer) const |
Convenience overload: reprojects the full extent of layer. | |
| OpenSWMMVisMapTool * | activeTool () const |
| void | setActiveTool (OpenSWMMVisMapTool *tool) |
| void | setMeshProfileOverlay (MeshProfileOverlay *overlay) |
| Bind the 2D-mesh profile overlay (line + position marker) drawn ON TOP of every map layer — including the QSG flood-map mesh, which a QGraphicsScene item can't sit above. Pass null to detach. The overlay is owned by MeshProfilePlotDialog / RasterProfilePlotDialog, not the canvas. Only one is bound at a time: a newer trace displaces an older one, so a dialog must check it still owns the binding (see meshProfileOverlay) before detaching on close. | |
| MeshProfileOverlay * | meshProfileOverlay () const |
| The currently bound profile overlay, or null. Lets a closing profile dialog detach only when the binding is still its own. | |
| void | setProfilePathOverlay (ProfilePathOverlay *overlay) |
| Bind the 1D profile-path candidate/accepted overlay. Painted above the QSG result frame so profile paths are not obscured by 1D/2D result layers. The profile selection tool owns the object. | |
| SelectionBeaconOverlay * | selectionBeacon () const |
| Locator for the current selection — flashes on change, then leaves a fixed-size beacon so a selected feature stays findable at model-wide zoom, where its own halo is sub-pixel. Owned by the canvas; refreshed from every visible SWMMModelLayer's selectionChanged. | |
| MapUndoStack * | undoStack () const |
| int | maxUndoCount () const |
| void | setMaxUndoCount (int count) |
| bool | showScaleBar () const |
| void | setShowScaleBar (bool show) |
| bool | showCoordinates () const |
| void | setShowCoordinates (bool show) |
| void | setTerrainElevation (const std::optional< double > &z) |
| Sets the terrain elevation to display alongside X/Y in the coordinate overlay. Pass an empty optional to hide the Z field. The value is in model vertical units (not converted here). | |
| void | setTerrainUnit (const QString &unit) |
| std::optional< double > | terrainZ () const |
| QString | terrainUnit () const |
| QColor | backgroundColor () const |
| void | setBackgroundColor (const QColor &color) |
| ScaleBarSettings * | scaleBarSettings () const |
| void | toMapCoords (int px, int py, double &mapX, double &mapY) const |
| void | toPixelCoords (double mapX, double mapY, int &px, int &py) const |
| void | invalidate (DirtyChannels channels, const QString &reason=QString()) |
| Single entry point for dirtying one or more rendering channels. | |
| void | suspendRefresh () |
| Bracket a batch of invalidate() calls so they fire once. Reference-counted — nested pairs are safe. On the matching resume() that brings the count back to zero, any pending channels fire at once. | |
| void | resumeRefresh () |
| void | refresh () |
| void | refreshLayerItems () |
| void | beginPan () |
| void | endPan () |
| bool | isPanning () const |
| void | applyCRSInternal (SpatialReferenceSystem *srs, bool ownsSRS) |
Static Public Member Functions | |
| static QString | layerOrderKey (const OpenSWMMVisLayer *layer) |
Protected Member Functions | |
| void | paintEvent (QPaintEvent *event) override |
| void | resizeEvent (QResizeEvent *event) override |
| void | showEvent (QShowEvent *event) override |
| void | hideEvent (QHideEvent *event) override |
| void | mousePressEvent (QMouseEvent *event) override |
| void | mouseMoveEvent (QMouseEvent *event) override |
| void | mouseReleaseEvent (QMouseEvent *event) override |
| void | mouseDoubleClickEvent (QMouseEvent *event) override |
| void | wheelEvent (QWheelEvent *event) override |
| void | keyPressEvent (QKeyEvent *event) override |
| void | keyReleaseEvent (QKeyEvent *event) override |
| bool | event (QEvent *event) override |
| void | gestureEvent (QGestureEvent *event) |
Properties | |
| MapExtent | extent |
| double | scale |
| bool | showScaleBar |
| bool | showCoordinates |
| int | maxUndoCount |
| QColor | backgroundColor |
| ScaleBarSettings * | scaleBarSettings |
The central map display widget — QGIS-style hybrid rendering.
MapCanvas uses a two-layer compositing approach inspired by QGIS:
Layer 1 — Raster buffer (WMS, WMTS, GIS rasters) Raster layers are rendered into an off-screen QImage (m_mapBuffer) by a background MapRenderJob. The buffer is blitted to the screen in paintEvent(). During a pan or zoom gesture the previous buffer is shown shifted/scaled via a preview transform for instant visual feedback.
Layer 2 — QGraphicsView overlay (SWMM nodes, links, GIS vectors) Interactive vector items live in a QGraphicsScene managed by a transparent OpenSWMMVisGraphicsView child widget stacked on top. The overlay uses a matching map→pixel transform and provides Qt's BSP-tree hit-testing and selection.
Coordinate systems:
Independent redraw channels — see Phase 0.9 in the GUI implementation plan. Each channel has a separate debounce timer so cheap updates don't pay for expensive ones.
|
explicit |
|
override |
| OpenSWMMVisMapTool * MapCanvas::activeTool | ( | ) | const |
|
signal |
| void MapCanvas::addLayer | ( | OpenSWMMVisLayer * | layer, |
| bool | pushUndo = true |
||
| ) |
| void MapCanvas::applyCRSInternal | ( | SpatialReferenceSystem * | srs, |
| bool | ownsSRS | ||
| ) |
| QColor MapCanvas::backgroundColor | ( | ) | const |
|
signal |
| void MapCanvas::beginPan | ( | ) |
| SpatialReferenceSystem * MapCanvas::canvasSRS | ( | ) | const |
|
signal |
|
slot |
Drops a standing beacon (a new selection has superseded it).
| void MapCanvas::endPan | ( | ) |
|
overrideprotected |
Override event so tooltip requests can pick the hovered SWMM object through each visible SWMMModelLayer's pickAt API (Slice R Phase 4). No tool activation needed — hover tooltips fire while any tool is active. Also dispatches QEvent::Gesture to gestureEvent so two-finger pinch (Slice AV) zooms the canvas regardless of the active map tool.
| MapExtent MapCanvas::extent | ( | ) | const |
|
signal |
| MapExtent MapCanvas::extentInCanvasCRS | ( | const OpenSWMMVisLayer * | layer, |
| const MapExtent & | nativeExtent | ||
| ) | const |
Reproject nativeExtent from layer's CRS into canvas CRS by transforming its four corners. Returns the unmodified extent when the CRSes match or when either SRS is unavailable.
|
slot |
Flash + beacon the CURRENT selection.
Deliberately explicit rather than automatic. The beacon answers "where is the thing I just picked?", which only needs asking when the selection came from somewhere non-spatial — the attribute table. Pick a feature on the map and you already know where it is, so firing a beacon there is noise. Any selection change from another source clears a standing beacon (see clearSelectionBeacon).
| MapExtent MapCanvas::fullExtent | ( | ) | const |
|
protected |
Handle pinch gestures (touchscreen + Precision touchpad). Delegates to zoomAroundCursor so behaviour matches wheel-zoom.
| int MapCanvas::groupedInsertPosition | ( | const OpenSWMMVisLayer * | layer | ) | const |
Stack index addLayer() will insert layer at: its saved-order slot when pendingLayerOrder() names it, otherwise the top of its category group (or the group's slot per layerGroupOrder() when the group is still empty).
|
overrideprotected |
| void MapCanvas::insertLayer | ( | int | position, |
| OpenSWMMVisLayer * | layer, | ||
| bool | pushUndo = true |
||
| ) |
| void MapCanvas::invalidate | ( | DirtyChannels | channels, |
| const QString & | reason = QString() |
||
| ) |
Single entry point for dirtying one or more rendering channels.
Independent per-channel timers coalesce bursts. Call from any place that mutates state a user would see on screen. Pass reason to feed the SWMMVIS_LOG_REDRAW instrumentation (the string appears in the log so regressions are spottable in CI screenshots / output capture).
| bool MapCanvas::isPanning | ( | ) | const |
|
overrideprotected |
|
overrideprotected |
|
signal |
| OpenSWMMVisLayer * MapCanvas::layerAt | ( | int | index | ) | const |
| int MapCanvas::layerCount | ( | ) | const |
| MapExtent MapCanvas::layerExtentInCanvasCRS | ( | const OpenSWMMVisLayer * | layer | ) | const |
Convenience overload: reprojects the full extent of layer.
| QVector< int > MapCanvas::layerGroupOrder | ( | ) | const |
Per-project top-to-bottom category order (CategoryId ints, every id exactly once). Seeded from kDefaultCategoryDisplayOrder until the user reorders a group or a saved order is applied.
|
signal |
|
static |
Stable identity of a layer for the .oswp layerOrder round-trip: "<layerType>|<sourceDescription>|<name>".
|
signal |
| const QList< OpenSWMMVisLayer * > & MapCanvas::layers | ( | ) | const |
| OpenSWMMVisScene * MapCanvas::mapScene | ( | ) | const |
| int MapCanvas::maxUndoCount | ( | ) | const |
|
signal |
|
inline |
The currently bound profile overlay, or null. Lets a closing profile dialog detach only when the binding is still its own.
|
overrideprotected |
|
overrideprotected |
|
overrideprotected |
|
overrideprotected |
| void MapCanvas::moveLayer | ( | int | fromIndex, |
| int | toIndex, | ||
| bool | pushUndo = true |
||
| ) |
| bool MapCanvas::moveSublayer | ( | OpenSWMMVisLayer * | host, |
| int | from, | ||
| int | to, | ||
| bool | pushUndo = true |
||
| ) |
Reorder a sublayer of host (an ISublayerHost layer in this stack) from paint index from to to. Pushes a MoveSublayerCommand when pushUndo; emits sublayerOrderChanged(host) on success so the layer tree can rebuild its sub-rows.
| OpenSWMMVisGraphicsView * MapCanvas::overlayView | ( | ) | const |
|
overrideprotected |
| QStringList MapCanvas::pendingLayerOrder | ( | ) | const |
| void MapCanvas::refresh | ( | ) |
| void MapCanvas::refreshLayerItems | ( | ) |
| void MapCanvas::reorderLayers | ( | const QList< OpenSWMMVisLayer * > & | newOrder, |
| bool | pushUndo = true |
||
| ) |
Atomically reorder the entire layer stack to match newOrder.
newOrder must be a permutation of the current layer list (same pointers, different sequence). A single undo command is pushed when pushUndo is true (default). Used by the layer tree panel when whole category groups are dragged to new positions.
|
overrideprotected |
| void MapCanvas::resumeRefresh | ( | ) |
| double MapCanvas::scale | ( | ) | const |
| ScaleBarSettings * MapCanvas::scaleBarSettings | ( | ) | const |
|
signal |
| double MapCanvas::scaleDenominator | ( | ) | const |
Current scale as a 1:N denominator, DPI-aware and CRS-aware.
Uses the actual screen DPI (logicalDotsPerInchX) so the readout is accurate on Retina / HiDPI displays, where the previous hardcoded 96 DPI assumption was off by ~2×. Falls back to 96 DPI when no screen is attached (e.g. during construction).
|
inline |
Locator for the current selection — flashes on change, then leaves a fixed-size beacon so a selected feature stays findable at model-wide zoom, where its own halo is sub-pixel. Owned by the canvas; refreshed from every visible SWMMModelLayer's selectionChanged.
| void MapCanvas::setActiveTool | ( | OpenSWMMVisMapTool * | tool | ) |
| void MapCanvas::setBackgroundColor | ( | const QColor & | color | ) |
| void MapCanvas::setCanvasSRS | ( | SpatialReferenceSystem * | srs, |
| bool | ownsSRS = false |
||
| ) |
| bool MapCanvas::setCanvasSRSByCode | ( | const QString & | authName, |
| int | code | ||
| ) |
| void MapCanvas::setExtent | ( | const MapExtent & | extent, |
| bool | pushUndo = true |
||
| ) |
| void MapCanvas::setLayerGroupOrder | ( | const QVector< int > & | order | ) |
Replaces the group order. Rejects anything that is not a permutation of [0, CatCount). Not undoable — it is a display preference; the accompanying reorderLayers() call is the undoable part.
| void MapCanvas::setMaxUndoCount | ( | int | count | ) |
| void MapCanvas::setMeshProfileOverlay | ( | MeshProfileOverlay * | overlay | ) |
Bind the 2D-mesh profile overlay (line + position marker) drawn ON TOP of every map layer — including the QSG flood-map mesh, which a QGraphicsScene item can't sit above. Pass null to detach. The overlay is owned by MeshProfilePlotDialog / RasterProfilePlotDialog, not the canvas. Only one is bound at a time: a newer trace displaces an older one, so a dialog must check it still owns the binding (see meshProfileOverlay) before detaching on close.
| void MapCanvas::setPendingLayerOrder | ( | const QStringList & | keysBottomToTop | ) |
Saved stack order (layerOrderKey() values, bottom → top) applied incrementally by addLayer() as layers arrive during project load — layers open asynchronously, so there is no single "load finished" moment to reorder at. A layer whose key is not listed falls back to the grouped insert.
| void MapCanvas::setProfilePathOverlay | ( | ProfilePathOverlay * | overlay | ) |
Bind the 1D profile-path candidate/accepted overlay. Painted above the QSG result frame so profile paths are not obscured by 1D/2D result layers. The profile selection tool owns the object.
| void MapCanvas::setScaleDenominator | ( | double | denom | ) |
Zoom the view to exactly the given 1:N scale, preserving the current centre point and canvas aspect ratio. CRS-aware: the physical metres-per-pixel implied by denom is converted back to map units using the canvas SRS (cosine-latitude for geographic, linearUnitsToMetres for projected).
| void MapCanvas::setShowCoordinates | ( | bool | show | ) |
| void MapCanvas::setShowScaleBar | ( | bool | show | ) |
| void MapCanvas::setTerrainElevation | ( | const std::optional< double > & | z | ) |
Sets the terrain elevation to display alongside X/Y in the coordinate overlay. Pass an empty optional to hide the Z field. The value is in model vertical units (not converted here).
| void MapCanvas::setTerrainUnit | ( | const QString & | unit | ) |
Sets the vertical unit label shown alongside the terrain Z value ("ft" or "m").
| bool MapCanvas::showCoordinates | ( | ) | const |
|
signal |
|
overrideprotected |
| bool MapCanvas::showScaleBar | ( | ) | const |
|
signal |
|
signal |
A sublayer of host changed paint position (moveSublayer()).
| void MapCanvas::suspendRefresh | ( | ) |
Bracket a batch of invalidate() calls so they fire once. Reference-counted — nested pairs are safe. On the matching resume() that brings the count back to zero, any pending channels fire at once.
| void MapCanvas::syncExtentFromView | ( | ) |
Recompute m_extent from the current overlay view transform. Call after translateViewBy() or direct transform manipulation.
| OpenSWMMVisLayer * MapCanvas::takeLayer | ( | int | index, |
| bool | pushUndo = true |
||
| ) |
|
inline |
Returns the vertical unit label currently assigned to the terrain Z display.
|
inline |
Returns the most-recently-sampled terrain elevation, or an empty optional when no terrain is active or the cursor is out of extent.
| void MapCanvas::translateViewBy | ( | int | dx, |
| int | dy | ||
| ) |
Smooth-pan the view by (dx, dy) screen pixels without updating m_extent or triggering tile reloads. Call endPan() on release.
| MapUndoStack * MapCanvas::undoStack | ( | ) | const |
|
overrideprotected |
| void MapCanvas::zoomAroundCursor | ( | double | factor, |
| const QPoint & | viewportPos | ||
| ) |
Zoom the view by factor anchored at viewportPos, then sync m_extent and schedule a tile refresh.
| void MapCanvas::zoomIn | ( | double | factor = 2.0 | ) |
| void MapCanvas::zoomOut | ( | double | factor = 2.0 | ) |
| void MapCanvas::zoomToFullExtent | ( | ) |
|
readwrite |
|
readwrite |
|
readwrite |
|
read |
|
read |
|
readwrite |
|
readwrite |