QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsmaplayerstore.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayerstore.cpp
3 --------------------
4 begin : May 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsmaplayerstore.h"
19#include "moc_qgsmaplayerstore.cpp"
20#include "qgsmaplayer.h"
21#include "qgslogger.h"
22#include "qgsthreadingutils.h"
23#include <QList>
24
26 : QObject( parent )
27{}
28
33
35{
37
38 return mMapLayers.size();
39}
40
42{
44
45 int i = 0;
46 const QList<QgsMapLayer *> cLayers = mMapLayers.values();
47 for ( const auto l : cLayers )
48 {
49 if ( l->isValid() )
50 i++;
51 }
52 return i;
53}
54
55QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const
56{
57 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
59
60 return mMapLayers.value( layerId );
61}
62
63QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const
64{
66
67 QList<QgsMapLayer *> myResultList;
68 const auto constMMapLayers = mMapLayers;
69 for ( QgsMapLayer *layer : constMMapLayers )
70 {
71 if ( layer->name() == layerName )
72 {
73 myResultList << layer;
74 }
75 }
76 return myResultList;
77}
78
79QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers( const QList<QgsMapLayer *> &layers, bool takeOwnership )
80{
82
83 QList<QgsMapLayer *> myResultList;
84 const auto constLayers = layers;
85 for ( QgsMapLayer *myLayer : constLayers )
86 {
87 if ( !myLayer )
88 {
89 QgsDebugError( QStringLiteral( "Cannot add null layers" ) );
90 continue;
91 }
92
94
95 // If the layer is already in the store but its validity has flipped to TRUE reset data source
96 if ( mMapLayers.contains( myLayer->id() ) && ! mMapLayers[myLayer->id()]->isValid() && myLayer->isValid() && myLayer->dataProvider() )
97 {
98 mMapLayers[myLayer->id()]->setDataSource( myLayer->dataProvider()->dataSourceUri(), myLayer->name(), myLayer->providerType(), QgsDataProvider::ProviderOptions() );
99 }
100 //check the layer is not already registered!
101 if ( !mMapLayers.contains( myLayer->id() ) )
102 {
103 mMapLayers[myLayer->id()] = myLayer;
104 myResultList << mMapLayers[myLayer->id()];
105 if ( takeOwnership )
106 {
107 myLayer->setParent( this );
108 }
109 connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted );
110 emit layerWasAdded( myLayer );
111 }
112 }
113 if ( !myResultList.isEmpty() )
114 {
115 emit layersAdded( myResultList );
116 }
117 return myResultList;
118}
119
121QgsMapLayerStore::addMapLayer( QgsMapLayer *layer, bool takeOwnership )
122{
124
125 QList<QgsMapLayer *> addedLayers;
126 addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer, takeOwnership );
127 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
128}
129
130void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds )
131{
133
134 QList<QgsMapLayer *> layers;
135 const auto constLayerIds = layerIds;
136 for ( const QString &myId : constLayerIds )
137 {
138 layers << mMapLayers.value( myId );
139 }
140
142}
143
144void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers )
145{
147
148 if ( layers.isEmpty() )
149 return;
150
151 QStringList layerIds;
152 QList<QgsMapLayer *> layerList;
153
154 const auto constLayers = layers;
155 for ( QgsMapLayer *layer : constLayers )
156 {
157 // check layer and the store contains it
158 if ( layer && mMapLayers.contains( layer->id() ) )
159 {
160 layerIds << layer->id();
161 layerList << layer;
162 }
163 }
164
165 if ( layerIds.isEmpty() )
166 return;
167
168 emit layersWillBeRemoved( layerIds );
169 emit layersWillBeRemoved( layerList );
170
171 const auto constLayerList = layerList;
172 for ( QgsMapLayer *lyr : constLayerList )
173 {
174 const QString myId( lyr->id() );
175 emit layerWillBeRemoved( myId );
176 emit layerWillBeRemoved( lyr );
177 mMapLayers.remove( myId );
178 if ( lyr->parent() == this )
179 {
180 delete lyr;
181 }
182 emit layerRemoved( myId );
183 }
184
185 emit layersRemoved( layerIds );
186}
187
188void QgsMapLayerStore::removeMapLayer( const QString &layerId )
189{
191
192 removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) );
193}
194
196{
198
199 if ( layer )
200 removeMapLayers( QList<QgsMapLayer *>() << layer );
201}
202
204{
206
207 if ( !layer )
208 return nullptr;
209
210 if ( mMapLayers.contains( layer->id() ) )
211 {
212 emit layersWillBeRemoved( QStringList() << layer->id() );
213 emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
214 emit layerWillBeRemoved( layer->id() );
215 emit layerWillBeRemoved( layer );
216
217 mMapLayers.remove( layer->id() );
218 layer->setParent( nullptr );
219 emit layerRemoved( layer->id() );
220 emit layersRemoved( QStringList() << layer->id() );
221 return layer;
222 }
223 return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
224}
225
227{
229
230 emit allLayersRemoved();
231 // now let all observers know to clear themselves,
232 // and then consequently any of their map legends
233 removeMapLayers( mMapLayers.keys() );
234 mMapLayers.clear();
235}
236
238{
240
241 if ( !other || other == this )
242 return;
243
244 Q_ASSERT_X( other->thread() == thread(), "QgsMapLayerStore::transferLayersFromStore", "Cannot transfer layers from store with different thread affinity" );
245
246 const QMap<QString, QgsMapLayer *> otherLayers = other->mapLayers();
247 QMap<QString, QgsMapLayer *>::const_iterator it = otherLayers.constBegin();
248 for ( ; it != otherLayers.constEnd(); ++it )
249 {
250 QgsMapLayer *layer = other->takeMapLayer( it.value() );
251 if ( layer )
252 addMapLayer( layer );
253 }
254}
255
256void QgsMapLayerStore::onMapLayerDeleted( QObject *obj )
257{
259
260 const QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );
261
262 if ( !id.isNull() )
263 {
264 QgsDebugError( QStringLiteral( "Map layer deleted without unregistering! %1" ).arg( id ) );
265 mMapLayers.remove( id );
266 }
267}
268
269QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const
270{
271 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
273
274 return mMapLayers;
275}
276
277QMap<QString, QgsMapLayer *> QgsMapLayerStore::validMapLayers() const
278{
279 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
281
282 QMap<QString, QgsMapLayer *> validLayers;
283 for ( auto it = mMapLayers.constBegin(); it != mMapLayers.constEnd(); it++ )
284 {
285 if ( it.value()->isValid() )
286 validLayers[it.key()] = it.value();
287 }
288 return validLayers;
289}
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
int count() const
Returns the number of layers contained in the store.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all layers by layer ID.
void removeAllMapLayers()
Removes all registered layers.
~QgsMapLayerStore() override
QgsMapLayerStore(QObject *parent=nullptr)
Constructor for QgsMapLayerStore.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
int validCount() const
Returns the number of valid layers contained in the store.
void removeMapLayer(const QString &id)
Remove a layer from the store by layer id.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QList< QgsMapLayer * > mapLayersByName(const QString &name) const
Retrieve a list of matching layers by layer name.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the store by layer ID.
QMap< QString, QgsMapLayer * > validMapLayers() const
Returns a map of all valid layers by layer ID.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
QgsMapLayer * addMapLayer(QgsMapLayer *layer, bool takeOwnership=true)
Add a layer to the store.
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &layers, bool takeOwnership=true)
Add a list of layers to the store.
Base class for all map layer types.
Definition qgsmaplayer.h:76
QString id
Definition qgsmaplayer.h:79
#define QgsDebugError(str)
Definition qgslogger.h:38
#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.