Skip to content

Commit

Permalink
Allow registering feature to label/diagram provider with obstacle geom
Browse files Browse the repository at this point in the history
Sponsored by City of Uster
  • Loading branch information
nyalldawson committed Nov 22, 2015
1 parent 2e0019d commit 6b0e7de
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 30 deletions.
2 changes: 0 additions & 2 deletions src/core/qgspallabeling.cpp
Expand Up @@ -2257,14 +2257,12 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
geos_geom = geom->asGeos();
}
const GEOSGeometry* geosObstacleGeom = 0;
const QgsGeometry* preparedObstacleGeom = obstacleGeometry;
QScopedPointer<QgsGeometry> scopedObstacleGeom;
if ( isObstacle )
{
if ( obstacleGeometry && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, ct, doClip ? extentGeom : 0 ) )
{
scopedObstacleGeom.reset( QgsPalLabeling::prepareGeometry( obstacleGeometry, context, ct, doClip ? extentGeom : 0 ) );
preparedObstacleGeom = scopedObstacleGeom.data();
geosObstacleGeom = scopedObstacleGeom.data()->asGeos();
}
else if ( obstacleGeometry )
Expand Down
12 changes: 6 additions & 6 deletions src/core/qgsrulebasedlabeling.cpp
Expand Up @@ -25,10 +25,10 @@ bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStrin
return true;
}

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

QList<QgsAbstractLabelProvider*> QgsRuleBasedLabelProvider::subProviders()
Expand Down Expand Up @@ -241,7 +241,7 @@ void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext& context, QStri
}
}

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

Expand All @@ -264,7 +264,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
// Don't process else rules yet
if ( !rule->isElse() )
{
RegisterResult res = rule->registerFeature( feature, context, subProviders );
RegisterResult res = rule->registerFeature( feature, context, subProviders, obstacleGeometry );
// consider inactive items as "registered" so the else rule will ignore them
willRegisterSomething |= ( res == Registered || res == Inactive );
registered |= willRegisterSomething;
Expand All @@ -276,7 +276,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
{
Q_FOREACH ( Rule* rule, mElseRules )
{
registered |= rule->registerFeature( feature, context, subProviders ) != Filtered;
registered |= rule->registerFeature( feature, context, subProviders, obstacleGeometry ) != Filtered;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/core/qgsrulebasedlabeling.h
Expand Up @@ -13,7 +13,7 @@ class QgsExpression;
class QgsFeature;
class QgsPalLayerSettings;
class QgsRenderContext;

class QgsGeometry;

class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
{
Expand Down Expand Up @@ -194,7 +194,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
void prepare( const QgsRenderContext& context, QStringList& attributeNames, RuleToProviderMap& subProviders );

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

protected:
/**
Expand Down Expand Up @@ -274,7 +274,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider

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

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

// new methods

Expand Down
29 changes: 25 additions & 4 deletions src/core/qgsvectorlayerdiagramprovider.cpp
Expand Up @@ -225,15 +225,15 @@ bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QS
}


void QgsVectorLayerDiagramProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context )
void QgsVectorLayerDiagramProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
{
QgsLabelFeature* label = registerDiagram( feature, context );
QgsLabelFeature* label = registerDiagram( feature, context, obstacleGeometry );
if ( label )
mFeatures << label;
}


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

Expand Down Expand Up @@ -284,9 +284,26 @@ QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& fea
{
return 0; // invalid geometry
}

GEOSGeometry* geomCopy = GEOSGeom_clone_r( QgsGeometry::getGEOSHandler(), geos_geom );

const GEOSGeometry* geosObstacleGeom = 0;
QScopedPointer<QgsGeometry> scopedObstacleGeom;
if ( mSettings.obstacle && obstacleGeometry && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, mSettings.ct, extentGeom.data() ) )
{
scopedObstacleGeom.reset( QgsPalLabeling::prepareGeometry( obstacleGeometry, context, mSettings.ct, extentGeom.data() ) );
geosObstacleGeom = scopedObstacleGeom.data()->asGeos();
}
else if ( mSettings.obstacle && obstacleGeometry )
{
geosObstacleGeom = obstacleGeometry->asGeos();
}
GEOSGeometry* geosObstacleGeomClone = 0;
if ( geosObstacleGeom )
{
geosObstacleGeomClone = GEOSGeom_clone_r( QgsGeometry::getGEOSHandler(), geosObstacleGeom );
}


double diagramWidth = 0;
double diagramHeight = 0;
if ( dr )
Expand Down Expand Up @@ -336,6 +353,10 @@ QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& fea
lf->setFixedAngle( 0 );
lf->setAlwaysShow( alwaysShow );
lf->setIsObstacle( mSettings.obstacle );
if ( geosObstacleGeomClone )
{
lf->setObstacleGeometry( geosObstacleGeomClone );
}

if ( dr )
{
Expand Down
9 changes: 7 additions & 2 deletions src/core/qgsvectorlayerdiagramprovider.h
Expand Up @@ -90,14 +90,19 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
* @param feature feature for diagram
* @param context render context. The QgsExpressionContext contained within the render context
* must have already had the feature and fields sets prior to calling this method.
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
* should be used as an obstacle for labels (eg, if the feature has been rendered with an offset point
* symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set,
* the feature's original geometry will be used as an obstacle for labels. Ownership of obstacleGeometry
* is transferred.
*/
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context );
virtual void registerFeature( QgsFeature& feature, QgsRenderContext &context, QgsGeometry* obstacleGeometry = 0 );

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

protected:

Expand Down
21 changes: 9 additions & 12 deletions src/core/qgsvectorlayerlabelprovider.cpp
Expand Up @@ -52,6 +52,7 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer,
mLayerId = layer->id();
mFields = layer->fields();
mCrs = layer->crs();

if ( withFeatureLoop )
{
mSource = new QgsVectorLayerFeatureSource( layer );
Expand All @@ -66,13 +67,12 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer,
init();
}

QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider(
const QgsPalLayerSettings& settings,
const QString& layerId,
const QgsFields& fields,
const QgsCoordinateReferenceSystem& crs,
QgsAbstractFeatureSource* source,
bool ownsSource )
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
const QString& layerId,
const QgsFields& fields,
const QgsCoordinateReferenceSystem& crs,
QgsAbstractFeatureSource* source,
bool ownsSource )
: mSettings( settings )
, mLayerId( layerId )
, mFields( fields )
Expand Down Expand Up @@ -269,17 +269,14 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
return mLabels;
}


void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context )
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
{
QgsLabelFeature* label = 0;
mSettings.registerFeature( feature, context, QString(), &label );
mSettings.registerFeature( feature, context, QString(), &label, obstacleGeometry );
if ( label )
mLabels << label;
}



void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
{
if ( !mSettings.drawLabels )
Expand Down
7 changes: 6 additions & 1 deletion src/core/qgsvectorlayerlabelprovider.h
Expand Up @@ -19,6 +19,7 @@
#include "qgslabelingenginev2.h"

class QgsAbstractFeatureSource;
class QgsFeatureRendererV2;

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

protected:
//! initialization method - called from constructors
Expand Down

0 comments on commit 6b0e7de

Please sign in to comment.