def test_exception(self): with self.assertRaises(Exception): find_inner_edges((0, 0), None, ((0, 0), ), 0, 1, 0) with self.assertRaises(Exception): find_inner_edges((0, 0), None, ((0, 0), (0, 0)), 0, 1, 0) with self.assertRaises(Exception): find_inner_edges((0, 0), None, ((0, 0), (1, 1), (2, 2)), 0, 1, 0)
def test_point_6(self): edges = find_inner_edges(point6, None, polygon, 0, 1, 0) self.assertEqual({point[0] for point in edges}, {(1, 1), (7, 1), (4, 2), (6, 2), (6, 4), (4, 3)})
def test_point_4(self): edges = find_inner_edges(point4, 3, polygon, 0, 1, 0) self.assertEqual({point[0] for point in edges}, {(4, 2), (6, 4), (4, 4), (4, 3)})
def test_point_3(self): edges = find_inner_edges(point3, 5, polygon, 0, 1, 0) self.assertEqual({point[0] for point in edges}, {(2, 5), (6, 4), (4, 4), (1, 3), (4, 3)})
def test_point_2(self): edges = find_inner_edges(point2, 1, polygon, 0, 1, 0) self.assertEqual({point[0] for point in edges}, {(4, 2), (1, 1)})
def incident_vertices(self, point_data, inside_percent=1): """ Find all incident vertices in visibility graph for given point. :param PointData point_data: point on the map to find incident vertices from :param float inside_percent: (from 0 to 1) - controls the number of inner polygon edges :return: All visible points from given point on the map. :rtype: List[PointData] """ if inside_percent < 0 or inside_percent > 1: raise ValueError("inside_percent should be from 1 to 0") point, obj_number, point_number, is_polygon = point_data[0:4] visible_vertices = SegmentVisibility() edges_inside = list() for i, polygon in enumerate(self.polygons): # if a point is not a part of an object if obj_number is None or point_number is None or is_polygon is None: if Polygon(polygon["geometry"][0]).contains(Point(point)): return find_inner_edges(point, None, polygon["geometry"], i, inside_percent, polygon["tag"][0]) else: continue # if a point is a part of a current polygon if is_polygon and i == obj_number: edges_inside = find_inner_edges(point, point_number, polygon["geometry"], i, inside_percent, polygon["tag"][0]) convex_hull_point_count = len(polygon["convex_hull"]) - 1 if convex_hull_point_count <= 2: continue # if a point is a part of convex hull if point_number in polygon["convex_hull_points"]: position = polygon["convex_hull_points"].index( point_number) left = polygon["convex_hull_points"][ (position - 1) % convex_hull_point_count] right = polygon["convex_hull_points"][ (position + 1) % convex_hull_point_count] restriction_pair = (polygon["geometry"][0][left], polygon["geometry"][0][right]) visible_vertices.set_restriction_angle( restriction_pair, point, True) # if a point is strictly inside a convex hull and a part of polygon else: restriction_pair = find_restriction_pair( point, polygon["geometry"][0], point_number) if restriction_pair is None: return edges_inside visible_vertices.set_restriction_angle( restriction_pair, point, False) # if a point not inside convex hull elif not localize_convex(point, polygon["convex_hull"], polygon["angles"])[0]: pair = find_supporting_pair(point, polygon["convex_hull"], i, polygon["angles"]) visible_vertices.add_pair(pair) # if a point is inside convex hull but not a part of polygon else: line = find_supporting_line(point, polygon["geometry"][0], i) if line is None: return list() visible_vertices.add_line(line) # loop over all linestrings for i, linestring in enumerate(self.multilinestrings["geometry"]): weight = self.multilinestrings["tag"][i][0] linestring_point_count = len(linestring) # if a point is a part of a current linestring if not is_polygon and i == obj_number: if point_number > 0: previous = point_number - 1 edges_inside.append( (linestring[previous], i, previous, False, weight)) elif point_number + 1 < linestring_point_count: following = point_number + 1 edges_inside.append( (linestring[following], i, following, False, weight)) else: # add whole linestring line = list() for j in range(linestring_point_count): line.append((linestring[j], i, j, False, 0)) visible_vertices.add_line(line) # building visibility graph of segments visible_edges = visible_vertices.get_edges_sweepline(point) visible_edges.extend(edges_inside) return visible_edges