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
featuresublayerstyle.h
Go to the documentation of this file.
1
17#ifndef OPENSWMM_RENDER_SUBLAYERS_FEATURE_FEATURESUBLAYERSTYLE_H
18#define OPENSWMM_RENDER_SUBLAYERS_FEATURE_FEATURESUBLAYERSTYLE_H
19
21#include "render/labelconfig.h" // L-1 — per-sublayer labels
22
23#include <QColor>
24#include <QJsonObject>
25#include <QString>
26#include <Qt>
27
28namespace OpenSWMM::Render
29{
30
47{
48 Q_OBJECT
49 Q_PROPERTY(QString attribute READ attribute WRITE setAttribute NOTIFY styleChanged)
50 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY styleChanged)
51 Q_PROPERTY(bool useColorRamp READ useColorRamp WRITE setUseColorRamp NOTIFY styleChanged)
52
53 Q_CLASSINFO("group:attribute", "Classification")
54 Q_CLASSINFO("group:color", "Symbology")
55 Q_CLASSINFO("group:useColorRamp", "Symbology")
56
57public:
58 explicit FeatureSublayerStyle(QObject *parent = nullptr) : SublayerStyle(parent) {}
59
60 [[nodiscard]] QString attribute() const { return m_attribute; }
61 [[nodiscard]] QColor color() const { return m_color; }
62 [[nodiscard]] bool useColorRamp() const { return m_useColorRamp; }
63
64 void setAttribute(const QString &v) { if (m_attribute == v) return; m_attribute = v; setDirty(); }
65 void setColor(const QColor &v) { if (m_color == v) return; m_color = v; setDirty(); }
66 void setUseColorRamp(bool v) { if (m_useColorRamp == v) return; m_useColorRamp = v; setDirty(); }
67
68 // L-1 — per-sublayer labels. Each sublayer (kind) carries its own
69 // LabelConfig so the user can label, say, Junctions but not Conduits,
70 // and give each its own expression ("{name}: {depth} m"). The results
71 // layer's refreshLabels() reads this instead of the layer-level config.
72 [[nodiscard]] const LabelConfig &labelConfig() const { return m_labelConfig; }
73 void setLabelConfig(const LabelConfig &c) { if (m_labelConfig == c) return; m_labelConfig = c; setDirty(); }
74
75 [[nodiscard]] QJsonObject toJson() const override
76 {
77 QJsonObject j;
78 j[QStringLiteral("attribute")] = m_attribute;
79 j[QStringLiteral("color")] = m_color.name(QColor::HexArgb);
80 j[QStringLiteral("useColorRamp")] = m_useColorRamp;
81 if (m_labelConfig.enabled || !m_labelConfig.expression.isEmpty())
82 j[QStringLiteral("labelConfig")] = m_labelConfig.toJson();
83 return j;
84 }
85 void fromJson(const QJsonObject &j) override
86 {
87 if (j.contains(QStringLiteral("attribute")))
88 m_attribute = j.value(QStringLiteral("attribute")).toString();
89 if (j.contains(QStringLiteral("color"))) {
90 const QColor c(j.value(QStringLiteral("color")).toString());
91 if (c.isValid()) m_color = c;
92 }
93 if (j.contains(QStringLiteral("useColorRamp")))
94 m_useColorRamp = j.value(QStringLiteral("useColorRamp")).toBool(true);
95 if (j.contains(QStringLiteral("labelConfig")))
96 m_labelConfig.fromJson(j.value(QStringLiteral("labelConfig")).toObject());
97 setDirty();
98 }
99
100private:
101 QString m_attribute = QStringLiteral("depth");
102 QColor m_color = QColor(60, 60, 60);
103 bool m_useColorRamp = true;
104 LabelConfig m_labelConfig; // L-1 — per-sublayer label settings
105};
106
107// ---------------------------------------------------------------------------
108// Point archetype — Junction / Outfall / Storage / Divider / RainGage
109// ---------------------------------------------------------------------------
110
112{
113 Q_OBJECT
114 Q_PROPERTY(double markerSizePx READ markerSizePx WRITE setMarkerSizePx NOTIFY styleChanged)
115 Q_PROPERTY(MarkerShape shape READ shape WRITE setShape NOTIFY styleChanged)
116
117 Q_CLASSINFO("group:markerSizePx", "Symbology")
118 Q_CLASSINFO("group:shape", "Symbology")
119
120public:
122 Q_ENUM(MarkerShape)
123
124 explicit PointFeatureSublayerStyle(QObject *parent = nullptr)
126
127 [[nodiscard]] double markerSizePx() const { return m_markerSizePx; }
128 [[nodiscard]] MarkerShape shape() const { return m_shape; }
129
130 void setMarkerSizePx(double v) { if (qFuzzyCompare(m_markerSizePx, v)) return; m_markerSizePx = v; setDirty(); }
131 void setShape(MarkerShape v) { if (m_shape == v) return; m_shape = v; setDirty(); }
132
133 [[nodiscard]] QJsonObject toJson() const override
134 {
135 QJsonObject j = FeatureSublayerStyle::toJson();
136 j[QStringLiteral("markerSizePx")] = m_markerSizePx;
137 j[QStringLiteral("shape")] = int(m_shape);
138 return j;
139 }
140 void fromJson(const QJsonObject &j) override
141 {
143 if (j.contains(QStringLiteral("markerSizePx")))
144 m_markerSizePx = j.value(QStringLiteral("markerSizePx")).toDouble(6.0);
145 if (j.contains(QStringLiteral("shape")))
146 m_shape = static_cast<MarkerShape>(j.value(QStringLiteral("shape")).toInt(int(Circle)));
147 setDirty();
148 }
149
150private:
151 double m_markerSizePx = 6.0;
152 MarkerShape m_shape = Circle;
153};
154
155// ---------------------------------------------------------------------------
156// Line archetype — Conduit / Pump / Orifice / Weir / Outlet
157//
158// Folds the legacy ConduitArrowSublayer in via showFlowArrows + the
159// arrow*Px knobs, so each link kind controls its own arrow behaviour.
160// ---------------------------------------------------------------------------
161
163{
164 Q_OBJECT
165 Q_PROPERTY(double lineWidthPx READ lineWidthPx WRITE setLineWidthPx NOTIFY styleChanged)
166 Q_PROPERTY(Qt::PenStyle dashPattern READ dashPattern WRITE setDashPattern NOTIFY styleChanged)
168 Q_PROPERTY(double arrowLengthPx READ arrowLengthPx WRITE setArrowLengthPx NOTIFY styleChanged)
169 Q_PROPERTY(double arrowWidthPx READ arrowWidthPx WRITE setArrowWidthPx NOTIFY styleChanged)
170 Q_PROPERTY(QColor arrowColor READ arrowColor WRITE setArrowColor NOTIFY styleChanged)
171 Q_PROPERTY(bool renderAsLine READ renderAsLine WRITE setRenderAsLine NOTIFY styleChanged)
172
173 Q_CLASSINFO("group:lineWidthPx", "Line")
174 Q_CLASSINFO("group:dashPattern", "Line")
175 Q_CLASSINFO("group:renderAsLine", "Line")
176 Q_CLASSINFO("group:showFlowArrows", "Flow arrows")
177 Q_CLASSINFO("group:arrowLengthPx", "Flow arrows")
178 Q_CLASSINFO("group:arrowWidthPx", "Flow arrows")
179 Q_CLASSINFO("group:arrowColor", "Flow arrows")
180
181public:
182 explicit LineFeatureSublayerStyle(QObject *parent = nullptr)
184
185 [[nodiscard]] double lineWidthPx() const { return m_lineWidthPx; }
186 [[nodiscard]] Qt::PenStyle dashPattern() const { return m_dashPattern; }
187 [[nodiscard]] bool showFlowArrows() const { return m_showFlowArrows; }
188 [[nodiscard]] double arrowLengthPx() const { return m_arrowLengthPx; }
189 [[nodiscard]] double arrowWidthPx() const { return m_arrowWidthPx; }
190 [[nodiscard]] QColor arrowColor() const { return m_arrowColor; }
194 [[nodiscard]] bool renderAsLine() const { return m_renderAsLine; }
195
196 void setLineWidthPx(double v) { if (qFuzzyCompare(m_lineWidthPx, v)) return; m_lineWidthPx = v; setDirty(); }
197 void setDashPattern(Qt::PenStyle v) { if (m_dashPattern == v) return; m_dashPattern = v; setDirty(); }
198 void setShowFlowArrows(bool v) { if (m_showFlowArrows == v) return; m_showFlowArrows = v; setDirty(); }
199 void setArrowLengthPx(double v) { if (qFuzzyCompare(m_arrowLengthPx, v)) return; m_arrowLengthPx = v; setDirty(); }
200 void setArrowWidthPx(double v) { if (qFuzzyCompare(m_arrowWidthPx, v)) return; m_arrowWidthPx = v; setDirty(); }
201 void setArrowColor(const QColor &v) { if (m_arrowColor == v) return; m_arrowColor = v; setDirty(); }
202 void setRenderAsLine(bool v) { if (m_renderAsLine == v) return; m_renderAsLine = v; setDirty(); }
203
204 [[nodiscard]] QJsonObject toJson() const override
205 {
206 QJsonObject j = FeatureSublayerStyle::toJson();
207 j[QStringLiteral("lineWidthPx")] = m_lineWidthPx;
208 j[QStringLiteral("dashPattern")] = int(m_dashPattern);
209 j[QStringLiteral("showFlowArrows")] = m_showFlowArrows;
210 j[QStringLiteral("arrowLengthPx")] = m_arrowLengthPx;
211 j[QStringLiteral("arrowWidthPx")] = m_arrowWidthPx;
212 j[QStringLiteral("arrowColor")] = m_arrowColor.name(QColor::HexArgb);
213 j[QStringLiteral("renderAsLine")] = m_renderAsLine;
214 return j;
215 }
216 void fromJson(const QJsonObject &j) override
217 {
219 if (j.contains(QStringLiteral("lineWidthPx"))) m_lineWidthPx = j.value(QStringLiteral("lineWidthPx")).toDouble(1.5);
220 if (j.contains(QStringLiteral("dashPattern"))) m_dashPattern = static_cast<Qt::PenStyle>(j.value(QStringLiteral("dashPattern")).toInt(int(Qt::SolidLine)));
221 if (j.contains(QStringLiteral("showFlowArrows"))) m_showFlowArrows = j.value(QStringLiteral("showFlowArrows")).toBool(true);
222 if (j.contains(QStringLiteral("arrowLengthPx"))) m_arrowLengthPx = j.value(QStringLiteral("arrowLengthPx")).toDouble(16.0);
223 if (j.contains(QStringLiteral("arrowWidthPx"))) m_arrowWidthPx = j.value(QStringLiteral("arrowWidthPx")).toDouble(8.0);
224 if (j.contains(QStringLiteral("arrowColor"))) {
225 const QColor c(j.value(QStringLiteral("arrowColor")).toString());
226 if (c.isValid()) m_arrowColor = c;
227 }
228 if (j.contains(QStringLiteral("renderAsLine"))) m_renderAsLine = j.value(QStringLiteral("renderAsLine")).toBool(true);
229 setDirty();
230 }
231
232private:
233 double m_lineWidthPx = 1.5;
234 Qt::PenStyle m_dashPattern = Qt::SolidLine;
235 // Line sublayers are the link kinds on a results layer, so arrows are
236 // on out of the box here too (matches the model layer's per-kind seed).
237 bool m_showFlowArrows = true;
238 double m_arrowLengthPx = 16.0;
243 double m_arrowWidthPx = 8.0;
244 QColor m_arrowColor = QColor(20, 20, 20, 220);
245 bool m_renderAsLine = true;
246};
247
248// ---------------------------------------------------------------------------
249// Polygon archetype — Subcatchment
250// ---------------------------------------------------------------------------
251
253{
254 Q_OBJECT
255 Q_PROPERTY(QColor outlineColor READ outlineColor WRITE setOutlineColor NOTIFY styleChanged)
256 Q_PROPERTY(double outlineWidthPx READ outlineWidthPx WRITE setOutlineWidthPx NOTIFY styleChanged)
257 Q_PROPERTY(double fillOpacity READ fillOpacity WRITE setFillOpacity NOTIFY styleChanged)
258 // VS.2b — Qt::BrushStyle (as int) so hatch / pattern fills are reachable
259 // and round-trip; the paint path composes the brush via FillSymbolLayerSpec.
260 // Qt::SolidPattern == 1, Qt::NoBrush == 0, hatches are 9..14.
261 Q_PROPERTY(int fillStyle READ fillStyle WRITE setFillStyle NOTIFY styleChanged)
262
263 Q_CLASSINFO("group:outlineColor", "Outline")
264 Q_CLASSINFO("group:outlineWidthPx", "Outline")
265 Q_CLASSINFO("group:fillOpacity", "Fill")
266 Q_CLASSINFO("group:fillStyle", "Fill")
267
268public:
269 explicit PolygonFeatureSublayerStyle(QObject *parent = nullptr)
271
272 [[nodiscard]] QColor outlineColor() const { return m_outlineColor; }
273 [[nodiscard]] double outlineWidthPx() const { return m_outlineWidthPx; }
274 [[nodiscard]] double fillOpacity() const { return m_fillOpacity; }
275 [[nodiscard]] int fillStyle() const { return m_fillStyle; }
276
277 void setOutlineColor(const QColor &v) { if (m_outlineColor == v) return; m_outlineColor = v; setDirty(); }
278 void setOutlineWidthPx(double v) { if (qFuzzyCompare(m_outlineWidthPx, v)) return; m_outlineWidthPx = v; setDirty(); }
279 void setFillOpacity(double v) { if (qFuzzyCompare(m_fillOpacity, v)) return; m_fillOpacity = v; setDirty(); }
280 void setFillStyle(int v) { if (m_fillStyle == v) return; m_fillStyle = v; setDirty(); }
281
282 [[nodiscard]] QJsonObject toJson() const override
283 {
284 QJsonObject j = FeatureSublayerStyle::toJson();
285 j[QStringLiteral("outlineColor")] = m_outlineColor.name(QColor::HexArgb);
286 j[QStringLiteral("outlineWidthPx")] = m_outlineWidthPx;
287 j[QStringLiteral("fillOpacity")] = m_fillOpacity;
288 j[QStringLiteral("fillStyle")] = m_fillStyle;
289 return j;
290 }
291 void fromJson(const QJsonObject &j) override
292 {
294 if (j.contains(QStringLiteral("outlineColor"))) {
295 const QColor c(j.value(QStringLiteral("outlineColor")).toString());
296 if (c.isValid()) m_outlineColor = c;
297 }
298 if (j.contains(QStringLiteral("outlineWidthPx")))
299 m_outlineWidthPx = j.value(QStringLiteral("outlineWidthPx")).toDouble(0.5);
300 if (j.contains(QStringLiteral("fillOpacity")))
301 m_fillOpacity = j.value(QStringLiteral("fillOpacity")).toDouble(0.55);
302 if (j.contains(QStringLiteral("fillStyle")))
303 m_fillStyle = j.value(QStringLiteral("fillStyle")).toInt(int(Qt::SolidPattern));
304 setDirty();
305 }
306
307private:
308 QColor m_outlineColor = QColor(40, 40, 40, 220);
309 double m_outlineWidthPx = 0.5;
310 double m_fillOpacity = 0.55;
311 int m_fillStyle = int(Qt::SolidPattern); // VS.2b
312};
313
314} // namespace OpenSWMM::Render
315
316#endif // OPENSWMM_RENDER_SUBLAYERS_FEATURE_FEATURESUBLAYERSTYLE_H
Common property bag for every per-Category result sublayer.
Definition featuresublayerstyle.h:47
void setAttribute(const QString &v)
Definition featuresublayerstyle.h:64
QColor color() const
Definition featuresublayerstyle.h:61
bool useColorRamp() const
Definition featuresublayerstyle.h:62
QString attribute
Definition featuresublayerstyle.h:49
QColor color
Definition featuresublayerstyle.h:50
QString attribute() const
Definition featuresublayerstyle.h:60
const LabelConfig & labelConfig() const
Definition featuresublayerstyle.h:72
void fromJson(const QJsonObject &j) override
Restore the style from JSON.
Definition featuresublayerstyle.h:85
void setColor(const QColor &v)
Definition featuresublayerstyle.h:65
QJsonObject toJson() const override
Serialize the style to JSON.
Definition featuresublayerstyle.h:75
void setLabelConfig(const LabelConfig &c)
Definition featuresublayerstyle.h:73
bool useColorRamp
Definition featuresublayerstyle.h:51
void setUseColorRamp(bool v)
Definition featuresublayerstyle.h:66
Definition featuresublayerstyle.h:163
void setShowFlowArrows(bool v)
Definition featuresublayerstyle.h:198
bool showFlowArrows
Definition featuresublayerstyle.h:167
double arrowLengthPx() const
Definition featuresublayerstyle.h:188
bool renderAsLine
Definition featuresublayerstyle.h:171
Qt::PenStyle dashPattern
Definition featuresublayerstyle.h:166
double arrowWidthPx
Definition featuresublayerstyle.h:169
double arrowLengthPx
Definition featuresublayerstyle.h:168
bool renderAsLine() const
Definition featuresublayerstyle.h:194
void setRenderAsLine(bool v)
Definition featuresublayerstyle.h:202
double lineWidthPx
Definition featuresublayerstyle.h:165
void setArrowColor(const QColor &v)
Definition featuresublayerstyle.h:201
void setDashPattern(Qt::PenStyle v)
Definition featuresublayerstyle.h:197
double lineWidthPx() const
Definition featuresublayerstyle.h:185
void setLineWidthPx(double v)
Definition featuresublayerstyle.h:196
QColor arrowColor() const
Definition featuresublayerstyle.h:190
double arrowWidthPx() const
Definition featuresublayerstyle.h:189
void fromJson(const QJsonObject &j) override
Restore the style from JSON.
Definition featuresublayerstyle.h:216
Qt::PenStyle dashPattern() const
Definition featuresublayerstyle.h:186
QColor arrowColor
Definition featuresublayerstyle.h:170
bool showFlowArrows() const
Definition featuresublayerstyle.h:187
void setArrowWidthPx(double v)
Definition featuresublayerstyle.h:200
QJsonObject toJson() const override
Serialize the style to JSON.
Definition featuresublayerstyle.h:204
void setArrowLengthPx(double v)
Definition featuresublayerstyle.h:199
Definition featuresublayerstyle.h:112
QJsonObject toJson() const override
Serialize the style to JSON.
Definition featuresublayerstyle.h:133
MarkerShape shape() const
Definition featuresublayerstyle.h:128
MarkerShape
Definition featuresublayerstyle.h:121
@ Circle
Definition featuresublayerstyle.h:121
@ Triangle
Definition featuresublayerstyle.h:121
@ Star
Definition featuresublayerstyle.h:121
@ Square
Definition featuresublayerstyle.h:121
@ Diamond
Definition featuresublayerstyle.h:121
double markerSizePx
Definition featuresublayerstyle.h:114
void setMarkerSizePx(double v)
Definition featuresublayerstyle.h:130
void fromJson(const QJsonObject &j) override
Restore the style from JSON.
Definition featuresublayerstyle.h:140
void setShape(MarkerShape v)
Definition featuresublayerstyle.h:131
double markerSizePx() const
Definition featuresublayerstyle.h:127
MarkerShape shape
Definition featuresublayerstyle.h:115
Definition featuresublayerstyle.h:253
double fillOpacity() const
Definition featuresublayerstyle.h:274
void setOutlineColor(const QColor &v)
Definition featuresublayerstyle.h:277
double outlineWidthPx() const
Definition featuresublayerstyle.h:273
QColor outlineColor
Definition featuresublayerstyle.h:255
void setOutlineWidthPx(double v)
Definition featuresublayerstyle.h:278
int fillStyle
Definition featuresublayerstyle.h:261
QColor outlineColor() const
Definition featuresublayerstyle.h:272
double fillOpacity
Definition featuresublayerstyle.h:257
void setFillOpacity(double v)
Definition featuresublayerstyle.h:279
QJsonObject toJson() const override
Serialize the style to JSON.
Definition featuresublayerstyle.h:282
void setFillStyle(int v)
Definition featuresublayerstyle.h:280
void fromJson(const QJsonObject &j) override
Restore the style from JSON.
Definition featuresublayerstyle.h:291
double outlineWidthPx
Definition featuresublayerstyle.h:256
int fillStyle() const
Definition featuresublayerstyle.h:275
Base class for per-sublayer style property bags.
Definition sublayerstyle.h:56
void styleChanged()
Emitted when any property changes.
void setDirty()
Definition sublayerstyle.h:97
Shared label-configuration value-type used by every layer that paints text labels.
Definition gisrasterlayer.h:40
MarkerShape
13 canonical marker shapes the Rule Model's Marker Symbol Layer supports (per RENDERING_RULE_MODEL_PL...
Definition markershape.h:53
QVector< int > v
pool vertex indices
Definition pslgminsize.cpp:159
QVector< int > parent
union-find
Definition pslgminsize.cpp:176
Per-layer label rendering parameters.
Definition labelconfig.h:47
bool enabled
Definition labelconfig.h:49
QJsonObject toJson() const
Definition labelconfig.cpp:13
void fromJson(const QJsonObject &j)
Definition labelconfig.cpp:46
QString expression
Definition labelconfig.h:63
QObject base class for per-sublayer style property bags.