34 #include <QDomElement> 40 #define M_SQRT2 1.41421356237309504880 45 , mLabelAttributeName( labelAttributeName )
51 , mCircleColor(
QColor( 125, 125, 125 ) )
52 , mCircleRadiusAddition( 0 )
53 , mMaxLabelScaleDenominator( -1 )
54 , mSpatialIndex( nullptr )
97 mRenderer->
toSld( doc, element, props );
103 Q_UNUSED( drawVertexMarker );
111 QgsSymbolV2* symbol = firstSymbolForFeature( mRenderer, feature, context );
127 mSelectedFeatures.
insert( feature.
id() );
131 if ( intersectList.
empty() )
136 newGroup.
insert( feature.
id(), qMakePair( feature, symbol ) );
137 mDisplacementGroups.push_back( newGroup );
139 mGroupIndex.
insert( feature.
id(), mDisplacementGroups.count() - 1 );
146 int groupIdx = mGroupIndex[ existingEntry ];
150 group.
insert( feature.
id(), qMakePair( feature, symbol ) );
152 mGroupIndex.
insert( feature.
id(), groupIdx );
159 bool selected = mSelectedFeatures.
contains( feature.
id() );
171 labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) :
QString() );
172 symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second );
173 featureList << attIt.
value().first;
174 groupMultiPoint->
addGeometry( attIt.value().first.constGeometry()->geometry()->clone() );
201 double circleRadius = -1.0;
202 calculateSymbolAndLabelPositions( symbolContext, pt, symbolList.
size(), diagonal, symbolPositions, labelPositions, circleRadius );
205 if ( circleRadius > 0 )
206 drawCircle( circleRadius, symbolContext, pt, symbolList.
size() );
209 if ( labelAttributeList.
size() > 1 )
213 mCenterSymbol->
renderPoint( pt, &feature, context, -1, selected );
222 drawSymbols( featureList, context, symbolList, symbolPositions, selected );
224 drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
273 if ( !mLabelAttributeName.
isEmpty() )
275 attributeList.
push_back( mLabelAttributeName );
281 return attributeList;
299 return mRenderer->
symbols( context );
355 mDisplacementGroups.clear();
358 mSelectedFeatures.
clear();
360 if ( mLabelAttributeName.
isEmpty() )
369 if ( mMaxLabelScaleDenominator > 0 && context.
rendererScale() > mMaxLabelScaleDenominator )
387 QgsDebugMsg(
"QgsPointDisplacementRenderer::stopRender" );
393 drawGroup( group, context );
396 mDisplacementGroups.clear();
398 delete mSpatialIndex;
399 mSpatialIndex =
nullptr;
400 mSelectedFeatures.
clear();
431 if ( !embeddedRendererElem.
isNull() )
438 if ( !centerSymbolElem.
isNull() )
440 r->
setCenterSymbol( QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( centerSymbolElem ) );
449 rendererElement.
setAttribute(
"type",
"pointDisplacement" );
450 rendererElement.
setAttribute(
"labelAttributeName", mLabelAttributeName );
456 rendererElement.
setAttribute(
"placement", static_cast< int >( mPlacement ) );
465 rendererElement.
appendChild( embeddedRendererElem );
484 return rendererElement;
506 QgsRectangle QgsPointDisplacementRenderer::searchRect(
const QgsPoint& p,
double distance )
const 508 return QgsRectangle( p.
x() - distance, p.
y() - distance, p.
x() + distance, p.
y() + distance );
511 void QgsPointDisplacementRenderer::printInfoDisplacementGroups()
513 int nGroups = mDisplacementGroups.size();
515 for (
int i = 0; i < nGroups; ++i )
519 for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
530 if ( mLabelIndex >= 0 && mLabelIndex < attrs.
count() )
532 attribute = attrs.
at( mLabelIndex ).toString();
539 delete mCenterSymbol;
540 mCenterSymbol = symbol;
548 symbolPositions.
clear();
555 else if ( nPosition == 1 )
557 symbolPositions.
append( centerPoint );
558 labelShifts.
append(
QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
562 double circleAdditionPainterUnits = symbolContext.
outputLineWidth( mCircleRadiusAddition );
564 switch ( mPlacement )
568 double minDiameterToFitSymbols = nPosition * symbolDiagonal / ( 2.0 *
M_PI );
569 double radius = qMax( symbolDiagonal / 2, minDiameterToFitSymbols ) + circleAdditionPainterUnits;
571 double fullPerimeter = 2 *
M_PI;
572 double angleStep = fullPerimeter / nPosition;
573 for (
double currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
575 double sinusCurrentAngle = sin( currentAngle );
576 double cosinusCurrentAngle = cos( currentAngle );
577 QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
578 QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
579 symbolPositions.
append( centerPoint + positionShift );
580 labelShifts.
append( labelShift );
583 circleRadius = radius;
592 int pointsRemaining = nPosition;
594 double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0;
595 while ( pointsRemaining > 0 )
597 double radiusCurrentRing = qMax( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 );
598 int maxPointsCurrentRing = qMax( floor( 2 *
M_PI * radiusCurrentRing / symbolDiagonal ), 1.0 );
599 int actualPointsCurrentRing = qMin( maxPointsCurrentRing, pointsRemaining );
601 double angleStep = 2 *
M_PI / actualPointsCurrentRing;
602 double currentAngle = 0.0;
603 for (
int i = 0; i < actualPointsCurrentRing; ++i )
605 double sinusCurrentAngle = sin( currentAngle );
606 double cosinusCurrentAngle = cos( currentAngle );
607 QPointF positionShift( radiusCurrentRing * sinusCurrentAngle, radiusCurrentRing * cosinusCurrentAngle );
608 QPointF labelShift(( radiusCurrentRing + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radiusCurrentRing + symbolDiagonal / 2 ) * cosinusCurrentAngle );
609 symbolPositions.
append( centerPoint + positionShift );
610 labelShifts.
append( labelShift );
611 currentAngle += angleStep;
614 pointsRemaining -= actualPointsCurrentRing;
616 circleRadius = radiusCurrentRing;
626 if ( nSymbols < 2 || !p )
632 QPen circlePen( mCircleColor );
635 p->
drawArc(
QRectF( centerPoint.
x() - radiusPainterUnits, centerPoint.
y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
644 for ( ; symbolPosIt != symbolPositions.
constEnd() && symbolIt != symbolList.
constEnd() && featIt != features.
constEnd();
645 ++symbolPosIt, ++symbolIt, ++featIt )
650 ( *symbolIt )->startRender( context );
651 ( *symbolIt )->renderPoint( *symbolPosIt, &( *featIt ), context, -1, selected );
652 ( *symbolIt )->stopRender( context );
665 QPen labelPen( mLabelColor );
669 QFont pixelSizeFont = mLabelFont;
671 QFont scaledFont = pixelSizeFont;
681 for ( ; labelPosIt != labelShifts.
constEnd() && text_it != labelList.
constEnd(); ++labelPosIt, ++text_it )
683 currentLabelShift = *labelPosIt;
684 if ( currentLabelShift.
x() < 0 )
686 currentLabelShift.
setX( currentLabelShift.
x() - fontMetrics.
width( *text_it ) );
688 if ( currentLabelShift.
y() > 0 )
690 currentLabelShift.
setY( currentLabelShift.
y() + fontMetrics.
ascent() );
693 QPointF drawingPoint( centerPoint + currentLabelShift );
695 p->
translate( drawingPoint.
x(), drawingPoint.
y() );
710 if ( symbolList.
size() < 1 )
715 return symbolList.
at( 0 );
720 if ( renderer->
type() ==
"pointDisplacement" )
725 if ( renderer->
type() ==
"singleSymbol" ||
726 renderer->
type() ==
"categorizedSymbol" ||
727 renderer->
type() ==
"graduatedSymbol" ||
728 renderer->
type() ==
"RuleRenderer" )
732 return pointRenderer;
static QString encodeOutputUnit(QgsSymbolV2::OutputUnit unit)
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
#define RENDERER_TAG_NAME
A rectangle specified with double values.
double rendererScale() const
virtual QSet< QString > legendKeysForFeature(QgsFeature &feature, QgsRenderContext &context)
Return legend keys matching a specified feature.
virtual QSet< QString > legendKeysForFeature(QgsFeature &feature, QgsRenderContext &context) override
Returns which legend keys match the feature.
QgsAttributes attributes() const
Returns the feature's attributes.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsPointDisplacementRenderer * clone() const override
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
~QgsPointDisplacementRenderer()
QList< QgsSymbolV2 * > QgsSymbolV2List
virtual void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
QDomNode appendChild(const QDomNode &newChild)
virtual void setLegendSymbolItem(const QString &key, QgsSymbolV2 *symbol) override
Sets the symbol to be used for a legend symbol item.
void push_back(const T &value)
QString attribute(const QString &name, const QString &defValue) const
static QgsFeatureRendererV2 * create(QDomElement &symbologyElem)
create a renderer from XML element
static double mapUnitScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns scale factor painter units -> map units.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
virtual Q_DECL_DEPRECATED QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feature)
Return symbol for feature.
void setLabelAttributeName(const QString &name)
static QString encodeColor(const QColor &color)
void setLabelFont(const QFont &f)
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
void setCenterSymbol(QgsMarkerSymbolV2 *symbol)
Sets the center symbol (takes ownership)
void scale(qreal sx, qreal sy)
QList< QgsFeatureId > intersects(const QgsRectangle &rect) const
Returns features that intersect the specified rectangle.
const_iterator constBegin() const
const T & at(int i) const
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
#define FID_TO_STRING(fid)
static QDomElement saveSymbol(const QString &symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
void setMaxLabelScaleDenominator(double d)
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
static QgsPointDisplacementRenderer * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsPointDisplacementRenderer from an existing renderer.
WkbType
Used for symbology operations.
QDomElement save(QDomDocument &doc) override
store renderer info to XML element
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat, QgsRenderContext &context) override
Proxy that will call this method on the embedded renderer.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
double size() const
Returns the size for the whole symbol, which is the maximum size of all marker symbol layers in the s...
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
virtual QList< QString > usedAttributes()=0
Returns a set of attributes required for this renderer.
Multi point geometry collection.
QgsPointDisplacementRenderer(const QString &labelAttributeName="")
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
double toDouble(bool *ok) const
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
Needs to be called when a new render cycle is started.
int wkbSize() const
Returns the size of the WKB in asWkb().
virtual Q_DECL_DEPRECATED bool willRenderFeature(QgsFeature &feat)
Returns whether the renderer will render a feature or not.
virtual bool legendSymbolItemChecked(const QString &key)
items of symbology items in legend is checked
QMap< QString, QString > QgsStringMap
qreal width(const QString &text) const
QgsPaintEffect * mPaintEffect
virtual void checkLegendSymbolItem(const QString &key, bool state=true)
item in symbology was checked
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
double y() const
Get the y value of the point.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
void setToleranceUnit(QgsSymbolV2::OutputUnit unit)
Sets the units for the tolerance distance.
virtual void stopRender(QgsRenderContext &context)=0
Needs to be called when a render cycle has finished to clean up.
static QgsSymbolV2::OutputUnit decodeOutputUnit(const QString &str)
virtual Q_DECL_DEPRECATED QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat)
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
void drawRect(const QRectF &rectangle)
void setPixelSize(int pixelSize)
virtual QgsFeatureRendererV2 * clone() const =0
void setFont(const QFont &font)
The output shall be in millimeters.
QString number(int n, int base)
virtual Q_DECL_DEPRECATED QgsSymbolV2 * symbolForFeature(QgsFeature &feature)
To be overridden.
void append(const T &value)
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat, QgsRenderContext &context) override
Proxy that will call this method on the embedded renderer.
void startRender(QgsRenderContext &context, const QgsFields *fields=nullptr)
bool fromString(const QString &descrip)
double outputLineWidth(double width) const
void drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
static double convertToPainterUnits(const QgsRenderContext &c, double size, QgsSymbolV2::OutputUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale())
Converts a size from the specied units to painter units.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="")
return a list of item text / symbol
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
const_iterator constEnd() const
virtual void toSld(QDomDocument &doc, QDomElement &element) const override
Writes the SLD element following the SLD v1.1 specs.
void setLabelColor(const QColor &c)
void setWidthF(qreal width)
OutputUnit sizeUnit() const
Returns the size units for the whole symbol (including all symbol layers).
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feat, QgsRenderContext &context) override
Proxy that will call this method on the embedded renderer.
void drawText(const QPointF &position, const QString &text)
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
void setPlacement(Placement placement)
Sets the placement method used for dispersing the points.
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
virtual Q_DECL_DEPRECATED QgsSymbolV2List symbols()
For symbol levels.
A class to represent a point.
bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Reimplemented from QgsFeatureRendererV2.
virtual bool willRenderFeature(QgsFeature &feat, QgsRenderContext &context) override
Proxy that will call this method on the embedded renderer.
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
virtual bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
void setCircleRadiusAddition(double d)
QgsFeatureId id() const
Get the feature ID for this feature.
void stopRender(QgsRenderContext &context) override
Needs to be called when a render cycle has finished to clean up.
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
QgsExpressionContext & expressionContext()
Gets the expression context.
A renderer that automatically displaces points with the same position.
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature, QgsRenderContext &context) override
Proxy that will call this method on the embedded renderer.
bool contains(const T &value) const
void setEmbeddedRenderer(QgsFeatureRendererV2 *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
void setCircleWidth(double w)
const T & at(int i) const
QgsFeatureRequest::OrderBy orderBy() const
Get the order in which features shall be processed by this renderer.
void copyRendererData(QgsFeatureRendererV2 *destRenderer) const
Clones generic renderer data to another renderer.
Contains information about the context of a rendering operation.
QgsMapUnitScale sizeMapUnitScale() const
Returns the size map unit scale for the whole symbol.
bool insertFeature(const QgsFeature &f)
Add feature to index.
void stopRender(QgsRenderContext &context)
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="") override
virtual Q_DECL_DEPRECATED QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
Returns list of symbols used for rendering the feature.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
void setCircleColor(const QColor &c)
QgsFeatureRequest::OrderBy mOrderBy
QgsRenderContext & renderContext()
QDomElement firstChildElement(const QString &tagName) const
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
int count(const T &value) const
void renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
void translate(const QPointF &offset)
virtual int capabilities() override
Proxy that will call this method on the embedded renderer.
static QColor decodeColor(const QString &str)
iterator insert(const Key &key, const T &value)
void setToleranceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the distance tolerance.
static QgsConstWkbPtr _getPoint(QPointF &pt, QgsRenderContext &context, QgsConstWkbPtr &wkb)
Creates a point in screen coordinates from a wkb string in map coordinates.
virtual bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
virtual bool legendSymbolItemsCheckable() const
items of symbology items in legend should be checkable
double rasterScaleFactor() const
const_iterator constEnd() const
virtual int capabilities()
returns bitwise OR-ed capabilities of the renderer
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
virtual QList< QString > usedAttributes() override
Partial proxy that will call this method on the embedded renderer.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
virtual void setLegendSymbolItem(const QString &key, QgsSymbolV2 *symbol)
Sets the symbol to be used for a legend symbol item.
const QgsFeatureRendererV2 * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
double x() const
Get the x value of the point.
virtual QgsMarkerSymbolV2 * clone() const override
void setTolerance(double t)
Sets the tolerance distance for grouping points.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.