2

I'm having a a GeoDataFrame of polygons. I want to find the maximum length of a straight line that can fit inside each polygon. You could call this the characteristic length of the polygon. The length I'm looking for is shown in below image. I took the image from Getting max length of polygon and average width using PostGIS, but they use PostGIS and I would like to do this with Python GeoPandas.

If this is possible with GeoPandas, could somebody explain how to do this?

I tried polygondf.length, but this gives me the length of the perimeter, which is not what I'm looking for.

Maximum length in Polygon

0

1 Answer 1

5

An approximation since it will measure distances between vertices:

import geopandas as gpd
from shapely import LineString, segmentize
from itertools import combinations

df = gpd.read_file(r"/home/bera/Desktop/gistest/nature_sample.shp")

#Create a column of densified geometry (vertices inserted every x distance).
#  Shorter length=more accurate longest line but longer computation time. Start with a high value and lower it,
#   until the accuracy of the longest line is acceptable. Otherwise the script will be very slow for large datasets.

df["densified_geometry"] = df.apply(
    lambda x: segmentize(geometry=x.geometry, max_segment_length=100), axis=1) #Insert extra vertices every 100 m.

def longestline(polygongeometry):
    """A function which finds the approximate longest line in an input polygon geometry"""
    #List all coordinates in the polygon exterior
    all_vertex_coordinates = list(polygongeometry.exterior.coords)
    #Create line between all combinations of them
    all_lines = [LineString(vertexpair) for vertexpair in combinations(all_vertex_coordinates, 2)]
    #Intersect/clip each of them with the input polygon geometry
    clipped = [polygongeometry.intersection(line) for line in all_lines]
    #Extract the lines, other possible intersection outputs can be geometry collections and points
    clipped = [line for line in clipped if isinstance(line, LineString)]
    #Find the longest line    
    longest_line = max(clipped, key=lambda x: x.length)
    return longest_line

df["longestline"] = df.densified_geometry.apply(longestline) #Apply the function
ax = df.plot(figsize=(15,20), zorder=1, color="honeydew", edgecolor="darkgreen")
df.longestline.plot(ax=ax, zorder=2, color="magenta")

enter image description here

0

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