Fixes to path_connect() and added units tests for it.

This commit is contained in:
jpcaram
2015-01-26 17:52:26 -05:00
parent 6b51f03db2
commit 573581ca80
2 changed files with 70 additions and 22 deletions

View File

@@ -502,7 +502,7 @@ class Geometry(object):
return optimized_paths return optimized_paths
@staticmethod @staticmethod
def path_connect(pathlist): def path_connect(pathlist, origin=(0, 0)):
""" """
Simplifies a list of paths by joining those whose ends touch. Simplifies a list of paths by joining those whose ends touch.
The list of paths of generated from the geometry.flatten() The list of paths of generated from the geometry.flatten()
@@ -512,8 +512,6 @@ class Geometry(object):
:return: None :return: None
""" """
# flat_geometry = self.flatten(pathonly=True)
## Index first and last points in paths ## Index first and last points in paths
def get_pts(o): def get_pts(o):
return [o.coords[0], o.coords[-1]] return [o.coords[0], o.coords[-1]]
@@ -525,20 +523,18 @@ class Geometry(object):
if shape is not None: # TODO: This shouldn't have happened. if shape is not None: # TODO: This shouldn't have happened.
storage.insert(shape) storage.insert(shape)
optimized_geometry = []
path_count = 0 path_count = 0
current_pt = (0, 0) pt, geo = storage.nearest(origin)
pt, geo = storage.nearest(current_pt) storage.remove(geo)
optimized_geometry = [geo]
try: try:
while True: while True:
path_count += 1 path_count += 1
try:
storage.remove(geo) print "geo is", geo
except Exception, e:
log.debug('path_connect(), geo not in storage:')
log.debug(str(e))
_, left = storage.nearest(geo.coords[0]) _, left = storage.nearest(geo.coords[0])
print "left is", left
if type(left) == LineString: if type(left) == LineString:
if left.coords[0] == geo.coords[0]: if left.coords[0] == geo.coords[0]:
@@ -550,11 +546,19 @@ class Geometry(object):
storage.remove(left) storage.remove(left)
geo.coords = list(left.coords) + list(geo.coords) geo.coords = list(left.coords) + list(geo.coords)
continue continue
else:
storage.remove(left) if left.coords[0] == geo.coords[-1]:
optimized_geometry.append(left) storage.remove(left)
geo.coords = list(geo.coords) + list(left.coords)
continue
if left.coords[-1] == geo.coords[-1]:
storage.remove(left)
geo.coords = list(geo.coords) + list(left.coords)[::-1]
continue
_, right = storage.nearest(geo.coords[-1]) _, right = storage.nearest(geo.coords[-1])
print "right is", right
if type(right) == LineString: if type(right) == LineString:
if right.coords[0] == geo.coords[-1]: if right.coords[0] == geo.coords[-1]:
@@ -566,19 +570,33 @@ class Geometry(object):
storage.remove(right) storage.remove(right)
geo.coords = list(geo.coords) + list(right.coords)[::-1] geo.coords = list(geo.coords) + list(right.coords)[::-1]
continue continue
else:
storage.remove(right) if right.coords[0] == geo.coords[0]:
optimized_geometry.append(right) storage.remove(right)
geo.coords = list(geo.coords)[::-1] + list(right.coords)
continue
if right.coords[-1] == geo.coords[0]:
storage.remove(right)
geo.coords = list(left.coords) + list(geo.coords)
continue
# No matches on either end # No matches on either end
optimized_geometry.append(geo) #optimized_geometry.append(geo)
optimized_geometry.append(right)
storage.remove(right)
geo = right
print "stored right, now geo<-right"
# Next # Next
_, geo = storage.nearest(geo.coords[0]) #_, geo = storage.nearest(geo.coords[0])
#optimized_geometry.append(geo)
except StopIteration: # Nothing found in storage. except StopIteration: # Nothing found in storage.
pass pass
print path_count
#self.flat_geometry = optimized_geometry #self.flat_geometry = optimized_geometry
return optimized_geometry return optimized_geometry

View File

@@ -4,6 +4,7 @@ from shapely.geometry import LineString, Polygon
from shapely.ops import cascaded_union, unary_union from shapely.ops import cascaded_union, unary_union
from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title
from camlib import * from camlib import *
from random import random
class PathConnectTest1(unittest.TestCase): class PathConnectTest1(unittest.TestCase):
@@ -13,15 +14,44 @@ class PathConnectTest1(unittest.TestCase):
def test_simple_connect(self): def test_simple_connect(self):
paths = [ paths = [
LineString([[0, 0], [0, 1]]), LineString([[0, 0], [1, 1]]),
LineString([[0, 1], [0, 2]]) LineString([[1, 1], [2, 1]])
] ]
result = Geometry.path_connect(paths) result = Geometry.path_connect(paths)
self.assertEqual(len(result), 1) self.assertEqual(len(result), 1)
self.assertTrue(result[0].equals(LineString([[0, 0], [0, 2]]))) self.assertTrue(result[0].equals(LineString([[0, 0], [1, 1], [2, 1]])))
def test_interfere_connect(self):
paths = [
LineString([[0, 0], [1, 1]]),
LineString([[1, 1], [2, 1]]),
LineString([[-0.5, 0.5], [0.5, 0]])
]
result = Geometry.path_connect(paths)
self.assertEqual(len(result), 2)
matches = [p for p in result if p.equals(LineString([[0, 0], [1, 1], [2, 1]]))]
self.assertEqual(len(matches), 1)
def test_simple_connect_offset1(self):
for i in range(20):
offset_x = random()
offset_y = random()
paths = [
LineString([[0 + offset_x, 0 + offset_y], [1 + offset_x, 1 + offset_y]]),
LineString([[1 + offset_x, 1 + offset_y], [2 + offset_x, 1 + offset_y]])
]
result = Geometry.path_connect(paths)
self.assertEqual(len(result), 1)
self.assertTrue(result[0].equals(LineString([[0 + offset_x, 0 + offset_y],
[1 + offset_x, 1 + offset_y],
[2 + offset_x, 1 + offset_y]])))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()