Skip to content

Commit 6b0e7de

Browse files
committed
Allow registering feature to label/diagram provider with obstacle geom
Sponsored by City of Uster
1 parent 2e0019d commit 6b0e7de

7 files changed

+56
-30
lines changed

src/core/qgspallabeling.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -2257,14 +2257,12 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
22572257
geos_geom = geom->asGeos();
22582258
}
22592259
const GEOSGeometry* geosObstacleGeom = 0;
2260-
const QgsGeometry* preparedObstacleGeom = obstacleGeometry;
22612260
QScopedPointer<QgsGeometry> scopedObstacleGeom;
22622261
if ( isObstacle )
22632262
{
22642263
if ( obstacleGeometry && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, ct, doClip ? extentGeom : 0 ) )
22652264
{
22662265
scopedObstacleGeom.reset( QgsPalLabeling::prepareGeometry( obstacleGeometry, context, ct, doClip ? extentGeom : 0 ) );
2267-
preparedObstacleGeom = scopedObstacleGeom.data();
22682266
geosObstacleGeom = scopedObstacleGeom.data()->asGeos();
22692267
}
22702268
else if ( obstacleGeometry )

src/core/qgsrulebasedlabeling.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStrin
2525
return true;
2626
}
2727

28-
void QgsRuleBasedLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext &context )
28+
void QgsRuleBasedLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsGeometry* obstacleGeometry )
2929
{
3030
// will register the feature to relevant sub-providers
31-
mRules.rootRule()->registerFeature( feature, context, mSubProviders );
31+
mRules.rootRule()->registerFeature( feature, context, mSubProviders, obstacleGeometry );
3232
}
3333

3434
QList<QgsAbstractLabelProvider*> QgsRuleBasedLabelProvider::subProviders()
@@ -241,7 +241,7 @@ void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext& context, QStri
241241
}
242242
}
243243

