I have a Multipolygon and I want to find the longest line in each polygon in Multipolygon in shapely. How do I find the largest line that can lie within a polygon in Multipolygon?
edit: I have understood the logic but facing difficulty in implementation.
- The longest line must pass through two vertices of the polygon( reference - ref1, ref2, ref3
- We iterate though each
polygoninmultipolygon - for each
polygonwe iterate through all pair ofvertices(points) of thepolygon - for each pair of
vertices, we find theline( extending both sides indefinitely ) joining thevertexpairs - for each
lineformed, we traverse alledges( line segments ) and check if thelineintersects theedge - we store all intersection
pointsin an arrayintersection_points[] - for each pair of
pointsinintersection_points[]we form alinesegment and check if it lies entirely within the polygon, if it does and its length is grater thanmax_lengththen we update max_length
Image illustrations is available in the reference links - ref1, ref2, ref3
Pseudocode -
for polygon in multipolygon {
for point1 in polygon {
for point2 in polygon {
if point1 == point2 {
continue
}
line = makeLine(point1,point2)
intersection_points = []
for edge in polygon {
if line_intersects_edge(line,edge) {
intersection_points.insert( intersection_point(line,edge) )
}
}
}
}
}
max_len = 0
for intersection_pt1 in intersection_points {
for intersection_pt2 in intersection_points {
if intersection_pt1 != intersection_pt2 {
line_segment = make_line_segment(intersection_pt1,intersection_pt2)
if line_segment.lies_within(polygon) {
max_len = max( max_len, line_segment.length() )
}
}
}
}
The python code is not working though, any help would be highly appreciated!
from shapely.geometry import MultiPolygon, Polygon, LineString, Point
def line_intersects_edge(line, edge):
# Implement a function to check if a line intersects with an edge
return line.intersects(edge)
def intersection_point(line, edge):
# Implement a function to find the intersection point between a line and an edge
return line.intersection(edge)
def make_line_segment(point1, point2):
# Implement a function to create a line segment from two points
return LineString([point1, point2])
multipolygon = MultiPolygon(
[
Polygon([(7, 10), (8, 11), (9, 11), (8, 10), (7, 9.5), (7, 10)]),
Polygon([(9.5, 8.5), (10, 9), (10, 10), (11, 9), (9.5, 8.5)]),
]
)
max_len = 0
# Iterate over each polygon in the multipolygon
for polygon in multipolygon.geoms:
# Iterate over each point in the polygon
for point1 in polygon.exterior.coords:
# Iterate over each point in the polygon again
for point2 in polygon.exterior.coords:
# Skip if points are the same
if point1 == point2:
continue
# Create a line from the two points
line = LineString([Point(point1), Point(point2)])
# Find intersection points
intersection_points = []
for edge in polygon.exterior.coords[:-1]:
if line_intersects_edge(line, LineString([edge, polygon.exterior.coords[polygon.exterior.coords.index(edge) + 1]])):
intersection_points.append(intersection_point(line, LineString([edge, polygon.exterior.coords[polygon.exterior.coords.index(edge) + 1]])))
# Iterate over intersection points
for intersection_pt1 in intersection_points:
for intersection_pt2 in intersection_points:
if intersection_pt1 != intersection_pt2:
# Create a line segment
line_segment = make_line_segment(intersection_pt1, intersection_pt2)
# Check if line segment lies within the polygon
if line_segment.within(polygon):
max_len = max(max_len, line_segment.length)
print("Max length:", max_len)
This code does the job. I have tested it with a few complex test cases and it is giving valid answer