26 #include <QDomElement>
33 , mLabelAttributeName( labelAttributeName )
35 , mTolerance( 0.00001 )
37 , mCircleColor( QColor( 125, 125, 125 ) )
38 , mCircleRadiusAddition( 0 )
39 , mMaxLabelScaleDenominator( -1 )
79 Q_UNUSED( drawVertexMarker );
93 QStringList labelAttributeList;
94 QList<QgsMarkerSymbolV2*> symbolList;
103 if ( feature.
id() == it->begin().key() )
105 QMap<QgsFeatureId, QgsFeature>::iterator attIt = it->begin();
106 for ( ; attIt != it->end(); ++attIt )
110 labelAttributeList <<
getLabel( attIt.value() );
114 labelAttributeList << QString();
126 labelAttributeList <<
getLabel( feature );
130 labelAttributeList << QString();
134 if ( symbolList.isEmpty() && labelAttributeList.isEmpty() )
142 double currentWidthFactor;
144 QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin();
145 for ( ; it != symbolList.constEnd(); ++it )
150 double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
151 if ( currentDiagonal > diagonal )
153 diagonal = currentDiagonal;
161 double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 /
M_PI ) + circleAdditionPainterUnits;
164 drawCircle( radius, symbolContext, pt, symbolList.size() );
166 QList<QPointF> symbolPositions;
167 QList<QPointF> labelPositions;
171 if ( labelAttributeList.size() > 1 )
184 drawSymbols( feature, context, symbolList, symbolPositions, selected );
186 drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
236 QgsDebugMsg(
"QgsPointDisplacementRenderer::stopRender" );
246 QList<QString> attributeList;
255 return attributeList;
275 labelFont.fromString( symbologyElem.attribute(
"labelFont",
"" ) );
277 r->
setCircleWidth( symbologyElem.attribute(
"circleWidth",
"0.4" ).toDouble() );
282 r->
setTolerance( symbologyElem.attribute(
"tolerance",
"0.00001" ).toDouble() );
285 QDomElement embeddedRendererElem = symbologyElem.firstChildElement(
"renderer-v2" );
286 if ( !embeddedRendererElem.isNull() )
292 QDomElement centerSymbolElem = symbologyElem.firstChildElement(
"symbol" );
293 if ( !centerSymbolElem.isNull() )
303 rendererElement.setAttribute(
"type",
"pointDisplacement" );
305 rendererElement.setAttribute(
"labelFont",
mLabelFont.toString() );
306 rendererElement.setAttribute(
"circleWidth", QString::number(
mCircleWidth ) );
311 rendererElement.setAttribute(
"tolerance", QString::number(
mTolerance ) );
316 rendererElement.appendChild( embeddedRendererElem );
321 rendererElement.appendChild( centerSymbolElem );
323 return rendererElement;
360 QList<QString>::const_iterator attStringIt = attributeStrings.constBegin();
361 for ( ; attStringIt != attributeStrings.constEnd(); ++attStringIt )
367 QList<QgsFeatureId> intersectList;
375 intersectList.clear();
381 if ( intersectList.empty() )
393 if ( it->size() > 0 && it->contains( existingEntry ) )
405 QMap<QgsFeatureId, QgsFeature> newMap;
420 QMap<QgsFeatureId, QgsFeature>::iterator mapIt = it->begin();
421 for ( ; mapIt != it->end(); ++mapIt )
439 QgsDebugMsg(
"number of displacement groups:" + QString::number( nGroups ) );
440 for (
int i = 0; i < nGroups; ++i )
442 QgsDebugMsg(
"***************displacement group " + QString::number( i ) );
443 QMap<QgsFeatureId, QgsFeature>::const_iterator it =
mDisplacementGroups.at( i ).constBegin();
449 QgsDebugMsg(
"********all displacement ids*********" );
462 QList<QMap<QgsFeatureId, QgsFeature> >::const_iterator list_it =
mDisplacementGroups.constBegin();
465 QMap<QgsFeatureId, QgsFeature>::const_iterator map_it = list_it->constBegin();
466 for ( ; map_it != list_it->constEnd(); ++map_it )
493 double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts )
const
495 symbolPositions.clear();
502 else if ( nPosition == 1 )
504 symbolPositions.append( centerPoint );
505 labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
509 double fullPerimeter = 2 *
M_PI;
510 double angleStep = fullPerimeter / nPosition;
513 for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
515 double sinusCurrentAngle = sin( currentAngle );
516 double cosinusCurrentAngle = cos( currentAngle );
517 QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
518 QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
519 symbolPositions.append( centerPoint + positionShift );
520 labelShifts.append( labelShift );
527 if ( nSymbols < 2 || !p )
535 p->setPen( circlePen );
536 p->drawArc( QRectF( centerPoint.x() - radiusPainterUnits, centerPoint.y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
541 QList<QPointF>::const_iterator symbolPosIt = symbolPositions.constBegin();
542 QList<QgsMarkerSymbolV2*>::const_iterator symbolIt = symbolList.constBegin();
543 for ( ; symbolPosIt != symbolPositions.constEnd() && symbolIt != symbolList.constEnd(); ++symbolPosIt, ++symbolIt )
547 ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
561 p->setPen( labelPen );
566 QFont scaledFont = pixelSizeFont;
568 p->setFont( scaledFont );
570 QFontMetricsF fontMetrics( pixelSizeFont );
571 QPointF currentLabelShift;
573 QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
574 QStringList::const_iterator text_it = labelList.constBegin();
576 for ( ; labelPosIt != labelShifts.constEnd() && text_it != labelList.constEnd(); ++labelPosIt, ++text_it )
578 currentLabelShift = *labelPosIt;
579 if ( currentLabelShift.x() < 0 )
581 currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( *text_it ) );
583 if ( currentLabelShift.y() > 0 )
585 currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
588 QPointF drawingPoint( centerPoint + currentLabelShift );
590 p->translate( drawingPoint.x(), drawingPoint.y() );
592 p->drawText( QPointF( 0, 0 ), *text_it );
605 if ( symbolList.size() < 1 )
610 return symbolList.at( 0 );
QgsFeatureId id() const
Get the feature id for this feature.
Wrapper for iterator of features from vector data provider or vector layer.
#define RENDERER_TAG_NAME
A rectangle specified with double values.
void createDisplacementGroups(QgsVectorLayer *vlayer, const QgsRectangle &viewExtent)
Create the displacement groups efficiently using a spatial index.
~QgsPointDisplacementRenderer()
QgsMarkerSymbolV2 * mCenterSymbol
Center symbol for a displacement group.
QList< QgsSymbolV2 * > QgsSymbolV2List
static const unsigned char * _getPoint(QPointF &pt, QgsRenderContext &context, const unsigned char *wkb)
static QgsFeatureRendererV2 * create(QDomElement &symbologyElem)
create a renderer from XML element
void setLabelAttributeName(const QString &name)
double rendererScale() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void setLabelFont(const QFont &f)
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
QgsSymbolV2List symbols()
for symbol levels
void setCenterSymbol(QgsMarkerSymbolV2 *symbol)
Sets the center symbol (takes ownership)
QList< QMap< QgsFeatureId, QgsFeature > > mDisplacementGroups
Groups of features that have the same position.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
#define FID_TO_STRING(fid)
QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
void setMaxLabelScaleDenominator(double d)
WkbType
Used for symbology operations.
static QColor decodeColor(QString str)
const QgsRectangle & extent() const
virtual QList< QString > usedAttributes()=0
QColor mCircleColor
Color to draw the circle.
QgsPointDisplacementRenderer(const QString &labelAttributeName="")
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void printInfoDisplacementGroups()
This is a debugging function to check the entries in the displacement groups.
double mCircleWidth
Line width for the circle.
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
void stopRender(QgsRenderContext &context)
int mLabelIndex
Label attribute index (or -1 if none).
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
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
QFont mLabelFont
Font that is passed to the renderer.
virtual QgsFeatureRendererV2 * clone()=0
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
void startRender(QgsRenderContext &context, const QgsVectorLayer *vlayer)
QDomElement save(QDomDocument &doc)
store renderer info to XML element
double mMaxLabelScaleDenominator
Maximum scale denominator for label display.
bool mDrawLabels
Is set internally from startRender() depending on scale denominator.
void setDisplacementGroups(const QList< QMap< QgsFeatureId, QgsFeature > > &list)
not available in python bindings
void drawCircle(double radiusPainterUnits, QgsSymbolV2RenderContext &context, const QPointF ¢erPoint, int nSymbols)
void setLabelColor(const QColor &c)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
double mTolerance
Tolerance.
const QgsAttributes & attributes() const
double rasterScaleFactor() const
QSet< QgsFeatureId > mDisplacementIds
Set that contains all the ids the display groups (for quicker lookup)
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
QList< QgsFeatureId > intersects(QgsRectangle rect)
returns features that intersect the specified rectangle
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
QString mLabelAttributeName
Attribute name for labeling.
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
bool insertFeature(QgsFeature &f)
add feature to index
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
A class to represent a point geometry.
void drawLabels(const QPointF ¢erPoint, QgsSymbolV2RenderContext &context, const QList< QPointF > &labelShifts, const QStringList &labelList)
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
void setCircleRadiusAddition(double d)
QgsFeatureRendererV2 * clone()
QString getLabel(const QgsFeature &f)
Returns the label for a feature (using mLabelAttributeName as attribute field)
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.
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
void setCircleWidth(double w)
QgsSymbolV2 * firstSymbolForFeature(QgsFeatureRendererV2 *r, QgsFeature &f)
Returns first symbol for feature or 0 if none.
Contains information about the context of a rendering operation.
void calculateSymbolAndLabelPositions(const QPointF ¢erPoint, int nPosition, double radius, double symbolDiagonal, QList< QPointF > &symbolPositions, QList< QPointF > &labelShifts) const
double mCircleRadiusAddition
Addition to the default circle radius.
void stopRender(QgsRenderContext &context)
QgsFeatureRendererV2 * mRenderer
Embedded renderer.
QVector< QVariant > QgsAttributes
virtual QgsSymbolV2 * clone() const
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()
QgsRectangle searchRect(const QgsPoint &p) const
Creates a search rectangle with mTolerance.
void startRender(QgsRenderContext &context, const QgsVectorLayer *layer=0)
bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false)
Reimplemented from QgsFeatureRendererV2.
static double lineWidthScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u)
Returns the line width scale factor depending on the unit and the paint device.
virtual void startRender(QgsRenderContext &context, const QgsVectorLayer *vlayer)=0
static QgsSymbolV2 * loadSymbol(QDomElement &element)
double outputLineWidth(double width) const
bool nextFeature(QgsFeature &f)
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
void drawSymbols(QgsFeature &f, QgsRenderContext &context, const QList< QgsMarkerSymbolV2 * > &symbolList, const QList< QPointF > &symbolPositions, bool selected=false)
QgsSymbolV2 * symbolForFeature(QgsFeature &feature)
to be overridden
QList< QString > usedAttributes()
void setTolerance(double t)