29 #include <QDomElement>
36 , mLabelAttributeName( labelAttributeName )
38 , mTolerance( 0.00001 )
40 , mCircleColor(
QColor( 125, 125, 125 ) )
41 , mCircleRadiusAddition( 0 )
42 , mMaxLabelScaleDenominator( -1 )
43 , mSpatialIndex( NULL )
77 mRenderer->
toSld( doc, element );
83 Q_UNUSED( drawVertexMarker );
91 QgsSymbolV2* symbol = firstSymbolForFeature( mRenderer, feature );
107 mSelectedFeatures.
insert( feature.
id() );
110 if ( intersectList.
empty() )
115 newGroup.
insert( feature.
id(), qMakePair( feature, symbol ) );
116 mDisplacementGroups.push_back( newGroup );
118 mGroupIndex.
insert( feature.
id(), mDisplacementGroups.count() - 1 );
125 int groupIdx = mGroupIndex[ existingEntry ];
129 group.
insert( feature.
id(), qMakePair( feature, symbol ) );
131 mGroupIndex.
insert( feature.
id(), groupIdx );
135 void QgsPointDisplacementRenderer::drawGroup(
const DisplacementGroup& group,
QgsRenderContext& context )
137 const QgsFeature& feature = group.begin().value().first;
138 bool selected = mSelectedFeatures.
contains( feature.
id() );
147 for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt )
149 labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) :
QString() );
150 symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second );
155 double currentWidthFactor;
158 for ( ; it != symbolList.
constEnd(); ++it )
163 double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
164 if ( currentDiagonal > diagonal )
166 diagonal = currentDiagonal;
173 double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition );
174 double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 /
M_PI ) + circleAdditionPainterUnits;
177 drawCircle( radius, symbolContext, pt, symbolList.
size() );
181 calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions );
184 if ( labelAttributeList.size() > 1 )
188 mCenterSymbol->
renderPoint( pt, &feature, context, -1, selected );
192 context.
painter()->
drawRect(
QRectF( pt.
x() - symbolContext.outputLineWidth( 1 ), pt.
y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) );
197 drawSymbols( feature, context, symbolList, symbolPositions, selected );
199 drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
211 if ( !mLabelAttributeName.
isEmpty() )
213 attributeList.
push_back( mLabelAttributeName );
219 return attributeList;
286 mDisplacementGroups.clear();
289 mSelectedFeatures.
clear();
291 if ( mLabelAttributeName.
isEmpty() )
300 if ( mMaxLabelScaleDenominator > 0 && context.
rendererScale() > mMaxLabelScaleDenominator )
317 QgsDebugMsg(
"QgsPointDisplacementRenderer::stopRender" );
322 drawGroup( *it, context );
324 mDisplacementGroups.clear();
326 delete mSpatialIndex;
328 mSelectedFeatures.
clear();
356 if ( !embeddedRendererElem.
isNull() )
363 if ( !centerSymbolElem.
isNull() )
365 r->
setCenterSymbol( QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( centerSymbolElem ) );
373 rendererElement.
setAttribute(
"type",
"pointDisplacement" );
374 rendererElement.
setAttribute(
"labelAttributeName", mLabelAttributeName );
386 rendererElement.
appendChild( embeddedRendererElem );
397 return rendererElement;
421 return QgsRectangle( p.
x() - mTolerance, p.
y() - mTolerance, p.
x() + mTolerance, p.
y() + mTolerance );
424 void QgsPointDisplacementRenderer::printInfoDisplacementGroups()
426 int nGroups = mDisplacementGroups.size();
428 for (
int i = 0; i < nGroups; ++i )
431 DisplacementGroup::const_iterator it = mDisplacementGroups.at( i ).constBegin();
432 for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
443 if ( mLabelIndex >= 0 && mLabelIndex < attrs.
count() )
445 attribute = attrs[mLabelIndex].toString();
452 delete mCenterSymbol;
453 mCenterSymbol = symbol;
458 void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions(
const QPointF& centerPoint,
int nPosition,
double radius,
461 symbolPositions.
clear();
468 else if ( nPosition == 1 )
470 symbolPositions.
append( centerPoint );
471 labelShifts.
append(
QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
475 double fullPerimeter = 2 *
M_PI;
476 double angleStep = fullPerimeter / nPosition;
479 for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
481 double sinusCurrentAngle = sin( currentAngle );
482 double cosinusCurrentAngle = cos( currentAngle );
483 QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
484 QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
485 symbolPositions.
append( centerPoint + positionShift );
486 labelShifts.
append( labelShift );
490 void QgsPointDisplacementRenderer::drawCircle(
double radiusPainterUnits,
QgsSymbolV2RenderContext& context,
const QPointF& centerPoint,
int nSymbols )
493 if ( nSymbols < 2 || !p )
499 QPen circlePen( mCircleColor );
502 p->
drawArc(
QRectF( centerPoint.
x() - radiusPainterUnits, centerPoint.
y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
509 for ( ; symbolPosIt != symbolPositions.
constEnd() && symbolIt != symbolList.
constEnd(); ++symbolPosIt, ++symbolIt )
513 ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
526 QPen labelPen( mLabelColor );
530 QFont pixelSizeFont = mLabelFont;
532 QFont scaledFont = pixelSizeFont;
542 for ( ; labelPosIt != labelShifts.
constEnd() && text_it != labelList.
constEnd(); ++labelPosIt, ++text_it )
544 currentLabelShift = *labelPosIt;
545 if ( currentLabelShift.
x() < 0 )
547 currentLabelShift.
setX( currentLabelShift.
x() - fontMetrics.width( *text_it ) );
549 if ( currentLabelShift.
y() > 0 )
551 currentLabelShift.
setY( currentLabelShift.
y() + fontMetrics.ascent() );
554 QPointF drawingPoint( centerPoint + currentLabelShift );
556 p->
translate( drawingPoint.x(), drawingPoint.y() );
571 if ( symbolList.
size() < 1 )
576 return symbolList.
at( 0 );
581 if ( renderer->
type() ==
"pointDisplacement" )
586 if ( renderer->
type() ==
"singleSymbol" ||
587 renderer->
type() ==
"categorizedSymbol" ||
588 renderer->
type() ==
"graduatedSymbol" ||
589 renderer->
type() ==
"RuleRenderer" )
593 return pointRenderer;
QgsFeatureId id() const
Get the feature ID for this feature.
#define RENDERER_TAG_NAME
virtual bool willRenderFeature(QgsFeature &feat)
return whether the renderer will render a feature or not.
A rectangle specified with double values.
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feature)
Return symbol for feature.
~QgsPointDisplacementRenderer()
QList< QgsSymbolV2 * > QgsSymbolV2List
QDomNode appendChild(const QDomNode &newChild)
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
void push_back(const T &value)
static const unsigned char * _getPoint(QPointF &pt, QgsRenderContext &context, const unsigned char *wkb)
QString attribute(const QString &name, const QString &defValue) const
static QgsFeatureRendererV2 * create(QDomElement &symbologyElem)
create a renderer from XML element
void setLabelAttributeName(const QString &name)
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
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 T & at(int i) const
QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
#define FID_TO_STRING(fid)
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
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.
static QColor decodeColor(QString str)
QDomElement save(QDomDocument &doc) override
store renderer info to XML element
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
virtual QList< QString > usedAttributes()=0
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
void startRender(QgsRenderContext &context, const QgsFields &fields) override
QList< QgsFeatureId > intersects(QgsRectangle rect) const
returns features that intersect the specified rectangle
QgsPaintEffect * mPaintEffect
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static QString encodeColor(QColor color)
virtual void stopRender(QgsRenderContext &context)=0
static QDomElement saveSymbol(QString symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
virtual QgsSymbolV2List symbols()=0
for symbol levels
virtual 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)
QString number(int n, int base)
void append(const T &value)
bool fromString(const QString &descrip)
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
void drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
QgsAttributes attributes() const
Returns the feature's attributes.
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
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)
virtual QgsSymbolV2 * clone() const override
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.)
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="") override
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.
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
void setCircleRadiusAddition(double d)
void stopRender(QgsRenderContext &context) override
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.
bool contains(const T &value) const
void setCircleWidth(double w)
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
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature) override
Proxy that will call this method on the embedded renderer.
void stopRender(QgsRenderContext &context)
void copyPaintEffect(QgsFeatureRendererV2 *destRenderer) const
Copies paint effect of this renderer to another renderer.
static double lineWidthScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns the line width scale factor depending on the unit and the paint device.
virtual QgsSymbolV2List symbols() override
Proxy that will call this method on the embedded renderer.
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
return list of symbols used for rendering the feature.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
void setCircleColor(const QColor &c)
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 translate(const QPointF &offset)
virtual int capabilities() override
Proxy that will call this method on the embedded renderer.
iterator insert(const Key &key, const T &value)
virtual bool willRenderFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
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
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
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature)=0
to be overridden
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QgsFeatureRendererV2 * clone() const override
void setTolerance(double t)
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.