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