1 /*************************************************************************** 2 qgsarrowsymbollayer.h 3 --------------------- 4 begin : January 2016 5 copyright : (C) 2016 by Hugo Mercier 6 email : hugo dot mercier at oslandia dot com 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 16 #ifndef QGSARROWSYMBOLLAYER_H 17 #define QGSARROWSYMBOLLAYER_H 18 19 #include "qgis_core.h" 20 #include "qgis.h" 21 #include "qgssymbollayer.h" 22 23 class QgsFillSymbol; 24 25 26 /** 27 * \ingroup core 28 * \class QgsArrowSymbolLayer 29 * \brief Line symbol layer used for representing lines as arrows. 30 * \since QGIS 2.16 31 */ 32 33 class CORE_EXPORT QgsArrowSymbolLayer : public QgsLineSymbolLayer 34 { 35 public: 36 //! Simple constructor 37 QgsArrowSymbolLayer(); 38 ~QgsArrowSymbolLayer() override; 39 40 /** 41 * Create a new QgsArrowSymbolLayer 42 * 43 * \param properties A property map to deserialize saved information from properties() 44 * 45 * \returns A new QgsArrowSymbolLayer 46 */ 47 static QgsSymbolLayer *create( const QVariantMap &properties = QVariantMap() ) SIP_FACTORY; 48 49 QgsArrowSymbolLayer *clone() const override SIP_FACTORY; 50 QgsSymbol *subSymbol() override; 51 bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER ) override; 52 QSet<QString> usedAttributes( const QgsRenderContext &context ) const override; 53 bool hasDataDefinedProperties() const override; 54 bool usesMapUnits() const override; 55 56 //! Gets current arrow width arrowWidth()57 double arrowWidth() const { return mArrowWidth; } 58 //! Sets the arrow width setArrowWidth(double width)59 void setArrowWidth( double width ) { mArrowWidth = width; } 60 //! Gets the unit for the arrow width arrowWidthUnit()61 QgsUnitTypes::RenderUnit arrowWidthUnit() const { return mArrowWidthUnit; } 62 //! Sets the unit for the arrow width setArrowWidthUnit(QgsUnitTypes::RenderUnit unit)63 void setArrowWidthUnit( QgsUnitTypes::RenderUnit unit ) { mArrowWidthUnit = unit; } 64 //! Gets the scale for the arrow width arrowWidthUnitScale()65 QgsMapUnitScale arrowWidthUnitScale() const { return mArrowWidthUnitScale; } 66 //! Sets the scale for the arrow width setArrowWidthUnitScale(const QgsMapUnitScale & scale)67 void setArrowWidthUnitScale( const QgsMapUnitScale &scale ) { mArrowWidthUnitScale = scale; } 68 69 //! Gets current arrow start width. Only meaningful for single headed arrows arrowStartWidth()70 double arrowStartWidth() const { return mArrowStartWidth; } 71 //! Sets the arrow start width setArrowStartWidth(double width)72 void setArrowStartWidth( double width ) { mArrowStartWidth = width; } 73 //! Gets the unit for the arrow start width arrowStartWidthUnit()74 QgsUnitTypes::RenderUnit arrowStartWidthUnit() const { return mArrowStartWidthUnit; } 75 //! Sets the unit for the arrow start width setArrowStartWidthUnit(QgsUnitTypes::RenderUnit unit)76 void setArrowStartWidthUnit( QgsUnitTypes::RenderUnit unit ) { mArrowStartWidthUnit = unit; } 77 //! Gets the scale for the arrow start width arrowStartWidthUnitScale()78 QgsMapUnitScale arrowStartWidthUnitScale() const { return mArrowStartWidthUnitScale; } 79 //! Sets the scale for the arrow start width setArrowStartWidthUnitScale(const QgsMapUnitScale & scale)80 void setArrowStartWidthUnitScale( const QgsMapUnitScale &scale ) { mArrowStartWidthUnitScale = scale; } 81 82 //! Gets the current arrow head length headLength()83 double headLength() const { return mHeadLength; } 84 //! Sets the arrow head length setHeadLength(double length)85 void setHeadLength( double length ) { mHeadLength = length; } 86 //! Gets the unit for the head length headLengthUnit()87 QgsUnitTypes::RenderUnit headLengthUnit() const { return mHeadLengthUnit; } 88 //! Sets the unit for the head length setHeadLengthUnit(QgsUnitTypes::RenderUnit unit)89 void setHeadLengthUnit( QgsUnitTypes::RenderUnit unit ) { mHeadLengthUnit = unit; } 90 //! Gets the scale for the head length headLengthUnitScale()91 QgsMapUnitScale headLengthUnitScale() const { return mHeadLengthUnitScale; } 92 //! Sets the scale for the head length setHeadLengthUnitScale(const QgsMapUnitScale & scale)93 void setHeadLengthUnitScale( const QgsMapUnitScale &scale ) { mHeadLengthUnitScale = scale; } 94 95 //! Gets the current arrow head height headThickness()96 double headThickness() const { return mHeadThickness; } 97 //! Sets the arrow head height setHeadThickness(double thickness)98 void setHeadThickness( double thickness ) { mHeadThickness = thickness; } 99 //! Gets the unit for the head height headThicknessUnit()100 QgsUnitTypes::RenderUnit headThicknessUnit() const { return mHeadThicknessUnit; } 101 //! Sets the unit for the head height setHeadThicknessUnit(QgsUnitTypes::RenderUnit unit)102 void setHeadThicknessUnit( QgsUnitTypes::RenderUnit unit ) { mHeadThicknessUnit = unit; } 103 //! Gets the scale for the head height headThicknessUnitScale()104 QgsMapUnitScale headThicknessUnitScale() const { return mHeadThicknessUnitScale; } 105 //! Sets the scale for the head height setHeadThicknessUnitScale(const QgsMapUnitScale & scale)106 void setHeadThicknessUnitScale( const QgsMapUnitScale &scale ) { mHeadThicknessUnitScale = scale; } 107 108 //! Returns whether it is a curved arrow or a straight one isCurved()109 bool isCurved() const { return mIsCurved; } 110 //! Sets whether it is a curved arrow or a straight one setIsCurved(bool isCurved)111 void setIsCurved( bool isCurved ) { mIsCurved = isCurved; } 112 113 //! Returns whether the arrow is repeated along the line or not isRepeated()114 bool isRepeated() const { return mIsRepeated; } 115 //! Sets whether the arrow is repeated along the line setIsRepeated(bool isRepeated)116 void setIsRepeated( bool isRepeated ) { mIsRepeated = isRepeated; } 117 118 //! Possible head types 119 enum HeadType 120 { 121 HeadSingle, //< One single head at the end 122 HeadReversed, //< One single head at the beginning 123 HeadDouble //< Two heads 124 }; 125 126 //! Gets the current head type headType()127 HeadType headType() const { return mHeadType; } 128 //! Sets the head type setHeadType(HeadType type)129 void setHeadType( HeadType type ) { mHeadType = type; } 130 131 //! Possible arrow types 132 enum ArrowType 133 { 134 ArrowPlain, //< Regular arrow 135 ArrowLeftHalf, //< Halved arrow, only the left side of the arrow is rendered (for straight arrows) or the side toward the exterior (for curved arrows) 136 ArrowRightHalf //< Halved arrow, only the right side of the arrow is rendered (for straight arrows) or the side toward the interior (for curved arrows) 137 }; 138 139 //! Gets the current arrow type arrowType()140 ArrowType arrowType() const { return mArrowType; } 141 //! Sets the arrow type setArrowType(ArrowType type)142 void setArrowType( ArrowType type ) { mArrowType = type; } 143 144 QVariantMap properties() const override; 145 QString layerType() const override; 146 void startRender( QgsSymbolRenderContext &context ) override; 147 void stopRender( QgsSymbolRenderContext &context ) override; 148 void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) override; 149 void setColor( const QColor &c ) override; 150 QColor color() const override; 151 bool canCauseArtifactsBetweenAdjacentTiles() const override; 152 153 private: 154 #ifdef SIP_RUN 155 QgsArrowSymbolLayer( const QgsArrowSymbolLayer & ); 156 #endif 157 158 //! Filling sub symbol 159 std::unique_ptr<QgsFillSymbol> mSymbol; 160 161 double mArrowWidth = 1.0; 162 QgsUnitTypes::RenderUnit mArrowWidthUnit = QgsUnitTypes::RenderMillimeters; 163 QgsMapUnitScale mArrowWidthUnitScale; 164 165 double mArrowStartWidth = 1.0; 166 QgsUnitTypes::RenderUnit mArrowStartWidthUnit = QgsUnitTypes::RenderMillimeters; 167 QgsMapUnitScale mArrowStartWidthUnitScale; 168 169 double mHeadLength = 1.5; 170 QgsUnitTypes::RenderUnit mHeadLengthUnit = QgsUnitTypes::RenderMillimeters; 171 QgsMapUnitScale mHeadLengthUnitScale; 172 double mHeadThickness = 1.5; 173 QgsUnitTypes::RenderUnit mHeadThicknessUnit = QgsUnitTypes::RenderMillimeters; 174 QgsMapUnitScale mHeadThicknessUnitScale; 175 176 HeadType mHeadType = HeadSingle; 177 ArrowType mArrowType = ArrowPlain; 178 bool mIsCurved = true; 179 bool mIsRepeated = true; 180 181 double mScaledArrowWidth = 1.0; 182 double mScaledArrowStartWidth = 1.0; 183 double mScaledHeadLength = 1.5; 184 double mScaledHeadThickness = 1.5; 185 double mScaledOffset = 0.0; 186 HeadType mComputedHeadType = HeadSingle; 187 ArrowType mComputedArrowType = ArrowPlain; 188 189 std::unique_ptr<QgsExpressionContextScope> mExpressionScope; 190 191 void _resolveDataDefined( QgsSymbolRenderContext & ); 192 }; 193 194 #endif 195 196 197