Geographic Information Systems Asked on March 2, 2021
I wan’t to filter features of a Shapefile
layer from a user’s selection with PyQGIS
. When I select less than 30 features with a method like fid=1 or fid=2 or fid=3 ...
, everything works fine but when I select over 30 features filter doesn’t work and return me all the features of the layer. If I try a filter like fid >= 1 and fid <=150
(for example), it works. But it doesn’t help for lists of unfollowing ids. I’m using QGIS 3.10.2
.
Is there something wrong with this ? Does filters have size limits ? Is there a better way to filter features ?
# Layer
layer = iface.activeLayer()
features = layer.selectedFeatures()
# List ID of selected features
l = []
for feature in features:
l.append(feature.id())
# Build arguments for the query
index = 0
query = []
prefix = 'fid='
while index < len(l)-1:
query.append(prefix)
query.append(l[index])
query.append(' or ')
index+=1
# Last element of the list
query.append(prefix)
query.append(l[index])
# Query
fullQuery = str(query).strip('[]').replace(',', '').replace("'", "")
# Filter
layer.setSubsetString(fullQuery)
I don't know if this solves your question, but in general, instead of
fid = 1 or fid = 2 or...
you should use
fid in (1,2,...)
It improves code readability.
Correct answer by Germán Carrillo on March 2, 2021
I am not sure what is wrong in your code but I have prepared a simple example that applies a filter based on features' id following the same logic of your example and it works fine with large number of features (e.g., 88 in this example). I am using QGIS 3.10.11:
# 1) Load a vector layer from natural earth database and import it to the project
gpkg_address = r"c:%DATA_PAATH%natural_earth_vector_50m_10m.gpkg"
lyr_name = "natural_earth_vector_50m_10m ne_10m_admin_0_countries"
lyr = QgsVectorLayer("{}|{}".format(gpkg_address, lyr_name), lyr_name, "ogr")
QgsProject.instance().addMapLayer(lyr)
# 2) Count the number of overall features, and select only the features with population over 10 millions
n_feat_tot = lyr.featureCount()
s_pop = "POP_EST"
lyr.selectByExpression('"{}" > {}'.format(s_pop, 10e6))
n_feat_sel = lyr.selectedFeatureCount()
print("Total features: {}, selected features: {}".format(n_feat_tot, n_feat_sel))
# Total features: 255, selected features: 88
# 3) Get the id of selected features. Remove the selection and then prepare the query. Finally, apply the query to the layer and count the remaining features.
feat_id = lyr.selectedFeatureIds()
lyr.removeSelection()
query = [" or ".join(["fid={}".format(el) for el in feat_id])]
lyr.setSubsetString(query[0])
n_feat_subset = lyr.featureCount()
print("Subset features: {}".format(n_feat_subset))
# Subset features: 88
The input data are from Natural Earth database. I hope this helps.
Answered by fastest on March 2, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP