mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Auxiliary layers may be created or loaded from auxiliary storage
This commit is contained in:
parent
de498314d2
commit
a550a32719
@ -12,6 +12,55 @@
|
||||
|
||||
|
||||
|
||||
class QgsAuxiliaryLayer : QgsVectorLayer
|
||||
{
|
||||
%Docstring
|
||||
|
||||
|
||||
Class allowing to manage the auxiliary storage for a vector layer
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsauxiliarystorage.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, const QgsVectorLayer *vlayer );
|
||||
%Docstring
|
||||
Constructor
|
||||
|
||||
\param pkField The primary key to use for joining
|
||||
\param filename The database path
|
||||
\param table The table name
|
||||
\param vlayer The target vector layer in join definition
|
||||
%End
|
||||
|
||||
virtual ~QgsAuxiliaryLayer();
|
||||
%Docstring
|
||||
Destructor
|
||||
%End
|
||||
|
||||
|
||||
|
||||
QgsVectorLayerJoinInfo joinInfo() const;
|
||||
%Docstring
|
||||
Returns information to use for joining with primary key and so on.
|
||||
:rtype: QgsVectorLayerJoinInfo
|
||||
%End
|
||||
|
||||
bool save();
|
||||
%Docstring
|
||||
Commit changes and starts editing then.
|
||||
|
||||
:return: true if commit step passed, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QgsAuxiliaryStorage
|
||||
{
|
||||
%Docstring
|
||||
@ -95,6 +144,19 @@ class QgsAuxiliaryStorage
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsAuxiliaryLayer *createAuxiliaryLayer( const QgsField &field, const QgsVectorLayer *layer ) const;
|
||||
%Docstring
|
||||
Creates an auxiliary layer for a vector layer. A new table is created if
|
||||
necessary. The primary key to use to construct the auxiliary layer is
|
||||
given in parameter.
|
||||
|
||||
\param field The primary key to join
|
||||
\param layer The vector layer for which the auxiliary layer has to be created
|
||||
|
||||
:return: A new auxiliary layer or a None if an error happened.
|
||||
:rtype: QgsAuxiliaryLayer
|
||||
%End
|
||||
|
||||
static QString extension();
|
||||
%Docstring
|
||||
Returns the extension used for auxiliary databases.
|
||||
|
@ -811,6 +811,14 @@ Returns the number of registered layers.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsAuxiliaryStorage *auxiliaryStorage();
|
||||
%Docstring
|
||||
Returns the current auxiliary storage.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsAuxiliaryStorage
|
||||
%End
|
||||
|
||||
signals:
|
||||
void readProject( const QDomDocument & );
|
||||
%Docstring
|
||||
|
@ -774,6 +774,39 @@ Return the provider type for this layer
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
bool loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage );
|
||||
%Docstring
|
||||
Loads the auxiliary layer for this vector layer. If there's no
|
||||
corresponding table in the database, then nothing happens and false is
|
||||
returned.
|
||||
|
||||
\param storage The auxiliary storage where to look for the table
|
||||
|
||||
:return: true if the auxiliary layer is well loaded, false otherwise
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setAuxiliaryLayer( QgsAuxiliaryLayer *layer = 0 );
|
||||
%Docstring
|
||||
Sets the current auxiliary layer. The auxiliary layer is automatically
|
||||
put in editable mode and fields are updated. Moreover, a join is created
|
||||
between the current layer and the auxiliary layer. Ownership is
|
||||
transferred.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QgsAuxiliaryLayer *auxiliaryLayer();
|
||||
%Docstring
|
||||
Returns the current auxiliary layer.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsAuxiliaryLayer
|
||||
%End
|
||||
|
||||
|
||||
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage, const QgsReadWriteContext &context );
|
||||
|
||||
%Docstring
|
||||
|
@ -573,6 +573,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgsactionmanager.h
|
||||
qgsactionscoperegistry.h
|
||||
qgsanimatedicon.h
|
||||
qgsauxiliarystorage.h
|
||||
qgsbrowsermodel.h
|
||||
qgscoordinatereferencesystem.h
|
||||
qgscredentials.h
|
||||
|
@ -24,6 +24,44 @@
|
||||
|
||||
const QString AS_JOINFIELD = "ASPK";
|
||||
const QString AS_EXTENSION = "qgd";
|
||||
const QString AS_JOINPREFIX = "auxiliary_storage_";
|
||||
|
||||
QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, const QgsVectorLayer *vlayer )
|
||||
: QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
|
||||
, mLayer( vlayer )
|
||||
{
|
||||
// init join info
|
||||
mJoinInfo.setPrefix( AS_JOINPREFIX );
|
||||
mJoinInfo.setJoinLayer( this );
|
||||
mJoinInfo.setJoinFieldName( AS_JOINFIELD );
|
||||
mJoinInfo.setTargetFieldName( pkField );
|
||||
mJoinInfo.setEditable( true );
|
||||
mJoinInfo.setUpsertOnEdit( true );
|
||||
mJoinInfo.setCascadedDelete( true );
|
||||
}
|
||||
|
||||
QgsVectorLayerJoinInfo QgsAuxiliaryLayer::joinInfo() const
|
||||
{
|
||||
return mJoinInfo;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::save()
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if ( isEditable() )
|
||||
{
|
||||
rc = commitChanges();
|
||||
}
|
||||
|
||||
startEditing();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
//
|
||||
// QgsAuxiliaryStorage
|
||||
//
|
||||
|
||||
QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QgsProject &project, bool copy )
|
||||
: mValid( false )
|
||||
@ -92,6 +130,31 @@ bool QgsAuxiliaryStorage::save() const
|
||||
}
|
||||
}
|
||||
|
||||
QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &field, const QgsVectorLayer *layer ) const
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = nullptr;
|
||||
|
||||
if ( mValid && layer && layer->isSpatial() )
|
||||
{
|
||||
const QString table( layer->id() );
|
||||
sqlite3 *handler = openDB( currentFileName() );
|
||||
|
||||
if ( !tableExists( table, handler ) )
|
||||
{
|
||||
if ( !createTable( field.typeName(), table, handler ) )
|
||||
{
|
||||
close( handler );
|
||||
return alayer;
|
||||
}
|
||||
}
|
||||
|
||||
alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
|
||||
close( handler );
|
||||
}
|
||||
|
||||
return alayer;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::saveAs( const QString &filename ) const
|
||||
{
|
||||
if ( QFile::exists( filename ) )
|
||||
@ -149,6 +212,16 @@ sqlite3 *QgsAuxiliaryStorage::openDB( const QString &filename )
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table ).arg( AS_JOINFIELD ).arg( type );
|
||||
|
||||
if ( !exec( sql, handler ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::createDB( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
@ -169,6 +242,26 @@ sqlite3 *QgsAuxiliaryStorage::createDB( const QString &filename )
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
|
||||
int rows = 0;
|
||||
int columns = 0;
|
||||
char **results = nullptr;
|
||||
const int rc = sqlite3_get_table( handler, sql.toStdString().c_str(), &results, &rows, &columns, nullptr );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
debugMsg( sql, handler );
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_free_table( results );
|
||||
if ( rows >= 1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::open( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsvectorlayerjoininfo.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
@ -27,6 +28,61 @@
|
||||
|
||||
class QgsProject;
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryLayer
|
||||
*
|
||||
* \ingroup core
|
||||
*
|
||||
* \brief Class allowing to manage the auxiliary storage for a vector layer
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param pkField The primary key to use for joining
|
||||
* \param filename The database path
|
||||
* \param table The table name
|
||||
* \param vlayer The target vector layer in join definition
|
||||
*/
|
||||
QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, const QgsVectorLayer *vlayer );
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~QgsAuxiliaryLayer() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor deactivated
|
||||
*/
|
||||
QgsAuxiliaryLayer( const QgsAuxiliaryLayer &rhs ) = delete;
|
||||
|
||||
QgsAuxiliaryLayer &operator=( QgsAuxiliaryLayer const &rhs ) = delete;
|
||||
|
||||
/**
|
||||
* Returns information to use for joining with primary key and so on.
|
||||
*/
|
||||
QgsVectorLayerJoinInfo joinInfo() const;
|
||||
|
||||
/**
|
||||
* Commit changes and starts editing then.
|
||||
*
|
||||
* \returns true if commit step passed, false otherwise
|
||||
*/
|
||||
bool save();
|
||||
|
||||
private:
|
||||
QgsVectorLayerJoinInfo mJoinInfo;
|
||||
const QgsVectorLayer *mLayer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryStorage
|
||||
*
|
||||
@ -102,6 +158,18 @@ class CORE_EXPORT QgsAuxiliaryStorage
|
||||
*/
|
||||
bool save() const;
|
||||
|
||||
/**
|
||||
* Creates an auxiliary layer for a vector layer. A new table is created if
|
||||
* necessary. The primary key to use to construct the auxiliary layer is
|
||||
* given in parameter.
|
||||
*
|
||||
* \param field The primary key to join
|
||||
* \param layer The vector layer for which the auxiliary layer has to be created
|
||||
*
|
||||
* \returns A new auxiliary layer or a nullptr if an error happened.
|
||||
*/
|
||||
QgsAuxiliaryLayer *createAuxiliaryLayer( const QgsField &field, const QgsVectorLayer *layer ) const;
|
||||
|
||||
/**
|
||||
* Returns the extension used for auxiliary databases.
|
||||
*/
|
||||
@ -117,6 +185,8 @@ class CORE_EXPORT QgsAuxiliaryStorage
|
||||
static sqlite3 *createDB( const QString &filename );
|
||||
static sqlite3 *openDB( const QString &filename );
|
||||
static void close( sqlite3 *handler );
|
||||
static bool tableExists( const QString &table, sqlite3 *handler );
|
||||
static bool createTable( const QString &type, const QString &table, sqlite3 *handler );
|
||||
|
||||
static bool exec( const QString &sql, sqlite3 *handler );
|
||||
static void debugMsg( const QString &sql, sqlite3 *handler );
|
||||
|
@ -2246,6 +2246,22 @@ QList<QgsMapLayer *> QgsProject::addMapLayers(
|
||||
if ( addToLegend )
|
||||
emit legendLayersAdded( myResultList );
|
||||
}
|
||||
|
||||
if ( mAuxiliaryStorage )
|
||||
{
|
||||
Q_FOREACH ( QgsMapLayer *mlayer, myResultList )
|
||||
{
|
||||
if ( mlayer->type() != QgsMapLayer::VectorLayer )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mlayer );
|
||||
if ( vl && vl->isSpatial() )
|
||||
{
|
||||
vl->loadAuxiliaryLayer( *mAuxiliaryStorage.get() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return myResultList;
|
||||
}
|
||||
|
||||
@ -2343,6 +2359,18 @@ void QgsProject::setTrustLayerMetadata( bool trust )
|
||||
|
||||
bool QgsProject::saveAuxiliaryStorage( const QString &filename )
|
||||
{
|
||||
Q_FOREACH ( QgsMapLayer *l, mapLayers().values() )
|
||||
{
|
||||
if ( l->type() != QgsMapLayer::VectorLayer )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
|
||||
if ( vl && vl->auxiliaryLayer() )
|
||||
{
|
||||
vl->auxiliaryLayer()->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !filename.isEmpty() )
|
||||
{
|
||||
return mAuxiliaryStorage->saveAs( filename );
|
||||
@ -2352,3 +2380,13 @@ bool QgsProject::saveAuxiliaryStorage( const QString &filename )
|
||||
return mAuxiliaryStorage->saveAs( *this );
|
||||
}
|
||||
}
|
||||
|
||||
const QgsAuxiliaryStorage *QgsProject::auxiliaryStorage() const
|
||||
{
|
||||
return mAuxiliaryStorage.get();
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage *QgsProject::auxiliaryStorage()
|
||||
{
|
||||
return mAuxiliaryStorage.get();
|
||||
}
|
||||
|
@ -810,6 +810,20 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
*/
|
||||
bool trustLayerMetadata() const { return mTrustLayerMetadata; }
|
||||
|
||||
/**
|
||||
* Returns the current const auxiliary storage.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAuxiliaryStorage *auxiliaryStorage() const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns the current auxiliary storage.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsAuxiliaryStorage *auxiliaryStorage();
|
||||
|
||||
signals:
|
||||
//! emitted when project is being read
|
||||
void readProject( const QDomDocument & );
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgstaskmanager.h"
|
||||
#include "qgstransaction.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include "diagram/qgsdiagram.h"
|
||||
|
||||
@ -139,6 +140,8 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
|
||||
bool readExtentFromXml )
|
||||
: QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
|
||||
, mProviderKey( providerKey )
|
||||
, mAuxiliaryLayer( nullptr )
|
||||
, mAuxiliaryLayerKey( QString() )
|
||||
, mReadExtentFromXml( readExtentFromXml )
|
||||
{
|
||||
mActions = new QgsActionManager( this );
|
||||
@ -1447,6 +1450,14 @@ bool QgsVectorLayer::readXml( const QDomNode &layer_node, const QgsReadWriteCont
|
||||
}
|
||||
}
|
||||
|
||||
// auxiliary layer
|
||||
const QDomNode asNode = layer_node.namedItem( QStringLiteral( "auxiliaryLayer" ) );
|
||||
const QDomElement asElem = asNode.toElement();
|
||||
if ( !asElem.isNull() )
|
||||
{
|
||||
mAuxiliaryLayerKey = asElem.attribute( QStringLiteral( "key" ) );
|
||||
}
|
||||
|
||||
return mValid; // should be true if read successfully
|
||||
|
||||
} // void QgsVectorLayer::readXml
|
||||
@ -1667,6 +1678,15 @@ bool QgsVectorLayer::writeXml( QDomNode &layer_node,
|
||||
|
||||
writeStyleManager( layer_node, document );
|
||||
|
||||
// auxiliary layer
|
||||
QDomElement asElem = document.createElement( QStringLiteral( "auxiliaryLayer" ) );
|
||||
if ( mAuxiliaryLayer )
|
||||
{
|
||||
const QString pkField = mAuxiliaryLayer->joinInfo().targetFieldName();
|
||||
asElem.setAttribute( QStringLiteral( "key" ), pkField );
|
||||
}
|
||||
layer_node.appendChild( asElem );
|
||||
|
||||
// renderer specific settings
|
||||
QString errorMsg;
|
||||
return writeSymbology( layer_node, document, errorMsg, context );
|
||||
@ -4223,6 +4243,58 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag
|
||||
return loadNamedStyle( theURI, resultFlag, false );
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage )
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if ( isSpatial() && storage.isValid() && !mAuxiliaryLayerKey.isEmpty() )
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = nullptr;
|
||||
|
||||
int idx = fields().lookupField( mAuxiliaryLayerKey );
|
||||
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
alayer = storage.createAuxiliaryLayer( fields().field( idx ), this );
|
||||
|
||||
if ( alayer )
|
||||
{
|
||||
setAuxiliaryLayer( alayer );
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setAuxiliaryLayer( QgsAuxiliaryLayer *alayer )
|
||||
{
|
||||
if ( alayer )
|
||||
{
|
||||
if ( mAuxiliaryLayer )
|
||||
removeJoin( mAuxiliaryLayer->id() );
|
||||
|
||||
addJoin( alayer->joinInfo() );
|
||||
|
||||
if ( !alayer->isEditable() )
|
||||
alayer->startEditing();
|
||||
}
|
||||
|
||||
mAuxiliaryLayer.reset( alayer );
|
||||
updateFields();
|
||||
}
|
||||
|
||||
const QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer() const
|
||||
{
|
||||
return mAuxiliaryLayer.get();
|
||||
}
|
||||
|
||||
QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer()
|
||||
{
|
||||
return mAuxiliaryLayer.get();
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag, bool loadFromLocalDB )
|
||||
{
|
||||
QgsDataSourceUri dsUri( theURI );
|
||||
|
@ -70,6 +70,8 @@ class QgsVectorLayerFeatureCounter;
|
||||
class QgsAbstractVectorLayerLabeling;
|
||||
class QgsPoint;
|
||||
class QgsFeedback;
|
||||
class QgsAuxiliaryStorage;
|
||||
class QgsAuxiliaryLayer;
|
||||
|
||||
typedef QList<int> QgsAttributeList;
|
||||
typedef QSet<int> QgsAttributeIds;
|
||||
@ -784,6 +786,44 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
virtual QString loadNamedStyle( const QString &theURI, bool &resultFlag SIP_OUT ) override;
|
||||
|
||||
/**
|
||||
* Loads the auxiliary layer for this vector layer. If there's no
|
||||
* corresponding table in the database, then nothing happens and false is
|
||||
* returned.
|
||||
*
|
||||
* \param storage The auxiliary storage where to look for the table
|
||||
*
|
||||
* \returns true if the auxiliary layer is well loaded, false otherwise
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage );
|
||||
|
||||
/**
|
||||
* Sets the current auxiliary layer. The auxiliary layer is automatically
|
||||
* put in editable mode and fields are updated. Moreover, a join is created
|
||||
* between the current layer and the auxiliary layer. Ownership is
|
||||
* transferred.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*
|
||||
*/
|
||||
void setAuxiliaryLayer( QgsAuxiliaryLayer *layer = nullptr );
|
||||
|
||||
/**
|
||||
* Returns the current auxiliary layer.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsAuxiliaryLayer *auxiliaryLayer();
|
||||
|
||||
/**
|
||||
* Returns the current const auxiliary layer.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAuxiliaryLayer *auxiliaryLayer() const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Read the symbology for the current layer from the Dom node supplied.
|
||||
* \param layerNode node that will contain the symbology definition for this layer.
|
||||
* \param errorMessage reference to string that will be updated with any error messages
|
||||
@ -2145,6 +2185,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
mutable bool mValidExtent = false;
|
||||
mutable bool mLazyExtent = true;
|
||||
|
||||
//! Auxiliary layer
|
||||
std::unique_ptr<QgsAuxiliaryLayer> mAuxiliaryLayer;
|
||||
|
||||
//! Key to use to join auxiliary layer
|
||||
QString mAuxiliaryLayerKey;
|
||||
|
||||
// Features in renderer classes counted
|
||||
bool mSymbolFeatureCounted = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user