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

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Jordy W
  • 73
  • 5

1 Answers1

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

BERA
  • 72,339
  • 13
  • 72
  • 161