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 )
91 mRenderer->
toSld( doc, element );
97 Q_UNUSED( drawVertexMarker );
105 QgsSymbolV2* symbol = firstSymbolForFeature( mRenderer, feature, context );
121 mSelectedFeatures.
insert( feature.
id() );
125 if ( intersectList.
empty() )
130 newGroup.
insert( feature.
id(), qMakePair( feature, symbol ) );
131 mDisplacementGroups.push_back( newGroup );
133 mGroupIndex.
insert( feature.
id(), mDisplacementGroups.count() - 1 );
140 int groupIdx = mGroupIndex[ existingEntry ];
144 group.
insert( feature.
id(), qMakePair( feature, symbol ) );
146 mGroupIndex.
insert( feature.
id(), groupIdx );
153 bool selected = mSelectedFeatures.
contains( feature.
id() );
165 labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) :
QString() );
166 symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second );
167 featureList << attIt.
value().first;
168 groupMultiPoint->
addGeometry( attIt.value().first.constGeometry()->geometry()->clone() );
194 double circleRadius = -1.0;
195 calculateSymbolAndLabelPositions( symbolContext, pt, symbolList.
size(), diagonal, symbolPositions, labelPositions, circleRadius );
198 if ( circleRadius > 0 )
199 drawCircle( circleRadius, symbolContext, pt, symbolList.
size() );
202 if ( labelAttributeList.
size() > 1 )
206 mCenterSymbol->
renderPoint( pt, &feature, context, -1, selected );
215 drawSymbols( featureList, context, symbolList, symbolPositions, selected );
217 drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
266 if ( !mLabelAttributeName.
isEmpty() )
268 attributeList.
push_back( mLabelAttributeName );
274 return attributeList;
292 return mRenderer->
symbols( context );
341 mDisplacementGroups.clear();
344 mSelectedFeatures.
clear();
346 if ( mLabelAttributeName.
isEmpty() )
355 if ( mMaxLabelScaleDenominator > 0 && context.
rendererScale() > mMaxLabelScaleDenominator )
373 QgsDebugMsg(
"QgsPointDisplacementRenderer::stopRender" );
379 drawGroup( group, context );
382 mDisplacementGroups.clear();
384 delete mSpatialIndex;
385 mSpatialIndex =
nullptr;
386 mSelectedFeatures.
clear();
417 if ( !embeddedRendererElem.
isNull() )
424 if ( !centerSymbolElem.
isNull() )
426 r->
setCenterSymbol( QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( centerSymbolElem ) );
435 rendererElement.
setAttribute(
"type",
"pointDisplacement" );
436 rendererElement.
setAttribute(
"labelAttributeName", mLabelAttributeName );
442 rendererElement.
setAttribute(
"placement", static_cast< int >( mPlacement ) );
451 rendererElement.
appendChild( embeddedRendererElem );
470 return rendererElement;
492 QgsRectangle QgsPointDisplacementRenderer::searchRect(
const QgsPoint& p,
double distance )
const 494 return QgsRectangle( p.
x() - distance, p.
y() - distance, p.
x() + distance, p.
y() + distance );
497 void QgsPointDisplacementRenderer::printInfoDisplacementGroups()
499 int nGroups = mDisplacementGroups.size();
501 for (
int i = 0; i < nGroups; ++i )
505 for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
516 if ( mLabelIndex >= 0 && mLabelIndex < attrs.
count() )
518 attribute = attrs.
at( mLabelIndex ).toString();
525 delete mCenterSymbol;
526 mCenterSymbol = symbol;
534 symbolPositions.
clear();
541 else if ( nPosition == 1 )
543 symbolPositions.
append( centerPoint );
544 labelShifts.
append(
QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
548 double circleAdditionPainterUnits = symbolContext.
outputLineWidth( mCircleRadiusAddition );
550 switch ( mPlacement )
554 double minDiameterToFitSymbols = nPosition * symbolDiagonal / ( 2.0 *
M_PI );
555 double radius = qMax( symbolDiagonal / 2, minDiameterToFitSymbols ) + circleAdditionPainterUnits;
557 double fullPerimeter = 2 *
M_PI;
558 double angleStep = fullPerimeter / nPosition;
559 for (
double currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
561 double sinusCurrentAngle = sin( currentAngle );
562 double cosinusCurrentAngle = cos( currentAngle );
563 QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
564 QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
565 symbolPositions.
append( centerPoint + positionShift );
566 labelShifts.
append( labelShift );
569 circleRadius = radius;
578 int pointsRemaining = nPosition;
580 double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0;
581 while ( pointsRemaining > 0 )
583 double radiusCurrentRing = qMax( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 );
584 int maxPointsCurrentRing = qMax( floor( 2 *
M_PI * radiusCurrentRing / symbolDiagonal ), 1.0 );
585 int actualPointsCurrentRing = qMin( maxPointsCurrentRing, pointsRemaining );
587 double angleStep = 2 *
M_PI / actualPointsCurrentRing;
588 double currentAngle = 0.0;
589 for (
int i = 0; i < actualPointsCurrentRing; ++i )
591 double sinusCurrentAngle = sin( currentAngle );
592 double cosinusCurrentAngle = cos( currentAngle );
593 QPointF positionShift( radiusCurrentRing * sinusCurrentAngle, radiusCurrentRing * cosinusCurrentAngle );
594 QPointF labelShift(( radiusCurrentRing + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radiusCurrentRing + symbolDiagonal / 2 ) * cosinusCurrentAngle );
595 symbolPositions.
append( centerPoint + positionShift );
596 labelShifts.
append( labelShift );
597 currentAngle += angleStep;
600 pointsRemaining -= actualPointsCurrentRing;
602 circleRadius = radiusCurrentRing;
612 if ( nSymbols < 2 || !p )
618 QPen circlePen( mCircleColor );
621 p->
drawArc(
QRectF( centerPoint.
x() - radiusPainterUnits, centerPoint.
y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
630 for ( ; symbolPosIt != symbolPositions.
constEnd() && symbolIt != symbolList.
constEnd() && featIt != features.
constEnd();
631 ++symbolPosIt, ++symbolIt, ++featIt )
636 ( *symbolIt )->startRender( context );
637 ( *symbolIt )->renderPoint( *symbolPosIt, &( *featIt ), context, -1, selected );
638 ( *symbolIt )->stopRender( context );
651 QPen labelPen( mLabelColor );
655 QFont pixelSizeFont = mLabelFont;
657 QFont scaledFont = pixelSizeFont;
667 for ( ; labelPosIt != labelShifts.
constEnd() && text_it != labelList.
constEnd(); ++labelPosIt, ++text_it )
669 currentLabelShift = *labelPosIt;
670 if ( currentLabelShift.
x() < 0 )
672 currentLabelShift.
setX( currentLabelShift.
x() - fontMetrics.
width( *text_it ) );
674 if ( currentLabelShift.
y() > 0 )
676 currentLabelShift.
setY( currentLabelShift.
y() + fontMetrics.
ascent() );
679 QPointF drawingPoint( centerPoint + currentLabelShift );
681 p->
translate( drawingPoint.
x(), drawingPoint.
y() );
696 if ( symbolList.
size() < 1 )
701 return symbolList.
at( 0 );
706 if ( renderer->
type() ==
"pointDisplacement" )
711 if ( renderer->
type() ==
"singleSymbol" ||
712 renderer->
type() ==
"categorizedSymbol" ||
713 renderer->
type() ==
"graduatedSymbol" ||
714 renderer->
type() ==
"RuleRenderer" )
718 return pointRenderer;
QgsFeatureId id() const
Get the feature ID for this feature.
static QString encodeOutputUnit(QgsSymbolV2::OutputUnit unit)
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
#define RENDERER_TAG_NAME
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
A rectangle specified with double values.
QgsPointDisplacementRenderer * clone() const override
~QgsPointDisplacementRenderer()
QgsMapUnitScale sizeMapUnitScale() const
Returns the size map unit scale for the whole symbol.
QList< QgsFeatureId > intersects(const QgsRectangle &rect) const
Returns features that intersect the specified rectangle.
QgsFeatureRequest::OrderBy orderBy() const
Get the order in which features shall be processed by this renderer.
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.
OutputUnit sizeUnit() const
Returns the size units for the whole symbol (including all symbol layers).
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)
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
double size() const
Returns the size for the whole symbol, which is the maximum size of all marker symbol layers in the s...
double rendererScale() const
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)
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.
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 startRender(QgsRenderContext &context, const QgsFields &fields) override
Needs to be called when a new render cycle is started.
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
qreal width(const QString &text) const
QgsPaintEffect * mPaintEffect
double x() const
Get the x value of the point.
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
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
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)
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
QgsAttributes attributes() const
Returns the feature's attributes.
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
used from subclasses to create SLD Rule elements following SLD v1.1 specs
void setLabelColor(const QColor &c)
void setWidthF(qreal width)
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)
double rasterScaleFactor() const
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.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
void setPlacement(Placement placement)
Sets the placement method used for dispersing the points.
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
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)
void stopRender(QgsRenderContext &context) override
Needs to be called when a render cycle has finished to clean up.
QgsExpressionContext & expressionContext()
Gets the expression context.
void copyRendererData(QgsFeatureRendererV2 *destRenderer) const
Clones generic renderer data to another renderer.
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
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
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
Contains information about the context of a rendering operation.
bool insertFeature(const QgsFeature &f)
Add feature to index.
void stopRender(QgsRenderContext &context)
int wkbSize() const
Returns the size of the WKB in asWkb().
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
virtual bool legendSymbolItemsCheckable() const
items of symbology items in legend should be checkable
QgsRenderContext & renderContext()
QDomElement firstChildElement(const QString &tagName) const
int count(const T &value) const
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
void renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
void translate(const QPointF &offset)
double y() const
Get the y value of the point.
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.
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.
double outputLineWidth(double width) const
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QgsConstWkbPtr _getPoint(QPointF &pt, QgsRenderContext &context, QgsConstWkbPtr wkb)
const_iterator constEnd() const
virtual int capabilities()
returns bitwise OR-ed capabilities of the renderer
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
virtual QList< QString > usedAttributes() override
Partial proxy that will call this method on the embedded renderer.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
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.
virtual QgsMarkerSymbolV2 * clone() const override
void setTolerance(double t)
Sets the tolerance distance for grouping points.