244-
QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderMap& subProviders )
244+
QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderMap& subProviders, QgsGeometry* obstacleGeometry )
245245
{
246246
if ( !isFilterOK( feature, context )
247247
|| !isScaleOK( context.rendererScale() ) )
@@ -252,7 +252,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
252252
// do we have active subprovider for the rule?
253253
if ( subProviders.contains( this ) && mIsActive )
254254
{
255-
subProviders[this]->registerFeature( feature, context );
255+
subProviders[this]->registerFeature( feature, context, obstacleGeometry );
256256
registered = true;
257257
}
258258

@@ -264,7 +264,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
264264
// Don't process else rules yet
265265
if ( !rule->isElse() )
266266
{
267-
RegisterResult res = rule->registerFeature( feature, context, subProviders );
267+
RegisterResult res = rule->registerFeature( feature, context, subProviders, obstacleGeometry );
268268
// consider inactive items as "registered" so the else rule will ignore them
269269
willRegisterSomething |= ( res == Registered || res == Inactive );
270270
registered |= willRegisterSomething;
@@ -276,7 +276,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
276276
{
277277
Q_FOREACH ( Rule* rule, mElseRules )
278278
{
279-
registered |= rule->registerFeature( feature, context, subProviders ) != Filtered;
279+
registered |= rule->registerFeature( feature, context, subProviders, obstacleGeometry ) != Filtered;
280280
}
281281
}
282282

src/core/qgsrulebasedlabeling.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class QgsExpression;
1313
class QgsFeature;
1414
class QgsPalLayerSettings;
1515
class QgsRenderContext;
16-
16+
class QgsGeometry;
1717

1818
class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
1919
{
@@ -194,7 +194,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
194194
void prepare( const QgsRenderContext& context, QStringList& attributeNames, RuleToProviderMap& subProviders );
195195

196196
//! register individual features
197-
RegisterResult registerFeature( QgsFeature& feature, QgsRenderContext& context, RuleToProviderMap& subProviders );
197+
RegisterResult registerFeature( QgsFeature& feature, QgsRenderContext& context, RuleToProviderMap& subProviders, QgsGeometry* obstacleGeometry = 0 );
198198

199199
protected:
200200
/**
@@ -274,7 +274,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
274274

275275
virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames ) override;
276276

277-
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context ) override;
277+
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry = 0 ) override;
278278

279279
// new methods
280280

src/core/qgsvectorlayerdiagramprovider.cpp

+25-4
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,15 @@ bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QS
225225
}
226226

227227

228-
void QgsVectorLayerDiagramProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context )
228+
void QgsVectorLayerDiagramProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
229229
{
230-
QgsLabelFeature* label = registerDiagram( feature, context );
230+
QgsLabelFeature* label = registerDiagram( feature, context, obstacleGeometry );
231231
if ( label )
232232
mFeatures << label;
233233
}
234234

235235

236-
QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& feat, QgsRenderContext &context )
236+
QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& feat, QgsRenderContext &context, QgsGeometry* obstacleGeometry )
237237
{
238238
const QgsMapSettings& mapSettings = mEngine->mapSettings();
239239

@@ -284,9 +284,26 @@ QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& fea
284284
{
285285
return 0; // invalid geometry
286286
}
287-
288287
GEOSGeometry* geomCopy = GEOSGeom_clone_r( QgsGeometry::getGEOSHandler(), geos_geom );
289288

289+
const GEOSGeometry* geosObstacleGeom = 0;
290+
QScopedPointer<QgsGeometry> scopedObstacleGeom;
291+
if ( mSettings.obstacle && obstacleGeometry && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, mSettings.ct, extentGeom.data() ) )
292+
{
293+
scopedObstacleGeom.reset( QgsPalLabeling::prepareGeometry( obstacleGeometry, context, mSettings.ct, extentGeom.data() ) );
294+
geosObstacleGeom = scopedObstacleGeom.data()->asGeos();
295+
}
296+
else if ( mSettings.obstacle && obstacleGeometry )
297+
{
298+
geosObstacleGeom = obstacleGeometry->asGeos();
299+
}
300+
GEOSGeometry* geosObstacleGeomClone = 0;
301+
if ( geosObstacleGeom )
302+
{
303+
geosObstacleGeomClone = GEOSGeom_clone_r( QgsGeometry::getGEOSHandler(), geosObstacleGeom );
304+
}
305+
306+
290307
double diagramWidth = 0;
291308
double diagramHeight = 0;
292309
if ( dr )
@@ -336,6 +353,10 @@ QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& fea
336353
lf->setFixedAngle( 0 );
337354
lf->setAlwaysShow( alwaysShow );
338355
lf->setIsObstacle( mSettings.obstacle );
356+
if ( geosObstacleGeomClone )
357+
{
358+
lf->setObstacleGeometry( geosObstacleGeomClone );
359+
}
339360

340361
if ( dr )
341362
{

src/core/qgsvectorlayerdiagramprovider.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,19 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
9090
* @param feature feature for diagram
9191
* @param context render context. The QgsExpressionContext contained within the render context
9292
* must have already had the feature and fields sets prior to calling this method.
93+
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
94+
* should be used as an obstacle for labels (eg, if the feature has been rendered with an offset point
95+
* symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set,
96+
* the feature's original geometry will be used as an obstacle for labels. Ownership of obstacleGeometry
97+
* is transferred.
9398
*/
94-
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context );
99+
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsGeometry* obstacleGeometry = 0 );
95100

96101
protected:
97102
//! initialization method - called from constructors
98103
void init();
99104
//! helper method to register one diagram feautre
100-
QgsLabelFeature* registerDiagram( QgsFeature& feat, QgsRenderContext& context );
105+
QgsLabelFeature* registerDiagram( QgsFeature& feat, QgsRenderContext& context, QgsGeometry* obstacleGeometry = 0 );
101106

102107
protected:
103108

src/core/qgsvectorlayerlabelprovider.cpp

+9-12
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer,
5252
mLayerId = layer->id();
5353
mFields = layer->fields();
5454
mCrs = layer->crs();
55+
5556
if ( withFeatureLoop )
5657
{
5758
mSource = new QgsVectorLayerFeatureSource( layer );
@@ -66,13 +67,12 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer,
6667
init();
6768
}
6869

69-
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider(
70-
const QgsPalLayerSettings& settings,
71-
const QString& layerId,
72-
const QgsFields& fields,
73-
const QgsCoordinateReferenceSystem& crs,
74-
QgsAbstractFeatureSource* source,
75-
bool ownsSource )
70+
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
71+
const QString& layerId,
72+
const QgsFields& fields,
73+
const QgsCoordinateReferenceSystem& crs,
74+
QgsAbstractFeatureSource* source,
75+
bool ownsSource )
7676
: mSettings( settings )
7777
, mLayerId( layerId )
7878
, mFields( fields )
@@ -269,17 +269,14 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
269269
return mLabels;
270270
}
271271

272-
273-
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context )
272+
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
274273
{
275274
QgsLabelFeature* label = 0;
276-
mSettings.registerFeature( feature, context, QString(), &label );
275+
mSettings.registerFeature( feature, context, QString(), &label, obstacleGeometry );
277276
if ( label )
278277
mLabels << label;
279278
}
280279

281-
282-
283280
void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
284281
{
285282
if ( !mSettings.drawLabels )

src/core/qgsvectorlayerlabelprovider.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgslabelingenginev2.h"
2020

2121
class QgsAbstractFeatureSource;
22+
class QgsFeatureRendererV2;
2223

2324
/**
2425
* @brief The QgsVectorLayerLabelProvider class implements a label provider
@@ -64,8 +65,12 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
6465
* @param feature feature to label
6566
* @param context render context. The QgsExpressionContext contained within the render context
6667
* must have already had the feature and fields sets prior to calling this method.
68+
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
69+
* should be used as an obstacle for labels (eg, if the feature has been rendered with an offset point
70+
* symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set,
71+
* the feature's original geometry will be used as an obstacle for labels.
6772
*/
68-
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context );
73+
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsGeometry* obstacleGeometry = 0 );
6974

7075
protected:
7176
//! initialization method - called from constructors

0 commit comments

Comments
 (0)