Фильтровать объекты по их атрибутам, используя Python?

16

Как получить объекты по их атрибутам (аналогично Iqueryfilter в arcobjects) в Qgis с использованием python? Вместо того, чтобы получать все функции и фильтровать их вручную, есть ли возможность использовать предложение where для его фильтрации?

Пример: у меня есть имя поля под названием «Графства». Он имеет более пятидесяти тысяч функций. То есть невозможно получить все функции и отфильтровать их из-за большого количества времени. Таким образом, я могу запросить его, используя iqueryfilter.whereclause = 'Counties = Norwich' в arcobjects. Подобная вещь мне нужна в PyQgis.

Venkat
источник
1
@NathanW да, ты прав. мне нужно только вернуть данные, используя запрос со слоя. Не могли бы вы дать мне пример в Pyqgis?
Венкат
@NathanW Привет, я понял. он работает как определение запроса в ArcGIS. посмотрите этот пример. t = outputLayer.setSubsetString ('UniqID =' + inputFeat.attribute ("UniqID"). toPyObject ()), если t == True: outputProvider = outputLayer.dataProvider () print outputProvider.featureCount (), т.е. он будет возвращать только запрос удовлетворены данными
венкат
@venkat, где в QGIS вы помещаете запрос? Благодарю.
ianbroad

Ответы:

12

Механизм выражений QGIS может сделать это, используя QgsFeatureRequest.setFilterExpression( unicode )метод (начиная с QGIS 2.2)

request = QgsFeatureRequest().setFilterExpression( u'"Counties" = \'Norwich\'' )
it = l.getFeatures( request )

Начиная с QGIS 2.10, даже возможно, что фильтрация таким способом даст вам дополнительную производительность по сравнению с другими типами фильтрации (например, реализациями на Python).

В основном это применимо, если выполняются следующие три условия:

  • Вы используете слой с провайдером postgis. На данный момент (2.16) это реализовано гораздо больше, чем просто провайдер postgis (пространственный, ogr, oracle ...).
  • Ваше выражение не слишком сложно (вещи , как >, =, IN, NOT NULL... поддерживаются)
  • Вы включили эту функцию в Настройки> Параметры> Источники данных> Обработка источников данных> Выполнить выражение на стороне сервера postgres
  • Повышение производительности является оптимальным при наличии соответствующих индексов в таблицах базы данных.

С QGIS 3.0 даже можно просто сделать

features = l.getFeatures('"Counties" = \'Norwicth\'')
Матиас Кун
источник
1

В этом посте, который можно считать ответом на дублирующий вопрос, подробно рассказывается, как извлечь все атрибуты из слоя. Автор описывает процесс, который вы ищете, как фильтрацию данных вручную после их возвращения. Это довольно полный справочник, и его ссылка действительно поможет вам.

Том
источник
2
Это не дублирующий вопрос. я не хочу получать все атрибуты из слоя. Сначала отфильтруйте его, а затем я хочу получить функции, которые подпадают под критерии фильтра. т.е. производительность намного лучше.
Венкат
1

С помощью SQL-запроса это также легко возможно с ogr. Вы можете выполнить этот код, например, в консоли Python QGIS или в автономном скрипте.
Пример :

from osgeo import ogr

path = "path to your shapefile.shp"
ID = "FieldID" # For instance 'Countries' 
datasource = ogr.Open(str(path)) # your datasource

layer = datasource.GetLayer(0) # Import layer 0 --> only works with shapefiles
layerName = str( layer.GetName() )# Save the Layersname first

# Do the sql query
# Selects all features from a layer datasource where Field Countries is equal to 'Germany'
layers = datasource.ExecuteSQL("SELECT * FROM %s WHERE %s = '%s'" % (layerName, ID, 'Germany') )
res = []
for i in range(0,layers.GetFeatureCount()):
   f = layers.GetFeature(i)
   g = f.GetGeometryRef()
   res.append(g.Area()) 

# res now contains the measured area of each feature where the attribute ID has the value 'Germany'
кроншнеп
источник
0

Задание фильтров SQL пока не поддерживается с использованием API QGIS начиная с версии 1.9.

Как я понял из этой статьи в списке рассылки , поддержка «SQL собственного провайдера» будет только в будущем выпуске.

Винаян
источник