[GIS] Calculating the longest distance within polygon in QGIS

distancemaximumpolygonpolyline-creationqgis

I want to calculate the "diameter" of polygons in QGIS.

The "diameter" defined as the distance between the two most distant points of the polygon.

I couldn't find a fitting solution in the field calculator. Maybe you have some ideas?

Best Answer

You can use PyQGIS to measure the distances between all vertices of each polygon and find max:

import itertools

layer = iface.activeLayer() #Click layer in tree

for feat in layer.getFeatures():
    verts = [v for v in feat.geometry().vertices()] #List all vertices
    maxdistance = max([p1.distance(p2) for p1,p2 in itertools.combinations(verts, 2)]) #Find max distance for all combinations of vertices (https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements)
    print('Polygon: {0}, max distance: {1}'.format(feat.id(), round(maxdistance,0))) #Print results

example1

To save max distances in a field:

import itertools

layer = iface.activeLayer() #Click layer in tree
field_to_save_maxdistance_in = 'maxdist' #Change maxdist to the name of your field

fields = layer.fields()
fx = fields.indexFromName(field_to_save_maxdistance_in)

with edit(layer):
    for feat in layer.getFeatures():
        verts = [v for v in feat.geometry().convexHull().vertices()] #List all vertices
        maxdistance = max([p1.distance(p2) for p1,p2 in itertools.combinations(verts, 2)]) #Find max distance for all combinations of vertices
        layer.changeAttributeValue(feat.id(), fx, maxdistance)

example2

You can also create a line layer:

import itertools

layer = iface.activeLayer() #Click layer in tree

#Create line layer
vl = QgsVectorLayer("LineString?crs={}&index=yes".format(layer.crs().authid()), "myLayer", "memory")
provider = vl.dataProvider()

#For each polygon find the two points most far apart
for feat in layer.getFeatures():
    all_points = []
    verts = [v for v in feat.geometry().vertices()] #List all vertices
    for p1,p2 in itertools.combinations(verts, 2):
        all_points.append([p1,p2])

    #Create a line feature
    pointpair_most_far_apart = max(all_points, key=lambda x: x[0].distance(x[1]))
    gLine = QgsGeometry.fromPolyline(pointpair_most_far_apart)
    f = QgsFeature()
    f.setGeometry(gLine)
    provider.addFeature(f)

QgsProject.instance().addMapLayer(vl)

enter image description here

Related Question