Skip to content
Permalink
Browse files

Label providers: Copy any information from vector layer

This will make them thread-safe (not prone to corruption on changes to the vector layer)

This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s.
  • Loading branch information
wonder-sk committed Sep 21, 2015
1 parent 1d0d0e0 commit f3fd96f4eede4ebe5305d956348ae8691b3ea9ce
@@ -18,34 +18,66 @@
#include "qgslabelsearchtree.h"
#include "qgspalgeometry.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerfeatureiterator.h"
#include "diagram/qgsdiagram.h"

#include "feature.h"
#include "labelposition.h"


QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( const QgsDiagramLayerSettings* diagSettings,
const QgsDiagramRendererV2* diagRenderer,
const QString& layerId,
const QgsFields& fields,
const QgsCoordinateReferenceSystem& crs,
QgsAbstractFeatureSource* source,
bool ownsSource )
: mSettings( *diagSettings )
, mDiagRenderer( diagRenderer->clone() )
, mLayerId( layerId )
, mFields( fields )
, mLayerCrs( crs )
, mSource( source )
, mOwnsSource( ownsSource )
{
init();
}


QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( QgsVectorLayer* layer )
: mLayer( layer )
: mSettings( *layer->diagramLayerSettings() )
, mDiagRenderer( layer->diagramRenderer()->clone() )
, mLayerId( layer->id() )
, mFields( layer->fields() )
, mLayerCrs( layer->crs() )
, mSource( new QgsVectorLayerFeatureSource( layer ) )
, mOwnsSource( true )
{
const QgsDiagramLayerSettings* diagSettings = layer->diagramLayerSettings();
init();
}

// initialize the local copy
mSettings = *diagSettings;

mPriority = 1 - diagSettings->priority / 10.0; // convert 0..10 --> 1..0
mPlacement = QgsPalLayerSettings::Placement( diagSettings->placement );
mLinePlacementFlags = diagSettings->placementFlags;
if ( diagSettings->obstacle ) mFlags |= GeometriesAreObstacles;
void QgsVectorLayerDiagramProvider::init()
{
mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
mPlacement = QgsPalLayerSettings::Placement( mSettings.placement );
mLinePlacementFlags = mSettings.placementFlags;
if ( mSettings.obstacle ) mFlags |= GeometriesAreObstacles;
}


QgsVectorLayerDiagramProvider::~QgsVectorLayerDiagramProvider()
{
qDeleteAll( mSettings.geometries );

if ( mOwnsSource )
delete mSource;
}


QString QgsVectorLayerDiagramProvider::id() const
{
return mLayer->id() + "d";
return mLayerId + "d";
}

QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context )
@@ -55,16 +87,15 @@ QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsM

s2.ct = 0;
if ( mapSettings.hasCrsTransformEnabled() )
s2.ct = new QgsCoordinateTransform( mLayer->crs(), mapSettings.destinationCrs() );
s2.ct = new QgsCoordinateTransform( mLayerCrs, mapSettings.destinationCrs() );

s2.xform = &mapSettings.mapToPixel();

s2.fields = mLayer->fields();
s2.fields = mFields;

s2.renderer = mLayer->diagramRenderer()->clone();
s2.renderer = mDiagRenderer;

const QgsDiagramRendererV2* diagRenderer = mLayer->diagramRenderer();
QgsFields fields = mLayer->fields();
const QgsDiagramRendererV2* diagRenderer = s2.renderer;

QStringList attributeNames;

@@ -99,23 +130,23 @@ QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsM
}
else
{
QString name = fields.at( linearlyInterpolatedDiagramRenderer->classificationAttribute() ).name();
QString name = mFields.at( linearlyInterpolatedDiagramRenderer->classificationAttribute() ).name();
if ( !attributeNames.contains( name ) )
attributeNames << name;
}
}

