Contando o número de vértices do objeto na camada vetorial PyQGIS

8

Antes de tudo, quero dizer que sei que um problema semelhante foi levantado antes, mas não forneceu uma solução satisfatória.

Preciso obter o número de vértices de cada objeto na camada de linha do vetor. Baseando-se neste artigo: https://joseguerreroa.wordpress.com/2014/07/28/contar-y-extraer-nodos-vertices-para-vectoriales-de-linea-o-poligono-mediante-pyqgis/

Eu fiz 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

E, como resultado, recebo um número de vértices, mas apenas o último objeto. Acho que estou perdendo um loop while na camada (para obter um número para cada objeto), estou certo? Mas não sei como deve ficar.

Eu sei que existe o plugin 'Contador de vértices', mas ele não funciona (nem inicia) no meu caso (QGIS 2.12, Win 8.1) .E eu preciso que seja feito em Python.

A propósito, vocês não acham pessoal, que é ridiculamente difícil obter o número de vértices enquanto é tão fácil obter as coordenadas de cada vértice?

EDIT: @nwduncan (@ArMoraer também) sugeriu a correção de um recuo, e foi uma boa pista. Percebi que o console Python precisa de atualização, porque às vezes não consegue lidar com recuos. Espero que ajude outros iniciantes. O código final é:

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
fonte
1
Não estou familiarizado com pyqgis, mas posso ver no seu código que seu recurso no loop de façanha está atribuindo o objeto geometry à variável geom e, em seguida, substituindo-o pelo próximo objeto geometry sem contar as vértices. Tente recuar as linhas 6 a 15, para que elas fiquem embaixo do loop for featuer no feat.
N
Eu tentei isso antes e recebi muitos erros de 'avanço inesperado'. Mas ... porque fiquei um pouco frustrada, segui sua dica. Então, novamente, mudei o recuo e desta vez salvei-o em um novo arquivo aaa e funcionou! Eu acho que o problema foi que o console QGIS Python não é perfeito e o salvamento do código em um novo arquivo de alguma forma ajudou. Não faço ideia de como, mas foi :) Obrigado pela dica!
antonio
1
Se você é novo no Python, eu evitaria os loops while, se puder. Muito fácil de obter um loop infinito. Também QgsPoint(0,0)é um ponto válido em algumas projeções.
Nathan W

Respostas:

4

Recuo.

A primeira parte do seu código está correta, mas o restante pode ser bastante simplificado se você quiser apenas o número 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

Se você também quiser as coordenadas dos vértices, poderá escrever (apenas polilinhas):

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
fonte
Muito obrigado. O código que você escreveu funciona para a Polyline. Tentei o mesmo para MultiPolyline vertices = feature.geometry().asPolyline()para vertices = feature.geometry().asMultiPolyline()Não contar o número de vértices, mas imprimir tipo de números aleatórios (não posso ligá-la a quaisquer dados que tenho)
antonio
Ok, eu editei meu primeiro script. Agora deve funcionar para MultiPolylines.
ArMoraer
2

No QGIS 2.14, uma nova função para contar vértices está disponível no field calculator:

Calculadora de campo no QGIS 2.14

etrimaille
fonte
1

Outra abordagem será usar uma expressão definida pelo usuário. O mecanismo de expressão fará um loop na camada para você. O blog Nathans tem uma boa demonstração disso:

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
fonte