From 573581ca80b4daa21c829f93db7fbb741f117b39 Mon Sep 17 00:00:00 2001 From: jpcaram Date: Mon, 26 Jan 2015 17:52:26 -0500 Subject: [PATCH] Fixes to path_connect() and added units tests for it. --- camlib.py | 56 ++++++++++++++++++++++++++------------- tests/test_pathconnect.py | 36 ++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/camlib.py b/camlib.py index e666cb2f..ef03c221 100644 --- a/camlib.py +++ b/camlib.py @@ -502,7 +502,7 @@ class Geometry(object): return optimized_paths @staticmethod - def path_connect(pathlist): + def path_connect(pathlist, origin=(0, 0)): """ Simplifies a list of paths by joining those whose ends touch. The list of paths of generated from the geometry.flatten() @@ -512,8 +512,6 @@ class Geometry(object): :return: None """ - # flat_geometry = self.flatten(pathonly=True) - ## Index first and last points in paths def get_pts(o): 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. storage.insert(shape) - optimized_geometry = [] path_count = 0 - current_pt = (0, 0) - pt, geo = storage.nearest(current_pt) + pt, geo = storage.nearest(origin) + storage.remove(geo) + optimized_geometry = [geo] try: while True: path_count += 1 - try: - storage.remove(geo) - except Exception, e: - log.debug('path_connect(), geo not in storage:') - log.debug(str(e)) + + print "geo is", geo _, left = storage.nearest(geo.coords[0]) + print "left is", left if type(left) == LineString: if left.coords[0] == geo.coords[0]: @@ -550,11 +546,19 @@ class Geometry(object): storage.remove(left) geo.coords = list(left.coords) + list(geo.coords) continue - else: - storage.remove(left) - optimized_geometry.append(left) + + if left.coords[0] == geo.coords[-1]: + 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]) + print "right is", right if type(right) == LineString: if right.coords[0] == geo.coords[-1]: @@ -566,19 +570,33 @@ class Geometry(object): storage.remove(right) geo.coords = list(geo.coords) + list(right.coords)[::-1] continue - else: - storage.remove(right) - optimized_geometry.append(right) + + if right.coords[0] == geo.coords[0]: + 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 - optimized_geometry.append(geo) + #optimized_geometry.append(geo) + optimized_geometry.append(right) + storage.remove(right) + geo = right + print "stored right, now geo<-right" # Next - _, geo = storage.nearest(geo.coords[0]) + #_, geo = storage.nearest(geo.coords[0]) + #optimized_geometry.append(geo) except StopIteration: # Nothing found in storage. pass + print path_count + #self.flat_geometry = optimized_geometry return optimized_geometry diff --git a/tests/test_pathconnect.py b/tests/test_pathconnect.py index 7b3f296c..d49ae8ca 100644 --- a/tests/test_pathconnect.py +++ b/tests/test_pathconnect.py @@ -4,6 +4,7 @@ from shapely.geometry import LineString, Polygon from shapely.ops import cascaded_union, unary_union from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title from camlib import * +from random import random class PathConnectTest1(unittest.TestCase): @@ -13,15 +14,44 @@ class PathConnectTest1(unittest.TestCase): def test_simple_connect(self): paths = [ - LineString([[0, 0], [0, 1]]), - LineString([[0, 1], [0, 2]]) + LineString([[0, 0], [1, 1]]), + LineString([[1, 1], [2, 1]]) ] result = Geometry.path_connect(paths) 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__": unittest.main() \ No newline at end of file