Fixes to path_connect() and added units tests for it.
This commit is contained in:
56
camlib.py
56
camlib.py
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
Reference in New Issue
Block a user