QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
20#include "qgslogger.h"
21#include "qgsmaplayer.h"
22#include "qgsthreadingutils.h"
23
24#include <QList>
25
26#include "moc_qgsmaplayerstore.cpp"
27
29 : QObject( parent )
30{}
31
36
38{
40
41 return mMapLayers.size();
42}
43
45{
47
48 int i = 0;
49 const QList<QgsMapLayer *> cLayers = mMapLayers.values();
50 for ( const auto l : cLayers )
51 {
52 if ( l->isValid() )
53 i++;
54 }
55 return i;
56}
57
58QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const
59{
60 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
62
63 return mMapLayers.value( layerId );
64}
65
66QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const
67{
69
70 QList<QgsMapLayer *> myResultList;
71 const auto constMMapLayers = mMapLayers;
72 for ( QgsMapLayer *layer : constMMapLayers )
73 {
74 if ( layer->name() == layerName )
75 {
76 myResultList << layer;
77 }
78 }
79 return myResultList;
80}
81
82QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers( const QList<QgsMapLayer *> &layers, bool takeOwnership )
83{
85
86 QList<QgsMapLayer *> myResultList;
87 const auto constLayers = layers;
88 for ( QgsMapLayer *myLayer : constLayers )
89 {
90 if ( !myLayer )
91 {
92 QgsDebugError( QStringLiteral( "Cannot add null layers" ) );
93 continue;
94 }
95
97
98 // If the layer is already in the store but its validity has flipped to TRUE reset data source
99 if ( mMapLayers.contains( myLayer->id() ) && ! mMapLayers[myLayer->id()]->isValid() && myLayer->isValid() && myLayer->dataProvider() )
100 {
101 mMapLayers[myLayer->id()]->setDataSource( myLayer->dataProvider()->dataSourceUri(), myLayer->name(), myLayer->providerType(), QgsDataProvider::ProviderOptions() );
102 }
103 //check the layer is not already registered!
104 if ( !mMapLayers.contains( myLayer->id() ) )
105 {
106 mMapLayers[myLayer->id()] = myLayer;
107 myResultList << mMapLayers[myLayer->id()];
108 if ( takeOwnership )
109 {
110 myLayer->setParent( this );
111 }
112 connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted );
113 emit layerWasAdded( myLayer );
114 }
115 }
116 if ( !myResultList.isEmpty() )
117 {
118 emit layersAdded( myResultList );
119 }
120 return myResultList;
121}
122
124QgsMapLayerStore::addMapLayer( QgsMapLayer *layer, bool takeOwnership )
125{
127
128 QList<QgsMapLayer *> addedLayers;
129 addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer, takeOwnership );
130 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
131}
132
133void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds )
134{
136
137 QList<QgsMapLayer *> layers;
138 const auto constLayerIds = layerIds;
139 for ( const QString &myId : constLayerIds )
140 {
141 layers << mMapLayers.value( myId );
142 }
143
145}
146
147void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers )
148{
150
151 if ( layers.isEmpty() )
152 return;
153
154 QStringList layerIds;
155 QList<QgsMapLayer *> layerList;
156
157 const auto constLayers = layers;
158 for ( QgsMapLayer *layer : constLayers )
159 {
160 // check layer and the store contains it
161 if ( layer && mMapLayers.contains( layer->id() ) )
162 {
163 layerIds << layer->id();
164 layerList << layer;
165 }
166 }
167
168 if ( layerIds.isEmpty() )
169 return;
170
171 emit layersWillBeRemoved( layerIds );
172 emit layersWillBeRemoved( layerList );
173
174 const auto constLayerList = layerList;
175 for ( QgsMapLayer *lyr : constLayerList )
176 {
177 const QString myId( lyr->id() );
178 emit layerWillBeRemoved( myId );
179 emit layerWillBeRemoved( lyr );
180 mMapLayers.remove( myId );
181 if ( lyr->parent() == this )
182 {
183 delete lyr;
184 }
185 emit layerRemoved( myId );
186 }
187
188 emit layersRemoved( layerIds );
189}
190
191void QgsMapLayerStore::removeMapLayer( const QString &layerId )
192{
194
195 removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) );
196}
197
199{
201
202 if ( layer )
203 removeMapLayers( QList<QgsMapLayer *>() << layer );
204}
205
207{
209
210 if ( !layer )
211 return nullptr;
212
213 if ( mMapLayers.contains( layer->id() ) )
214 {
215 emit layersWillBeRemoved( QStringList() << layer->id() );
216 emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
217 emit layerWillBeRemoved( layer->id() );
218 emit layerWillBeRemoved( layer );
219
220 mMapLayers.remove( layer->id() );
221 layer->setParent( nullptr );
222 emit layerRemoved( layer->id() );
223 emit layersRemoved( QStringList() << layer->id() );
224 return layer;
225 }
226 return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
227}
228
230{
232
233 emit allLayersRemoved();
234 // now let all observers know to clear themselves,
235 // and then consequently any of their map legends
236 removeMapLayers( mMapLayers.keys() );
237 mMapLayers.clear();
238}
239
241{
243
244 if ( !other || other == this )
245 return;
246
247 Q_ASSERT_X( other->thread() == thread(), "QgsMapLayerStore::transferLayersFromStore", "Cannot transfer layers from store with different thread affinity" );
248
249 const QMap<QString, QgsMapLayer *> otherLayers = other->mapLayers();
250 QMap<QString, QgsMapLayer *>::const_iterator it = otherLayers.constBegin();
251 for ( ; it != otherLayers.constEnd(); ++it )
252 {
253 QgsMapLayer *layer = other->takeMapLayer( it.value() );
254 if ( layer )
255 addMapLayer( layer );
256 }
257}
258
259void QgsMapLayerStore::onMapLayerDeleted( QObject *obj )
260{
262
263 const QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );
264
265 if ( !id.isNull() )
266 {
267 QgsDebugError( QStringLiteral( "Map layer deleted without unregistering! %1" ).arg( id ) );
268 mMapLayers.remove( id );
269 }
270}
271
272QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const
273{
274 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
276
277 return mMapLayers;
278}
279
280QMap<QString, QgsMapLayer *> QgsMapLayerStore::validMapLayers() const
281{
282 // because QgsVirtualLayerProvider is not anywhere NEAR thread safe:
284
285 QMap<QString, QgsMapLayer *> validLayers;
286 for ( auto it = mMapLayers.constBegin(); it != mMapLayers.constEnd(); it++ )
287 {
288 if ( it.value()->isValid() )
289 validLayers[it.key()] = it.value();
290 }
291 return validLayers;
292}
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:80
QString id
Definition qgsmaplayer.h:83
#define QgsDebugError(str)
Definition qgslogger.h:57
#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.