//and the ones needed for data defined diagram positions
if ( mSettings.xPosColumn != -1 )
attributeNames << fields.at( mSettings.xPosColumn ).name();
attributeNames << mFields.at( mSettings.xPosColumn ).name();
if ( mSettings.yPosColumn != -1 )
attributeNames << fields.at( mSettings.yPosColumn ).name();
attributeNames << mFields.at( mSettings.yPosColumn ).name();


QgsFeatureRequest request;
request.setFilterRect( context.extent() );
request.setSubsetOfAttributes( attributeNames, mLayer->fields() );
QgsFeatureIterator fit = mLayer->getFeatures( request );
request.setSubsetOfAttributes( attributeNames, mFields );
QgsFeatureIterator fit = mSource->getFeatures( request );

QList<QgsLabelFeature*> features;

@@ -20,6 +20,7 @@

//#include "qgsdiagramrendererv2.h"

class QgsAbstractFeatureSource;

/**
* @brief The QgsVectorLayerDiagramProvider class implements support for diagrams within
@@ -30,7 +31,18 @@
class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvider
{
public:
QgsVectorLayerDiagramProvider( QgsVectorLayer* layer );

//! Convenience constructor to initialize the provider from given vector layer
explicit QgsVectorLayerDiagramProvider( QgsVectorLayer* layer );

QgsVectorLayerDiagramProvider( const QgsDiagramLayerSettings* diagSettings,
const QgsDiagramRendererV2* diagRenderer,
const QString& layerId,
const QgsFields& fields,
const QgsCoordinateReferenceSystem& crs,
QgsAbstractFeatureSource* source,
bool ownsSource );

~QgsVectorLayerDiagramProvider();

virtual QString id() const override;
@@ -40,12 +52,20 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;

protected:
void init();
QgsLabelFeature* registerDiagram( QgsFeature& feat, const QgsMapSettings& mapSettings, const QgsRenderContext& context );

protected:
QgsVectorLayer* mLayer;

QgsDiagramLayerSettings mSettings;
QgsDiagramRendererV2* mDiagRenderer;

QString mLayerId;
QgsFields mFields;
QgsCoordinateReferenceSystem mLayerCrs;
QgsAbstractFeatureSource* mSource;
bool mOwnsSource;

};

#endif // QGSVECTORLAYERDIAGRAMPROVIDER_H
@@ -26,7 +26,6 @@

QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( QgsVectorLayer *layer )
{
mLayer = layer;
mProviderFeatureSource = layer->dataProvider()->featureSource();
mFields = layer->fields();
mJoinBuffer = layer->mJoinBuffer->clone();
@@ -43,8 +43,6 @@ class QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource

protected:

QgsVectorLayer* mLayer;

QgsAbstractFeatureSource* mProviderFeatureSource;

QgsVectorLayerJoinBuffer* mJoinBuffer;
@@ -21,6 +21,7 @@
#include "qgspalgeometry.h"
#include "qgspallabeling.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerfeatureiterator.h"

#include "feature.h"
#include "labelposition.h"
@@ -45,13 +46,35 @@ static void _fixQPictureDPI( QPainter* p )
typedef QgsPalLayerSettings QgsVectorLayerLabelSettings;

QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer )
: mLayer( layer )
{
if ( mLayer->customProperty( "labeling" ).toString() != QString( "pal" ) || !mLayer->labelsEnabled() )
if ( layer->customProperty( "labeling" ).toString() != QString( "pal" ) || !layer->labelsEnabled() )
return;

mSettings = QgsVectorLayerLabelSettings::fromLayer( mLayer );
mSettings = QgsVectorLayerLabelSettings::fromLayer( layer );
mLayerId = layer->id();
mFields = layer->fields();
mSource = new QgsVectorLayerFeatureSource( layer );

init();
}

QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
const QString& layerId,
const QgsFields& fields,
QgsAbstractFeatureSource* source,
bool ownsSource )
: mSettings( settings )
, mLayerId( layerId )
, mFields( fields )
, mSource( source )
, mOwnsSource( ownsSource )
{
init();
}


void QgsVectorLayerLabelProvider::init()
{
mPlacement = mSettings.placement;
mLinePlacementFlags = mSettings.placementFlags;
mFlags = Flags();
@@ -67,21 +90,23 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer
mUpsidedownLabels = mSettings.upsidedownLabels;
}


QgsVectorLayerLabelProvider::~QgsVectorLayerLabelProvider()
{
qDeleteAll( mSettings.geometries );
}

QString QgsVectorLayerLabelProvider::id() const
{
return mLayer->id();
return mLayerId;
}


QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& ctx )
{
QgsVectorLayerLabelSettings& lyr = mSettings;

QgsDebugMsgLevel( "PREPARE LAYER " + mLayer->id(), 4 );
QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );

if ( lyr.drawLabels )
{
@@ -102,7 +127,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
else
{
// If we aren't an expression, we check to see if we can find the column.
if ( mLayer->fieldNameIndex( lyr.fieldName ) == -1 )
if ( mFields.fieldNameIndex( lyr.fieldName ) == -1 )
{
return QList<QgsLabelFeature*>();
}
@@ -111,7 +136,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap

QStringList attrNames;

lyr.mCurFields = mLayer->fields();
lyr.mCurFields = mFields;

if ( lyr.drawLabels )
{
@@ -172,7 +197,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
lyr.rasterCompressFactor = ctx.rasterScaleFactor();

// save the pal layer to our layer context (with some additional info)
lyr.fieldIndex = mLayer->fieldNameIndex( lyr.fieldName );
lyr.fieldIndex = mFields.fieldNameIndex( lyr.fieldName );

lyr.xform = &mapSettings.mapToPixel();
lyr.ct = 0;
@@ -194,8 +219,8 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap

QgsFeatureRequest request;
request.setFilterRect( ctx.extent() );
request.setSubsetOfAttributes( attrNames, mLayer->fields() );
QgsFeatureIterator fit = mLayer->getFeatures( request );
request.setSubsetOfAttributes( attrNames, mFields );
QgsFeatureIterator fit = mSource->getFeatures( request );

QList<QgsLabelFeature*> labels;

@@ -211,6 +236,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
return labels;
}


void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
{
if ( !mSettings.drawLabels )
@@ -309,7 +335,6 @@ void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::Lab
}



void QgsVectorLayerLabelProvider::drawLabelPrivate( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, QgsPalLabeling::DrawLabelType drawType, double dpiRatio ) const
{
// NOTE: this is repeatedly called for multi-part labels
@@ -18,6 +18,8 @@

#include "qgslabelingenginev2.h"

class QgsAbstractFeatureSource;

/**
* @brief The QgsVectorLayerLabelProvider class implements a label provider
* for vector layers. Parameters for the labeling are taken from the layer's
@@ -28,7 +30,16 @@
class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
{
public:
QgsVectorLayerLabelProvider( QgsVectorLayer* layer );

//! Convenience constructor to initialize the provider from given vector layer
explicit QgsVectorLayerLabelProvider( QgsVectorLayer* layer );

QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
const QString& layerId,
const QgsFields& fields,
QgsAbstractFeatureSource* source,
bool ownsSource );

~QgsVectorLayerLabelProvider();

virtual QString id() const override;
@@ -39,12 +50,15 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider


protected:
void init();
void drawLabelPrivate( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, QgsPalLabeling::DrawLabelType drawType, double dpiRatio = 1.0 ) const;

protected:
QgsVectorLayer* mLayer;

QgsPalLayerSettings mSettings;
QString mLayerId;
QgsFields mFields;
QgsAbstractFeatureSource* mSource;
bool mOwnsSource;
};


0 comments on commit f3fd96f

Please sign in to comment.
You can’t perform that action at this time.