summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLex Neva <github.com@lexneva.name>2023-05-29 21:01:55 -0400
committerKaalleen <reni@allenka.de>2023-07-01 08:23:46 +0200
commit81e84db8a2ab7893cc5984e1da7843e248734d15 (patch)
tree7447d755a0647ad96a57cf6285ae99e55900a575 /lib
parentacc2b1a7fbf519cbe4aaed2383211d5ca76a0996 (diff)
avoid losing start and end of path when clamping
Diffstat (limited to 'lib')
-rw-r--r--lib/utils/clamp_path.py15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/utils/clamp_path.py b/lib/utils/clamp_path.py
index e5ef78d8..f1fc7765 100644
--- a/lib/utils/clamp_path.py
+++ b/lib/utils/clamp_path.py
@@ -1,6 +1,6 @@
from shapely.geometry import LineString, Point as ShapelyPoint, MultiPolygon
from shapely.prepared import prep
-from .geometry import Point, ensure_multi_line_string
+from .geometry import Point, ensure_geometry_collection
def path_to_segments(path):
@@ -69,20 +69,25 @@ def clamp_path_to_polygon(path, polygon):
Description: https://gis.stackexchange.com/questions/428848/clamp-linestring-to-polygon
"""
- path = LineString(path)
+ start = path[0]
+ end = path[-1]
# This splits the path at the points where it intersects with the polygon
# border and returns the pieces in the same order as the original path.
- split_path = ensure_multi_line_string(path.difference(polygon.boundary))
+ split_path = ensure_geometry_collection(LineString(path).difference(polygon.boundary))
- # contains() checks can fail without this.
+ # Add the start and end points to avoid losing part of the path if the
+ # start or end coincides with the polygon boundary
+ split_path = [ShapelyPoint(start), *split_path.geoms, ShapelyPoint(end)]
+
+ # contains() checks can fail without the buffer.
buffered_polygon = prep(polygon.buffer(1e-9))
last_segment_inside = None
was_inside = False
result = []
- for segment in split_path.geoms:
+ for segment in split_path:
if buffered_polygon.contains(segment):
if not was_inside:
if last_segment_inside is not None: