22
22
#include " qgspallabeling.h"
23
23
#include " qgsvectorlayer.h"
24
24
#include " qgsvectorlayerfeatureiterator.h"
25
+ #include " qgsrendererv2.h"
26
+ #include " qgspolygonv2.h"
27
+ #include " qgslinestringv2.h"
28
+ #include " qgsmultipolygonv2.h"
25
29
26
30
#include " feature.h"
27
31
#include " labelposition.h"
@@ -46,12 +50,13 @@ static void _fixQPictureDPI( QPainter* p )
46
50
47
51
48
52
QgsVectorLayerLabelProvider::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 () )
49
58
{
50
- mSettings = settings ? *settings : QgsPalLayerSettings::fromLayer ( layer );
51
59
mName = layerName.isEmpty () ? layer->id () : layerName;
52
- mLayerId = layer->id ();
53
- mFields = layer->fields ();
54
- mCrs = layer->crs ();
55
60
56
61
if ( withFeatureLoop )
57
62
{
@@ -72,9 +77,10 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( const QgsPalLayerSetti
72
77
const QgsFields& fields,
73
78
const QgsCoordinateReferenceSystem& crs,
74
79
QgsAbstractFeatureSource* source,
75
- bool ownsSource )
80
+ bool ownsSource, QgsFeatureRendererV2* renderer )
76
81
: mSettings( settings )
77
82
, mLayerId( layerId )
83
+ , mRenderer( renderer )
78
84
, mFields( fields )
79
85
, mCrs( crs )
80
86
, mSource( source )
@@ -263,7 +269,13 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
263
269
QgsFeature fet;
264
270
while ( fit.nextFeature ( fet ) )
265
271
{
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 () );
267
279
}
268
280
269
281
return mLabels ;
@@ -277,6 +289,86 @@ void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRende
277
289
mLabels << label;
278
290
}
279
291
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
+
280
372
void QgsVectorLayerLabelProvider::drawLabel ( QgsRenderContext& context, pal::LabelPosition* label ) const
281
373
{
282
374
if ( !mSettings .drawLabels )
0 commit comments