Skip to content
Permalink
Browse files

Merge pull request #4095 from nyalldawson/label_engine_layers

Use weak layer pointers in labeling engine
  • Loading branch information
nyalldawson committed Feb 4, 2017
2 parents 11150dd + 615745f commit a0cb64520a84cd096b5d135a008250d4bc815908
@@ -348,7 +348,7 @@ class CORE_EXPORT QgsAnnotation : public QObject
QPointF mBalloonSegmentPoint2;

//! Associated layer (or nullptr if not attached to a layer)
QPointer<QgsMapLayer> mMapLayer;
QgsWeakMapLayerPointer mMapLayer;

//! Associated feature, or invalid feature if no feature associated
QgsFeature mFeature;
@@ -1231,7 +1231,7 @@ bool QgsComposerMap::writeXml( QDomElement& elem, QDomDocument & doc ) const

//layer set
QDomElement layerSetElem = doc.createElement( QStringLiteral( "LayerSet" ) );
Q_FOREACH ( const QPointer<QgsMapLayer>& layerPtr, mLayers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layerPtr, mLayers )
{
QgsMapLayer* layer = layerPtr.data();
if ( !layer )
@@ -1557,7 +1557,7 @@ void QgsComposerMap::setLayerStyleOverrides( const QMap<QString, QString>& overr
void QgsComposerMap::storeCurrentLayerStyles()
{
mLayerStyleOverrides.clear();
Q_FOREACH ( const QPointer<QgsMapLayer>& layerPtr, mLayers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layerPtr, mLayers )
{
if ( QgsMapLayer* layer = layerPtr.data() )
{
@@ -23,6 +23,7 @@
#include "qgsrectangle.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrendercontext.h"
#include "qgsmaplayer.h"
#include <QFont>
#include <QGraphicsRectItem>

@@ -542,7 +543,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
bool mKeepLayerSet;

//! Stored layer list (used if layer live-link mKeepLayerSet is disabled)
QList< QPointer<QgsMapLayer> > mLayers;
QgsWeakMapLayerPointerList mLayers;

bool mKeepLayerStyles;
//! Stored style names (value) to be used with particular layer IDs (key) instead of default style
@@ -332,7 +332,7 @@ static QgsExpression::Node* getNode( const QVariant& value, QgsExpression* paren

QgsVectorLayer* getVectorLayer( const QVariant& value, QgsExpression* )
{
QgsMapLayer* ml = value.value< QPointer<QgsMapLayer> >().data();
QgsMapLayer* ml = value.value< QgsWeakMapLayerPointer >().data();
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( ml );
if ( !vl )
{
@@ -760,7 +760,7 @@ QgsExpressionContextScope* QgsExpressionContextUtils::layerScope( const QgsMapLa

scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QPointer<QgsMapLayer> >( QPointer<QgsMapLayer>( const_cast<QgsMapLayer*>( layer ) ) ), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer*>( layer ) ) ), true ) );

const QgsVectorLayer* vLayer = dynamic_cast< const QgsVectorLayer* >( layer );
if ( vLayer )
@@ -25,6 +25,7 @@
#include "pal.h"
#include "problem.h"
#include "qgsrendercontext.h"
#include "qgsmaplayer.h"


// helper function for checking for job cancelation within PAL
@@ -88,20 +89,20 @@ QgsLabelingEngine::~QgsLabelingEngine()
qDeleteAll( mSubProviders );
}

QStringList QgsLabelingEngine::participatingLayerIds() const
QList< QgsMapLayer* > QgsLabelingEngine::participatingLayers() const
{
QSet< QString > ids;
QSet< QgsMapLayer* > layers;
Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
{
if ( !provider->layerId().isEmpty() )
ids << provider->layerId();
if ( provider->layer() )
layers << provider->layer();
}
Q_FOREACH ( QgsAbstractLabelProvider* provider, mSubProviders )
{
if ( !provider->layerId().isEmpty() )
ids << provider->layerId();
if ( provider->layer() )
layers << provider->layer();
}
return ids.toList();
return layers.toList();
}

void QgsLabelingEngine::addProvider( QgsAbstractLabelProvider* provider )
@@ -230,7 +231,7 @@ void QgsLabelingEngine::run( QgsRenderContext& context )
Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
{
bool appendedLayerScope = false;
if ( QgsMapLayer* ml = QgsProject::instance()->mapLayer( provider->layerId() ) )
if ( QgsMapLayer* ml = provider->layer() )
{
appendedLayerScope = true;
context.expressionContext().appendScope( QgsExpressionContextUtils::layerScope( ml ) );
@@ -415,9 +416,10 @@ QgsAbstractLabelProvider*QgsLabelFeature::provider() const

}

QgsAbstractLabelProvider::QgsAbstractLabelProvider( const QString& layerId, const QString& providerId )
QgsAbstractLabelProvider::QgsAbstractLabelProvider( QgsMapLayer* layer, const QString& providerId )
: mEngine( nullptr )
, mLayerId( layerId )
, mLayerId( layer ? layer->id() : QString() )
, mLayer( layer )
, mProviderId( providerId )
, mFlags( DrawLabels )
, mPlacement( QgsPalLayerSettings::AroundPoint )
@@ -43,7 +43,7 @@ class CORE_EXPORT QgsAbstractLabelProvider

public:
//! Construct the provider with default values
QgsAbstractLabelProvider( const QString& layerId = QString(), const QString& providerId = QString() );
QgsAbstractLabelProvider( QgsMapLayer* layer, const QString& providerId = QString() );

virtual ~QgsAbstractLabelProvider() = default;

@@ -75,6 +75,9 @@ class CORE_EXPORT QgsAbstractLabelProvider
//! Returns ID of associated layer, or empty string if no layer is associated with the provider.
QString layerId() const { return mLayerId; }

//! Returns the associated layer, or nullptr if no layer is associated with the provider.
QgsMapLayer* layer() const { return mLayer.data(); }

//! Returns provider ID - useful in case there is more than one label provider within a layer
//! (e.g. in case of rule-based labeling - provider ID = rule's key). May be empty string if
//! layer ID is sufficient for identification of provider's configuration.
@@ -106,6 +109,8 @@ class CORE_EXPORT QgsAbstractLabelProvider
QString mName;
//! Associated layer's ID, if applicable
QString mLayerId;
//! Weak pointer to source layer
QgsWeakMapLayerPointer mLayer;
//! Associated provider ID (one layer may have multiple providers, e.g. in rule-based labeling)
QString mProviderId;
//! Flags altering drawing and registration of features
@@ -187,10 +192,10 @@ class CORE_EXPORT QgsLabelingEngine
const QgsMapSettings& mapSettings() const { return mMapSettings; }

/**
* Returns a list of layer IDs for layers with providers in the engine.
* Returns a list of layers with providers in the engine.
* @note added in QGIS 3.0
*/
QStringList participatingLayerIds() const;
QList< QgsMapLayer* > participatingLayers() const;

//! Add provider of label features. Takes ownership of the provider
void addProvider( QgsAbstractLabelProvider* provider );
@@ -920,4 +920,18 @@ class CORE_EXPORT QgsMapLayer : public QObject

Q_DECLARE_METATYPE( QgsMapLayer* )

/**
* Weak pointer for QgsMapLayer
* @note added in QGIS 3.0
* @note not available in Python bindings
*/
typedef QPointer< QgsMapLayer > QgsWeakMapLayerPointer;

/**
* A list of weak pointers to QgsMapLayers.
* @note added in QGIS 3.0
* @note not available in Python bindings
*/
typedef QList< QgsWeakMapLayerPointer > QgsWeakMapLayerPointerList;

#endif
@@ -16,21 +16,21 @@

/// @cond PRIVATE

inline QList<QgsMapLayer*> _qgis_listQPointerToRaw( const QList< QPointer<QgsMapLayer> >& layers )
inline QList<QgsMapLayer*> _qgis_listQPointerToRaw( const QgsWeakMapLayerPointerList& layers )
{
QList<QgsMapLayer*> lst;
lst.reserve( layers.count() );
Q_FOREACH ( const QPointer<QgsMapLayer>& layerPtr, layers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layerPtr, layers )
{
if ( layerPtr )
lst.append( layerPtr.data() );
}
return lst;
}

inline QList< QPointer<QgsMapLayer> > _qgis_listRawToQPointer( const QList<QgsMapLayer*>& layers )
inline QgsWeakMapLayerPointerList _qgis_listRawToQPointer( const QList<QgsMapLayer*>& layers )
{
QList< QPointer<QgsMapLayer> > lst;
QgsWeakMapLayerPointerList lst;
lst.reserve( layers.count() );
Q_FOREACH ( QgsMapLayer* layer, layers )
{
@@ -39,11 +39,11 @@ inline QList< QPointer<QgsMapLayer> > _qgis_listRawToQPointer( const QList<QgsMa
return lst;
}

inline QStringList _qgis_listQPointerToIDs( const QList< QPointer<QgsMapLayer> >& layers )
inline QStringList _qgis_listQPointerToIDs( const QgsWeakMapLayerPointerList& layers )
{
QStringList lst;
lst.reserve( layers.count() );
Q_FOREACH ( const QPointer<QgsMapLayer>& layerPtr, layers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layerPtr, layers )
{
if ( layerPtr )
lst << layerPtr->id();
@@ -93,7 +93,7 @@ inline static QgsMapLayer* _qgis_findLayer( const QList< QgsMapLayer*> layers, c
}
}

inline uint qHash( const QPointer< QgsMapLayer >& key )
inline uint qHash( const QgsWeakMapLayerPointer& key )
{
return qHash( key ? key->id() : QString() );
}
@@ -35,7 +35,7 @@ void QgsMapRendererCache::clearInternal()
mScale = 0;

// make sure we are disconnected from all layers
Q_FOREACH ( const QPointer< QgsMapLayer >& layer, mConnectedLayers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layer, mConnectedLayers )
{
if ( layer.data() )
{
@@ -48,9 +48,9 @@ void QgsMapRendererCache::clearInternal()

void QgsMapRendererCache::dropUnusedConnections()
{
QSet< QPointer< QgsMapLayer > > stillDepends = dependentLayers();
QSet< QPointer< QgsMapLayer > > disconnects = mConnectedLayers.subtract( stillDepends );
Q_FOREACH ( const QPointer< QgsMapLayer >& layer, disconnects )
QSet< QgsWeakMapLayerPointer > stillDepends = dependentLayers();
QSet< QgsWeakMapLayerPointer > disconnects = mConnectedLayers.subtract( stillDepends );
Q_FOREACH ( const QgsWeakMapLayerPointer& layer, disconnects )
{
if ( layer.data() )
{
@@ -61,13 +61,13 @@ void QgsMapRendererCache::dropUnusedConnections()
mConnectedLayers = stillDepends;
}

QSet<QPointer<QgsMapLayer> > QgsMapRendererCache::dependentLayers() const
QSet<QgsWeakMapLayerPointer > QgsMapRendererCache::dependentLayers() const
{
QSet< QPointer< QgsMapLayer > > result;
QSet< QgsWeakMapLayerPointer > result;
QMap<QString, CacheParameters>::const_iterator it = mCachedImages.constBegin();
for ( ; it != mCachedImages.constEnd(); ++it )
{
Q_FOREACH ( const QPointer< QgsMapLayer >& l, it.value().dependentLayers )
Q_FOREACH ( const QgsWeakMapLayerPointer& l, it.value().dependentLayers )
{
if ( l.data() )
result << l;
@@ -107,7 +107,7 @@ void QgsMapRendererCache::setCacheImage( const QString& cacheKey, const QImage&
if ( layer )
{
params.dependentLayers << layer;
if ( !mConnectedLayers.contains( QPointer< QgsMapLayer >( layer ) ) )
if ( !mConnectedLayers.contains( QgsWeakMapLayerPointer( layer ) ) )
{
connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapRendererCache::layerRequestedRepaint );
mConnectedLayers << layer;
@@ -99,7 +99,7 @@ class CORE_EXPORT QgsMapRendererCache : public QObject
struct CacheParameters
{
QImage cachedImage;
QList< QPointer< QgsMapLayer > > dependentLayers;
QgsWeakMapLayerPointerList dependentLayers;
};

//! Invalidate cache contents (without locking)
@@ -108,7 +108,7 @@ class CORE_EXPORT QgsMapRendererCache : public QObject
//! Disconnects from layers we no longer care about
void dropUnusedConnections();

QSet< QPointer< QgsMapLayer > > dependentLayers() const;
QSet< QgsWeakMapLayerPointer > dependentLayers() const;

mutable QMutex mMutex;
QgsRectangle mExtent;
@@ -117,7 +117,7 @@ class CORE_EXPORT QgsMapRendererCache : public QObject
//! Map of cache key to cache parameters
QMap<QString, CacheParameters> mCachedImages;
//! List of all layers on which this cache is currently connected
QSet< QPointer< QgsMapLayer > > mConnectedLayers;
QSet< QgsWeakMapLayerPointer > mConnectedLayers;
};


@@ -50,7 +50,7 @@ struct LayerRenderJob
QPainter::CompositionMode blendMode;
double opacity;
bool cached; // if true, img already contains cached image from previous rendering
QPointer< QgsMapLayer > layer;
QgsWeakMapLayerPointer layer;
int renderingTime; //!< Time it took to render the layer in ms (it is -1 if not rendered or still rendering)
};

@@ -551,7 +551,7 @@ QgsRectangle QgsMapSettings::fullExtent() const
// iterate through the map layers and test each layers extent
// against the current min and max values
QgsDebugMsg( QString( "Layer count: %1" ).arg( mLayers.count() ) );
Q_FOREACH ( const QPointer<QgsMapLayer>& layerPtr, mLayers )
Q_FOREACH ( const QgsWeakMapLayerPointer& layerPtr, mLayers )
{
if ( QgsMapLayer* lyr = layerPtr.data() )
{
@@ -30,13 +30,13 @@
#include "qgsrectangle.h"
#include "qgsscalecalculator.h"
#include "qgsexpressioncontext.h"
#include "qgsmaplayer.h"

class QPainter;

class QgsCoordinateTransform;
class QgsScaleCalculator;
class QgsMapRendererJob;
class QgsMapLayer;


/** \ingroup core
@@ -310,7 +310,7 @@ class CORE_EXPORT QgsMapSettings
double mMagnificationFactor;

//! list of layers to be rendered (stored as weak pointers)
QList< QPointer<QgsMapLayer> > mLayers;
QgsWeakMapLayerPointerList mLayers;
QMap<QString, QString> mLayerStyleOverrides;
QString mCustomRenderFlags;
QgsExpressionContext mExpressionContext;
@@ -84,7 +84,7 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
QSet<QString> checkedLegendItems;
private:
//! Weak pointer to the layer
QPointer<QgsMapLayer> mLayer;
QgsWeakMapLayerPointer mLayer;
};

/**
@@ -24,29 +24,8 @@
#include "feature.h"
#include "labelposition.h"


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


QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( QgsVectorLayer* layer, bool ownFeatureLoop )
: QgsAbstractLabelProvider( layer->id() )
: QgsAbstractLabelProvider( layer )
, mSettings( *layer->diagramLayerSettings() )
, mDiagRenderer( layer->diagramRenderer()->clone() )
, mFields( layer->fields() )

0 comments on commit a0cb645

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