def test_exception(self): with self.assertRaises(Exception): build_convex_hull(((0, 0),)) with self.assertRaises(Exception): build_convex_hull(((0, 0), (0, 0))) with self.assertRaises(Exception): build_convex_hull(((0, 0), (1, 1), (2, 2)))
import unittest from offroad_routing.geometry.ch_localization import * from offroad_routing.geometry.convex_hull import build_convex_hull polygon1 = ((0, 0), (1, -1), (3, -1), (6, 1), (5, 3), (1, 3), (0, 0)) polygon1, _, angles1 = build_convex_hull(polygon1) polygon2 = ((-1, -1), (6, -1), (6, 6), (-1, -1)) polygon2, _, angles2 = build_convex_hull(polygon2) points_in = ((2, 1), (5, 1), (1, 0), (2, 0), (3, 0), (4, 0), (3, 1), (4, 1), (3, 2), (4, 2), (5, 2)) points_out = ((-1, 2), (3, 4), (5, -5), (10, -1), (-5, -5)) points_on = ((2, -1), (3, 3)) class TestLocalizeConvexLinear(unittest.TestCase): def test_polygon1(self): for p in points_in: self.assertTrue(localize_convex_linear(p, polygon1)) for p in points_out: self.assertFalse(localize_convex_linear(p, polygon1)) for p in points_on: self.assertFalse(localize_convex_linear(p, polygon1)) def test_polygon2(self): for p in points_in: self.assertTrue(localize_convex_linear(p, polygon2)) for p in points_out: self.assertFalse(localize_convex_linear(p, polygon2)) for p in points_on: self.assertFalse(localize_convex_linear(p, polygon2))
def prune_geometry(self, epsilon_polygon=None, epsilon_polyline=None, bbox_comp=15, remove_inner=False): """ Transform retrieved map data: 1. Transform geometry to tuple of points. 2. Run Ramer-Douglas-Peucker (RDP) to geometry. 3. Get rid of small objects with bbox_comp parameter. 4. Add data about convex hull for polygons. Default RDP parameters will be computed for the given area to provide best performance. :param Optional[float] epsilon_polygon: RDP parameter for polygons :param Optional[float] epsilon_polyline: RDP parameter for polylines :param Optional[int] bbox_comp: scale polygon comparison parameter (to size of map bbox) :param bool remove_inner: remove inner polygons for other polygons """ for param in {epsilon_polygon, epsilon_polyline, bbox_comp}: assert param is None or param >= 0 # auto-compute parameters if epsilon_polygon is None: epsilon_polygon = (self.bbox_size[0]**2 + self.bbox_size[1]**2)**0.5 / bbox_comp / 5 if epsilon_polyline is None: epsilon_polyline = (self.bbox_size[0]**2 + self.bbox_size[1]**2)**0.5 / bbox_comp / 10 # compare to bounding box self.polygons.geometry = \ self.polygons.geometry.apply(self.__compare_bbox, args=[bbox_comp, self.bbox_size]) self.polygons = DataFrame( self.polygons[self.polygons['geometry'].notna()]) # shapely.geometry.Polygon to tuple of points self.polygons.geometry = self.polygons.geometry.apply( self.__polygon_coords, args=[epsilon_polygon]) self.polygons = self.polygons[self.polygons['geometry'].notna()] # remove equal polygons self.__remove_equal_polygons() self.polygons = self.polygons.reset_index().drop(columns='index') # remove polygons which are inner for other polygons if remove_inner: self.__remove_inner_polygons() # add info about convex hull if self.polygons.shape[0] > 0: self.polygons = self.polygons.join( DataFrame(self.polygons.geometry).apply( lambda x: build_convex_hull(x[0][0]), axis=1, result_type='expand').rename(columns={ 0: 'convex_hull', 1: 'convex_hull_points', 2: 'angles' })) # compare to bounding box self.multilinestrings.geometry = \ self.multilinestrings.geometry.apply(self.__compare_bbox, args=[bbox_comp, self.bbox_size]) self.multilinestrings = DataFrame(self.multilinestrings[ self.multilinestrings['geometry'].notna()].reset_index().drop( columns='index')) # shapely.geometry.MultiLineString to tuple of points and simplify self.multilinestrings.geometry = self.multilinestrings.geometry.apply( self.__linestring_coords, args=[epsilon_polyline]) self.multilinestrings = self.multilinestrings.to_records(index=False) self.polygons = self.polygons.to_records(index=False)
def test_non_convex(self): self.assertNotEqual(set(build_convex_hull(polygon2)[0]), set(polygon2)) self.assertEqual(len(build_convex_hull(polygon2)[0]), len(polygon2) - 2) self.assertEqual(set(build_convex_hull(polygon2)[1]), {0, 2, 3, 5}) self.assertEqual(len(build_convex_hull(polygon2)[2]), len(polygon2) - 2 - 2)
def test_convex(self): self.assertEqual(set(build_convex_hull(polygon1)[0]), set(polygon1)) self.assertEqual(len(build_convex_hull(polygon1)[0]), len(polygon1)) self.assertEqual(set(build_convex_hull(polygon1)[1]), {0, 1, 2}) self.assertEqual(len(build_convex_hull(polygon1)[2]), len(polygon1) - 2)
def test_simple(self): self.assertEqual(set(build_convex_hull(polygon0)[0]), set(polygon0)) self.assertEqual(len(build_convex_hull(polygon0)[0]), len(polygon0)) self.assertEqual(set(build_convex_hull(polygon0)[1]), {0, 1}) self.assertIs(build_convex_hull(polygon0)[2], None)
def test_incorrect(self): with self.assertRaises(Exception): build_convex_hull(polygon0[:-1])