26 #include <QDomElement>
33 , mLabelAttributeName( labelAttributeName )
35 , mTolerance( 0.00001 )
37 , mCircleColor( QColor( 125, 125, 125 ) )
38 , mCircleRadiusAddition( 0 )
39 , mMaxLabelScaleDenominator( -1 )
78 Q_UNUSED( drawVertexMarker );
99 if ( intersectList.empty() )
104 newGroup.insert( feature.
id(), feature );
118 group.insert( feature.
id(), feature );
126 const QgsFeature& feature = group.begin().value();
133 QStringList labelAttributeList;
134 QList<QgsMarkerSymbolV2*> symbolList;
136 for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt )
145 double currentWidthFactor;
147 QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin();
148 for ( ; it != symbolList.constEnd(); ++it )
153 double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
154 if ( currentDiagonal > diagonal )
156 diagonal = currentDiagonal;
164 double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 /
M_PI ) + circleAdditionPainterUnits;
167 drawCircle( radius, symbolContext, pt, symbolList.size() );
169 QList<QPointF> symbolPositions;
170 QList<QPointF> labelPositions;
174 if ( labelAttributeList.size() > 1 )
187 drawSymbols( feature, context, symbolList, symbolPositions, selected );
189 drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
239 QgsDebugMsg(
"QgsPointDisplacementRenderer::stopRender" );
261 QList<QString> attributeList;
270 return attributeList;
290 labelFont.fromString( symbologyElem.attribute(
"labelFont",
"" ) );
292 r->
setCircleWidth( symbologyElem.attribute(
"circleWidth",
"0.4" ).toDouble() );
297 r->
setTolerance( symbologyElem.attribute(
"tolerance",
"0.00001" ).toDouble() );
300 QDomElement embeddedRendererElem = symbologyElem.firstChildElement(
"renderer-v2" );
301 if ( !embeddedRendererElem.isNull() )
307 QDomElement centerSymbolElem = symbologyElem.firstChildElement(
"symbol" );
308 if ( !centerSymbolElem.isNull() )
318 rendererElement.setAttribute(
"type",
"pointDisplacement" );
320 rendererElement.setAttribute(
"labelFont",
mLabelFont.toString() );
321 rendererElement.setAttribute(
"circleWidth", QString::number(
mCircleWidth ) );
326 rendererElement.setAttribute(
"tolerance", QString::number(
mTolerance ) );
331 rendererElement.appendChild( embeddedRendererElem );
336 rendererElement.appendChild( centerSymbolElem );
338 return rendererElement;
368 QgsDebugMsg(
"number of displacement groups:" + QString::number( nGroups ) );
369 for (
int i = 0; i < nGroups; ++i )
371 QgsDebugMsg(
"***************displacement group " + QString::number( i ) );
372 QMap<QgsFeatureId, QgsFeature>::const_iterator it =
mDisplacementGroups.at( i ).constBegin();
400 double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts )
const
402 symbolPositions.clear();
409 else if ( nPosition == 1 )
411 symbolPositions.append( centerPoint );
412 labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
416 double fullPerimeter = 2 *
M_PI;
417 double angleStep = fullPerimeter / nPosition;
420 for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
422 double sinusCurrentAngle = sin( currentAngle );
423 double cosinusCurrentAngle = cos( currentAngle );
424 QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
425 QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
426 symbolPositions.append( centerPoint + positionShift );
427 labelShifts.append( labelShift );
434 if ( nSymbols < 2 || !p )
442 p->setPen( circlePen );
443 p->drawArc( QRectF( centerPoint.x() - radiusPainterUnits, centerPoint.y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
448 QList<QPointF>::const_iterator symbolPosIt = symbolPositions.constBegin();
449 QList<QgsMarkerSymbolV2*>::const_iterator symbolIt = symbolList.constBegin();
450 for ( ; symbolPosIt != symbolPositions.constEnd() && symbolIt != symbolList.constEnd(); ++symbolPosIt, ++symbolIt )
454 ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
468 p->setPen( labelPen );
473 QFont scaledFont = pixelSizeFont;
475 p->setFont( scaledFont );
477 QFontMetricsF fontMetrics( pixelSizeFont );
478 QPointF currentLabelShift;
480 QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
481 QStringList::const_iterator text_it = labelList.constBegin();
483 for ( ; labelPosIt != labelShifts.constEnd() && text_it != labelList.constEnd(); ++labelPosIt, ++text_it )
485 currentLabelShift = *labelPosIt;
486 if ( currentLabelShift.x() < 0 )
488 currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( *text_it ) );
490 if ( currentLabelShift.y() > 0 )
492 currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
495 QPointF drawingPoint( centerPoint + currentLabelShift );
497 p->translate( drawingPoint.x(), drawingPoint.y() );
499 p->drawText( QPointF( 0, 0 ), *text_it );
512 if ( symbolList.size() < 1 )
517 return symbolList.at( 0 );
QgsFeatureId id() const
Get the feature id for this feature.
void startRender(QgsRenderContext &context, const QgsFields &fields)
#define RENDERER_TAG_NAME
A rectangle specified with double values.
~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 drawSymbols(const QgsFeature &f, QgsRenderContext &context, const QList< QgsMarkerSymbolV2 * > &symbolList, const QList< QPointF > &symbolPositions, bool selected=false)
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
QgsSymbolV2List symbols()
for symbol levels
void setCenterSymbol(QgsMarkerSymbolV2 *symbol)
Sets the center symbol (takes ownership)
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)
Container of fields for a vector layer.
WkbType
Used for symbology operations.
static QColor decodeColor(QString str)
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.
QList< QgsFeatureId > intersects(QgsRectangle rect) const
returns features that intersect the specified rectangle
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).
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
QFont mLabelFont
Font that is passed to the renderer.
virtual QgsFeatureRendererV2 * clone()=0
QSet< QgsFeatureId > mSelectedFeatures
keeps trask which features are selected
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
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 drawCircle(double radiusPainterUnits, QgsSymbolV2RenderContext &context, const QPointF ¢erPoint, int nSymbols)
void setLabelColor(const QColor &c)
double mTolerance
Tolerance.
const QgsAttributes & attributes() const
double rasterScaleFactor() const
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
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)
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.
QMap< QgsFeatureId, QgsFeature > DisplacementGroup
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
QgsSpatialIndex * mSpatialIndex
Spatial index for fast lookup of close points.
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.
bool insertFeature(const QgsFeature &f)
add feature to index
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)
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.
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.
QMap< QgsFeatureId, int > mGroupIndex
Mapping from feature ID to its group index.
bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false)
Reimplemented from QgsFeatureRendererV2.
QList< DisplacementGroup > mDisplacementGroups
Groups of features that have the same position.
static QgsSymbolV2 * loadSymbol(QDomElement &element)
double outputLineWidth(double width) const
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QgsSymbolV2 * symbolForFeature(QgsFeature &feature)
to be overridden
QList< QString > usedAttributes()
void drawGroup(const DisplacementGroup &group, QgsRenderContext &context)
void setTolerance(double t)