743 lines
22 KiB
Python
743 lines
22 KiB
Python
"""See test_creation_indices.py for tests with 'indices' parameter."""
|
|
|
|
import numpy as np
|
|
import pytest
|
|
from numpy.testing import assert_array_equal
|
|
|
|
import shapely
|
|
|
|
# Note: Point is not imported because it is overridden for testing
|
|
from shapely import (
|
|
GeometryCollection,
|
|
GeometryType,
|
|
LinearRing,
|
|
LineString,
|
|
MultiLineString,
|
|
MultiPoint,
|
|
MultiPolygon,
|
|
Polygon,
|
|
)
|
|
from shapely.testing import assert_geometries_equal
|
|
from shapely.tests.common import (
|
|
empty_polygon,
|
|
geometry_collection,
|
|
ignore_invalid,
|
|
line_string,
|
|
linear_ring,
|
|
multi_line_string,
|
|
multi_point,
|
|
multi_polygon,
|
|
point,
|
|
polygon,
|
|
)
|
|
|
|
|
|
def box_tpl(x1, y1, x2, y2):
|
|
return (x2, y1), (x2, y2), (x1, y2), (x1, y1), (x2, y1)
|
|
|
|
|
|
def test_points_from_coords():
|
|
actual = shapely.points([[0, 0], [2, 2]])
|
|
assert_geometries_equal(actual, [shapely.Point(0, 0), shapely.Point(2, 2)])
|
|
|
|
|
|
def test_points_from_xy():
|
|
actual = shapely.points(2, [0, 1])
|
|
assert_geometries_equal(actual, [shapely.Point(2, 0), shapely.Point(2, 1)])
|
|
|
|
|
|
def test_points_from_xyz():
|
|
actual = shapely.points(1, 1, [0, 1])
|
|
assert_geometries_equal(actual, [shapely.Point(1, 1, 0), shapely.Point(1, 1, 1)])
|
|
|
|
|
|
def test_points_invalid_ndim():
|
|
with pytest.raises(ValueError, match="dimension should be 2 or 3, got 4"):
|
|
shapely.points([0, 1, 2, 3])
|
|
|
|
with pytest.raises(ValueError, match="dimension should be 2 or 3, got 1"):
|
|
shapely.points([0])
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
shapely.geos_version[:2] not in ((3, 10), (3, 11), (3, 12)),
|
|
reason="GEOS not in 3.10, 3.11, 3.12",
|
|
)
|
|
def test_points_nan_all_nan_becomes_empty():
|
|
actual = shapely.points(np.nan, np.nan)
|
|
assert actual.wkt == "POINT EMPTY"
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
shapely.geos_version[:2] not in ((3, 10), (3, 11)),
|
|
reason="GEOS not in 3.10, 3.11",
|
|
)
|
|
def test_points_nan_3D_all_nan_becomes_empty_2D():
|
|
actual = shapely.points(np.nan, np.nan, np.nan)
|
|
assert actual.wkt == "POINT EMPTY"
|
|
|
|
|
|
@pytest.mark.skipif(shapely.geos_version[:2] != (3, 12), reason="GEOS != 3.12")
|
|
def test_points_nan_3D_all_nan_becomes_empty():
|
|
actual = shapely.points(np.nan, np.nan, np.nan)
|
|
assert actual.wkt == "POINT Z EMPTY"
|
|
|
|
|
|
@pytest.mark.skipif(shapely.geos_version < (3, 12, 0), reason="GEOS < 3.12")
|
|
@pytest.mark.parametrize(
|
|
"coords,expected_wkt",
|
|
[
|
|
pytest.param(
|
|
[np.nan, np.nan],
|
|
"POINT (NaN NaN)",
|
|
marks=pytest.mark.skipif(
|
|
shapely.geos_version < (3, 13, 0), reason="GEOS < 3.13"
|
|
),
|
|
),
|
|
pytest.param(
|
|
[np.nan, np.nan, np.nan],
|
|
"POINT Z (NaN NaN NaN)",
|
|
marks=pytest.mark.skipif(
|
|
shapely.geos_version < (3, 13, 0), reason="GEOS < 3.13"
|
|
),
|
|
),
|
|
([1, np.nan], "POINT (1 NaN)"),
|
|
([np.nan, 1], "POINT (NaN 1)"),
|
|
([np.nan, 1, np.nan], "POINT Z (NaN 1 NaN)"),
|
|
([np.nan, np.nan, 1], "POINT Z (NaN NaN 1)"),
|
|
],
|
|
)
|
|
def test_points_handle_nan_allow(coords, expected_wkt):
|
|
actual = shapely.points(coords, handle_nan="allow")
|
|
assert actual.wkt == expected_wkt
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords,handle_nan,expected_wkt",
|
|
[
|
|
([0, np.nan], "skip", "POINT EMPTY"),
|
|
([np.nan, 0], "skip", "POINT EMPTY"),
|
|
([0, np.nan, 1], "skip", "POINT Z EMPTY"),
|
|
([0, 1, np.nan], "skip", "POINT Z EMPTY"),
|
|
([0, 1], "error", "POINT (0 1)"),
|
|
([0, 1, 2], "error", "POINT Z (0 1 2)"),
|
|
([0, np.inf], "skip", "POINT EMPTY"),
|
|
],
|
|
)
|
|
def test_points_handle_nan(coords, handle_nan, expected_wkt):
|
|
actual = shapely.points(coords, handle_nan=handle_nan)
|
|
assert actual.wkt in expected_wkt
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords",
|
|
[
|
|
[0, np.nan],
|
|
[np.nan, 0],
|
|
[0, 0, np.nan],
|
|
[0, np.inf],
|
|
[0, -np.inf],
|
|
],
|
|
)
|
|
def test_points_handle_nan_error(coords):
|
|
with pytest.raises(ValueError, match=".*NaN.*"):
|
|
shapely.points(coords, handle_nan="error")
|
|
|
|
|
|
def test_linestrings_from_coords():
|
|
actual = shapely.linestrings([[[0, 0], [1, 1]], [[0, 0], [2, 2]]])
|
|
assert_geometries_equal(
|
|
actual,
|
|
[
|
|
LineString([(0, 0), (1, 1)]),
|
|
LineString([(0, 0), (2, 2)]),
|
|
],
|
|
)
|
|
|
|
|
|
def test_linestrings_from_xy():
|
|
actual = shapely.linestrings([0, 1], [2, 3])
|
|
assert_geometries_equal(actual, LineString([(0, 2), (1, 3)]))
|
|
|
|
|
|
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,
|
|
[
|
|
LineString([(0, 2), (1, 3)]),
|
|
LineString([(0, 4), (1, 5)]),
|
|
],
|
|
)
|
|
|
|
|
|
def test_linestrings_from_xyz():
|
|
actual = shapely.linestrings([0, 1], [2, 3], 0)
|
|
assert_geometries_equal(actual, LineString([(0, 2, 0), (1, 3, 0)]))
|
|
|
|
|
|
@pytest.mark.parametrize("dim", [2, 3])
|
|
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 test_linestrings_empty():
|
|
actual = shapely.linestrings(np.empty((0, 2)))
|
|
assert actual.is_empty
|
|
|
|
|
|
def test_linestrings_invalid_shape_scalar():
|
|
with pytest.raises(ValueError):
|
|
shapely.linestrings((1, 1))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"shape",
|
|
[
|
|
(2, 1, 2), # 2 linestrings of 1 2D point
|
|
(1, 1, 2), # 1 linestring of 1 2D point
|
|
(1, 2), # 1 linestring of 1 2D point (scalar)
|
|
],
|
|
)
|
|
def test_linestrings_invalid_shape(shape):
|
|
with pytest.raises(shapely.GEOSException):
|
|
shapely.linestrings(np.ones(shape))
|
|
|
|
|
|
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)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords",
|
|
[
|
|
[[0, 1], [2, float("nan")]],
|
|
[[0, 1, float("nan")], [2, 2, float("nan")]],
|
|
[[0, 1, 2], [2, 2, float("nan")]],
|
|
[[0, 1, float("nan")], [2, 2, 3]],
|
|
[[float("nan"), float("nan")], [float("nan"), float("nan")]],
|
|
],
|
|
)
|
|
def test_linestrings_handle_nan_allow(coords):
|
|
with ignore_invalid():
|
|
actual = shapely.linestrings(coords, handle_nan="allow")
|
|
actual = shapely.get_coordinates(actual, include_z=len(coords[0]) == 3)
|
|
|
|
assert_array_equal(actual, coords)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords",
|
|
[
|
|
[[2, float("nan")], [0, 1], [2, 3]],
|
|
[[0, 1], [2, float("nan")], [2, 3]],
|
|
[[0, 1], [2, 3], [2, float("nan")]],
|
|
],
|
|
)
|
|
def test_linestrings_handle_nan_skip(coords):
|
|
actual = shapely.linestrings(coords, handle_nan="skip")
|
|
assert_geometries_equal(actual, LineString([(0, 1), (2, 3)]))
|
|
|
|
|
|
def test_linestrings_handle_nan_skip_invalid():
|
|
with pytest.raises(shapely.GEOSException):
|
|
shapely.linestrings([[0, 1], [2, float("nan")]], handle_nan="skip")
|
|
|
|
|
|
def test_linestrings_handle_nan_skip_only_nan():
|
|
# all-nan becomes an empty linestring
|
|
actual = shapely.linestrings(np.full((3, 2), fill_value=np.nan), handle_nan="skip")
|
|
assert actual.is_empty
|
|
|
|
|
|
def test_linestrings_handle_nan_error():
|
|
with pytest.raises(ValueError, match=".*NaN.*"):
|
|
shapely.linestrings([[0, 1], [2, float("nan")], [2, 3]], handle_nan="error")
|
|
|
|
|
|
def test_linearrings():
|
|
actual = shapely.linearrings(box_tpl(0, 0, 1, 1))
|
|
assert_geometries_equal(
|
|
actual, LinearRing([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)])
|
|
)
|
|
|
|
|
|
def test_linearrings_empty():
|
|
actual = shapely.linearrings(np.empty((0, 2)))
|
|
assert actual.is_empty
|
|
|
|
|
|
def test_linearrings_from_xy():
|
|
actual = shapely.linearrings([0, 1, 2, 0], [3, 4, 5, 3])
|
|
assert_geometries_equal(actual, LinearRing([(0, 3), (1, 4), (2, 5), (0, 3)]))
|
|
|
|
|
|
def test_linearrings_unclosed():
|
|
actual = shapely.linearrings(box_tpl(0, 0, 1, 1)[:-1])
|
|
assert_geometries_equal(
|
|
actual, LinearRing([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)])
|
|
)
|
|
|
|
|
|
def test_linearrings_unclosed_all_coords_equal():
|
|
actual = shapely.linearrings([(0, 0), (0, 0), (0, 0)])
|
|
assert_geometries_equal(actual, LinearRing([(0, 0), (0, 0), (0, 0), (0, 0)]))
|
|
|
|
|
|
def test_linearrings_invalid_shape_scalar():
|
|
with pytest.raises(ValueError):
|
|
shapely.linearrings((1, 1))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"shape",
|
|
[
|
|
(2, 1, 2), # 2 linearrings of 1 2D point
|
|
(1, 1, 2), # 1 linearring of 1 2D point
|
|
(1, 2), # 1 linearring of 1 2D point (scalar)
|
|
(2, 2, 2), # 2 linearrings of 2 2D points
|
|
(1, 2, 2), # 1 linearring of 2 2D points
|
|
(2, 2), # 1 linearring of 2 2D points (scalar)
|
|
],
|
|
)
|
|
def test_linearrings_invalid_shape(shape):
|
|
coords = np.ones(shape)
|
|
with pytest.raises(ValueError):
|
|
shapely.linearrings(coords)
|
|
|
|
# make sure the first coordinate != second coordinate
|
|
coords[..., 1] += 1
|
|
with pytest.raises(ValueError):
|
|
shapely.linearrings(coords)
|
|
|
|
|
|
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.linearrings(coords3)
|
|
|
|
|
|
def test_linearrings_all_nan():
|
|
coords = np.full((4, 2), np.nan)
|
|
with pytest.raises(shapely.GEOSException):
|
|
shapely.linearrings(coords)
|
|
|
|
|
|
@pytest.mark.parametrize("dim", [2, 3])
|
|
@pytest.mark.parametrize("order", ["C", "F"])
|
|
def test_linearrings_buffer(dim, order):
|
|
coords1 = np.random.randn(10, 4, dim)
|
|
coords1 = np.asarray(coords1, order=order)
|
|
result1 = shapely.linearrings(coords1)
|
|
|
|
# with manual closure -> can directly copy from buffer if C order
|
|
coords2 = np.hstack((coords1, coords1[:, [0], :]))
|
|
coords2 = np.asarray(coords2, order=order)
|
|
result2 = shapely.linearrings(coords2)
|
|
assert_geometries_equal(result1, result2)
|
|
|
|
# create scalar -> can also directly copy from buffer if F order
|
|
coords3 = np.asarray(coords2[0], order=order)
|
|
result3 = shapely.linearrings(coords3)
|
|
assert_geometries_equal(result3, result1[0])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords",
|
|
[
|
|
[[0, 2], [1, float("nan")], [1, 3], [0, 2]],
|
|
[[0, 2], [float("nan"), 0], [1, 3], [0, 2]],
|
|
[[0, 2, 5], [float("nan"), 2, 5], [1, 3, 5], [0, 2, 5]],
|
|
[[0, 2, 5], [1, 2, float("nan")], [1, 3, 5], [0, 2, 5]],
|
|
],
|
|
)
|
|
def test_linearrings_handle_nan_allow(coords):
|
|
with ignore_invalid():
|
|
actual = shapely.linearrings(coords, handle_nan="allow")
|
|
actual = shapely.get_coordinates(actual, include_z=len(coords[0]) == 3)
|
|
|
|
assert_array_equal(actual, coords)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"x,y",
|
|
[
|
|
([0, 1, float("nan"), 2, 0], [3, 4, 5, 5, 3]),
|
|
([0, 1, 1, 2, 0], [3, 4, float("nan"), 5, 3]),
|
|
([0, 1, 2, 0, float("nan")], [3, 4, 5, 3, 3]),
|
|
([float("nan"), 0, 1, 2, 0], [3, 3, 4, 5, 3]),
|
|
],
|
|
)
|
|
def test_linearrings_handle_nan_skip(x, y):
|
|
actual = shapely.linearrings(x, y, handle_nan="skip")
|
|
assert_geometries_equal(actual, LinearRing([(0, 3), (1, 4), (2, 5), (0, 3)]))
|
|
|
|
|
|
def test_linearrings_handle_nan_skip_invalid():
|
|
with pytest.raises(ValueError):
|
|
shapely.linearrings([0, float("nan"), 0], [3, 4, 3], handle_nan="skip")
|
|
|
|
|
|
def test_linearrings_handle_nan_skip_only_nan():
|
|
actual = shapely.linearrings(np.full((5, 2), fill_value=np.nan), handle_nan="skip")
|
|
assert actual.is_empty
|
|
|
|
|
|
def test_linearrings_handle_nan_error():
|
|
with pytest.raises(ValueError, match=".*NaN.*"):
|
|
shapely.linearrings(
|
|
[0, 1, float("nan"), 2, 0], [3, 4, 5, 5, 3], handle_nan="error"
|
|
)
|
|
|
|
|
|
def test_polygon_from_linearring():
|
|
actual = shapely.polygons(shapely.linearrings(box_tpl(0, 0, 1, 1)))
|
|
assert_geometries_equal(actual, Polygon([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)]))
|
|
|
|
|
|
def test_polygons_none():
|
|
assert_geometries_equal(shapely.polygons(None), empty_polygon)
|
|
assert_geometries_equal(shapely.polygons(None, holes=[linear_ring]), empty_polygon)
|
|
|
|
|
|
def test_polygons():
|
|
actual = shapely.polygons(box_tpl(0, 0, 1, 1))
|
|
assert_geometries_equal(actual, Polygon([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)]))
|
|
|
|
|
|
def test_polygon_no_hole_list_raises():
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(box_tpl(0, 0, 10, 10), box_tpl(1, 1, 2, 2))
|
|
|
|
|
|
def test_polygon_no_hole_wrong_type():
|
|
with pytest.raises((TypeError, shapely.GEOSException)):
|
|
shapely.polygons(point)
|
|
|
|
|
|
def test_polygon_with_hole_wrong_type():
|
|
with pytest.raises((TypeError, shapely.GEOSException)):
|
|
shapely.polygons(point, [linear_ring])
|
|
|
|
|
|
def test_polygon_wrong_hole_type():
|
|
with pytest.raises((TypeError, shapely.GEOSException)):
|
|
shapely.polygons(linear_ring, [point])
|
|
|
|
|
|
def test_polygon_with_1_hole():
|
|
actual = shapely.polygons(box_tpl(0, 0, 10, 10), [box_tpl(1, 1, 2, 2)])
|
|
assert shapely.area(actual) == 99.0
|
|
|
|
|
|
def test_polygon_with_2_holes():
|
|
actual = shapely.polygons(
|
|
box_tpl(0, 0, 10, 10), [box_tpl(1, 1, 2, 2), box_tpl(3, 3, 4, 4)]
|
|
)
|
|
assert shapely.area(actual) == 98.0
|
|
|
|
|
|
def test_polygon_with_none_hole():
|
|
actual = shapely.polygons(
|
|
shapely.linearrings(box_tpl(0, 0, 10, 10)),
|
|
[
|
|
shapely.linearrings(box_tpl(1, 1, 2, 2)),
|
|
None,
|
|
shapely.linearrings(box_tpl(3, 3, 4, 4)),
|
|
],
|
|
)
|
|
assert shapely.area(actual) == 98.0
|
|
|
|
|
|
def test_2_polygons_with_same_hole():
|
|
actual = shapely.polygons(
|
|
[box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)], [box_tpl(1, 1, 2, 2)]
|
|
)
|
|
assert shapely.area(actual).tolist() == [99.0, 24.0]
|
|
|
|
|
|
def test_2_polygons_with_2_same_holes():
|
|
actual = shapely.polygons(
|
|
[box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)],
|
|
[box_tpl(1, 1, 2, 2), box_tpl(3, 3, 4, 4)],
|
|
)
|
|
assert shapely.area(actual).tolist() == [98.0, 23.0]
|
|
|
|
|
|
def test_2_polygons_with_different_holes():
|
|
actual = shapely.polygons(
|
|
[box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)],
|
|
[[box_tpl(1, 1, 3, 3)], [box_tpl(1, 1, 2, 2)]],
|
|
)
|
|
assert shapely.area(actual).tolist() == [96.0, 24.0]
|
|
|
|
|
|
def test_polygons_not_enough_points_in_shell_scalar():
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons((1, 1))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"shape",
|
|
[
|
|
(2, 1, 2), # 2 linearrings of 1 2D point
|
|
(1, 1, 2), # 1 linearring of 1 2D point
|
|
(1, 2), # 1 linearring of 1 2D point (scalar)
|
|
(2, 2, 2), # 2 linearrings of 2 2D points
|
|
(1, 2, 2), # 1 linearring of 2 2D points
|
|
(2, 2), # 1 linearring of 2 2D points (scalar)
|
|
],
|
|
)
|
|
def test_polygons_not_enough_points_in_shell(shape):
|
|
coords = np.ones(shape)
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(coords)
|
|
|
|
# make sure the first coordinate != second coordinate
|
|
coords[..., 1] += 1
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(coords)
|
|
|
|
|
|
def test_polygons_not_enough_points_in_holes_scalar():
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(np.ones((1, 4, 2)), (1, 1))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"shape",
|
|
[
|
|
(2, 1, 2), # 2 linearrings of 1 2D point
|
|
(1, 1, 2), # 1 linearring of 1 2D point
|
|
(1, 2), # 1 linearring of 1 2D point (scalar)
|
|
(2, 2, 2), # 2 linearrings of 2 2D points
|
|
(1, 2, 2), # 1 linearring of 2 2D points
|
|
(2, 2), # 1 linearring of 2 2D points (scalar)
|
|
],
|
|
)
|
|
def test_polygons_not_enough_points_in_holes(shape):
|
|
coords = np.ones(shape)
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(np.ones((1, 4, 2)), coords)
|
|
|
|
# make sure the first coordinate != second coordinate
|
|
coords[..., 1] += 1
|
|
with pytest.raises(ValueError):
|
|
shapely.polygons(np.ones((1, 4, 2)), coords)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"func,expected",
|
|
[
|
|
(shapely.multipoints, MultiPoint()),
|
|
(shapely.multilinestrings, MultiLineString()),
|
|
(shapely.multipolygons, MultiPolygon()),
|
|
(shapely.geometrycollections, GeometryCollection()),
|
|
],
|
|
)
|
|
def test_create_collection_only_none(func, expected):
|
|
actual = func(np.array([None], dtype=object))
|
|
assert_geometries_equal(actual, expected)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"func,sub_geom",
|
|
[
|
|
(shapely.multipoints, point),
|
|
(shapely.multilinestrings, line_string),
|
|
(shapely.multilinestrings, linear_ring),
|
|
(shapely.multipolygons, polygon),
|
|
(shapely.geometrycollections, point),
|
|
(shapely.geometrycollections, line_string),
|
|
(shapely.geometrycollections, linear_ring),
|
|
(shapely.geometrycollections, polygon),
|
|
(shapely.geometrycollections, multi_point),
|
|
(shapely.geometrycollections, multi_line_string),
|
|
(shapely.geometrycollections, multi_polygon),
|
|
(shapely.geometrycollections, geometry_collection),
|
|
],
|
|
)
|
|
def test_create_collection(func, sub_geom):
|
|
actual = func([sub_geom, sub_geom])
|
|
assert shapely.get_num_geometries(actual) == 2
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"func,sub_geom",
|
|
[
|
|
(shapely.multipoints, point),
|
|
(shapely.multilinestrings, line_string),
|
|
(shapely.multipolygons, polygon),
|
|
(shapely.geometrycollections, polygon),
|
|
],
|
|
)
|
|
def test_create_collection_skips_none(func, sub_geom):
|
|
actual = func([sub_geom, None, None, sub_geom])
|
|
assert shapely.get_num_geometries(actual) == 2
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"func,sub_geom",
|
|
[
|
|
(shapely.multipoints, line_string),
|
|
(shapely.multipoints, geometry_collection),
|
|
(shapely.multipoints, multi_point),
|
|
(shapely.multilinestrings, point),
|
|
(shapely.multilinestrings, polygon),
|
|
(shapely.multilinestrings, multi_line_string),
|
|
(shapely.multipolygons, linear_ring),
|
|
(shapely.multipolygons, multi_point),
|
|
(shapely.multipolygons, multi_polygon),
|
|
],
|
|
)
|
|
def test_create_collection_wrong_geom_type(func, sub_geom):
|
|
with pytest.raises(TypeError):
|
|
func([sub_geom])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords,ccw,expected",
|
|
[
|
|
((0, 0, 1, 1), True, Polygon([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)])),
|
|
(
|
|
(0, 0, 1, 1),
|
|
False,
|
|
Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]),
|
|
),
|
|
],
|
|
)
|
|
def test_box(coords, ccw, expected):
|
|
actual = shapely.box(*coords, ccw=ccw)
|
|
assert_geometries_equal(actual, expected)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords,ccw,expected",
|
|
[
|
|
(
|
|
(0, 0, [1, 2], [1, 2]),
|
|
True,
|
|
[
|
|
Polygon([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)]),
|
|
Polygon([(2, 0), (2, 2), (0, 2), (0, 0), (2, 0)]),
|
|
],
|
|
),
|
|
(
|
|
(0, 0, [1, 2], [1, 2]),
|
|
[True, False],
|
|
[
|
|
Polygon([(1, 0), (1, 1), (0, 1), (0, 0), (1, 0)]),
|
|
Polygon([(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
def test_box_array(coords, ccw, expected):
|
|
actual = shapely.box(*coords, ccw=ccw)
|
|
assert_geometries_equal(actual, expected)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"coords",
|
|
[
|
|
[np.nan, np.nan, np.nan, np.nan],
|
|
[np.nan, 0, 1, 1],
|
|
[0, np.nan, 1, 1],
|
|
[0, 0, np.nan, 1],
|
|
[0, 0, 1, np.nan],
|
|
],
|
|
)
|
|
def test_box_nan(coords):
|
|
assert shapely.box(*coords) is None
|
|
|
|
|
|
def test_box_deprecate_positional():
|
|
with pytest.deprecated_call(
|
|
match="positional argument `ccw` for `box` is deprecated"
|
|
):
|
|
shapely.box(0, 0, 1, 1, True)
|
|
|
|
|
|
def test_prepare():
|
|
arr = np.array([shapely.points(1, 1), None, shapely.box(0, 0, 1, 1)])
|
|
assert arr[0]._geom_prepared == 0
|
|
assert arr[2]._geom_prepared == 0
|
|
shapely.prepare(arr)
|
|
assert arr[0]._geom_prepared != 0
|
|
assert arr[1] is None
|
|
assert arr[2]._geom_prepared != 0
|
|
|
|
# preparing again actually does nothing
|
|
original = arr[0]._geom_prepared
|
|
shapely.prepare(arr)
|
|
assert arr[0]._geom_prepared == original
|
|
|
|
|
|
def test_destroy_prepared():
|
|
arr = np.array([shapely.points(1, 1), None, shapely.box(0, 0, 1, 1)])
|
|
shapely.prepare(arr)
|
|
assert arr[0]._geom_prepared != 0
|
|
assert arr[2]._geom_prepared != 0
|
|
shapely.destroy_prepared(arr)
|
|
assert arr[0]._geom_prepared == 0
|
|
assert arr[1] is None
|
|
assert arr[2]._geom_prepared == 0
|
|
shapely.destroy_prepared(arr) # does not error
|
|
|
|
|
|
@pytest.mark.parametrize("geom_type", [None, GeometryType.MISSING, -1])
|
|
def test_empty_missing(geom_type):
|
|
actual = shapely.empty((2,), geom_type=geom_type)
|
|
assert shapely.is_missing(actual).all()
|
|
|
|
|
|
@pytest.mark.parametrize("geom_type", range(8))
|
|
def test_empty(geom_type):
|
|
actual = shapely.empty((2,), geom_type=geom_type)
|
|
assert (~shapely.is_missing(actual)).all()
|
|
assert shapely.is_empty(actual).all()
|
|
assert (shapely.get_type_id(actual) == geom_type).all()
|