QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 "qgsmaplayer.h"
20#include "qgslogger.h"
21#include <QList>
22
24 : QObject( parent )
25{}
26
28{
30}
31
33{
34 return mMapLayers.size();
35}
36
38{
39 int i = 0;
40 const QList<QgsMapLayer *> cLayers = mMapLayers.values();
41 for ( const auto l : cLayers )
42 {
43 if ( l->isValid() )
44 i++;
45 }
46 return i;
47}
48
49QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const
50{
51 return mMapLayers.value( layerId );
52}
53
54QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const
55{
56 QList<QgsMapLayer *> myResultList;
57 const auto constMMapLayers = mMapLayers;
58 for ( QgsMapLayer *layer : constMMapLayers )
59 {
60 if ( layer->name() == layerName )
61 {
62 myResultList << layer;
63 }
64 }
65 return myResultList;
66}
67
68QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers( const QList<QgsMapLayer *> &layers, bool takeOwnership )
69{
70 QList<QgsMapLayer *> myResultList;
71 const auto constLayers = layers;
72 for ( QgsMapLayer *myLayer : constLayers )
73 {
74 if ( !myLayer )
75 {
76 QgsDebugMsg( QStringLiteral( "Cannot add null layers" ) );
77 continue;
78 }
79 // If the layer is already in the store but its validity has flipped to TRUE reset data source
80 if ( mMapLayers.contains( myLayer->id() ) && ! mMapLayers[myLayer->id()]->isValid() && myLayer->isValid() && myLayer->dataProvider() )
81 {
82 mMapLayers[myLayer->id()]->setDataSource( myLayer->dataProvider()->dataSourceUri(), myLayer->name(), myLayer->providerType(), QgsDataProvider::ProviderOptions() );
83 }
84 //check the layer is not already registered!
85 if ( !mMapLayers.contains( myLayer->id() ) )
86 {
87 mMapLayers[myLayer->id()] = myLayer;
88 myResultList << mMapLayers[myLayer->id()];
89 if ( takeOwnership )
90 {
91 myLayer->setParent( this );
92 }
93 connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted );
94 emit layerWasAdded( myLayer );
95 }
96 }
97 if ( !myResultList.isEmpty() )
98 {
99 emit layersAdded( myResultList );
100 }
101 return myResultList;
102}
103
105QgsMapLayerStore::addMapLayer( QgsMapLayer *layer, bool takeOwnership )
106{
107 QList<QgsMapLayer *> addedLayers;
108 addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer, takeOwnership );
109 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
110}
111
112void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds )
113{
114 QList<QgsMapLayer *> layers;
115 const auto constLayerIds = layerIds;
116 for ( const QString &myId : constLayerIds )
117 {
118 layers << mMapLayers.value( myId );
119 }
120
122}
123
124void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers )
125{
126 if ( layers.isEmpty() )
127 return;
128
129 QStringList layerIds;
130 QList<QgsMapLayer *> layerList;
131
132 const auto constLayers = layers;
133 for ( QgsMapLayer *layer : constLayers )
134 {
135 // check layer and the store contains it
136 if ( layer && mMapLayers.contains( layer->id() ) )
137 {
138 layerIds << layer->id();
139 layerList << layer;
140 }
141 }
142
143 if ( layerIds.isEmpty() )
144 return;
145
146 emit layersWillBeRemoved( layerIds );
147 emit layersWillBeRemoved( layerList );
148
149 const auto constLayerList = layerList;
150 for ( QgsMapLayer *lyr : constLayerList )
151 {
152 const QString myId( lyr->id() );
153 emit layerWillBeRemoved( myId );
154 emit layerWillBeRemoved( lyr );
155 mMapLayers.remove( myId );
156 if ( lyr->parent() == this )
157 {
158 delete lyr;
159 }
160 emit layerRemoved( myId );
161 }
162
163 emit layersRemoved( layerIds );
164}
165
166void QgsMapLayerStore::removeMapLayer( const QString &layerId )
167{
168 removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) );
169}
170
172{
173 if ( layer )
174 removeMapLayers( QList<QgsMapLayer *>() << layer );
175}
176
178{
179 if ( !layer )
180 return nullptr;
181
182 if ( mMapLayers.contains( layer->id() ) )
183 {
184 emit layersWillBeRemoved( QStringList() << layer->id() );
185 emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
186 emit layerWillBeRemoved( layer->id() );
187 emit layerWillBeRemoved( layer );
188
189 mMapLayers.remove( layer->id() );
190 layer->setParent( nullptr );
191 emit layerRemoved( layer->id() );
192 emit layersRemoved( QStringList() << layer->id() );
193 return layer;
194 }
195 return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
196}
197
199{
200 emit allLayersRemoved();
201 // now let all observers know to clear themselves,
202 // and then consequently any of their map legends
203 removeMapLayers( mMapLayers.keys() );
204 mMapLayers.clear();
205}
206
208{
209 if ( !other || other == this )
210 return;
211
212 Q_ASSERT_X( other->thread() == thread(), "QgsMapLayerStore::transferLayersFromStore", "Cannot transfer layers from store with different thread affinity" );
213
214 const QMap<QString, QgsMapLayer *> otherLayers = other->mapLayers();
215 QMap<QString, QgsMapLayer *>::const_iterator it = otherLayers.constBegin();
216 for ( ; it != otherLayers.constEnd(); ++it )
217 {
218 QgsMapLayer *layer = other->takeMapLayer( it.value() );
219 if ( layer )
220 addMapLayer( layer );
221 }
222}
223
224void QgsMapLayerStore::onMapLayerDeleted( QObject *obj )
225{
226 const QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );
227
228 if ( !id.isNull() )
229 {
230 QgsDebugMsg( QStringLiteral( "Map layer deleted without unregistering! %1" ).arg( id ) );
231 mMapLayers.remove( id );
232 }
233}
234
235QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const
236{
237 return mMapLayers;
238}
239
240QMap<QString, QgsMapLayer *> QgsMapLayerStore::validMapLayers() const
241{
242 QMap<QString, QgsMapLayer *> validLayers;
243 for ( const auto &id : mMapLayers.keys() )
244 {
245 if ( mMapLayers[id]->isValid() )
246 validLayers[id] = mMapLayers[id];
247 }
248 return validLayers;
249}
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:73
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Setting options for creating vector data providers.