[GIS] Duplicating layer and applying filter using PyQGIS

fields-attributeslayerspyqgis

Is there a way, using Python, to duplicate a layer in QGIS as many times as the single occurrences of a variable contained in a field and with a filter applied on the duplicated layer based on the variable itself?

An example: I have layer0 with a field0 that contains var1, var2, var3, etc. I would like the layer0 duplicated to layer1, layer2, layer3 etc. so that layer1 has a filter where field0 = var1, layer2 has a filter where field0 = var2, etc.

The idea is similar to the LayersByField plugin but instead of creating a new layer for each occurrence of a variable I wish to just duplicate the "master" layer (so to avoid unnecessary files on disk)

Best Answer

The following Python script was tested with Shape files, PostGIS layers, and SpatiaLite using QGIS 2.8.2 on Windows 7. Specify the field you want to filter in the first code line (replace rtt).

# specify field to filter
field_name = 'rtt'

# get active layer
layer = iface.activeLayer()

# get reference to the field named above
fni = layer.fieldNameIndex(field_name)
f = layer.dataProvider().fields()

# get field type, necessary to build valid SQL string
is_string = False
if f[fni].type() in [7, 10]:
    is_string = True

# get list of unique values
unique_values = layer.uniqueValues(fni)
for i in unique_values:
    # add layer to the map
    lyr_copy = iface.addVectorLayer(layer.source(), layer.name() + '_' + str(i), layer.providerType())
    # build subset string in SQL like syntax
    if is_string:
        lyr_copy.setSubsetString('"%s" = \'%s\'' % (field_name, i))
    else:
        lyr_copy.setSubsetString('"%s" = %d' % (field_name, int(i)))

ESRI file Geodatabase didn't work for me since for all field indices layer.uniqueValues(fni) returns the list of unique values of the first attribute. Thus filtering of an attribut by these values returns an empty list or the wrong result set. Maybe an issue of QGIS 2.8.2.

Related Question