mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
More labeling engine refactoring
- QgsPalLabeling now internally uses new engine - label/diagram providers can hook into rendering loop to avoid extra feature loops - map rendering uses the new engine instead of QgsPalLabeling This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s.
This commit is contained in:
parent
8100495df6
commit
d0fcc9557f
@ -47,9 +47,14 @@ class QgsLabelingEngineInterface
|
|||||||
//! called when starting rendering of a layer
|
//! called when starting rendering of a layer
|
||||||
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
||||||
//! returns PAL layer settings for a registered layer
|
//! returns PAL layer settings for a registered layer
|
||||||
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
|
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
|
||||||
|
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0 /Deprecated/;
|
||||||
//! adds a diagram layer to the labeling engine
|
//! adds a diagram layer to the labeling engine
|
||||||
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s );
|
//! @note added in QGIS 2.12
|
||||||
|
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx );
|
||||||
|
//! adds a diagram layer to the labeling engine
|
||||||
|
//! @deprecated since 2.12 - use prepareDiagramLayer()
|
||||||
|
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s ) /Deprecated/;
|
||||||
//! called for every feature
|
//! called for every feature
|
||||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
|
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
|
||||||
//! called for every diagram feature
|
//! called for every diagram feature
|
||||||
|
@ -699,7 +699,8 @@ class QgsPalLabeling : QgsLabelingEngineInterface
|
|||||||
|
|
||||||
bool isShowingCandidates() const;
|
bool isShowingCandidates() const;
|
||||||
void setShowingCandidates( bool showing );
|
void setShowingCandidates( bool showing );
|
||||||
const QList<QgsLabelCandidate>& candidates();
|
//! @deprecated since 2.12
|
||||||
|
const QList<QgsLabelCandidate>& candidates() /Deprecated/;
|
||||||
|
|
||||||
bool isShowingShadowRectangles() const;
|
bool isShowingShadowRectangles() const;
|
||||||
void setShowingShadowRectangles( bool showing );
|
void setShowingShadowRectangles( bool showing );
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
#include "qgspalgeometry.h"
|
#include "qgspalgeometry.h"
|
||||||
|
#include "qgsproject.h"
|
||||||
|
|
||||||
#include "feature.h"
|
#include "feature.h"
|
||||||
#include "labelposition.h"
|
#include "labelposition.h"
|
||||||
@ -33,9 +34,8 @@ static bool _palIsCancelled( void* ctx )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QgsLabelingEngineV2::QgsLabelingEngineV2( const QgsMapSettings& mapSettings )
|
QgsLabelingEngineV2::QgsLabelingEngineV2()
|
||||||
: mMapSettings( mapSettings )
|
: mFlags( RenderOutlineLabels | UsePartialCandidates )
|
||||||
, mFlags( RenderOutlineLabels | UsePartialCandidates )
|
|
||||||
, mSearchMethod( QgsPalLabeling::Chain )
|
, mSearchMethod( QgsPalLabeling::Chain )
|
||||||
, mCandPoint( 8 )
|
, mCandPoint( 8 )
|
||||||
, mCandLine( 8 )
|
, mCandLine( 8 )
|
||||||
@ -57,6 +57,15 @@ void QgsLabelingEngineV2::addProvider( QgsAbstractLabelProvider* provider )
|
|||||||
mProviders << provider;
|
mProviders << provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsLabelingEngineV2::removeProvider( QgsAbstractLabelProvider* provider )
|
||||||
|
{
|
||||||
|
int idx = mProviders.indexOf( provider );
|
||||||
|
if ( idx >= 0 )
|
||||||
|
{
|
||||||
|
delete mProviders.takeAt( idx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QgsLabelingEngineV2::run( QgsRenderContext& context )
|
void QgsLabelingEngineV2::run( QgsRenderContext& context )
|
||||||
{
|
{
|
||||||
pal::Pal p;
|
pal::Pal p;
|
||||||
@ -146,7 +155,7 @@ void QgsLabelingEngineV2::run( QgsRenderContext& context )
|
|||||||
l->setUpsidedownLabels( upsdnlabels );
|
l->setUpsidedownLabels( upsdnlabels );
|
||||||
|
|
||||||
|
|
||||||
QList<QgsLabelFeature*> features = provider->labelFeatures( mMapSettings, context );
|
QList<QgsLabelFeature*> features = provider->labelFeatures( context );
|
||||||
|
|
||||||
foreach ( QgsLabelFeature* feature, features )
|
foreach ( QgsLabelFeature* feature, features )
|
||||||
{
|
{
|
||||||
@ -286,6 +295,40 @@ QgsLabelingResults* QgsLabelingEngineV2::takeResults()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QgsLabelingEngineV2::readSettingsFromProject()
|
||||||
|
{
|
||||||
|
bool saved = false;
|
||||||
|
QgsProject* prj = QgsProject::instance();
|
||||||
|
mSearchMethod = ( QgsPalLabeling::Search )( prj->readNumEntry( "PAL", "/SearchMethod", ( int ) QgsPalLabeling::Chain, &saved ) );
|
||||||
|
mCandPoint = prj->readNumEntry( "PAL", "/CandidatesPoint", 8, &saved );
|
||||||
|
mCandLine = prj->readNumEntry( "PAL", "/CandidatesLine", 8, &saved );
|
||||||
|
mCandPolygon = prj->readNumEntry( "PAL", "/CandidatesPolygon", 8, &saved );
|
||||||
|
|
||||||
|
mFlags = 0;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/ShowingCandidates", false, &saved ) ) mFlags |= DrawCandidates;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/DrawRectOnly", false, &saved ) ) mFlags |= DrawLabelRectOnly;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/ShowingShadowRects", false, &saved ) ) mFlags |= DrawShadowRects;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/ShowingAllLabels", false, &saved ) ) mFlags |= UseAllLabels;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/ShowingPartialsLabels", true, &saved ) ) mFlags |= UsePartialCandidates;
|
||||||
|
if ( prj->readBoolEntry( "PAL", "/DrawOutlineLabels", true, &saved ) ) mFlags |= RenderOutlineLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsLabelingEngineV2::writeSettingsToProject()
|
||||||
|
{
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/SearchMethod", ( int )mSearchMethod );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPoint", mCandPoint );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/CandidatesLine", mCandLine );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPolygon", mCandPolygon );
|
||||||
|
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/ShowingCandidates", mFlags.testFlag( DrawCandidates ) );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/DrawRectOnly", mFlags.testFlag( DrawLabelRectOnly ) );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mFlags.testFlag( DrawShadowRects ) );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mFlags.testFlag( UseAllLabels ) );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mFlags.testFlag( UsePartialCandidates ) );
|
||||||
|
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", mFlags.testFlag( RenderOutlineLabels ) );
|
||||||
|
}
|
||||||
|
|
||||||
QgsAbstractLabelProvider* QgsLabelingEngineV2::providerById( const QString& id )
|
QgsAbstractLabelProvider* QgsLabelingEngineV2::providerById( const QString& id )
|
||||||
{
|
{
|
||||||
Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
|
Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
|
||||||
|
@ -164,7 +164,7 @@ class CORE_EXPORT QgsAbstractLabelProvider
|
|||||||
virtual QString id() const = 0;
|
virtual QString id() const = 0;
|
||||||
|
|
||||||
//! Return list of labels
|
//! Return list of labels
|
||||||
virtual QList<QgsLabelFeature*> labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context ) = 0;
|
virtual QList<QgsLabelFeature*> labelFeatures( const QgsRenderContext& context ) = 0;
|
||||||
|
|
||||||
//! draw this label at the position determined by the labeling engine
|
//! draw this label at the position determined by the labeling engine
|
||||||
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const = 0;
|
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const = 0;
|
||||||
@ -210,7 +210,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAbstractLabelProvider::Flags )
|
|||||||
class CORE_EXPORT QgsLabelingEngineV2
|
class CORE_EXPORT QgsLabelingEngineV2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QgsLabelingEngineV2( const QgsMapSettings& mapSettings );
|
QgsLabelingEngineV2();
|
||||||
~QgsLabelingEngineV2();
|
~QgsLabelingEngineV2();
|
||||||
|
|
||||||
enum Flag
|
enum Flag
|
||||||
@ -224,9 +224,18 @@ class CORE_EXPORT QgsLabelingEngineV2
|
|||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( Flags, Flag )
|
Q_DECLARE_FLAGS( Flags, Flag )
|
||||||
|
|
||||||
|
void setMapSettings( const QgsMapSettings& mapSettings ) { mMapSettings = mapSettings; }
|
||||||
|
const QgsMapSettings& mapSettings() const { return mMapSettings; }
|
||||||
|
|
||||||
//! Add provider of label features. Takes ownership of the provider
|
//! Add provider of label features. Takes ownership of the provider
|
||||||
void addProvider( QgsAbstractLabelProvider* provider );
|
void addProvider( QgsAbstractLabelProvider* provider );
|
||||||
|
|
||||||
|
//! Remove provider if the provider's initialization failed. Provider instance is deleted.
|
||||||
|
void removeProvider( QgsAbstractLabelProvider* provider );
|
||||||
|
|
||||||
|
//! Lookup provider by its ID
|
||||||
|
QgsAbstractLabelProvider* providerById( const QString& id );
|
||||||
|
|
||||||
//! compute the labeling with given map settings and providers
|
//! compute the labeling with given map settings and providers
|
||||||
void run( QgsRenderContext& context );
|
void run( QgsRenderContext& context );
|
||||||
|
|
||||||
@ -238,6 +247,8 @@ class CORE_EXPORT QgsLabelingEngineV2
|
|||||||
|
|
||||||
void setFlags( Flags flags ) { mFlags = flags; }
|
void setFlags( Flags flags ) { mFlags = flags; }
|
||||||
Flags flags() const { return mFlags; }
|
Flags flags() const { return mFlags; }
|
||||||
|
bool testFlag( Flag f ) const { return mFlags.testFlag( f ); }
|
||||||
|
void setFlag( Flag f, bool enabled ) { if ( enabled ) mFlags |= f; else mFlags &= ~f; }
|
||||||
|
|
||||||
void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon ) { candPoint = mCandPoint; candLine = mCandLine; candPolygon = mCandPolygon; }
|
void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon ) { candPoint = mCandPoint; candLine = mCandLine; candPolygon = mCandPolygon; }
|
||||||
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon ) { mCandPoint = candPoint; mCandLine = candLine; mCandPolygon = candPolygon; }
|
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon ) { mCandPoint = candPoint; mCandLine = candLine; mCandPolygon = candPolygon; }
|
||||||
@ -245,8 +256,8 @@ class CORE_EXPORT QgsLabelingEngineV2
|
|||||||
void setSearchMethod( QgsPalLabeling::Search s ) { mSearchMethod = s; }
|
void setSearchMethod( QgsPalLabeling::Search s ) { mSearchMethod = s; }
|
||||||
QgsPalLabeling::Search searchMethod() const { return mSearchMethod; }
|
QgsPalLabeling::Search searchMethod() const { return mSearchMethod; }
|
||||||
|
|
||||||
protected:
|
void readSettingsFromProject();
|
||||||
QgsAbstractLabelProvider* providerById( const QString& id );
|
void writeSettingsToProject();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QgsMapSettings mMapSettings;
|
QgsMapSettings mMapSettings;
|
||||||
|
@ -84,9 +84,15 @@ class CORE_EXPORT QgsLabelingEngineInterface
|
|||||||
//! called when starting rendering of a layer
|
//! called when starting rendering of a layer
|
||||||
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
||||||
//! returns PAL layer settings for a registered layer
|
//! returns PAL layer settings for a registered layer
|
||||||
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
|
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
|
||||||
|
Q_DECL_DEPRECATED virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
|
||||||
//! adds a diagram layer to the labeling engine
|
//! adds a diagram layer to the labeling engine
|
||||||
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
|
//! @note added in QGIS 2.12
|
||||||
|
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
|
||||||
|
{ Q_UNUSED( layer ); Q_UNUSED( attrNames ); Q_UNUSED( ctx ); return 0; }
|
||||||
|
//! adds a diagram layer to the labeling engine
|
||||||
|
//! @deprecated since 2.12 - use prepareDiagramLayer()
|
||||||
|
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
|
||||||
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
|
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
|
||||||
//! called for every feature
|
//! called for every feature
|
||||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
|
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
|
||||||
|
@ -85,7 +85,9 @@ void QgsMapRendererCustomPainterJob::start()
|
|||||||
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
|
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
|
||||||
{
|
{
|
||||||
#ifdef LABELING_V2
|
#ifdef LABELING_V2
|
||||||
mLabelingEngineV2 = new QgsLabelingEngineV2( mSettings );
|
mLabelingEngineV2 = new QgsLabelingEngineV2();
|
||||||
|
mLabelingEngineV2->readSettingsFromProject();
|
||||||
|
mLabelingEngineV2->setMapSettings( mSettings );
|
||||||
#else
|
#else
|
||||||
mLabelingEngine = new QgsPalLabeling;
|
mLabelingEngine = new QgsPalLabeling;
|
||||||
mLabelingEngine->loadEngineSettings();
|
mLabelingEngine->loadEngineSettings();
|
||||||
|
@ -64,7 +64,9 @@ void QgsMapRendererParallelJob::start()
|
|||||||
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
|
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
|
||||||
{
|
{
|
||||||
#ifdef LABELING_V2
|
#ifdef LABELING_V2
|
||||||
mLabelingEngineV2 = new QgsLabelingEngineV2( mSettings );
|
mLabelingEngineV2 = new QgsLabelingEngineV2();
|
||||||
|
mLabelingEngineV2->readSettingsFromProject();
|
||||||
|
mLabelingEngineV2->setMapSettings( mSettings );
|
||||||
#else
|
#else
|
||||||
mLabelingEngine = new QgsPalLabeling;
|
mLabelingEngine = new QgsPalLabeling;
|
||||||
mLabelingEngine->loadEngineSettings();
|
mLabelingEngine->loadEngineSettings();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -56,6 +56,9 @@ class QgsCoordinateTransform;
|
|||||||
class QgsLabelSearchTree;
|
class QgsLabelSearchTree;
|
||||||
class QgsMapSettings;
|
class QgsMapSettings;
|
||||||
class QgsLabelFeature;
|
class QgsLabelFeature;
|
||||||
|
class QgsLabelingEngineV2;
|
||||||
|
class QgsVectorLayerLabelProvider;
|
||||||
|
class QgsVectorLayerDiagramProvider;
|
||||||
|
|
||||||
class CORE_EXPORT QgsPalLayerSettings
|
class CORE_EXPORT QgsPalLayerSettings
|
||||||
{
|
{
|
||||||
@ -781,7 +784,8 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
QgsPalLabeling();
|
QgsPalLabeling();
|
||||||
~QgsPalLabeling();
|
~QgsPalLabeling();
|
||||||
|
|
||||||
QgsPalLayerSettings& layer( const QString& layerName ) override;
|
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
|
||||||
|
Q_DECL_DEPRECATED QgsPalLayerSettings& layer( const QString& layerName ) override;
|
||||||
|
|
||||||
void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon );
|
void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon );
|
||||||
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon );
|
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon );
|
||||||
@ -791,29 +795,30 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
void setSearchMethod( Search s );
|
void setSearchMethod( Search s );
|
||||||
Search searchMethod() const;
|
Search searchMethod() const;
|
||||||
|
|
||||||
bool isShowingCandidates() const { return mShowingCandidates; }
|
bool isShowingCandidates() const;
|
||||||
void setShowingCandidates( bool showing ) { mShowingCandidates = showing; }
|
void setShowingCandidates( bool showing );
|
||||||
const QList<QgsLabelCandidate>& candidates() { return mCandidates; }
|
//! @deprecated since 2.12
|
||||||
|
Q_DECL_DEPRECATED const QList<QgsLabelCandidate>& candidates() { return mCandidates; }
|
||||||
|
|
||||||
bool isShowingShadowRectangles() const { return mShowingShadowRects; }
|
bool isShowingShadowRectangles() const;
|
||||||
void setShowingShadowRectangles( bool showing ) { mShowingShadowRects = showing; }
|
void setShowingShadowRectangles( bool showing );
|
||||||
|
|
||||||
bool isShowingAllLabels() const { return mShowingAllLabels; }
|
bool isShowingAllLabels() const;
|
||||||
void setShowingAllLabels( bool showing ) { mShowingAllLabels = showing; }
|
void setShowingAllLabels( bool showing );
|
||||||
|
|
||||||
bool isShowingPartialsLabels() const { return mShowingPartialsLabels; }
|
bool isShowingPartialsLabels() const;
|
||||||
void setShowingPartialsLabels( bool showing ) { mShowingPartialsLabels = showing; }
|
void setShowingPartialsLabels( bool showing );
|
||||||
|
|
||||||
//! @note added in 2.4
|
//! @note added in 2.4
|
||||||
bool isDrawingOutlineLabels() const { return mDrawOutlineLabels; }
|
bool isDrawingOutlineLabels() const;
|
||||||
void setDrawingOutlineLabels( bool outline ) { mDrawOutlineLabels = outline; }
|
void setDrawingOutlineLabels( bool outline );
|
||||||
|
|
||||||
/** Returns whether the engine will only draw the outline rectangles of labels,
|
/** Returns whether the engine will only draw the outline rectangles of labels,
|
||||||
* not the label contents themselves. Used for debugging and testing purposes.
|
* not the label contents themselves. Used for debugging and testing purposes.
|
||||||
* @see setDrawLabelRectOnly
|
* @see setDrawLabelRectOnly
|
||||||
* @note added in QGIS 2.12
|
* @note added in QGIS 2.12
|
||||||
*/
|
*/
|
||||||
bool drawLabelRectOnly() const { return mDrawLabelRectOnly; }
|
bool drawLabelRectOnly() const;
|
||||||
|
|
||||||
/** Sets whether the engine should only draw the outline rectangles of labels,
|
/** Sets whether the engine should only draw the outline rectangles of labels,
|
||||||
* not the label contents themselves. Used for debugging and testing purposes.
|
* not the label contents themselves. Used for debugging and testing purposes.
|
||||||
@ -821,7 +826,7 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
* @see drawLabelRectOnly
|
* @see drawLabelRectOnly
|
||||||
* @note added in QGIS 2.12
|
* @note added in QGIS 2.12
|
||||||
*/
|
*/
|
||||||
void setDrawLabelRectOnly( bool drawRect ) { mDrawLabelRectOnly = drawRect; }
|
void setDrawLabelRectOnly( bool drawRect );
|
||||||
|
|
||||||
// implemented methods from labeling engine interface
|
// implemented methods from labeling engine interface
|
||||||
|
|
||||||
@ -845,7 +850,11 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
//! hook called when drawing layer before issuing select()
|
//! hook called when drawing layer before issuing select()
|
||||||
virtual int prepareLayer( QgsVectorLayer* layer, QStringList &attrNames, QgsRenderContext& ctx ) override;
|
virtual int prepareLayer( QgsVectorLayer* layer, QStringList &attrNames, QgsRenderContext& ctx ) override;
|
||||||
//! adds a diagram layer to the labeling engine
|
//! adds a diagram layer to the labeling engine
|
||||||
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings *s ) override;
|
//! @note added in QGIS 2.12
|
||||||
|
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) override;
|
||||||
|
//! adds a diagram layer to the labeling engine
|
||||||
|
//! @deprecated since 2.12 - use prepareDiagramLayer()
|
||||||
|
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings *s ) override;
|
||||||
|
|
||||||
/** Register a feature for labelling.
|
/** Register a feature for labelling.
|
||||||
* @param layerID string identifying layer associated with label
|
* @param layerID string identifying layer associated with label
|
||||||
@ -976,31 +985,18 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
*/
|
*/
|
||||||
static bool checkMinimumSizeMM( const QgsRenderContext &context, const QgsGeometry *geom, double minSize );
|
static bool checkMinimumSizeMM( const QgsRenderContext &context, const QgsGeometry *geom, double minSize );
|
||||||
|
|
||||||
// hashtable of layer settings, being filled during labeling (key = layer ID)
|
//! hashtable of label providers, being filled during labeling (key = layer ID)
|
||||||
QHash<QString, QgsPalLayerSettings> mActiveLayers;
|
QHash<QString, QgsVectorLayerLabelProvider*> mLabelProviders;
|
||||||
// hashtable of active diagram layers (key = layer ID)
|
//! hashtable of diagram providers (key = layer ID)
|
||||||
QHash<QString, QgsDiagramLayerSettings> mActiveDiagramLayers;
|
QHash<QString, QgsVectorLayerDiagramProvider*> mDiagramProviders;
|
||||||
QgsPalLayerSettings mInvalidLayerSettings;
|
QgsPalLayerSettings mInvalidLayerSettings;
|
||||||
|
|
||||||
const QgsMapSettings* mMapSettings;
|
//! New labeling engine to interface with PAL
|
||||||
int mCandPoint, mCandLine, mCandPolygon;
|
QgsLabelingEngineV2* mEngine;
|
||||||
Search mSearch;
|
|
||||||
|
|
||||||
pal::Pal* mPal;
|
|
||||||
|
|
||||||
// list of candidates from last labeling
|
// list of candidates from last labeling
|
||||||
QList<QgsLabelCandidate> mCandidates;
|
QList<QgsLabelCandidate> mCandidates;
|
||||||
|
|
||||||
//! Whether to only draw the label rect and not the actual label text (used for unit tests)
|
|
||||||
bool mDrawLabelRectOnly;
|
|
||||||
bool mShowingCandidates;
|
|
||||||
bool mShowingAllLabels; // whether to avoid collisions or not
|
|
||||||
bool mShowingShadowRects; // whether to show debugging rectangles for drop shadows
|
|
||||||
bool mShowingPartialsLabels; // whether to avoid partials labels or not
|
|
||||||
bool mDrawOutlineLabels; // whether to draw labels as text or outlines
|
|
||||||
|
|
||||||
QgsLabelingResults* mResults;
|
|
||||||
|
|
||||||
friend class QgsPalLayerSettings;
|
friend class QgsPalLayerSettings;
|
||||||
};
|
};
|
||||||
Q_NOWARN_DEPRECATED_POP
|
Q_NOWARN_DEPRECATED_POP
|
||||||
|
@ -45,14 +45,14 @@ QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( QgsVectorLayer* layer )
|
QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( QgsVectorLayer* layer, bool ownFeatureLoop )
|
||||||
: mSettings( *layer->diagramLayerSettings() )
|
: mSettings( *layer->diagramLayerSettings() )
|
||||||
, mDiagRenderer( layer->diagramRenderer()->clone() )
|
, mDiagRenderer( layer->diagramRenderer()->clone() )
|
||||||
, mLayerId( layer->id() )
|
, mLayerId( layer->id() )
|
||||||
, mFields( layer->fields() )
|
, mFields( layer->fields() )
|
||||||
, mLayerCrs( layer->crs() )
|
, mLayerCrs( layer->crs() )
|
||||||
, mSource( new QgsVectorLayerFeatureSource( layer ) )
|
, mSource( ownFeatureLoop ? new QgsVectorLayerFeatureSource( layer ) : 0 )
|
||||||
, mOwnsSource( true )
|
, mOwnsSource( ownFeatureLoop )
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -81,67 +81,18 @@ QString QgsVectorLayerDiagramProvider::id() const
|
|||||||
return mLayerId + "d";
|
return mLayerId + "d";
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context )
|
QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsRenderContext& context )
|
||||||
{
|
{
|
||||||
|
if ( !mSource )
|
||||||
QgsDiagramLayerSettings& s2 = mSettings;
|
{
|
||||||
|
// we have created the provider with "own feature loop" == false
|
||||||
s2.ct = 0;
|
// so it is assumed that prepare() has been already called followed by registerFeature() calls
|
||||||
if ( mapSettings.hasCrsTransformEnabled() )
|
return mFeatures;
|
||||||
s2.ct = new QgsCoordinateTransform( mLayerCrs, mapSettings.destinationCrs() );
|
}
|
||||||
|
|
||||||
s2.xform = &mapSettings.mapToPixel();
|
|
||||||
|
|
||||||
s2.fields = mFields;
|
|
||||||
|
|
||||||
s2.renderer = mDiagRenderer;
|
|
||||||
|
|
||||||
const QgsDiagramRendererV2* diagRenderer = s2.renderer;
|
|
||||||
|
|
||||||
QStringList attributeNames;
|
QStringList attributeNames;
|
||||||
|
if ( !prepare( context, attributeNames ) )
|
||||||
//add attributes needed by the diagram renderer
|
return QList<QgsLabelFeature*>();
|
||||||
QList<QString> att = diagRenderer->diagramAttributes();
|
|
||||||
QList<QString>::const_iterator attIt = att.constBegin();
|
|
||||||
for ( ; attIt != att.constEnd(); ++attIt )
|
|
||||||
{
|
|
||||||
QgsExpression* expression = diagRenderer->diagram()->getExpression( *attIt, context.expressionContext() );
|
|
||||||
QStringList columns = expression->referencedColumns();
|
|
||||||
QStringList::const_iterator columnsIterator = columns.constBegin();
|
|
||||||
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
|
||||||
{
|
|
||||||
if ( !attributeNames.contains( *columnsIterator ) )
|
|
||||||
attributeNames << *columnsIterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QgsLinearlyInterpolatedDiagramRenderer* linearlyInterpolatedDiagramRenderer = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( diagRenderer );
|
|
||||||
if ( linearlyInterpolatedDiagramRenderer != NULL )
|
|
||||||
{
|
|
||||||
if ( linearlyInterpolatedDiagramRenderer->classificationAttributeIsExpression() )
|
|
||||||
{
|
|
||||||
QgsExpression* expression = diagRenderer->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), context.expressionContext() );
|
|
||||||
QStringList columns = expression->referencedColumns();
|
|
||||||
QStringList::const_iterator columnsIterator = columns.constBegin();
|
|
||||||
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
|
||||||
{
|
|
||||||
if ( !attributeNames.contains( *columnsIterator ) )
|
|
||||||
attributeNames << *columnsIterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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 << mFields.at( mSettings.xPosColumn ).name();
|
|
||||||
if ( mSettings.yPosColumn != -1 )
|
|
||||||
attributeNames << mFields.at( mSettings.yPosColumn ).name();
|
|
||||||
|
|
||||||
QgsRectangle layerExtent = context.extent();
|
QgsRectangle layerExtent = context.extent();
|
||||||
if ( mSettings.ct )
|
if ( mSettings.ct )
|
||||||
@ -152,19 +103,17 @@ QList<QgsLabelFeature*> QgsVectorLayerDiagramProvider::labelFeatures( const QgsM
|
|||||||
request.setSubsetOfAttributes( attributeNames, mFields );
|
request.setSubsetOfAttributes( attributeNames, mFields );
|
||||||
QgsFeatureIterator fit = mSource->getFeatures( request );
|
QgsFeatureIterator fit = mSource->getFeatures( request );
|
||||||
|
|
||||||
QList<QgsLabelFeature*> features;
|
|
||||||
|
|
||||||
QgsFeature fet;
|
QgsFeature fet;
|
||||||
while ( fit.nextFeature( fet ) )
|
while ( fit.nextFeature( fet ) )
|
||||||
{
|
{
|
||||||
QgsLabelFeature* label = registerDiagram( fet, mapSettings, context );
|
registerFeature( fet, context );
|
||||||
if ( label )
|
|
||||||
features << label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return features;
|
return mFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
|
void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
|
||||||
{
|
{
|
||||||
#if 1 // XXX strk
|
#if 1 // XXX strk
|
||||||
@ -210,8 +159,88 @@ void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::L
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& feat, const QgsMapSettings& mapSettings, const QgsRenderContext& context )
|
bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
|
||||||
{
|
{
|
||||||
|
QgsDiagramLayerSettings& s2 = mSettings;
|
||||||
|
const QgsMapSettings& mapSettings = mEngine->mapSettings();
|
||||||
|
|
||||||
|
s2.ct = 0;
|
||||||
|
if ( mapSettings.hasCrsTransformEnabled() )
|
||||||
|
{
|
||||||
|
if ( context.coordinateTransform() )
|
||||||
|
// this is context for layer rendering - use its CT as it includes correct datum transform
|
||||||
|
s2.ct = context.coordinateTransform()->clone();
|
||||||
|
else
|
||||||
|
// otherwise fall back to creating our own CT - this one may not have the correct datum transform!
|
||||||
|
s2.ct = new QgsCoordinateTransform( mLayerCrs, mapSettings.destinationCrs() );
|
||||||
|
}
|
||||||
|
|
||||||
|
s2.xform = &mapSettings.mapToPixel();
|
||||||
|
|
||||||
|
s2.fields = mFields;
|
||||||
|
|
||||||
|
s2.renderer = mDiagRenderer;
|
||||||
|
|
||||||
|
const QgsDiagramRendererV2* diagRenderer = s2.renderer;
|
||||||
|
|
||||||
|
//add attributes needed by the diagram renderer
|
||||||
|
QList<QString> att = diagRenderer->diagramAttributes();
|
||||||
|
QList<QString>::const_iterator attIt = att.constBegin();
|
||||||
|
for ( ; attIt != att.constEnd(); ++attIt )
|
||||||
|
{
|
||||||
|
QgsExpression* expression = diagRenderer->diagram()->getExpression( *attIt, context.expressionContext() );
|
||||||
|
QStringList columns = expression->referencedColumns();
|
||||||
|
QStringList::const_iterator columnsIterator = columns.constBegin();
|
||||||
|
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
||||||
|
{
|
||||||
|
if ( !attributeNames.contains( *columnsIterator ) )
|
||||||
|
attributeNames << *columnsIterator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QgsLinearlyInterpolatedDiagramRenderer* linearlyInterpolatedDiagramRenderer = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( diagRenderer );
|
||||||
|
if ( linearlyInterpolatedDiagramRenderer != NULL )
|
||||||
|
{
|
||||||
|
if ( linearlyInterpolatedDiagramRenderer->classificationAttributeIsExpression() )
|
||||||
|
{
|
||||||
|
QgsExpression* expression = diagRenderer->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), context.expressionContext() );
|
||||||
|
QStringList columns = expression->referencedColumns();
|
||||||
|
QStringList::const_iterator columnsIterator = columns.constBegin();
|
||||||
|
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
||||||
|
{
|
||||||
|
if ( !attributeNames.contains( *columnsIterator ) )
|
||||||
|
attributeNames << *columnsIterator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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 << mFields.at( mSettings.xPosColumn ).name();
|
||||||
|
if ( mSettings.yPosColumn != -1 )
|
||||||
|
attributeNames << mFields.at( mSettings.yPosColumn ).name();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QgsVectorLayerDiagramProvider::registerFeature( QgsFeature& feature, const QgsRenderContext& context )
|
||||||
|
{
|
||||||
|
QgsLabelFeature* label = registerDiagram( feature, context );
|
||||||
|
if ( label )
|
||||||
|
mFeatures << label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QgsLabelFeature* QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature& feat, const QgsRenderContext& context )
|
||||||
|
{
|
||||||
|
const QgsMapSettings& mapSettings = mEngine->mapSettings();
|
||||||
|
|
||||||
QgsDiagramRendererV2* dr = mSettings.renderer;
|
QgsDiagramRendererV2* dr = mSettings.renderer;
|
||||||
if ( dr )
|
if ( dr )
|
||||||
|
@ -33,7 +33,7 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//! Convenience constructor to initialize the provider from given vector layer
|
//! Convenience constructor to initialize the provider from given vector layer
|
||||||
explicit QgsVectorLayerDiagramProvider( QgsVectorLayer* layer );
|
explicit QgsVectorLayerDiagramProvider( QgsVectorLayer* layer, bool ownFeatureLoop = true );
|
||||||
|
|
||||||
QgsVectorLayerDiagramProvider( const QgsDiagramLayerSettings* diagSettings,
|
QgsVectorLayerDiagramProvider( const QgsDiagramLayerSettings* diagSettings,
|
||||||
const QgsDiagramRendererV2* diagRenderer,
|
const QgsDiagramRendererV2* diagRenderer,
|
||||||
@ -47,13 +47,19 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
|
|||||||
|
|
||||||
virtual QString id() const override;
|
virtual QString id() const override;
|
||||||
|
|
||||||
virtual QList<QgsLabelFeature*> labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context ) override;
|
virtual QList<QgsLabelFeature*> labelFeatures( const QgsRenderContext& context ) override;
|
||||||
|
|
||||||
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
||||||
|
|
||||||
|
// new virtual methods
|
||||||
|
|
||||||
|
virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames );
|
||||||
|
|
||||||
|
virtual void registerFeature( QgsFeature& feature, const QgsRenderContext& context );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
QgsLabelFeature* registerDiagram( QgsFeature& feat, const QgsMapSettings& mapSettings, const QgsRenderContext& context );
|
QgsLabelFeature* registerDiagram( QgsFeature& feat, const QgsRenderContext& context );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -66,6 +72,7 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
|
|||||||
QgsAbstractFeatureSource* mSource;
|
QgsAbstractFeatureSource* mSource;
|
||||||
bool mOwnsSource;
|
bool mOwnsSource;
|
||||||
|
|
||||||
|
QList<QgsLabelFeature*> mFeatures;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSVECTORLAYERDIAGRAMPROVIDER_H
|
#endif // QGSVECTORLAYERDIAGRAMPROVIDER_H
|
||||||
|
@ -45,7 +45,7 @@ static void _fixQPictureDPI( QPainter* p )
|
|||||||
|
|
||||||
typedef QgsPalLayerSettings QgsVectorLayerLabelSettings;
|
typedef QgsPalLayerSettings QgsVectorLayerLabelSettings;
|
||||||
|
|
||||||
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer )
|
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer, bool withFeatureLoop )
|
||||||
{
|
{
|
||||||
if ( layer->customProperty( "labeling" ).toString() != QString( "pal" ) || !layer->labelsEnabled() )
|
if ( layer->customProperty( "labeling" ).toString() != QString( "pal" ) || !layer->labelsEnabled() )
|
||||||
return;
|
return;
|
||||||
@ -54,7 +54,16 @@ QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer
|
|||||||
mLayerId = layer->id();
|
mLayerId = layer->id();
|
||||||
mFields = layer->fields();
|
mFields = layer->fields();
|
||||||
mCrs = layer->crs();
|
mCrs = layer->crs();
|
||||||
|
if ( withFeatureLoop )
|
||||||
|
{
|
||||||
mSource = new QgsVectorLayerFeatureSource( layer );
|
mSource = new QgsVectorLayerFeatureSource( layer );
|
||||||
|
mOwnsSource = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSource = 0;
|
||||||
|
mOwnsSource = false;
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -97,7 +106,19 @@ void QgsVectorLayerLabelProvider::init()
|
|||||||
|
|
||||||
QgsVectorLayerLabelProvider::~QgsVectorLayerLabelProvider()
|
QgsVectorLayerLabelProvider::~QgsVectorLayerLabelProvider()
|
||||||
{
|
{
|
||||||
|
// delete all QgsDataDefined objects (which also deletes their QgsExpression object)
|
||||||
|
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = mSettings.dataDefinedProperties.begin();
|
||||||
|
for ( ; it != mSettings.dataDefinedProperties.constEnd(); ++it )
|
||||||
|
{
|
||||||
|
delete( it.value() );
|
||||||
|
it.value() = 0;
|
||||||
|
}
|
||||||
|
mSettings.dataDefinedProperties.clear();
|
||||||
|
|
||||||
qDeleteAll( mSettings.geometries );
|
qDeleteAll( mSettings.geometries );
|
||||||
|
|
||||||
|
if ( mOwnsSource )
|
||||||
|
delete mSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsVectorLayerLabelProvider::id() const
|
QString QgsVectorLayerLabelProvider::id() const
|
||||||
@ -105,10 +126,10 @@ QString QgsVectorLayerLabelProvider::id() const
|
|||||||
return mLayerId;
|
return mLayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
|
||||||
QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& ctx )
|
|
||||||
{
|
{
|
||||||
QgsVectorLayerLabelSettings& lyr = mSettings;
|
QgsVectorLayerLabelSettings& lyr = mSettings;
|
||||||
|
const QgsMapSettings& mapSettings = mEngine->mapSettings();
|
||||||
|
|
||||||
QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
|
QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
|
||||||
|
|
||||||
@ -116,7 +137,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
{
|
{
|
||||||
if ( lyr.fieldName.isEmpty() )
|
if ( lyr.fieldName.isEmpty() )
|
||||||
{
|
{
|
||||||
return QList<QgsLabelFeature*>();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lyr.isExpression )
|
if ( lyr.isExpression )
|
||||||
@ -125,7 +146,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
if ( exp.hasEvalError() )
|
if ( exp.hasEvalError() )
|
||||||
{
|
{
|
||||||
QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
|
QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
|
||||||
return QList<QgsLabelFeature*>();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -133,13 +154,11 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
// If we aren't an expression, we check to see if we can find the column.
|
// If we aren't an expression, we check to see if we can find the column.
|
||||||
if ( mFields.fieldNameIndex( lyr.fieldName ) == -1 )
|
if ( mFields.fieldNameIndex( lyr.fieldName ) == -1 )
|
||||||
{
|
{
|
||||||
return QList<QgsLabelFeature*>();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList attrNames;
|
|
||||||
|
|
||||||
lyr.mCurFields = mFields;
|
lyr.mCurFields = mFields;
|
||||||
|
|
||||||
if ( lyr.drawLabels )
|
if ( lyr.drawLabels )
|
||||||
@ -149,7 +168,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
{
|
{
|
||||||
// prepare expression for use in QgsPalLayerSettings::registerFeature()
|
// prepare expression for use in QgsPalLayerSettings::registerFeature()
|
||||||
QgsExpression* exp = lyr.getLabelExpression();
|
QgsExpression* exp = lyr.getLabelExpression();
|
||||||
exp->prepare( &ctx.expressionContext() );
|
exp->prepare( &context.expressionContext() );
|
||||||
if ( exp->hasEvalError() )
|
if ( exp->hasEvalError() )
|
||||||
{
|
{
|
||||||
QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
|
QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
|
||||||
@ -157,12 +176,12 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
Q_FOREACH ( const QString& name, exp->referencedColumns() )
|
Q_FOREACH ( const QString& name, exp->referencedColumns() )
|
||||||
{
|
{
|
||||||
QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
|
QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
|
||||||
attrNames.append( name );
|
attributeNames.append( name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
attrNames.append( lyr.fieldName );
|
attributeNames.append( lyr.fieldName );
|
||||||
}
|
}
|
||||||
|
|
||||||
// add field indices of data defined expression or field
|
// add field indices of data defined expression or field
|
||||||
@ -179,26 +198,29 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
|
|
||||||
// store parameters for data defined expressions
|
// store parameters for data defined expressions
|
||||||
QMap<QString, QVariant> exprParams;
|
QMap<QString, QVariant> exprParams;
|
||||||
exprParams.insert( "scale", ctx.rendererScale() );
|
exprParams.insert( "scale", context.rendererScale() );
|
||||||
|
|
||||||
dd->setExpressionParams( exprParams );
|
dd->setExpressionParams( exprParams );
|
||||||
|
|
||||||
// this will return columns for expressions or field name, depending upon what is set to be used
|
// this will return columns for expressions or field name, depending upon what is set to be used
|
||||||
QStringList cols = dd->referencedColumns( ctx.expressionContext() ); // <-- prepares any expressions, too
|
QStringList cols = dd->referencedColumns( context.expressionContext() ); // <-- prepares any expressions, too
|
||||||
|
|
||||||
//QgsDebugMsgLevel( QString( "Data defined referenced columns:" ) + cols.join( "," ), 4 );
|
//QgsDebugMsgLevel( QString( "Data defined referenced columns:" ) + cols.join( "," ), 4 );
|
||||||
Q_FOREACH ( const QString& name, cols )
|
Q_FOREACH ( const QString& name, cols )
|
||||||
{
|
{
|
||||||
attrNames.append( name );
|
attributeNames.append( name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOW INITIALIZE QgsPalLayerSettings
|
// NOW INITIALIZE QgsPalLayerSettings
|
||||||
|
|
||||||
|
// TODO: ideally these (non-configuration) members should get out of QgsPalLayerSettings to here
|
||||||
|
// (together with registerFeature() & related methods) and QgsPalLayerSettings just stores config
|
||||||
|
|
||||||
//raster and vector scale factors
|
//raster and vector scale factors
|
||||||
lyr.vectorScaleFactor = ctx.scaleFactor();
|
lyr.vectorScaleFactor = context.scaleFactor();
|
||||||
lyr.rasterCompressFactor = ctx.rasterScaleFactor();
|
lyr.rasterCompressFactor = context.rasterScaleFactor();
|
||||||
|
|
||||||
// save the pal layer to our layer context (with some additional info)
|
// save the pal layer to our layer context (with some additional info)
|
||||||
lyr.fieldIndex = mFields.fieldNameIndex( lyr.fieldName );
|
lyr.fieldIndex = mFields.fieldNameIndex( lyr.fieldName );
|
||||||
@ -206,7 +228,14 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
lyr.xform = &mapSettings.mapToPixel();
|
lyr.xform = &mapSettings.mapToPixel();
|
||||||
lyr.ct = 0;
|
lyr.ct = 0;
|
||||||
if ( mapSettings.hasCrsTransformEnabled() )
|
if ( mapSettings.hasCrsTransformEnabled() )
|
||||||
|
{
|
||||||
|
if ( context.coordinateTransform() )
|
||||||
|
// this is context for layer rendering - use its CT as it includes correct datum transform
|
||||||
|
lyr.ct = context.coordinateTransform()->clone();
|
||||||
|
else
|
||||||
|
// otherwise fall back to creating our own CT - this one may not have the correct datum transform!
|
||||||
lyr.ct = new QgsCoordinateTransform( mCrs, mapSettings.destinationCrs() );
|
lyr.ct = new QgsCoordinateTransform( mCrs, mapSettings.destinationCrs() );
|
||||||
|
}
|
||||||
lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
|
lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
|
||||||
lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
|
lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
|
||||||
|
|
||||||
@ -220,30 +249,53 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsMap
|
|||||||
|
|
||||||
lyr.mFeatsSendingToPal = 0;
|
lyr.mFeatsSendingToPal = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( const QgsRenderContext& ctx )
|
||||||
|
{
|
||||||
|
if ( !mSource )
|
||||||
|
{
|
||||||
|
// we have created the provider with "own feature loop" == false
|
||||||
|
// so it is assumed that prepare() has been already called followed by registerFeature() calls
|
||||||
|
return mLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList attrNames;
|
||||||
|
if ( !prepare( ctx, attrNames ) )
|
||||||
|
return QList<QgsLabelFeature*>();
|
||||||
|
|
||||||
QgsRectangle layerExtent = ctx.extent();
|
QgsRectangle layerExtent = ctx.extent();
|
||||||
if ( lyr.ct )
|
if ( mSettings.ct )
|
||||||
layerExtent = lyr.ct->transformBoundingBox( ctx.extent(), QgsCoordinateTransform::ReverseTransform );
|
layerExtent = mSettings.ct->transformBoundingBox( ctx.extent(), QgsCoordinateTransform::ReverseTransform );
|
||||||
|
|
||||||
QgsFeatureRequest request;
|
QgsFeatureRequest request;
|
||||||
request.setFilterRect( layerExtent );
|
request.setFilterRect( layerExtent );
|
||||||
request.setSubsetOfAttributes( attrNames, mFields );
|
request.setSubsetOfAttributes( attrNames, mFields );
|
||||||
QgsFeatureIterator fit = mSource->getFeatures( request );
|
QgsFeatureIterator fit = mSource->getFeatures( request );
|
||||||
|
|
||||||
QList<QgsLabelFeature*> labels;
|
|
||||||
|
|
||||||
QgsFeature fet;
|
QgsFeature fet;
|
||||||
while ( fit.nextFeature( fet ) )
|
while ( fit.nextFeature( fet ) )
|
||||||
{
|
{
|
||||||
QgsLabelFeature* label = 0;
|
registerFeature( fet, ctx );
|
||||||
lyr.registerFeature( fet, ctx, QString(), &label );
|
|
||||||
if ( label )
|
|
||||||
labels << label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return labels;
|
return mLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, const QgsRenderContext& context )
|
||||||
|
{
|
||||||
|
QgsLabelFeature* label = 0;
|
||||||
|
mSettings.registerFeature( feature, context, QString(), &label );
|
||||||
|
if ( label )
|
||||||
|
mLabels << label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
|
void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
|
||||||
{
|
{
|
||||||
if ( !mSettings.drawLabels )
|
if ( !mSettings.drawLabels )
|
||||||
@ -303,7 +355,7 @@ void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::Lab
|
|||||||
// update tmpLyr with any data defined drop shadow values
|
// update tmpLyr with any data defined drop shadow values
|
||||||
QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
|
QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
|
||||||
|
|
||||||
tmpLyr.showingShadowRects = mEngine->flags().testFlag( QgsLabelingEngineV2::DrawShadowRects );
|
tmpLyr.showingShadowRects = mEngine->testFlag( QgsLabelingEngineV2::DrawShadowRects );
|
||||||
|
|
||||||
// Render the components of a label in reverse order
|
// Render the components of a label in reverse order
|
||||||
// (backgrounds -> text)
|
// (backgrounds -> text)
|
||||||
@ -367,7 +419,7 @@ void QgsVectorLayerLabelProvider::drawLabelPrivate( pal::LabelPosition* label, Q
|
|||||||
component.setOrigin( outPt );
|
component.setOrigin( outPt );
|
||||||
component.setRotation( label->getAlpha() );
|
component.setRotation( label->getAlpha() );
|
||||||
|
|
||||||
if ( mEngine->flags().testFlag( QgsLabelingEngineV2::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
|
if ( mEngine->testFlag( QgsLabelingEngineV2::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
|
||||||
{
|
{
|
||||||
//debugging rect
|
//debugging rect
|
||||||
if ( drawType != QgsPalLabeling::LabelText )
|
if ( drawType != QgsPalLabeling::LabelText )
|
||||||
@ -602,7 +654,7 @@ void QgsVectorLayerLabelProvider::drawLabelPrivate( pal::LabelPosition* label, Q
|
|||||||
// scale for any print output or image saving @ specific dpi
|
// scale for any print output or image saving @ specific dpi
|
||||||
painter->scale( component.dpiRatio(), component.dpiRatio() );
|
painter->scale( component.dpiRatio(), component.dpiRatio() );
|
||||||
|
|
||||||
if ( mEngine->flags().testFlag( QgsLabelingEngineV2::RenderOutlineLabels ) )
|
if ( mEngine->testFlag( QgsLabelingEngineV2::RenderOutlineLabels ) )
|
||||||
{
|
{
|
||||||
// draw outlined text
|
// draw outlined text
|
||||||
_fixQPictureDPI( painter );
|
_fixQPictureDPI( painter );
|
||||||
|
@ -32,7 +32,7 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//! Convenience constructor to initialize the provider from given vector layer
|
//! Convenience constructor to initialize the provider from given vector layer
|
||||||
explicit QgsVectorLayerLabelProvider( QgsVectorLayer* layer );
|
explicit QgsVectorLayerLabelProvider( QgsVectorLayer* layer, bool withFeatureLoop = true );
|
||||||
|
|
||||||
QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
|
QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,
|
||||||
const QString& layerId,
|
const QString& layerId,
|
||||||
@ -45,10 +45,28 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
|
|||||||
|
|
||||||
virtual QString id() const override;
|
virtual QString id() const override;
|
||||||
|
|
||||||
virtual QList<QgsLabelFeature*> labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context ) override;
|
virtual QList<QgsLabelFeature*> labelFeatures( const QgsRenderContext& context ) override;
|
||||||
|
|
||||||
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
||||||
|
|
||||||
|
// new virtual methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare for registration of features. Must be called after provider has been added to engine (uses its map settings)
|
||||||
|
* @param context render context.
|
||||||
|
* @param attributeNames list of attribute names to which additional required attributes shall be added
|
||||||
|
* @return List of attributes necessary for labeling
|
||||||
|
*/
|
||||||
|
virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
virtual void registerFeature( QgsFeature& feature, const QgsRenderContext& context );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
@ -57,10 +75,13 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
|
|||||||
protected:
|
protected:
|
||||||
QgsPalLayerSettings mSettings;
|
QgsPalLayerSettings mSettings;
|
||||||
QString mLayerId;
|
QString mLayerId;
|
||||||
|
// these are needed only if using own renderer loop
|
||||||
QgsFields mFields;
|
QgsFields mFields;
|
||||||
QgsCoordinateReferenceSystem mCrs;
|
QgsCoordinateReferenceSystem mCrs;
|
||||||
QgsAbstractFeatureSource* mSource;
|
QgsAbstractFeatureSource* mSource;
|
||||||
bool mOwnsSource;
|
bool mOwnsSource;
|
||||||
|
|
||||||
|
QList<QgsLabelFeature*> mLabels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender
|
|||||||
, mCache( 0 )
|
, mCache( 0 )
|
||||||
, mLabeling( false )
|
, mLabeling( false )
|
||||||
, mDiagrams( false )
|
, mDiagrams( false )
|
||||||
|
, mLabelProvider( 0 )
|
||||||
|
, mDiagramProvider( 0 )
|
||||||
, mLayerTransparency( 0 )
|
, mLayerTransparency( 0 )
|
||||||
{
|
{
|
||||||
mSource = new QgsVectorLayerFeatureSource( layer );
|
mSource = new QgsVectorLayerFeatureSource( layer );
|
||||||
@ -312,6 +314,18 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
|
|||||||
mContext.labelingEngine()->registerDiagramFeature( mLayerID, fet, mContext );
|
mContext.labelingEngine()->registerDiagramFeature( mLayerID, fet, mContext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// new labeling engine
|
||||||
|
if ( rendered && mContext.labelingEngineV2() )
|
||||||
|
{
|
||||||
|
if ( mLabelProvider )
|
||||||
|
{
|
||||||
|
mLabelProvider->registerFeature( fet, mContext );
|
||||||
|
}
|
||||||
|
if ( mDiagramProvider )
|
||||||
|
{
|
||||||
|
mDiagramProvider->registerFeature( fet, mContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch ( const QgsCsException &cse )
|
catch ( const QgsCsException &cse )
|
||||||
{
|
{
|
||||||
@ -469,9 +483,15 @@ void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QStringList
|
|||||||
if ( QgsLabelingEngineV2* engine2 = mContext.labelingEngineV2() )
|
if ( QgsLabelingEngineV2* engine2 = mContext.labelingEngineV2() )
|
||||||
{
|
{
|
||||||
if ( layer->labelsEnabled() )
|
if ( layer->labelsEnabled() )
|
||||||
engine2->addProvider( new QgsVectorLayerLabelProvider( layer ) );
|
{
|
||||||
if ( layer->diagramsEnabled() )
|
mLabelProvider = new QgsVectorLayerLabelProvider( layer, false );
|
||||||
engine2->addProvider( new QgsVectorLayerDiagramProvider( layer ) );
|
engine2->addProvider( mLabelProvider );
|
||||||
|
if ( !mLabelProvider->prepare( mContext, attributeNames ) )
|
||||||
|
{
|
||||||
|
engine2->removeProvider( mLabelProvider );
|
||||||
|
mLabelProvider = 0; // deleted by engine
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -480,10 +500,9 @@ void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QStringList
|
|||||||
{
|
{
|
||||||
mLabeling = true;
|
mLabeling = true;
|
||||||
|
|
||||||
QgsPalLayerSettings& palyr = mContext.labelingEngine()->layer( mLayerID );
|
|
||||||
Q_UNUSED( palyr );
|
|
||||||
|
|
||||||
#if 0 // TODO: limit of labels, font not found
|
#if 0 // TODO: limit of labels, font not found
|
||||||
|
QgsPalLayerSettings& palyr = mContext.labelingEngine()->layer( mLayerID );
|
||||||
|
|
||||||
// see if feature count limit is set for labeling
|
// see if feature count limit is set for labeling
|
||||||
if ( palyr.limitNumLabels && palyr.maxNumLabels > 0 )
|
if ( palyr.limitNumLabels && palyr.maxNumLabels > 0 )
|
||||||
{
|
{
|
||||||
@ -514,58 +533,29 @@ void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QStringList
|
|||||||
void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList& attributeNames )
|
void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList& attributeNames )
|
||||||
{
|
{
|
||||||
if ( !mContext.labelingEngine() )
|
if ( !mContext.labelingEngine() )
|
||||||
|
{
|
||||||
|
if ( QgsLabelingEngineV2* engine2 = mContext.labelingEngineV2() )
|
||||||
|
{
|
||||||
|
if ( layer->diagramsEnabled() )
|
||||||
|
{
|
||||||
|
mDiagramProvider = new QgsVectorLayerDiagramProvider( layer );
|
||||||
|
// need to be added before calling prepare() - uses map settings from engine
|
||||||
|
engine2->addProvider( mDiagramProvider );
|
||||||
|
if ( !mDiagramProvider->prepare( mContext, attributeNames ) )
|
||||||
|
{
|
||||||
|
engine2->removeProvider( mDiagramProvider );
|
||||||
|
mDiagramProvider = 0; // deleted by engine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !layer->diagramsEnabled() )
|
if ( !layer->diagramsEnabled() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDiagrams = true;
|
mDiagrams = true;
|
||||||
|
|
||||||
const QgsDiagramRendererV2* diagRenderer = layer->diagramRenderer();
|
mContext.labelingEngine()->prepareDiagramLayer( layer, attributeNames, mContext ); // will make internal copy of diagSettings + initialize it
|
||||||
const QgsDiagramLayerSettings* diagSettings = layer->diagramLayerSettings();
|
|
||||||
|
|
||||||
mContext.labelingEngine()->addDiagramLayer( layer, diagSettings ); // will make internal copy of diagSettings + initialize it
|
|
||||||
|
|
||||||
//add attributes needed by the diagram renderer
|
|
||||||
QList<QString> att = diagRenderer->diagramAttributes();
|
|
||||||
QList<QString>::const_iterator attIt = att.constBegin();
|
|
||||||
for ( ; attIt != att.constEnd(); ++attIt )
|
|
||||||
{
|
|
||||||
QgsExpression* expression = diagRenderer->diagram()->getExpression( *attIt, mContext.expressionContext() );
|
|
||||||
QStringList columns = expression->referencedColumns();
|
|
||||||
QStringList::const_iterator columnsIterator = columns.constBegin();
|
|
||||||
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
|
||||||
{
|
|
||||||
if ( !attributeNames.contains( *columnsIterator ) )
|
|
||||||
attributeNames << *columnsIterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QgsLinearlyInterpolatedDiagramRenderer* linearlyInterpolatedDiagramRenderer = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( layer->diagramRenderer() );
|
|
||||||
if ( linearlyInterpolatedDiagramRenderer != NULL )
|
|
||||||
{
|
|
||||||
if ( linearlyInterpolatedDiagramRenderer->classificationAttributeIsExpression() )
|
|
||||||
{
|
|
||||||
QgsExpression* expression = diagRenderer->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), mContext.expressionContext() );
|
|
||||||
QStringList columns = expression->referencedColumns();
|
|
||||||
QStringList::const_iterator columnsIterator = columns.constBegin();
|
|
||||||
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
|
|
||||||
{
|
|
||||||
if ( !attributeNames.contains( *columnsIterator ) )
|
|
||||||
attributeNames << *columnsIterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QString name = mFields.at( linearlyInterpolatedDiagramRenderer->classificationAttribute() ).name();
|
|
||||||
if ( !attributeNames.contains( name ) )
|
|
||||||
attributeNames << name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//and the ones needed for data defined diagram positions
|
|
||||||
if ( diagSettings->xPosColumn != -1 )
|
|
||||||
attributeNames << mFields.at( diagSettings->xPosColumn ).name();
|
|
||||||
if ( diagSettings->yPosColumn != -1 )
|
|
||||||
attributeNames << mFields.at( diagSettings->yPosColumn ).name();
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ typedef QList<int> QgsAttributeList;
|
|||||||
|
|
||||||
#include "qgsmaplayerrenderer.h"
|
#include "qgsmaplayerrenderer.h"
|
||||||
|
|
||||||
|
class QgsVectorLayerLabelProvider;
|
||||||
|
class QgsVectorLayerDiagramProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of threaded rendering for vector layers.
|
* Implementation of threaded rendering for vector layers.
|
||||||
@ -102,9 +104,18 @@ class QgsVectorLayerRenderer : public QgsMapLayerRenderer
|
|||||||
|
|
||||||
QStringList mAttrNames;
|
QStringList mAttrNames;
|
||||||
|
|
||||||
|
//! used with old labeling engine (QgsPalLabeling): whether labeling is enabled
|
||||||
bool mLabeling;
|
bool mLabeling;
|
||||||
|
//! used with new labeling engine (QgsPalLabeling): whether diagrams are enabled
|
||||||
bool mDiagrams;
|
bool mDiagrams;
|
||||||
|
|
||||||
|
//! used with new labeling engine (QgsLabelingEngineV2): provider for labels.
|
||||||
|
//! may be null. no need to delete: if exists it is owned by labeling engine
|
||||||
|
QgsVectorLayerLabelProvider* mLabelProvider;
|
||||||
|
//! used with new labeling engine (QgsLabelingEngineV2): provider for diagrams.
|
||||||
|
//! may be null. no need to delete: if exists it is owned by labeling engine
|
||||||
|
QgsVectorLayerDiagramProvider* mDiagramProvider;
|
||||||
|
|
||||||
int mLayerTransparency;
|
int mLayerTransparency;
|
||||||
QPainter::CompositionMode mFeatureBlendMode;
|
QPainter::CompositionMode mFeatureBlendMode;
|
||||||
|
|
||||||
|
@ -77,7 +77,8 @@ void TestQgsLabelingEngineV2::testBasic()
|
|||||||
vl->setCustomProperty( "labeling/enabled", true );
|
vl->setCustomProperty( "labeling/enabled", true );
|
||||||
vl->setCustomProperty( "labeling/fieldName", "Class" );
|
vl->setCustomProperty( "labeling/fieldName", "Class" );
|
||||||
|
|
||||||
QgsLabelingEngineV2 engine( mapSettings );
|
QgsLabelingEngineV2 engine;
|
||||||
|
engine.setMapSettings( mapSettings );
|
||||||
engine.addProvider( new QgsVectorLayerLabelProvider( vl ) );
|
engine.addProvider( new QgsVectorLayerLabelProvider( vl ) );
|
||||||
//engine.setFlags( QgsLabelingEngineV2::RenderOutlineLabels | QgsLabelingEngineV2::DrawLabelRectOnly );
|
//engine.setFlags( QgsLabelingEngineV2::RenderOutlineLabels | QgsLabelingEngineV2::DrawLabelRectOnly );
|
||||||
engine.run( context );
|
engine.run( context );
|
||||||
@ -87,6 +88,12 @@ void TestQgsLabelingEngineV2::testBasic()
|
|||||||
// TODO: replace with render checker
|
// TODO: replace with render checker
|
||||||
img.save( "/tmp/tstlabels.png" );
|
img.save( "/tmp/tstlabels.png" );
|
||||||
|
|
||||||
|
// now let's test the variant when integrated into rendering loop
|
||||||
|
job.start();
|
||||||
|
job.waitForFinished();
|
||||||
|
QImage img2 = job.renderedImage();
|
||||||
|
img2.save( "/tmp/tstlabels2.png" );
|
||||||
|
|
||||||
vl->setCustomProperty( "labeling/enabled", false );
|
vl->setCustomProperty( "labeling/enabled", false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +119,8 @@ void TestQgsLabelingEngineV2::testDiagrams()
|
|||||||
vl->loadNamedStyle( QString( TEST_DATA_DIR ) + "/points_diagrams.qml", res );
|
vl->loadNamedStyle( QString( TEST_DATA_DIR ) + "/points_diagrams.qml", res );
|
||||||
Q_ASSERT( res );
|
Q_ASSERT( res );
|
||||||
|
|
||||||
QgsLabelingEngineV2 engine( mapSettings );
|
QgsLabelingEngineV2 engine;
|
||||||
|
engine.setMapSettings( mapSettings );
|
||||||
engine.addProvider( new QgsVectorLayerDiagramProvider( vl ) );
|
engine.addProvider( new QgsVectorLayerDiagramProvider( vl ) );
|
||||||
engine.run( context );
|
engine.run( context );
|
||||||
|
|
||||||
@ -120,6 +128,12 @@ void TestQgsLabelingEngineV2::testDiagrams()
|
|||||||
|
|
||||||
// TODO: replace with render checker
|
// TODO: replace with render checker
|
||||||
img.save( "/tmp/tstdiagrams.png" );
|
img.save( "/tmp/tstdiagrams.png" );
|
||||||
|
|
||||||
|
// now let's test the variant when integrated into rendering loop
|
||||||
|
job.start();
|
||||||
|
job.waitForFinished();
|
||||||
|
QImage img2 = job.renderedImage();
|
||||||
|
img2.save( "/tmp/tstdiagrams2.png" );
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN( TestQgsLabelingEngineV2 )
|
QTEST_MAIN( TestQgsLabelingEngineV2 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user