def test_second_nearest_point_including_intersect(self): geom = Point(0, 0) non_intersect_geom = Point(2, 2) targets = [Point(1, 1), Point(2, 2), Point(3, 3)] closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10, n=2) self.assertEqual(closest, Point(3, 3))
def test_requesting_third_of_two_non_intersecting_targets_throws(self): geom = Point(0, 0) non_intersect_geom = Point(1, 1) targets = [Point(1, 1), Point(2, 2), Point(3, 3)] with self.assertRaises(ValueError): closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10, n=3)
def test_nearest_point_after_intersect_is_outside_radius(self): geom = Point(0, 0) non_intersect_geom = Point(1, 1) targets = [Point(1, 1), Point(20, 20)] closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10) self.assertEqual(closest, None)
def test_nearest_point_no_intersect(self): geom = Point(0, 0) non_intersect_geom = Point(1, 2) targets = [Point(1, 1), Point(2, 2)] closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10) self.assertEqual(closest, Point(1, 1))
def test_nearest_point_closest_through_geom(self): geom = Point(0, 0) non_intersect_geom = LinearRing([(0.5, 0.5), (0.5, 1.5), (1.5, 1.5), (1.5, 0.5)]) targets = [Point(1, 1), Point(2, 2)] closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10) self.assertEqual(closest, Point(1, 1))
def test_nearest_point_all_intersect(self): geom = Point(0, 0) non_intersect_geom = Polygon([(0.5, 0.5), (0.5, 2.5), (2.5, 2.5), (2.5, 0.5)]) targets = [Point(1, 1), Point(2, 2)] closest = common.closest_non_intersecting_within_radius( geom, non_intersect_geom, targets, 10) self.assertEqual(closest, None)
def snap_linestrings(r, lines): """ Geometrically 'snaps' LineStrings within an array together within a tolerance. An endpoint is only snapped if it is not otherwise connected. Arguments: r {int|float} -- Tolerance radius in metres within which to snap lines together lines {list} -- Array of Shapely LineStrings Returns: array -- Array of snapped Shapely LineStrings """ # create an empty spatial index object index = rtree.index.Index() snapped = [] # populate the spatial index for index_id, geom in enumerate(lines): index.insert(index_id, geom.bounds) # create snapped lines for search_id, geom in enumerate(lines): e1 = Point(geom.coords[0]) e2 = Point(geom.coords[-1]) new_geom = copy.deepcopy(geom) # endpoint 1 if intersects_with_index(search_id, index, e1, lines): new_e1_coords = [] else: e1buff = e1.buffer(r) e1_line_indices = [ int(i) for i in index.intersection(e1buff.bounds) if i != search_id ] if len(e1_line_indices) > 0: closest_line = closest_non_intersecting_within_radius( e1, geom, [lines[i] for i in e1_line_indices], r) new_e1_coords = [ nearest_points(e1, closest_line)[1].coords[0] ] if closest_line else [] else: new_e1_coords = [] # endpoint 2 if intersects_with_index(search_id, index, e2, lines): new_e2_coords = [] else: e2buff = e2.buffer(r) e2_line_indices = [ int(i) for i in index.intersection(e2buff.bounds) if i != search_id ] if len(e2_line_indices) > 0: closest_line = closest_non_intersecting_within_radius( e2, geom, [lines[i] for i in e2_line_indices], r) new_e2_coords = [ nearest_points(e2, closest_line)[1].coords[0] ] if closest_line else [] else: new_e2_coords = [] snapped_geom_coords = new_e1_coords + \ [c for c in new_geom.coords] + new_e2_coords if len(snapped_geom_coords ) == 3 and snapped_geom_coords[0] == snapped_geom_coords[-1]: snapped_geom_coords.pop(-1) snapped_geom = LineString(snapped_geom_coords) snapped.append(snapped_geom) index.delete(search_id, geom.bounds) index.insert(search_id, snapped_geom.bounds) lines[search_id] = snapped_geom return snapped