use blazing-fast STRtree for intersection detection

pull/409/head
Lex Neva 2019-03-19 19:59:40 -04:00
rodzic 2ba333c8a7
commit ba2b78d349
1 zmienionych plików z 11 dodań i 4 usunięć

Wyświetl plik

@ -5,6 +5,7 @@ import math
import networkx import networkx
from shapely import geometry as shgeo from shapely import geometry as shgeo
from shapely.strtree import STRtree
from ..exceptions import InkstitchException from ..exceptions import InkstitchException
from ..i18n import _ from ..i18n import _
@ -248,16 +249,22 @@ def build_travel_graph(fill_stitch_graph, shape, fill_stitch_angle, underpath):
segments = [] segments = []
for start, end, key, data in fill_stitch_graph.edges(keys=True, data=True): for start, end, key, data in fill_stitch_graph.edges(keys=True, data=True):
if key == 'segment': if key == 'segment':
segments.append((shgeo.LineString((start, end)), data)) segments.append(shgeo.LineString((start, end)))
# The shapely documentation is pretty unclear on this. An STRtree
# allows for building a set of shapes and then efficiently testing
# the set for intersection. This allows us to do blazing-fast
# queries of which line segments overlap each underpath edge.
rtree = STRtree(segments)
interior_edges = grating1.symmetric_difference(grating2) interior_edges = grating1.symmetric_difference(grating2)
for ls in interior_edges.geoms: for ls in interior_edges.geoms:
p1, p2 = [InkstitchPoint(*coord) for coord in ls.coords] p1, p2 = [InkstitchPoint(*coord) for coord in ls.coords]
edge = (p1.as_tuple(), p2.as_tuple()) edge = (p1.as_tuple(), p2.as_tuple())
for segment, data in segments: for segment in rtree.query(ls):
if ls.crosses(segment): start, end = segment.coords
data['underpath_edges'].append(edge) fill_stitch_graph[start][end]['segment']['underpath_edges'].append(edge)
graph.add_edge(*edge, weight=p1.distance(p2)) graph.add_edge(*edge, weight=p1.distance(p2))