def test_frechet_densify_ndarray(): actual = shapely.frechet_distance( shapely.linestrings([[0, 0], [100, 0]]), shapely.linestrings([[0, 0], [50, 50], [100, 0]]), densify=[0.1, 0.2, 1], ) expected = np.array([50, 50.99019514, 70.7106781186548]) np.testing.assert_array_almost_equal(actual, expected)
def test_hausdorff_distance_densify(): # example from GEOS docs a = shapely.linestrings([[0, 0], [100, 0], [10, 100], [10, 100]]) b = shapely.linestrings([[0, 100], [0, 10], [80, 10]]) with ignore_invalid(): # Hausdorff distance emits "invalid value encountered" # (see https://github.com/libgeos/geos/issues/515) actual = shapely.hausdorff_distance(a, b, densify=0.001) assert actual == pytest.approx(47.8, abs=0.1)
def test_linearrings_invalid_ndim(): msg = r"The ordinate \(last\) dimension should be 2 or 3, got {}" coords1 = np.random.randn(10, 3, 4) with pytest.raises(ValueError, match=msg.format(4)): shapely.linearrings(coords1) coords2 = np.hstack((coords1, coords1[:, [0], :])) with pytest.raises(ValueError, match=msg.format(4)): shapely.linearrings(coords2) # too few ordinates coords3 = np.random.randn(10, 3, 1) with pytest.raises(ValueError, match=msg.format(1)): shapely.linestrings(coords3)
def test_linestrings_buffer(dim): coords = np.random.randn(10, 3, dim) coords1 = np.asarray(coords, order="C") result1 = shapely.linestrings(coords1) coords2 = np.asarray(coords1, order="F") result2 = shapely.linestrings(coords2) assert_geometries_equal(result1, result2) # creating (.., 8, 8*3) strided array so it uses copyFromArrays coords3 = np.asarray(np.swapaxes(np.swapaxes(coords, 0, 2), 1, 0), order="F") coords3 = np.swapaxes(np.swapaxes(coords3, 0, 2), 1, 2) result3 = shapely.linestrings(coords3) assert_geometries_equal(result1, result3)
def __new__(self, coordinates=None): if coordinates is None: # empty geometry # TODO better constructor return shapely.from_wkt("LINESTRING EMPTY") elif isinstance(coordinates, LineString): if type(coordinates) == LineString: # return original objects since geometries are immutable return coordinates else: # LinearRing # TODO convert LinearRing to LineString more directly coordinates = coordinates.coords else: # check coordinates on points def _coords(o): if isinstance(o, Point): return o.coords[0] else: return o coordinates = [_coords(o) for o in coordinates] if len(coordinates) == 0: # empty geometry # TODO better constructor + should shapely.linestrings handle this? return shapely.from_wkt("LINESTRING EMPTY") geom = shapely.linestrings(coordinates) if not isinstance(geom, LineString): raise ValueError("Invalid values passed to LineString constructor") return geom
def test_relate_pattern(): g = shapely.linestrings([(0, 0), (1, 0), (1, 1)]) polygon = shapely.box(0, 0, 2, 2) assert shapely.relate(g, polygon) == "11F00F212" assert shapely.relate_pattern(g, polygon, "11F00F212") assert shapely.relate_pattern(g, polygon, "*********") assert not shapely.relate_pattern(g, polygon, "F********")
def test_pickle(geom): if shapely.get_type_id(geom) == 2: # Linearrings get converted to linestrings expected = shapely.linestrings(shapely.get_coordinates(geom)) else: expected = geom pickled = pickle.dumps(geom) assert_geometries_equal(pickle.loads(pickled), expected, tolerance=0)
def test_linestrings_from_coords(): actual = shapely.linestrings([[[0, 0], [1, 1]], [[0, 0], [2, 2]]]) assert_geometries_equal( actual, [ shapely.Geometry("LINESTRING (0 0, 1 1)"), shapely.Geometry("LINESTRING (0 0, 2 2)"), ], )
def test_linestrings_out(indices, expected): out = np.empty(4, dtype=object) out[2] = empty_point actual = shapely.linestrings( [(0, 0), (1, 0), (1, 1), (0, 0), (1, 0), (1, 1)], indices=indices, out=out, ) assert_geometries_equal(out, expected) assert actual is out
def test_linestrings_from_xy_broadcast(): x = [0, 1] # the same X coordinates for both linestrings y = [2, 3], [4, 5] # each linestring has a different set of Y coordinates actual = shapely.linestrings(x, y) assert_geometries_equal( actual, [ shapely.Geometry("LINESTRING (0 2, 1 3)"), shapely.Geometry("LINESTRING (0 4, 1 5)"), ], )
def __new__(self, coordinates=None): """ Parameters ---------- coordinates : sequence A sequence of (x, y [,z]) numeric coordinate pairs or triples or an object that provides the numpy array interface, including another instance of LineString. Example ------- Create a line with two segments >>> a = LineString([[0, 0], [1, 0], [1, 1]]) >>> a.length 2.0 """ if coordinates is None: # empty geometry # TODO better constructor return shapely.from_wkt("LINESTRING EMPTY") elif isinstance(coordinates, LineString): if type(coordinates) == LineString: # return original objects since geometries are immutable return coordinates else: # LinearRing # TODO convert LinearRing to LineString more directly coordinates = coordinates.coords else: # check coordinates on points def _coords(o): if isinstance(o, Point): return o.coords[0] else: return o coordinates = [_coords(o) for o in coordinates] if len(coordinates) == 0: # empty geometry # TODO better constructor + should shapely.linestrings handle this? return shapely.from_wkt("LINESTRING EMPTY") geom = shapely.linestrings(coordinates) if not isinstance(geom, LineString): raise ValueError("Invalid values passed to LineString constructor") return geom
def test_linestrings_invalid_ndim(): msg = r"The ordinate \(last\) dimension should be 2 or 3, got {}" coords = np.ones((10, 2, 4), order="C") with pytest.raises(ValueError, match=msg.format(4)): shapely.linestrings(coords) coords = np.ones((10, 2, 4), order="F") with pytest.raises(ValueError, match=msg.format(4)): shapely.linestrings(coords) coords = np.swapaxes(np.swapaxes(np.ones((10, 2, 4)), 0, 2), 1, 0) coords = np.swapaxes(np.swapaxes(np.asarray(coords, order="F"), 0, 2), 1, 2) with pytest.raises(ValueError, match=msg.format(4)): shapely.linestrings(coords) # too few ordinates coords = np.ones((10, 2, 1)) with pytest.raises(ValueError, match=msg.format(1)): shapely.linestrings(coords)
def test_shared_paths_non_linestring(): g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)]) g2 = shapely.points(0, 1) with pytest.raises(shapely.GEOSException): shapely.shared_paths(g1, g2)
def test_shared_paths_linestring(): g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)]) g2 = shapely.linestrings([(0, 0), (1, 0)]) actual1 = shapely.shared_paths(g1, g2) assert_geometries_equal(shapely.get_geometry(actual1, 0), shapely.multilinestrings([g2]))
def test_set_nan(): # As NaN != NaN, you can have multiple "NaN" points in a set # set([float("nan"), float("nan")]) also returns a set with 2 elements a = set(shapely.linestrings([[[np.nan, np.nan], [np.nan, np.nan]]] * 10)) assert len(a) == 10 # different objects: NaN != NaN
def test_linestrings_invalid(): # attempt to construct linestrings with 1 coordinate with pytest.raises(shapely.GEOSException): shapely.linestrings([[1, 1], [2, 2]], indices=[0, 1])
def test_linestrings_invalid_shape(shape): with pytest.raises(shapely.GEOSException): shapely.linestrings(np.ones(shape))
line_string, line_string_nan, line_string_z, point, ) EMPTY_GEOMS = ( empty_point, empty_point_z, empty_line_string, empty_line_string_z, empty_polygon, empty, ) line_string_reversed = shapely.linestrings([(0, 0), (1, 0), (1, 1)][::-1]) PRE_GEOS_390 = pytest.mark.skipif( shapely.geos_version < (3, 9, 0), reason="2D and 3D empty geometries did not have dimensionality before GEOS 3.9", ) def make_array(left, right, use_array): if use_array in ("left", "both"): left = np.array([left] * 3, dtype=object) if use_array in ("right", "both"): right = np.array([right] * 3, dtype=object) return left, right
def test_linestrings_invalid_shape_scalar(): with pytest.raises(ValueError): shapely.linestrings((1, 1))
"properties": { "prop1": { "this": "that" }, "prop0": "value0" }, }, ], }, indent=4, ) GEOJSON_GEOMETRY_EXPECTED = shapely.points(125.6, 10.1) GEOJSON_COLLECTION_EXPECTED = [ shapely.points([102.0, 0.6]), shapely.linestrings([[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]]), shapely.polygons([[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]), ] class ShapelyGeometryMock: def __init__(self, g): self.g = g self.__geom__ = g._ptr if hasattr(g, "_ptr") else g @property def __array_interface__(self): # this should not be called # (starting with numpy 1.20 it is called, but not used) return np.array([1.0, 2.0]).__array_interface__
def test_linestrings_from_xyz(): actual = shapely.linestrings([0, 1], [2, 3], 0) assert_geometries_equal(actual, shapely.Geometry("LINESTRING Z (0 2 0, 1 3 0)"))
def test_shortest_line(prepare): g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)]) g2 = shapely.linestrings([(0, 3), (3, 0)]) actual = shapely.shortest_line(_prepare_input(g1, prepare), g2) expected = shapely.linestrings([(1, 1), (1.5, 1.5)]) assert shapely.equals(actual, expected)
import numpy as np import pytest import shapely shapely20_todo = pytest.mark.xfail( strict=False, reason="Not yet implemented for Shapely 2.0" ) point_polygon_testdata = ( shapely.points(np.arange(6), np.arange(6)), shapely.box(2, 2, 4, 4), ) point = shapely.points(2, 3) line_string = shapely.linestrings([(0, 0), (1, 0), (1, 1)]) linear_ring = shapely.linearrings([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]) polygon = shapely.polygons([(0, 0), (2, 0), (2, 2), (0, 2), (0, 0)]) multi_point = shapely.multipoints([(0, 0), (1, 2)]) multi_line_string = shapely.multilinestrings([[(0, 0), (1, 2)]]) multi_polygon = shapely.multipolygons( [ [(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)], [(2.1, 2.1), (2.2, 2.1), (2.2, 2.2), (2.1, 2.2), (2.1, 2.1)], ] ) geometry_collection = shapely.geometrycollections( [shapely.points(51, -1), shapely.linestrings([(52, -1), (49, 2)])] ) point_z = shapely.points(2, 3, 4) line_string_z = shapely.linestrings([(0, 0, 4), (1, 0, 4), (1, 1, 4)])
def test_linestrings(coordinates, indices, expected): actual = shapely.linestrings(np.array(coordinates, dtype=float), indices=np.array(indices, dtype=np.intp)) assert_geometries_equal(actual, expected)
def test_repr_max_length(): # the repr is limited to 80 characters geom = shapely.linestrings(np.arange(1000), np.arange(1000)) representation = repr(geom) assert len(representation) == 80 assert representation.endswith("...>")
actual = shapely.distance(*point_polygon_testdata) expected = [2 * 2**0.5, 2**0.5, 0, 0, 0, 2**0.5] np.testing.assert_allclose(actual, expected) def test_distance_missing(): actual = shapely.distance(point, None) assert np.isnan(actual) @pytest.mark.parametrize( "geom,expected", [ (point, [2, 3, 2, 3]), ([point, multi_point], [[2, 3, 2, 3], [0, 0, 1, 2]]), (shapely.linestrings([[0, 0], [0, 1]]), [0, 0, 0, 1]), (shapely.linestrings([[0, 0], [1, 0]]), [0, 0, 1, 0]), (multi_point, [0, 0, 1, 2]), (multi_polygon, [0, 0, 2.2, 2.2]), (geometry_collection, [49, -1, 52, 2]), (empty, [np.nan, np.nan, np.nan, np.nan]), (None, [np.nan, np.nan, np.nan, np.nan]), ], ) def test_bounds(geom, expected): assert_array_equal(shapely.bounds(geom), expected) @pytest.mark.parametrize( "geom,shape", [