Quais são as funções equivalentes do QGIS para Atualização / Exclusão de Linha / Campo do ArcPy?

8

Estou tentando reprogramar alguns scripts do ArcPy para o QGIS (1.8 ou 2.0) e há algumas funções simples que desejo refazer, mas infelizmente a documentação do QGIS está ausente em determinadas áreas.

Nomeadamente, os três mais importantes para mim são:

Adicionar campo - Adicionar campo

arcpy.AddField_management(Feature, "ID", "SHORT")

Calcular Gerenciamento de Campo - Atualize esse campo

arcpy.CalculateField_management(Feature,"ID","!FID!")

Atualizar / excluir linhas - Atualizar / excluir linhas com base na condição (sem copiar o shapefile)

keep = ["Bob","Janet","John","Mike"]
Counter = 0
rows = arcpy.UpdateCursor(Feature)

for row in rows:
    if row.Name in keep:
        row.ID = Counter
        rows.updateRow(row)
    else:
        rows.deleteRow(row)
    Counter += 1

Agora eu posso percorrer cada recurso do QGIS usando o SEXTANTE e obter sua geometria que eu poderia reescrever em um novo shapefile e, assim, atualizar / excluir uma linha ou campo. Começando com algo como ...

layer = st.getobject(Polygon)
features = st.getfeatures(layer)
for f in features:
    f.geometry().asPolygon()

mas não consigo encontrar uma solução simples para as funções mencionadas acima?

BJEBN
fonte
Não sei ao certo qual é o objetivo da última parte da sua pergunta. Por que você menciona o SEXTANTE? Você pede um método para reescrever em um novo shapefile, mas seu trecho de código não faz nada desse tipo.
Matthias Kuhn

Respostas:

16

Os exemplos a seguir são baseados na API QGIS 2.0 (que será lançada em breve). Isso mudou desde a versão 1.8; portanto, a sintaxe desta versão será diferente em alguns lugares.

O melhor recurso para soluções compatíveis com 1.8 e explicações detalhadas sobre o histórico de parâmetros (também aplicável ao 2.0) são o Cookbook do PyQGIS

Vamos supor que você já tenha uma referência a uma camada vetorial chamada vlobtida por

vl = iface.activeLayer()

Transações

Os exemplos a seguir estão trabalhando em uma transação (armazenada em cache localmente no QGIS). Antes de iniciar a sessão de edição, você deve ligar

vl.startEditing()

e termine com

vl.commitChanges()

para escrever suas alterações na fonte de dados. ou

vl.rollBack()

para descartar as alterações

Você também pode trabalhar diretamente vl.dataProvider()e esquecer as instruções de controle de transação. (Resultando em comportamento semelhante à confirmação automática)

Adicionando um campo

QgsVectorLayer.addAttribute (QgsField)

from PyQt4.QtCore import QVariant
vl.addAttribute( QgsField( 'fieldname', QVariant.String ) )

Isso funciona apenas se o provedor de dados implementar o recurso AddAttributes. Você pode verificar isso com:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Calcular campos

Veja esta resposta:

É possível adicionar programaticamente campos calculados?

O objetivo ainda é o 1.8, então, em vez de vl.select()você precisar chamar o equivalente a 2.0 vl.getFeatures()(consulte Alterações na API do QGIS )

Atualizar linhas

QgsVectorLayer.updateField (featureId, fieldIndex, value)

vl.updateField( 1000, 5, 'hello' )

Verificação de pré-requisitos (opcional):

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Para conhecer o fieldIndex, você pode usar QgsVectorLayer.pendingFields()

Edit: Veja também o comentário de NathanW, que menciona o QgsVectorLayer.updateFeature( feature )método bem legível .

Excluir linhas

QgsVectorLayer.deleteFeature (featureId)

vl.deleteFeature( 1000 )

Verificação opcional de pré-requisitos:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures
Matthias Kuhn
fonte
2
Usando feature[5] = 'hello'e layer.updateFeature(feature)é melhor, em seguida, utilizando vl.updateField IMO
Nathan W
5

É assim que você faria seu código no PyQGIS:

keep = ["Bob","Janet","John","Mike"]

for counter, feature in enumerate(layer.getFeatures()):
    if feature['Name'] in keep:
        feature['ID'] = counter
        layer.updateFeature(feature)
    else:
        layer.deleteFeature(feature.id())
Nathan W
fonte