Как изменить значение атрибута, используя QgsFeature в PyQGIS?

12

Я хотел бы обновить один атрибут функции. Тем не менее, я не знаю, чтобы обновить его с помощью объекта функции. Я должен использовать поставщика данных, чтобы обновить его.

layers = QgsMapLayerRegistry.instance().mapLayersByName('my_line') 
layer = layers[0]
dp = layer.dataProvider()
it = dp.getFeatures()

for i in range(0, dp.featureCount()):
  feat = it.next()
  attrs = { 2 : 30 }
  layer.dataProvider().changeAttributeValues({ feat.id() : attrs })

Могу ли я изменить значение атрибута, используя QgsFeatureобъект?

Кроме того, возможно ли зацикливание с использованием объекта итератора?

wannik
источник
Как я могу изменить значения без использования индекса? Я хотел бы изменить значения, назвав их имя поля. Это было бы намного удобнее. Большое спасибо! Приветствия Роберт
Роберт Б.К.
Просто используйте, my_index = layer.fieldNameIndex("my_field_name")чтобы получить индекс.
Герман Каррильо
в этом случае я не могу добавить в поле строку, как я могу сделать?
Хамед Макиан
Если у вас есть новый вопрос, задайте его, нажав кнопку « Задать вопрос» . Включите ссылку на этот вопрос, если это помогает обеспечить контекст. - Из Обзора
Дан С
Хамед, добро пожаловать в ГИС Stack Exchange! Поскольку на этот вопрос уже дан ответ, задайте его как новый отдельный вопрос здесь: gis.stackexchange.com/questions/ask .
cm1

Ответы:

17

Отвечая на два ваших вопроса:

  1. Вы можете изменить значения вашего объекта из layerобъекта, нет необходимости доступа к dataProvider().

  2. Да, вы можете использовать итератор в forцикле.

Проверьте код ниже:

layers = QgsMapLayerRegistry.instance().mapLayersByName('my_line') 
layer = layers[0]
it = layer.getFeatures()

layer.startEditing()
for feat in it:
  layer.changeAttributeValue(feat.id(), 2, 30)

layer.commitChanges()

Это обновляет значение третьего поля (индекс 2) до 30 для всех объектов слоя.


Примечание. Как вы указали, по какой-то причине объект QgsFeature не может обновить значения функций, хотя API говорит, что это возможно.

Герман Каррильо
источник
5

Да, но вы должны знать индекс поля:

QgsFeature::setAttribute(int field,const QVariant & attr )  

Вы можете получить поля, используя, QgsFeature::fieldsа затем перебирать их, пока не найдете то, что вам нужно, или QgsFeature::attribute(const QString & name )найти индекс поля по имени.

Причина для QVariant заключается в том, что setAttribute может принимать типы Integer, Float, Date и Text. QgsFeature.attribute (name) возвращает вариант также типа int, если атрибут найден, и что-то еще, если он не может быть найден. Помните об этом в своем коде. Будет гарантирован блок try..except, попробуйте преобразовать его в int, кроме случаев, когда type не является int.

Возможно, ваша функция не поддерживает этот метод. Другой метод, который я использовал, это QgsVectorLayer::changeAttributeValue:

self.canvas.currentLayer().changeAttributeValue(UpdateFeatureID,FieldToUpdate,self.CurrentWidget.text(),True)

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

Майкл Стимсон
источник
Я пытался, feat.setAttribute(1, QVariant(20))но система сказала TypeError: PyQt4.QtCore.QVariant представляет сопоставленный тип и не может быть
создан
feat.setAttribute (1, 20) - это то, как я делал это раньше. То есть в атрибуте 1 указано значение «20».
Майкл Стимсон,
Я пытался, feat.setAttribute(1, 20)но значения не меняются. Тем не менее, я могуprint(feat.attributes()[1])
wannik
Смотрите правки, возможно, вам нужно вызвать QgsVectorLayer.changeAttributeValue, который должен использовать драйвер для внесения изменений.
Майкл Стимсон