SWMMVis  6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
gisvectorlayer.h
Go to the documentation of this file.
1
10#ifndef GISVECTORLAYER_H
11#define GISVECTORLAYER_H
12
14#include "render/iattributeprovider.h" // Slice DM.3
15#include "render/labelconfig.h"
16
17#include <QColor>
18#include <QFont>
19#include <QJsonObject>
20#include <QList>
21#include <QPainterPath>
22#include <QPen>
23#include <QBrush>
24#include <QString>
25#include <QVariantMap>
26
27#include <memory>
28
29class QGraphicsItem;
30
31// Forward-declare GDAL/OGR types
32class GDALDataset;
33class OGRLayer;
34class OGRFeature;
35class OGRCoordinateTransformation;
36
39class GisVectorSymbolAdapter; // persistent symbol adapter — styleSubjects()
40
41namespace OpenSWMM::Render {
42class IFeatureRenderer;
43class RuleList; // Slice B.3 — see m_ruleList below.
44}
45
52{
53 // ----- Point / marker -------------------------------------------------
55
57 double markerSize = 6.0;
58 QColor markerFill = QColor(Qt::red);
59 QColor markerOutline = QColor(Qt::darkRed);
60 double markerOutlineW = 1.0;
61
62 // ----- Line -----------------------------------------------------------
63 // Width is in screen pixels (cosmetic pen applied at populate time).
64 // Default 2.0 — temporary until the theming component (Slice AC) takes
65 // over per-attribute styling.
66 QPen linePen = QPen(QColor(Qt::blue), 2.0);
67
68 // ----- Polygon --------------------------------------------------------
69 QBrush polygonFill = QBrush(QColor(100, 149, 237, 160)); // cornflower blue
70 QPen polygonOutline = QPen(QColor(Qt::darkBlue), 2.0);
71
72 // ----- Labels ---------------------------------------------------------
73 bool showLabels = false;
74 QString labelField;
75 QFont labelFont;
76 QColor labelColor = Qt::black;
77
84
85 [[nodiscard]] QJsonObject toJson() const;
86 void fromJson(const QJsonObject &j);
87};
88
102 public OpenSWMM::Render::IAttributeProvider // Slice DM.3
103{
104 Q_OBJECT
105 Q_INTERFACES(OpenSWMM::Render::IAttributeProvider) // Slice DM.3
106 Q_PROPERTY(QString filePath READ filePath NOTIFY filePathChanged)
107 Q_PROPERTY(QString layerName READ ogrLayerName NOTIFY layerNameChanged)
109 Q_PROPERTY(QString filterExpr READ filterExpression WRITE setFilterExpression
112
113public:
114
115 explicit GISVectorLayer(const QString &filePath,
116 const QString &layerName = {},
117 OpenSWMMVisWorkspace *parent = nullptr);
118
119 ~GISVectorLayer() override;
120
129 void openAsync(const QString &filePath, const QString &layerName = {});
130
131 // ----- Multi-layer enumeration (sublayer picker) ----------------------
132
138 {
139 QString name;
140 QString geometryType;
141 long long featureCount = -1;
143 int index = -1;
144 };
145
155 [[nodiscard]] static QList<OgrSublayerInfo>
156 enumerateSublayers(const QString &filePath, QString *errorOut = nullptr);
157
158 // ----- Dataset info ---------------------------------------------------
159
163 [[nodiscard]] QString filePath() const;
164
168 [[nodiscard]] QString ogrLayerName() const;
169
175 [[nodiscard]] class OGRLayer *ogrLayer() const { return m_ogrLayer; }
176
193 void appendScenePolygonsTo(QPainterPath &out) const;
194
198 [[nodiscard]] int featureCount() const;
199
203 [[nodiscard]] QStringList fieldNames() const;
204
205 // ----- Self-description for the Layer Properties dialog ----------------
206 [[nodiscard]] QString sourceDescription() const override;
207 [[nodiscard]] QVector<QPair<QString, QString>> extendedMetadata() const override;
208
209 // ----- IAttributeProvider (Slice DM.3) --------------------------------
210 //
211 // GIS layers have no SWMM category. The interface's `cat` arg is
212 // ignored; we always return the OGR field list (the same data
213 // fieldNames() exposes) wrapped as AttributeField. All entries
214 // are isDynamic=false — vector attributes don't change per
215 // animation frame.
216 [[nodiscard]] QVector<OpenSWMM::Render::AttributeField>
218
219 // ----- Filtering ------------------------------------------------------
220
224 [[nodiscard]] QString filterExpression() const;
225
231 void setFilterExpression(const QString &expr);
232
233 // ----- Symbology ------------------------------------------------------
234
235 [[nodiscard]] GISVectorSymbol symbol() const;
236 void setSymbol(const GISVectorSymbol &symbol);
237
244 // VS.10 — labelConfig() inherited from OpenSWMMVisLayer; only the setter
245 // is overridden to mirror fields onto the legacy GISVectorSymbol bag.
246 void setLabelConfig(const OpenSWMM::Render::LabelConfig &cfg) override;
247
251 [[nodiscard]] QStringList ogrFieldNames() const;
252
255 [[nodiscard]] std::vector<std::unique_ptr<openswmmvis::ui::ILayerStyleSubject>>
256 styleSubjects() override;
257
258 // ----- Renderer (Slice BI Phase 8.13.6.6 + Slice B.3) -----------------
259 // API plumbing only — paint loop still consults m_symbol directly.
260 // Sub-phase 8.13.6.4 (deferred until Slice BB ColorRamp lands) will
261 // refactor the paint loop to consult the renderer instead. Slice B.3
262 // migrated the renderer's home to the m_ruleList's active Rule —
263 // renderer() / setRenderer() are facades over the Rule.
264
270 [[nodiscard]] OpenSWMM::Render::IFeatureRenderer *renderer() const;
271
278 void setRenderer(std::unique_ptr<OpenSWMM::Render::IFeatureRenderer> r);
279
280 // ----- Rule Model (Slice B.3, Phase B) --------------------------------
281 //
282 // GISVectorLayer is the first concrete layer to migrate to the Rule
283 // Model. The layer owns a single-Rule RuleList that wraps the
284 // renderer; `renderer()` and `setRenderer()` are facades over the
285 // active Rule's owned IFeatureRenderer. LayerStyleDialog detects
286 // `ruleList() != nullptr` and mounts RuleSymbologyTab in the
287 // Symbology tab (Slice B.2 dispatch).
288 [[nodiscard]] OpenSWMM::Render::RuleList *ruleList() override;
289 [[nodiscard]] const OpenSWMM::Render::RuleList *ruleList() const override;
290
291 // ----- Selection ------------------------------------------------------
292
296 [[nodiscard]] QSet<long long> selectedFeatureIds() const;
297
301 void setSelectedFeatureIds(const QSet<long long> &ids);
302
306 void clearSelection();
307
315 [[nodiscard]] QSet<long long> featureIdsInRect(
316 const MapExtent &rectCanvasCrs) const;
317
322 [[nodiscard]] QVector<QPointF> selectedFeatureAnchors() const;
323
324 // ----- Identify -------------------------------------------------------
325
334 [[nodiscard]] QList<QVariantMap> identifyAt(double mapX, double mapY,
335 const SpatialReferenceSystem *canvasSRS,
336 double tolerance = 1e-6) const;
337
341 [[nodiscard]] QList<QVariantMap> identifyAt(double mapX, double mapY,
342 double tolerance = 1e-6) const;
343
344 // ----- OpenSWMMVisLayer interface -----------------------------------------
345
346 void populateScene(QGraphicsScene *scene,
347 const MapExtent &canvasExtent,
348 const SpatialReferenceSystem *canvasSRS) override;
349
350 void depopulateScene(QGraphicsScene *scene) override;
351
352 void refreshScene(QGraphicsScene *scene,
353 const MapExtent &canvasExtent,
354 const SpatialReferenceSystem *canvasSRS) override;
355
356 void onCanvasCRSChanged(const SpatialReferenceSystem *newCanvasSRS) override;
357
358signals:
359 void filePathChanged(const QString &path);
360 void layerNameChanged(const QString &name);
362 void filterExpressionChanged(const QString &expr);
364
365 // VS.10 — labelConfigChanged() is inherited from OpenSWMMVisLayer.
366 void selectionChanged(const QSet<long long> &selectedIds);
369
371 void openFinished(bool ok);
372
381 void crsAssumed(const QString &filePath);
382
383private:
384 // Worker-thread payload for openAsync(): GDALOpenEx + GetLayer + extent +
385 // CRS produce this POD (no QObject state), folded into the layer on the
386 // GUI thread by applyOpenResult(). Defined in the .cpp.
387 struct OpenResult;
391 [[nodiscard]] static OpenResult doOpenWork(const QString &filePath,
392 const QString &layerName,
393 unsigned openFlags);
394 void applyOpenResult(const OpenResult &r);
395
396protected:
411 void setOpenFlags(unsigned flags) { m_openFlags = flags; }
412 [[nodiscard]] unsigned openFlags() const { return m_openFlags; }
413
417 [[nodiscard]] GDALDataset *dataset() const { return m_dataset; }
418
422 void markSceneDirty() { m_needsRebuild = true; }
423
431 void openDataset(const QString &filePath, const QString &layerName);
432
434 void closeDataset();
435
436private:
437 void rebuildTransform(const SpatialReferenceSystem *canvasSRS) const;
438
459 void ensureTransform(const SpatialReferenceSystem *canvasSRS) const;
460
467 void syncSymbolFromRenderer();
468
469 QString m_filePath;
470 QString m_ogrLayerName;
471 QString m_filterExpr;
472 GISVectorSymbol m_symbol;
473 // Persistent symbol adapter (adapter-ownership refactor) — lazily built
474 // by styleSubjects(), owned via QObject parenting.
475 GisVectorSymbolAdapter *m_symbolAdapter = nullptr;
476 // VS.10 — m_labelConfig moved to OpenSWMMVisLayer (base owns it now).
477 QSet<long long> m_selectedIds;
478
482 unsigned m_openFlags = 0; // seeded in the ctor
483
484 GDALDataset *m_dataset = nullptr;
485 OGRLayer *m_ogrLayer = nullptr;
486 mutable OGRCoordinateTransformation *m_transform = nullptr;
490 mutable QString m_transformCanvasWkt;
491
493 mutable bool m_warnedNoCRS = false;
494
495 // Slice BI Phase 8.13.6.6 — renderer plumbing. Initialised eagerly in
496 // the ctor (default SingleSymbolRenderer) so renderer() never returns
497 // null. Paint refactor deferred until Slice BB ColorRamp ships.
498 //
499 // Slice B.3 — renderer ownership migrated to m_ruleList. The
500 // canonical home for the renderer is now the active Rule's owned
501 // IFeatureRenderer. renderer() and setRenderer() are thin facades
502 // over m_ruleList->activeRule()->renderer() — no per-layer unique_ptr
503 // duplicate. Legend code paths (legendoverlay, legendlayertreemodel,
504 // legendclasseditcommands) keep working through the facade.
505 std::unique_ptr<OpenSWMM::Render::RuleList> m_ruleList;
506
507 // Dirty flag — skip scene rebuild when only the view extent changed
508 bool m_needsRebuild = true;
509
510 // Owned QGraphicsItems currently in the scene — avoids O(n) scene scan
511 // in depopulateScene (which previously used dynamic_cast on every item).
512 QList<QGraphicsItem *> m_sceneItems;
513};
514
515Q_DECLARE_METATYPE(GISVectorLayer *)
516Q_DECLARE_METATYPE(GISVectorSymbol)
517
518#endif // GISVECTORLAYER_H
A map layer backed by a GDAL/OGR vector dataset.
Definition gisvectorlayer.h:103
void setSelectedFeatureIds(const QSet< long long > &ids)
Selects the features with the given IDs (replacing any prior selection).
Definition gisvectorlayer.cpp:640
QString filterExpr
Definition gisvectorlayer.h:110
QString sourceDescription() const override
Human-readable source of this layer: a file path, a service URL, or a description for in-memory / der...
Definition gisvectorlayer.cpp:230
void rendererChanged()
Emitted when setRenderer() swaps the renderer pointer.
void selectionChanged(const QSet< long long > &selectedIds)
QStringList fieldNames() const
Returns the list of field (attribute column) names.
Definition gisvectorlayer.cpp:255
QVector< QPointF > selectedFeatureAnchors() const
Scene-space centres of the selected features' items — beacon anchors for MapCanvas::flashSelection.
Definition gisvectorlayer.cpp:781
int featureCount
Definition gisvectorlayer.h:108
void setOpenFlags(unsigned flags)
GDALOpenEx flags used by openDataset and openAsync.
Definition gisvectorlayer.h:411
void setRenderer(std::unique_ptr< OpenSWMM::Render::IFeatureRenderer > r)
Replaces the current renderer.
Definition gisvectorlayer.cpp:607
void populateScene(QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
Creates / updates QGraphicsItems representing this layer in the scene.
Definition gisvectorlayer.cpp:814
class OGRLayer * ogrLayer() const
Read-only OGRLayer handle for callers that need to walk features directly (e.g. mesh-generator constr...
Definition gisvectorlayer.h:175
void crsAssumed(const QString &filePath)
Emitted once when this layer's file declares no CRS and its coordinates are therefore assumed to alre...
QString filterExpression() const
Returns the current OGR attribute filter expression.
Definition gisvectorlayer.cpp:370
unsigned openFlags() const
Definition gisvectorlayer.h:412
void setSymbol(const GISVectorSymbol &symbol)
Definition gisvectorlayer.cpp:488
GDALDataset * dataset() const
The open dataset, or nullptr. Non-owning; the layer closes it. Exposed for subclasses that must reach...
Definition gisvectorlayer.h:417
QList< QVariantMap > identifyAt(double mapX, double mapY, const SpatialReferenceSystem *canvasSRS, double tolerance=1e-6) const
Returns attributes of features that intersect the given map point.
Definition gisvectorlayer.cpp:663
void layerNameChanged(const QString &name)
void filterExpressionChanged(const QString &expr)
GISVectorSymbol symbol
Definition gisvectorlayer.h:111
QSet< long long > featureIdsInRect(const MapExtent &rectCanvasCrs) const
SVBC round B — fids of every feature whose GEOMETRY intersects rectCanvasCrs (OGR bbox prefilter,...
Definition gisvectorlayer.cpp:724
QStringList ogrFieldNames() const
Names of the OGR fields available for label expressions. Empty when no dataset has been opened yet....
Definition gisvectorlayer.cpp:551
void setFilterExpression(const QString &expr)
Sets an OGR SQL WHERE-clause filter on the features.
Definition gisvectorlayer.cpp:372
void openAsync(const QString &filePath, const QString &layerName={})
Asynchronously open filePath / layerName. GDALOpenEx + GetExtent (which forces a scan on some drivers...
Definition gisvectorlayer.cpp:1261
void depopulateScene(QGraphicsScene *scene) override
Removes all QGraphicsItems belonging to this layer from the scene.
Definition gisvectorlayer.cpp:1037
void symbolChanged(const GISVectorSymbol &symbol)
static QList< OgrSublayerInfo > enumerateSublayers(const QString &filePath, QString *errorOut=nullptr)
Enumerate the layers in a vector datasource without fully loading any of them. Opens read-only,...
Definition gisvectorlayer.cpp:1083
QVector< OpenSWMM::Render::AttributeField > availableAttributes(OpenSWMMVis::SwmmCategory cat) const override
Definition gisvectorlayer.cpp:278
QString layerName
Definition gisvectorlayer.h:107
void closeDataset()
Closes whatever is open, releasing the dataset.
Definition gisvectorlayer.cpp:1286
void openFinished(bool ok)
Emitted on the GUI thread when openAsync() completes.
void clearSelection()
Clears all selected features.
Definition gisvectorlayer.cpp:648
OpenSWMM::Render::IFeatureRenderer * renderer() const
The IFeatureRenderer that will drive this layer's paint pass.
Definition gisvectorlayer.cpp:599
~GISVectorLayer() override
Definition gisvectorlayer.cpp:212
QString filePath
Definition gisvectorlayer.h:106
void appendScenePolygonsTo(QPainterPath &out) const
Slice Z.14-paint — append every polygon ring this layer currently exposes (post-attribute-filter) to ...
Definition gisvectorlayer.cpp:306
void openDataset(const QString &filePath, const QString &layerName)
Open filePath / layerName synchronously.
Definition gisvectorlayer.cpp:1256
void markSceneDirty()
Force the next populateScene() to rebuild its items. Call after mutating the underlying dataset so th...
Definition gisvectorlayer.h:422
QSet< long long > selectedFeatureIds() const
Returns the set of currently selected feature IDs.
Definition gisvectorlayer.cpp:638
void setLabelConfig(const OpenSWMM::Render::LabelConfig &cfg) override
Slice X.18 — full label configuration.
Definition gisvectorlayer.cpp:531
OpenSWMM::Render::RuleList * ruleList() override
Definition gisvectorlayer.cpp:624
QString ogrLayerName() const
Returns the OGR sub-layer name opened within the dataset.
Definition gisvectorlayer.cpp:228
void onCanvasCRSChanged(const SpatialReferenceSystem *newCanvasSRS) override
Called when the user changes the canvas CRS so layers can pre-compute any CRS-dependent transform cac...
Definition gisvectorlayer.cpp:1051
QVector< QPair< QString, QString > > extendedMetadata() const override
Ordered key→value pairs of TYPE-SPECIFIC metadata, rendered by the Metadata tab below the common bloc...
Definition gisvectorlayer.cpp:236
void featureCountChanged(int count)
std::vector< std::unique_ptr< openswmmvis::ui::ILayerStyleSubject > > styleSubjects() override
Definition gisvectorlayer.cpp:574
void filePathChanged(const QString &path)
void refreshScene(QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
Smart scene refresh — updates existing items instead of destroying and recreating.
Definition gisvectorlayer.cpp:1059
Definition gisvectorsymboladapter.h:26
An axis-aligned bounding box in the coordinate space of a given CRS.
Definition mapextent.h:26
Interface every themeable layer implements so renderer panels can populate attribute combos without h...
Definition iattributeprovider.h:73
Abstract interface — every vector layer's paint path goes here.
Definition ifeaturerenderer.h:85
Ordered owning container for Rules on one layer.
Definition rulelist.h:48
Abstract base class for all layers displayed in the MapCanvas.
Definition openswmmvislayer.h:116
QString name() const
Returns the user-visible name of this layer.
Definition openswmmvislayer.cpp:62
Top-level project container managing sessions, the SWMM model layer, and persistence paths for one SW...
Definition openswmmvisworkspace.h:42
Represents a coordinate reference system backed by a GDAL OGRSpatialReference.
Definition spatialreferencesystem.h:28
Layer-side seam for "what attributes can I theme by?" — Slice DM.1.
QGraphicsScene * scene
Definition inletdrawingview.cpp:78
int e
Definition inpmeshreader.cpp:41
bool ok
Definition inpmeshwriter.cpp:575
Shared label-configuration value-type used by every layer that paints text labels.
Definition gisrasterlayer.h:40
SwmmCategory
Stable ordinal categorising every SWMM-element kind that has per-kind styling, per-kind tree rows,...
Definition swmm_category.h:28
int count
Definition numberformat.cpp:101
Abstract base class for all map layers displayed in the MapCanvas.
int path
Definition pslgminsize.cpp:234
QVector< int > parent
union-find
Definition pslgminsize.cpp:176
Lightweight description of one OGR layer inside a datasource, produced by enumerateSublayers() withou...
Definition gisvectorlayer.h:138
QString name
OGR layer name (GetName()).
Definition gisvectorlayer.h:139
QString crsDescription
From GetSpatialRef(); empty if none.
Definition gisvectorlayer.h:142
int index
GetLayer(i) ordinal.
Definition gisvectorlayer.h:143
QString geometryType
Human label, e.g. "Polygon", "3D Line String".
Definition gisvectorlayer.h:140
long long featureCount
GetFeatureCount(); -1 if unknown.
Definition gisvectorlayer.h:141
Definition gisvectorlayer.cpp:1154
Rendering symbology for a vector layer.
Definition gisvectorlayer.h:52
QColor markerFill
Definition gisvectorlayer.h:58
double markerSize
Definition gisvectorlayer.h:57
double markerOutlineW
Definition gisvectorlayer.h:60
QColor labelColor
Definition gisvectorlayer.h:76
MarkerShape markerShape
Definition gisvectorlayer.h:56
QJsonObject toJson() const
Definition gisvectorlayer.cpp:404
QString labelField
Definition gisvectorlayer.h:74
MarkerShape
Definition gisvectorlayer.h:54
@ Star
Definition gisvectorlayer.h:54
@ Square
Definition gisvectorlayer.h:54
@ Cross
Definition gisvectorlayer.h:54
@ Diamond
Definition gisvectorlayer.h:54
@ Circle
Definition gisvectorlayer.h:54
@ Triangle
Definition gisvectorlayer.h:54
QColor markerOutline
Definition gisvectorlayer.h:59
QBrush polygonFill
Definition gisvectorlayer.h:69
QPen polygonOutline
Definition gisvectorlayer.h:70
bool showLabels
Definition gisvectorlayer.h:73
QPen linePen
Definition gisvectorlayer.h:66
OpenSWMM::Render::LabelConfig labelConfig
Definition gisvectorlayer.h:83
void fromJson(const QJsonObject &j)
Definition gisvectorlayer.cpp:433
QFont labelFont
Definition gisvectorlayer.h:75
Per-layer label rendering parameters.
Definition labelconfig.h:47