¿Cuáles son las funciones equivalentes de QGIS para la actualización / eliminación de fila / campo de ArcPy?

8

Estoy tratando de reprogramar algunos scripts de ArcPy a QGIS (1.8 o 2.0) y hay algunas funciones simples que quiero poder rehacer, pero desafortunadamente falta documentación en QGIS en ciertas áreas.

A saber, los tres más importantes para mí son:

Agregar campo - Agregar campo

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

Calcular gestión de campo : actualice ese campo

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

Actualizar / Eliminar filas - Actualizar / Eliminar filas según la condición (sin copiar el archivo de forma)

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

Ahora puedo iterar a través de cada característica en QGIS usando SEXTANTE y obtener su geometría que debería poder reescribir en un nuevo archivo de forma y así actualizar / eliminar una fila o campo. Comenzando con algo parecido a ...

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

pero no puedo encontrar una solución simple para esas funciones mencionadas anteriormente?

BJEBN
fuente
No estoy muy seguro de cuál es el objetivo de la última parte de su pregunta. ¿Por qué mencionas SEXTANTE? Pide un método para reescribir en un nuevo archivo de forma, pero su extracto de código no hace nada de eso.
Matthias Kuhn

Respuestas:

16

Los siguientes ejemplos se basan en la API QGIS 2.0 (próximamente a ser lanzada). Esto ha cambiado desde 1.8, por lo que la sintaxis de esta versión diferirá en algunos lugares.

El mejor recurso para soluciones compatibles con 1.8 y una explicación en profundidad para el fondo de los parámetros (también se aplica para 2.0) son el Libro de cocina PyQGIS

Asumiremos que ya tiene una referencia a una capa vectorial llamada vlobtenida por ej.

vl = iface.activeLayer()

Actas

Los siguientes ejemplos están trabajando en una transacción (localmente en caché en QGIS). Antes de comenzar la sesión de edición, debe llamar

vl.startEditing()

y terminar con

vl.commitChanges()

para escribir sus cambios en la fuente de datos. o

vl.rollBack()

para descartar los cambios

También puede trabajar directamente vl.dataProvider()y olvidarse de las declaraciones de control de transacciones. (Resultando en un comportamiento similar a la confirmación automática)

Agregar un campo

QgsVectorLayer.addAttribute (QgsField)

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

Esto solo funciona si el proveedor de datos implementa la capacidad AddAttributes. Puede verificar esto con:

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

Calcular campos

Ver esta respuesta:

¿Es posible agregar mediante programación campos calculados?

Todavía está dirigido a 1.8, por lo que en lugar de vl.select()tener que llamar al equivalente 2.0 vl.getFeatures()(ver cambios en la API de QGIS )

Actualizar filas

QgsVectorLayer.updateField (featureId, fieldIndex, value)

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

Comprobación de requisitos previos (opcional):

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

Para conocer el fieldIndex, puede usar QgsVectorLayer.pendingFields()

Editar: Vea también el comentario de NathanW que menciona el QgsVectorLayer.updateFeature( feature )método legible .

Eliminar filas

QgsVectorLayer.deleteFeature (featureId)

vl.deleteFeature( 1000 )

Comprobación de requisitos previos opcionales:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures
Matthias Kuhn
fuente
2
Usar feature[5] = 'hello'y layer.updateFeature(feature)es mejor que usar vl.updateField IMO
Nathan W
5

Así es como haría su código en 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
fuente