8

First of all, I want to say that I know that similar issue was raised before, but it didn't provide satisfying solution.

I need to get the number of vertices of every object on vector line layer. Basing on this article: https://joseguerreroa.wordpress.com/2014/07/28/contar-y-extraer-nodos-vertices-para-vectoriales-de-linea-o-poligono-mediante-pyqgis/

I did this code:

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

And as the result I get number of vertices, but only of the last object. I guess I'm missing one while loop on the layer (to get number for every object), am I right? But I don't know how it should look.

I know that there is 'Vertices counter" plugin, but it doesn't work (doesn't even start) in my case (QGIS 2.12, Win 8.1). And I need it to be done in Python.

By the way, don't you think guys, that it is ridiculously hard to get number of vertices while it is so easy to get to coordinates of every vertex?

EDIT: @nwduncan ( @ArMoraer too) suggested fixing up an indentation, and it was good clue. I noticed that Python console need refreshment, because sometimes it can't handle indentations. Hope it will help other beginners. The final code is:

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
  • 1
    I'm not familiar with pyqgis, but I can see from your code that your feature in feat loop is assigning the geometry object to the geom variable and then overwriting it with the next geometry object without actually counting the verticies. Try indenting lines 6-15 so they sit under the for featuer in feat loop. – nwduncan Feb 24 '16 at 21:35
  • I tried it before, and I got a lot of 'unexpected indent' errors. But... because I was little bit frustrated I followed your tip. So again, I changed the indentation and this time I saved it to new file aaaand it worked! I think the problem was that QGIS Python console is not perfect and saving code to new file somehow helped. No idea how, but it did :) Thanks for the clue! – antonio Feb 24 '16 at 22:37
  • 1
    If you are only new to Python I would avoid the while loops if you can. Very easy to get yourself into a infinite loop. Also QgsPoint(0,0) is a valid point in some projections. – Nathan W Feb 25 '16 at 10:59
4

Indentation.

The first part of your code is correct, but the rest can be greatly simplified if you just want the number of vertices:

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

If you also want the coordinates of the vertices, then you can write (polylines only):

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

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

    for v in vertices:
        points.append(v)
| improve this answer | |
  • Thanks a lot. The code you wrote works for Polyline. I tried the same for MultiPolyline vertices = feature.geometry().asPolyline() to vertices = feature.geometry().asMultiPolyline() It doesn't count number of vertices but print kind of random numbers (I can't link it to any data I have) – antonio Feb 25 '16 at 11:53
  • Ok, I edited my first script. It should now work for MultiPolylines. – ArMoraer Feb 25 '16 at 12:10
2

In QGIS 2.14, a new function to count vertices is available in the field calculator :

Field calculator in QGIS 2.14

| improve this answer | |
1

Another approach will be to use a user defined expression. The expression engine will loop the layer for you. Nathans blog has a good demo on that:

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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.