UPDATE: 10.04.2018
Using QGIS 3.x you can use the mapLayersByName
method from QgsProject
class in this way:
layers = QgsProject.instance().mapLayersByName('my layer name')
Since you can have several layers in QGIS with the same name in the layers panel, the method above gives you a list of matching layers.
Before accessing any element in the layer list, you should check if the list has elements. If so you can access, for instance, its first element (layer) in this way:
if layers:
layer = layers[0]
Which would be the common case of having a single layer matching the name you searched for.
For QGIS 2.x:
You would just need to make sure your layer has a name you can distinguish from others. Instead of layer = self.iface.activeLayer()
, do:
layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "YOUR_LAYER_NAME":
layer = lyr
break
If you don't trust the layer name (after all, it can be changed by the user at any time), you could try to check the layer source. If your layer is a Shapefile, you could check the path to the Shapefile, this way:
layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.source() == "/path/to/shapefile.shp":
layer = lyr
break
EDIT: As @Jakob has pointed out in comments, you can write the first block in one line:
layerList = QgsMapLayerRegistry.instance().mapLayersByName("YOUR_LAYER_NAME")
Or:
layerList = [lyr for lyr in QgsMapLayerRegistry.instance().mapLayers().values() if lyr.name() == "YOUR_LAYER_NAME"]
Anyway, you would need to check that layerList
is not empty before accessing its first element:
if layerList:
layer = layerList[0]
TL;DR
To get all features of a layer by the layer name you do not need to activate it. Just use
name = 'counties'
layer = QgsProject.instance().mapLayersByName( name )[0]
poles = layer.getFeatures()
for pole in poles:
if is_north(pole):
print('it is the north pole')
Active Layer
First of all, you do not need to care about the active layer. The active layer is the layer which is currently selected in the layer tree and therefore is nice for two things
- letting the user select a layer to operate on
- selecting a layer for quickly testing code from the python console
The second one is handy when you are developing, the first one is what all the maptools are based on: the currently selected layer (the active one) is modified, selected, deleted...
Methods to access layers
However, you seem to want to access layers not based on user input but based on something else.
Identifying layers
All layers have
- An id that needs to be unique
- A name that is not necessarily (but often) unique and can be changed by the user
- A reference (also often referred to as pointer but in python the two terms are interchangeable) that is unique and stable for the lifetime of a layer during the application run time and can be assigned to a variable (e.g.
vlayer
is a reference to the currently active layer in your example).
- Properties like the URI (table name etc.)
If you already have a reference to the layer (because you created/added it in your plugin) just use that one.
If you don't, think about what property you want to use to get access to the layer. Most likely something that is stable (the layer id is very stable for the lifetime of a project but always is different for different projects), the name is user adjustable, the table may depend on the data source.
Accessing layers
There is the map layer registry which lets you access layers. It manages references to all layers. This used to be called QgsMapLayerRegistry, but that is no longer available in QGIS 3, so QgsProject can be used instead.
registry = QgsProject.instance()
If you have the layer id go with
layer = registry.mapLayer( id )
If you have the layer name
layer = registry.mapLayersByName( name )[0] # The method returns a list since it can be ambiguous, 0 picks the first entry in the list
If you have something else you have to write your own code:
for lyr in registry.mapLayers().values():
if lyr.dataProvider().dataSourceUri().table() == 'mytable':
layer = lyr
break
Or a shorthand that does the same and makes you feel more hacker'ish but will make the people who will have to maintain the code later on cost some extra time to decipher:
layer = (l for l in registry.mapLayers().values() if l.dataProvider().dataSourceUri().table() == 'mytable').next()
Best Answer
Here is how you could do this:
Simply replace
'line'
with your keyword to search for. This example will iterate over all layers having the letter sequenceline
in it.Some more examples how to apply a filter more than once: