cleanup geometry cache and improve cut_polgon_with_line speed again
This commit is contained in:
parent
b63ab7d4e4
commit
31886d829d
1 changed files with 19 additions and 5 deletions
|
@ -1,5 +1,6 @@
|
|||
import math
|
||||
from collections import deque, namedtuple
|
||||
from contextlib import suppress
|
||||
from itertools import chain
|
||||
from typing import List, Sequence, Union
|
||||
|
||||
|
@ -9,7 +10,6 @@ from matplotlib.patches import PathPatch
|
|||
from matplotlib.path import Path
|
||||
from shapely import speedups
|
||||
from shapely.geometry import GeometryCollection, LinearRing, LineString, MultiLineString, MultiPolygon, Point, Polygon
|
||||
from shapely.geometry.polygon import orient
|
||||
|
||||
if speedups.available:
|
||||
speedups.enable()
|
||||
|
@ -134,8 +134,13 @@ def cut_line_with_point(line: LineString, point: Point):
|
|||
|
||||
def cut_polygon_with_line(polygon: Union[Polygon, MultiPolygon], line: LineString, debug=False) -> Sequence[Polygon]:
|
||||
orig_polygon = polygon
|
||||
polygons = (orient(polygon) for polygon in assert_multipolygon(polygon))
|
||||
polygons: List[List[LinearRing]] = [[polygon.exterior, *polygon.interiors] for polygon in polygons]
|
||||
polygons: List[List[LinearRing]] = []
|
||||
for polygon in assert_multipolygon(polygon):
|
||||
rings = getattr(polygon, 'c3nav_cache', None)
|
||||
if not rings:
|
||||
rings = [polygon.exterior, *polygon.interiors]
|
||||
polygon.c3nav_cache = rings
|
||||
polygons.append(rings)
|
||||
|
||||
# find intersection points between the line and polygon rings
|
||||
points = deque()
|
||||
|
@ -263,8 +268,14 @@ def cut_polygon_with_line(polygon: Union[Polygon, MultiPolygon], line: LineStrin
|
|||
for item in points)
|
||||
|
||||
last = cutpoint(current.point, new_i, 0)
|
||||
return tuple(Polygon(polygon[0], tuple(ring for ring in polygon[1:] if ring is not None))
|
||||
for polygon in polygons)
|
||||
|
||||
result = deque()
|
||||
for polygon in polygons:
|
||||
polygon = [ring for ring in polygon if ring is not None]
|
||||
new_polygon = Polygon(polygon[0], tuple(polygon[1:]))
|
||||
new_polygon.c3nav_cache = polygon
|
||||
result.append(new_polygon)
|
||||
return tuple(result)
|
||||
|
||||
|
||||
def clean_cut_polygon(polygon: Polygon) -> Polygon:
|
||||
|
@ -272,6 +283,9 @@ def clean_cut_polygon(polygon: Polygon) -> Polygon:
|
|||
interiors.extend(cut_ring(polygon.exterior))
|
||||
exteriors = [(i, ring) for (i, ring) in enumerate(interiors) if ring.is_ccw]
|
||||
|
||||
with suppress(AttributeError):
|
||||
delattr(polygon, 'c3nav_cache')
|
||||
|
||||
if len(exteriors) != 1:
|
||||
raise ValueError('Invalid cut polygon!')
|
||||
exterior = interiors[exteriors[0][0]]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue