1 /*************************************************************************** 2 qgsellipsesymbollayer.h 3 --------------------- 4 begin : June 2011 5 copyright : (C) 2011 by Marco Hugentobler 6 email : marco dot hugentobler at sourcepole dot ch 7 *************************************************************************** 8 * * 9 * This program is free software; you can redistribute it and/or modify * 10 * it under the terms of the GNU General Public License as published by * 11 * the Free Software Foundation; either version 2 of the License, or * 12 * (at your option) any later version. * 13 * * 14 ***************************************************************************/ 15 #ifndef QGSELLIPSESYMBOLLAYER_H 16 #define QGSELLIPSESYMBOLLAYER_H 17 18 #define DEFAULT_ELLIPSE_JOINSTYLE Qt::MiterJoin 19 20 #include "qgis_core.h" 21 #include "qgis.h" 22 #include "qgsmarkersymbollayer.h" 23 #include <QPainterPath> 24 25 class QgsExpression; 26 27 /** 28 * \ingroup core 29 * \brief A symbol layer for rendering objects with major and minor axis (e.g. ellipse, rectangle, etc). 30 */ 31 class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer 32 { 33 public: 34 35 //! Marker symbol shapes 36 enum Shape 37 { 38 Circle, //!< Circle 39 Rectangle, //!< Rectangle 40 Diamond, //!< Diamond 41 Cross, //!< Stroke-only cross 42 Arrow, //!< Stroke-only arrow (since QGIS 3.20) 43 HalfArc, //!< Stroke-only half arc (since QGIS 3.20) 44 Triangle, //!< Triangle 45 RightHalfTriangle, //!< Right half of a triangle 46 LeftHalfTriangle, //!< Left half of a triangle 47 SemiCircle, //!< Semi circle 48 }; 49 50 //! Returns a list of all available shape types. 51 static QList< QgsEllipseSymbolLayer::Shape > availableShapes(); 52 53 /** 54 * Returns TRUE if a \a shape has a fill. 55 * \returns TRUE if shape uses a fill, or FALSE if shape uses lines only 56 * \since QGIS 3.20 57 */ 58 static bool shapeIsFilled( const QgsEllipseSymbolLayer::Shape &shape ); 59 60 QgsEllipseSymbolLayer(); 61 ~QgsEllipseSymbolLayer() override; 62 63 //! Creates the symbol layer 64 static QgsSymbolLayer *create( const QVariantMap &properties = QVariantMap() ) SIP_FACTORY; 65 static QgsSymbolLayer *createFromSld( QDomElement &element ) SIP_FACTORY; 66 67 void renderPoint( QPointF point, QgsSymbolRenderContext &context ) override; 68 QString layerType() const override; 69 void startRender( QgsSymbolRenderContext &context ) override; 70 void stopRender( QgsSymbolRenderContext &context ) override; 71 QgsEllipseSymbolLayer *clone() const override SIP_FACTORY; 72 QVariantMap properties() const override; 73 74 void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const override; 75 void writeSldMarker( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const override; 76 77 bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const override; 78 79 /** 80 * Sets the rendered ellipse marker shape using a symbol \a name. 81 * \see setShape() 82 * \see shape() 83 * \deprecated since QGIS 3.20 84 */ setSymbolName(const QString & name)85 Q_DECL_DEPRECATED void setSymbolName( const QString &name ) SIP_DEPRECATED { mShape = decodeShape( name ); } 86 87 /** 88 * Returns the shape name for the rendered ellipse marker symbol. 89 * \see shape() 90 * \see setShape() 91 * \deprecated since QGIS 3.20 92 */ symbolName()93 Q_DECL_DEPRECATED QString symbolName() const SIP_DEPRECATED { return encodeShape( mShape ); } 94 95 /** 96 * Returns the shape for the rendered ellipse marker symbol. 97 * \see setShape() 98 * \since QGIS 3.20 99 */ shape()100 QgsEllipseSymbolLayer::Shape shape() const { return mShape; } 101 102 /** 103 * Sets the rendered ellipse marker shape. 104 * \param shape new ellipse marker shape 105 * \see shape() 106 * \since QGIS 3.20 107 */ setShape(QgsEllipseSymbolLayer::Shape shape)108 void setShape( QgsEllipseSymbolLayer::Shape shape ) { mShape = shape; } 109 110 /** 111 * Attempts to decode a string representation of a shape name to the corresponding 112 * shape. 113 * \param name encoded shape name 114 * \param ok if specified, will be set to TRUE if shape was successfully decoded 115 * \returns decoded name 116 * \see encodeShape() 117 * \since QGIS 3.20 118 */ 119 static QgsEllipseSymbolLayer::Shape decodeShape( const QString &name, bool *ok = nullptr ); 120 121 /** 122 * Encodes a shape to its string representation. 123 * \param shape shape to encode 124 * \returns encoded string 125 * \see decodeShape() 126 * \since QGIS 3.20 127 */ 128 static QString encodeShape( QgsEllipseSymbolLayer::Shape shape ); 129 130 void setSize( double size ) override; 131 132 void setSymbolWidth( double w ); symbolWidth()133 double symbolWidth() const { return mSymbolWidth; } 134 135 void setSymbolHeight( double h ); symbolHeight()136 double symbolHeight() const { return mSymbolHeight; } 137 strokeStyle()138 Qt::PenStyle strokeStyle() const { return mStrokeStyle; } setStrokeStyle(Qt::PenStyle strokeStyle)139 void setStrokeStyle( Qt::PenStyle strokeStyle ) { mStrokeStyle = strokeStyle; } 140 141 /** 142 * Gets stroke join style. 143 * \since QGIS 2.16 144 */ penJoinStyle()145 Qt::PenJoinStyle penJoinStyle() const { return mPenJoinStyle; } 146 147 /** 148 * Set stroke join style. 149 * \since QGIS 2.16 150 */ setPenJoinStyle(Qt::PenJoinStyle style)151 void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; } 152 153 /** 154 * Returns the marker's stroke cap style (e.g., flat, round, etc). 155 * \see setPenCapStyle() 156 * \see penJoinStyle() 157 * \see strokeColor() 158 * \see strokeStyle() 159 * \since QGIS 3.20 160 */ penCapStyle()161 Qt::PenCapStyle penCapStyle() const { return mPenCapStyle; } 162 163 /** 164 * Sets the marker's stroke cap \a style (e.g., flat, round, etc). 165 * \see penCapStyle() 166 * \see penJoinStyle() 167 * \see setStrokeColor() 168 * \see setStrokeStyle() 169 * \since QGIS 3.20 170 */ setPenCapStyle(Qt::PenCapStyle style)171 void setPenCapStyle( Qt::PenCapStyle style ) { mPenCapStyle = style; } 172 setStrokeWidth(double w)173 void setStrokeWidth( double w ) { mStrokeWidth = w; } strokeWidth()174 double strokeWidth() const { return mStrokeWidth; } 175 setFillColor(const QColor & c)176 void setFillColor( const QColor &c ) override { setColor( c ); } fillColor()177 QColor fillColor() const override { return color(); } 178 setStrokeColor(const QColor & c)179 void setStrokeColor( const QColor &c ) override { mStrokeColor = c; } strokeColor()180 QColor strokeColor() const override { return mStrokeColor; } 181 182 /** 183 * Sets the units for the symbol's width. 184 * \param unit symbol units 185 * \see symbolWidthUnit() 186 * \see setSymbolHeightUnit() 187 */ setSymbolWidthUnit(QgsUnitTypes::RenderUnit unit)188 void setSymbolWidthUnit( QgsUnitTypes::RenderUnit unit ) { mSymbolWidthUnit = unit; } 189 190 /** 191 * Returns the units for the symbol's width. 192 * \see setSymbolWidthUnit() 193 * \see symbolHeightUnit() 194 */ symbolWidthUnit()195 QgsUnitTypes::RenderUnit symbolWidthUnit() const { return mSymbolWidthUnit; } 196 setSymbolWidthMapUnitScale(const QgsMapUnitScale & scale)197 void setSymbolWidthMapUnitScale( const QgsMapUnitScale &scale ) { mSymbolWidthMapUnitScale = scale; } symbolWidthMapUnitScale()198 const QgsMapUnitScale &symbolWidthMapUnitScale() const { return mSymbolWidthMapUnitScale; } 199 200 /** 201 * Sets the units for the symbol's height. 202 * \param unit symbol units 203 * \see symbolHeightUnit() 204 * \see setSymbolWidthUnit() 205 */ setSymbolHeightUnit(QgsUnitTypes::RenderUnit unit)206 void setSymbolHeightUnit( QgsUnitTypes::RenderUnit unit ) { mSymbolHeightUnit = unit; } 207 208 /** 209 * Returns the units for the symbol's height. 210 * \see setSymbolHeightUnit() 211 * \see symbolWidthUnit() 212 */ symbolHeightUnit()213 QgsUnitTypes::RenderUnit symbolHeightUnit() const { return mSymbolHeightUnit; } 214 setSymbolHeightMapUnitScale(const QgsMapUnitScale & scale)215 void setSymbolHeightMapUnitScale( const QgsMapUnitScale &scale ) { mSymbolHeightMapUnitScale = scale; } symbolHeightMapUnitScale()216 const QgsMapUnitScale &symbolHeightMapUnitScale() const { return mSymbolHeightMapUnitScale; } 217 218 /** 219 * Sets the units for the symbol's stroke width. 220 * \param unit symbol units 221 * \see strokeWidthUnit() 222 */ setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)223 void setStrokeWidthUnit( QgsUnitTypes::RenderUnit unit ) { mStrokeWidthUnit = unit; } 224 225 /** 226 * Returns the units for the symbol's stroke width. 227 * \see setStrokeWidthUnit() 228 */ strokeWidthUnit()229 QgsUnitTypes::RenderUnit strokeWidthUnit() const { return mStrokeWidthUnit; } 230 setStrokeWidthMapUnitScale(const QgsMapUnitScale & scale)231 void setStrokeWidthMapUnitScale( const QgsMapUnitScale &scale ) { mStrokeWidthMapUnitScale = scale; } strokeWidthMapUnitScale()232 const QgsMapUnitScale &strokeWidthMapUnitScale() const { return mStrokeWidthMapUnitScale; } 233 234 void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override; 235 QgsUnitTypes::RenderUnit outputUnit() const override; 236 bool usesMapUnits() const override; 237 238 void setMapUnitScale( const QgsMapUnitScale &scale ) override; 239 QgsMapUnitScale mapUnitScale() const override; 240 241 QRectF bounds( QPointF point, QgsSymbolRenderContext &context ) override; 242 243 private: 244 Shape mShape = Circle; 245 double mSymbolWidth = 4; 246 QgsUnitTypes::RenderUnit mSymbolWidthUnit = QgsUnitTypes::RenderMillimeters; 247 QgsMapUnitScale mSymbolWidthMapUnitScale; 248 double mSymbolHeight = 3; 249 QgsUnitTypes::RenderUnit mSymbolHeightUnit = QgsUnitTypes::RenderMillimeters; 250 QgsMapUnitScale mSymbolHeightMapUnitScale; 251 QColor mStrokeColor; 252 Qt::PenStyle mStrokeStyle = Qt::SolidLine; 253 Qt::PenJoinStyle mPenJoinStyle = DEFAULT_ELLIPSE_JOINSTYLE; 254 Qt::PenCapStyle mPenCapStyle = Qt::SquareCap; 255 double mStrokeWidth = 0; 256 QgsUnitTypes::RenderUnit mStrokeWidthUnit = QgsUnitTypes::RenderMillimeters; 257 QgsMapUnitScale mStrokeWidthMapUnitScale; 258 259 QPainterPath mPainterPath; 260 261 QPen mPen; 262 QBrush mBrush; 263 //! QPen to use as stroke of selected symbols 264 QPen mSelPen; 265 //! QBrush to use as fill of selected symbols 266 QBrush mSelBrush; 267 268 /** 269 * Setup mPainterPath 270 * \param shape name of symbol 271 * \param context render context 272 * \param scaledWidth optional width 273 * \param scaledHeight optional height 274 * \param f optional feature to render (0 if no data defined rendering) 275 */ 276 void preparePath( const QgsEllipseSymbolLayer::Shape &shape, QgsSymbolRenderContext &context, double *scaledWidth = nullptr, double *scaledHeight = nullptr, const QgsFeature *f = nullptr ); 277 QSizeF calculateSize( QgsSymbolRenderContext &context, double *scaledWidth = nullptr, double *scaledHeight = nullptr ); 278 void calculateOffsetAndRotation( QgsSymbolRenderContext &context, double scaledWidth, double scaledHeight, bool &hasDataDefinedRotation, QPointF &offset, double &angle ) const; 279 }; 280 281 // clazy:excludeall=qstring-allocations 282 283 #endif // QGSELLIPSESYMBOLLAYER_H 284 285 286