Contando el número de vértices del objeto en la capa vectorial PyQGIS

8

En primer lugar, quiero decir que sé que se planteó un problema similar antes, pero no proporcionó una solución satisfactoria.

Necesito obtener el número de vértices de cada objeto en la capa de línea vectorial. Basándose en este artículo: https://joseguerreroa.wordpress.com/2014/07/28/contar-y-extraer-nodos-vertices-para-vectoriales-de-linea-o-poligono-mediante-pyqgis/

Hice este código:

layer = qgis.utils.iface.activeLayer()
feat = layer.getFeatures()
for feature in feat:
    geom = feature.geometry()

n = 1
ver = geom.vertexAt(0)
points=[]

while(ver != QgsPoint(0,0)):
    n +=1
    points.append(ver)
    ver = geom.vertexAt(n)

print n

Y como resultado obtengo el número de vértices, pero solo del último objeto. Supongo que me falta uno mientras bucle en la capa (para obtener el número de cada objeto), ¿estoy en lo cierto? Pero no sé cómo debería verse.

Sé que en mi caso existe el complemento 'Contador de vértices ", pero no funciona (ni siquiera se inicia) (QGIS 2.12, Win 8.1). Y necesito que se haga en Python.

Por cierto, ¿no les parece, chicos, que es ridículamente difícil obtener el número de vértices mientras que es tan fácil llegar a las coordenadas de cada vértice?

EDITAR: @nwduncan (@ArMoraer también) sugirió arreglar una sangría, y fue una buena pista. Noté que la consola Python necesita refresco, porque a veces no puede manejar las sangrías. Espero que ayude a otros principiantes. El código final es:

layer = qgis.utils.iface.activeLayer()
feat = layer.getFeatures()
for feature in feat:
    geom = feature.geometry()
    n   = 1
    ver = geom.vertexAt(0)
    points=[]

    while(ver != QgsPoint(0,0)):
        n +=1
        points.append(ver)
        ver=geom.vertexAt(n)

    print n
antonio
fuente
1
No estoy familiarizado con pyqgis, pero puedo ver en su código que su característica en el bucle feat está asignando el objeto de geometría a la variable geom y luego sobrescribiéndola con el siguiente objeto de geometría sin contar las verticies. Intente sangrar las líneas 6-15 para que se asienten debajo del bucle for featuer in feat.
nwduncan
Lo intenté antes, y obtuve muchos errores de 'sangría inesperada'. Pero ... porque estaba un poco frustrado, seguí tu consejo. Así que de nuevo, cambié la sangría y esta vez la guardé en un nuevo archivo y ¡funcionó! Creo que el problema fue que la consola QGIS Python no es perfecta y de alguna manera fue útil guardar el código en un nuevo archivo. No tengo idea de cómo, pero lo hizo :) ¡Gracias por la pista!
antonio
1
Si solo eres nuevo en Python, evitaría los bucles while si puedes. Muy fácil entrar en un bucle infinito. También QgsPoint(0,0)es un punto válido en algunas proyecciones.
Nathan W

Respuestas:

4

Sangría.

La primera parte de su código es correcta, pero el resto puede simplificarse enormemente si solo desea la cantidad de vértices:

layer = qgis.utils.iface.activeLayer()
feat = layer.getFeatures()

for feature in feat:
    if feature.geometry().isMultipart(): # new part for multipolylines
        vertices = feature.geometry().asMultiPolyline()
        print [len(v) for v in vertices]
    else:
        vertices = feature.geometry().asPolyline()
        n = len(vertices)
        print n

Si también desea las coordenadas de los vértices, puede escribir (solo polilíneas):

layer = qgis.utils.iface.activeLayer()
feat = layer.getFeatures()

for feature in feat:
    vertices = feature.geometry().asPolyline()
    points = []

    for v in vertices:
        points.append(v)
ArMoraer
fuente
Muchas gracias. El código que escribió funciona para Polyline. Intenté lo mismo para MultiPolyline vertices = feature.geometry().asPolyline()para vertices = feature.geometry().asMultiPolyline()que no cuente el número de vértices, pero imprime números aleatorios (no puedo vincularlo con los datos que tengo)
antonio
Ok, edité mi primer guión. Ahora debería funcionar para MultiPolylines.
ArMoraer
2

En QGIS 2.14, una nueva función para contar vértices está disponible en field calculator:

Calculadora de campo en QGIS 2.14

etrimaille
fuente
1

Otro enfoque será utilizar una expresión definida por el usuario. El motor de expresión repetirá la capa por ti. El blog de Nathans tiene una buena demostración sobre eso:

http://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/

from qgis.utils import qgsfunction
from qgis.core import QGis

@qgsfunction(0, "Python")
def vertices(values, feature, parent):
    """
        Returns the number of vertices for a features geometry
    """
    count = None
    geom = feature.geometry()
    if geom is None: return None
    if geom.type() == QGis.Polygon:
        count = 0
        if geom.isMultipart():
          polygons = geom.asMultiPolygon()
        else:
          polygons = [ geom.asPolygon() ]
        for polygon in polygons:
          for ring in polygon:
            count += len(ring)
    return count
Jakob
fuente