Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgspointdisplacementrenderer.cpp 3 : : -------------------------------- 4 : : begin : January 26, 2010 5 : : copyright : (C) 2010 by Marco Hugentobler 6 : : email : marco at hugis dot net 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #ifndef QGSPOINTDISPLACEMENTRENDERER_H 19 : : #define QGSPOINTDISPLACEMENTRENDERER_H 20 : : 21 : : #include "qgis_core.h" 22 : : #include "qgis.h" 23 : : #include "qgspointdistancerenderer.h" 24 : : 25 : : /** 26 : : * \class QgsPointDisplacementRenderer 27 : : * \ingroup core 28 : : * \brief A renderer that automatically displaces points with the same geographic location. 29 : : */ 30 : 0 : class CORE_EXPORT QgsPointDisplacementRenderer: public QgsPointDistanceRenderer 31 : : { 32 : : public: 33 : : 34 : : /** 35 : : * Placement methods for dispersing points 36 : : */ 37 : : enum Placement 38 : : { 39 : : Ring, //!< Place points in a single ring around group 40 : : ConcentricRings, //!< Place points in concentric rings around group 41 : : Grid //!< Place points in a grid around group 42 : : }; 43 : : 44 : : /** 45 : : * Constructor for QgsPointDisplacementRenderer. 46 : : * \param labelAttributeName optional attribute name for labeling points 47 : : */ 48 : : QgsPointDisplacementRenderer( const QString &labelAttributeName = QString() ); 49 : : 50 : : QgsPointDisplacementRenderer *clone() const override SIP_FACTORY; 51 : : void startRender( QgsRenderContext &context, const QgsFields &fields ) override; 52 : : void stopRender( QgsRenderContext &context ) override; 53 : : QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) override; 54 : : QSet<QString> usedAttributes( const QgsRenderContext &context ) const override; 55 : : bool accept( QgsStyleEntityVisitorInterface *visitor ) const override; 56 : : 57 : : //! Create a renderer from XML element 58 : : static QgsFeatureRenderer *create( QDomElement &symbologyElem, const QgsReadWriteContext &context ) SIP_FACTORY; 59 : : 60 : : /** 61 : : * Sets the line width for the displacement group circle. 62 : : * \param width line width in mm 63 : : * \see circleWidth() 64 : : * \see setCircleColor() 65 : : */ 66 : 0 : void setCircleWidth( double width ) { mCircleWidth = width; } 67 : : 68 : : /** 69 : : * Returns the line width for the displacement group circle in mm. 70 : : * \see setCircleWidth() 71 : : * \see circleColor() 72 : : */ 73 : : double circleWidth() const { return mCircleWidth; } 74 : : 75 : : /** 76 : : * Sets the color used for drawing the displacement group circle. 77 : : * \param color circle color 78 : : * \see circleColor() 79 : : * \see setCircleWidth() 80 : : */ 81 : 0 : void setCircleColor( const QColor &color ) { mCircleColor = color; } 82 : : 83 : : /** 84 : : * Returns the color used for drawing the displacement group circle. 85 : : * \see setCircleColor() 86 : : * \see circleWidth() 87 : : */ 88 : : QColor circleColor() const { return mCircleColor; } 89 : : 90 : : /** 91 : : * Sets a factor for increasing the ring size of displacement groups. 92 : : * \param distance addition factor 93 : : * \see circleRadiusAddition() 94 : : */ 95 : 0 : void setCircleRadiusAddition( double distance ) { mCircleRadiusAddition = distance; } 96 : : 97 : : /** 98 : : * Returns the factor for increasing the ring size of displacement groups. 99 : : * \see setCircleRadiusAddition() 100 : : */ 101 : : double circleRadiusAddition() const { return mCircleRadiusAddition; } 102 : : 103 : : /** 104 : : * Sets a factor for increasing the label distances from the symbol. 105 : : * \param factor addition factor 106 : : * \see labelDistanceFactor() 107 : : * \since QGIS 3.8 108 : : */ 109 : 0 : void setLabelDistanceFactor( double factor ) { mLabelDistanceFactor = factor; } 110 : : 111 : : /** 112 : : * Returns the factor for label distance from the symbol. 113 : : * \see setLabelDistanceFactor() 114 : : * \since QGIS 3.8 115 : : */ 116 : : double labelDistanceFactor() const { return mLabelDistanceFactor; } 117 : : 118 : : /** 119 : : * Returns the placement method used for dispersing the points. 120 : : * \see setPlacement() 121 : : * \since QGIS 2.12 122 : : */ 123 : : Placement placement() const { return mPlacement; } 124 : : 125 : : /** 126 : : * Sets the placement method used for dispersing the points. 127 : : * \param placement placement method 128 : : * \see placement() 129 : : * \since QGIS 2.12 130 : : */ 131 : 0 : void setPlacement( Placement placement ) { mPlacement = placement; } 132 : : 133 : : /** 134 : : * Returns the symbol for the center of a displacement group (but not ownership of the symbol). 135 : : * \see setCenterSymbol() 136 : : */ 137 : : QgsMarkerSymbol *centerSymbol(); 138 : : 139 : : /** 140 : : * Sets the center symbol for a displacement group. 141 : : * \param symbol new center symbol. Ownership is transferred to the renderer. 142 : : * \see centerSymbol() 143 : : */ 144 : : void setCenterSymbol( QgsMarkerSymbol *symbol SIP_TRANSFER ); 145 : : 146 : : /** 147 : : * Creates a QgsPointDisplacementRenderer from an existing renderer. 148 : : * \returns a new renderer if the conversion was possible, otherwise NULLPTR. 149 : : * \since QGIS 2.5 150 : : */ 151 : : static QgsPointDisplacementRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer ) SIP_FACTORY; 152 : : 153 : : private: 154 : : #ifdef SIP_RUN 155 : : QgsPointDisplacementRenderer( const QgsPointDisplacementRenderer & ); 156 : : QgsPointDisplacementRenderer &operator=( const QgsPointDisplacementRenderer & ); 157 : : #endif 158 : : 159 : : //! Center symbol for a displacement group 160 : : std::unique_ptr< QgsMarkerSymbol > mCenterSymbol; 161 : : 162 : : //! Displacement placement mode 163 : : Placement mPlacement = Ring; 164 : : 165 : : //! Line width for the circle 166 : : double mCircleWidth = 0.4; 167 : : //! Color to draw the circle 168 : : QColor mCircleColor; 169 : : //! Addition to the default circle radius 170 : : double mCircleRadiusAddition = 0; 171 : : //! Factor for label distance 172 : : double mLabelDistanceFactor = 0.5; 173 : : 174 : : void drawGroup( QPointF centerPoint, QgsRenderContext &context, const QgsPointDistanceRenderer::ClusteredGroup &group ) override SIP_FORCE; 175 : : 176 : : //helper functions 177 : : void calculateSymbolAndLabelPositions( QgsSymbolRenderContext &symbolContext, QPointF centerPoint, int nPosition, double symbolDiagonal, QList<QPointF> &symbolPositions, QList<QPointF> &labelShifts, double &circleRadius, 178 : : double &gridRadius, int &gridSize, QVector<double> &diagonals ) const; 179 : : void drawCircle( double radiusPainterUnits, QgsSymbolRenderContext &context, QPointF centerPoint, int nSymbols ); 180 : : void drawSymbols( const ClusteredGroup &group, QgsRenderContext &context, const QList<QPointF> &symbolPositions ); 181 : : void drawGrid( int gridSizeUnits, QgsSymbolRenderContext &context, 182 : : QList<QPointF> pointSymbolPositions, int nSymbols ); 183 : : void centralizeGrid( QList<QPointF> &pointSymbolPositions, double radius, int size ) const; 184 : : }; 185 : : 186 : : #endif // QGSPOINTDISPLACEMENTRENDERER_H