2222#include " qgspallabeling.h"
2323#include " qgsvectorlayer.h"
2424#include " qgsvectorlayerfeatureiterator.h"
25+ #include " qgsrendererv2.h"
26+ #include " qgspolygonv2.h"
27+ #include " qgslinestringv2.h"
28+ #include " qgsmultipolygonv2.h"
2529
2630#include " feature.h"
2731#include " labelposition.h"
@@ -46,12 +50,13 @@ static void _fixQPictureDPI( QPainter* p )
4650
4751
4852QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider ( QgsVectorLayer* layer, bool withFeatureLoop, const QgsPalLayerSettings* settings, const QString& layerName )
53+ : mSettings( settings ? *settings : QgsPalLayerSettings::fromLayer( layer ) )
54+ , mLayerId( layer->id () )
55+ , mRenderer( layer->rendererV2 () )
56+ , mFields( layer->fields () )
57+ , mCrs( layer->crs () )
4958{
50- mSettings = settings ? *settings : QgsPalLayerSettings::fromLayer ( layer );
5159 mName = layerName.isEmpty () ? layer->id () : layerName;
52- mLayerId = layer->id ();
53- mFields = layer->fields ();
54- mCrs = layer->crs ();
5560
5661 if ( withFeatureLoop )
5762 {
@@ -72,9 +77,10 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( const QgsPalLayerSetti
7277 const QgsFields& fields,
7378 const QgsCoordinateReferenceSystem& crs,
7479 QgsAbstractFeatureSource* source,
75- bool ownsSource )
80+ bool ownsSource, QgsFeatureRendererV2* renderer )
7681 : mSettings( settings )
7782 , mLayerId( layerId )
83+ , mRenderer( renderer )
7884 , mFields( fields )
7985 , mCrs( crs )
8086 , mSource( source )
@@ -263,7 +269,13 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
263269 QgsFeature fet;
264270 while ( fit.nextFeature ( fet ) )
265271 {
266- registerFeature ( fet, ctx );
272+ QScopedPointer<QgsGeometry> obstacleGeometry;
273+ if ( fet.constGeometry ()->type () == QGis::Point )
274+ {
275+ // point feature, use symbol bounds as obstacle
276+ obstacleGeometry.reset ( getPointObstacleGeometry ( fet, ctx, mRenderer ) );
277+ }
278+ registerFeature ( fet, ctx, obstacleGeometry.data () );
267279 }
268280
269281 return mLabels ;
@@ -277,6 +289,86 @@ void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRende
277289 mLabels << label;
278290}
279291
292+ QgsGeometry* QgsVectorLayerLabelProvider::getPointObstacleGeometry ( QgsFeature& fet, QgsRenderContext& context, QgsFeatureRendererV2* renderer )
293+ {
294+ if ( !fet.constGeometry () || fet.constGeometry ()->isEmpty () || fet.constGeometry ()->type () != QGis::Point || !renderer )
295+ return 0 ;
296+
297+ // calculate bounds for symbols for feature
298+ QgsSymbolV2List symbols = renderer->originalSymbolsForFeature ( fet, context );
299+
300+ bool isMultiPoint = fet.constGeometry ()->geometry ()->nCoordinates () > 1 ;
301+ QgsAbstractGeometryV2* obstacleGeom = 0 ;
302+ if ( isMultiPoint )
303+ obstacleGeom = new QgsMultiPolygonV2 ();
304+ else
305+ obstacleGeom = new QgsPolygonV2 ();
306+
307+ // for each point
308+ for ( int i = 0 ; i < fet.constGeometry ()->geometry ()->nCoordinates (); ++i )
309+ {
310+ QRectF bounds;
311+ QgsPointV2 p = fet.constGeometry ()->geometry ()->vertexAt ( QgsVertexId ( i, 0 , 0 ) );
312+ double x = p.x ();
313+ double y = p.y ();
314+ double z = 0 ; // dummy variable for coordinate transforms
315+
316+ // transform point to pixels
317+ if ( context.coordinateTransform () )
318+ {
319+ context.coordinateTransform ()->transformInPlace ( x, y, z );
320+ }
321+ context.mapToPixel ().transformInPlace ( x, y );
322+
323+ QPointF pt ( x, y );
324+ Q_FOREACH ( QgsSymbolV2* symbol, symbols )
325+ {
326+ if ( symbol->type () == QgsSymbolV2::Marker )
327+ {
328+ if ( bounds.isValid () )
329+ bounds = bounds.united ( static_cast < QgsMarkerSymbolV2* >( symbol )->bounds ( pt, context ) );
330+ else
331+ bounds = static_cast < QgsMarkerSymbolV2* >( symbol )->bounds ( pt, context );
332+ }
333+ }
334+
335+ // convert bounds to a geometry
336+ QgsLineStringV2* boundLineString = new QgsLineStringV2 ();
337+ boundLineString->addVertex ( QgsPointV2 ( bounds.topLeft () ) );
338+ boundLineString->addVertex ( QgsPointV2 ( bounds.topRight () ) );
339+ boundLineString->addVertex ( QgsPointV2 ( bounds.bottomRight () ) );
340+ boundLineString->addVertex ( QgsPointV2 ( bounds.bottomLeft () ) );
341+
342+ // then transform back to map units
343+ // TODO - remove when labeling is refactored to use screen units
344+ for ( int i = 0 ; i < boundLineString->numPoints (); ++i )
345+ {
346+ QgsPoint point = context.mapToPixel ().toMapCoordinates ( boundLineString->xAt ( i ), boundLineString->yAt ( i ) );
347+ boundLineString->setXAt ( i, point.x () );
348+ boundLineString->setYAt ( i, point.y () );
349+ }
350+ if ( context.coordinateTransform () )
351+ {
352+ boundLineString->transform ( *context.coordinateTransform (), QgsCoordinateTransform::ReverseTransform );
353+ }
354+ boundLineString->close ();
355+
356+ QgsPolygonV2* obstaclePolygon = new QgsPolygonV2 ();
357+ obstaclePolygon->setExteriorRing ( boundLineString );
358+
359+ if ( isMultiPoint )
360+ {
361+ static_cast <QgsMultiPolygonV2*>( obstacleGeom )->addGeometry ( obstaclePolygon );
362+ }
363+ else
364+ {
365+ obstacleGeom = obstaclePolygon;
366+ }
367+ }
368+
369+ return new QgsGeometry ( obstacleGeom );
370+ }
371+
280372void QgsVectorLayerLabelProvider::drawLabel ( QgsRenderContext& context, pal::LabelPosition* label ) const
281373{
282374 if ( !mSettings .drawLabels )
0 commit comments