diff --git a/pygeoif/functions.py b/pygeoif/functions.py index 1d771285..034f669e 100644 --- a/pygeoif/functions.py +++ b/pygeoif/functions.py @@ -220,7 +220,7 @@ def move_coordinates( Move the coordinates recursively by the given vector. This forcefully changes the dimension of each of the coordinate to match - the dimension of the vector. + the dimensionality of the vector. >>> move_coordinates(((0, 0), (-1, 1)), (-1, 1)) ((-1, 1), (-2, 2)) >>> move_coordinates(((0, 0, 0), (-1, 1, 0)), (-1, 1)) @@ -228,15 +228,27 @@ def move_coordinates( >>> move_coordinates(((0, 0), (-1, 1)), (-1, 1, 0)) ((-1, 1, 0), (-2, 2, 0)) """ - if isinstance(coordinates, (tuple, list)) and isinstance( - coordinates[0], - (int, float), - ): - # coordinates is just a list of numbers, i.e. represents a single coordinate + if is_coordinate(coordinates): + # a single coordinate return move_coordinate(coordinates, move_by, z) + # a list of coordinates return tuple(move_coordinates(c, move_by, z) for c in coordinates) +def is_coordinate(val: Any) -> bool: # noqa: ANN401 + """ + Check if given value is a coordinate i.e. vector of generic dimensionality. + + >>> is_coordinate((1, 0)) + True + >>> is_coordinate(1) + False + >>> is_coordinate([(1, 2), (3, 4)]) + False + """ + return isinstance(val, tuple) and all(isinstance(x, (int, float)) for x in val) + + __all__ = [ "centroid", "compare_coordinates", @@ -245,5 +257,6 @@ def move_coordinates( "dedupe", "move_coordinate", "move_coordinates", + "is_coordinate", "signed_area", ] diff --git a/tests/test_functions.py b/tests/test_functions.py index e1441a22..8966e215 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -12,6 +12,7 @@ from pygeoif.functions import convex_hull from pygeoif.functions import dedupe from pygeoif.functions import signed_area +from pygeoif.functions import is_coordinate def circle_ish(x, y, r, steps): @@ -452,3 +453,18 @@ def test_compare_neq_empty_geo_interface() -> None: } assert compare_geo_interface(geo_if, {}) is False + + +def test_is_coordinate() -> None: + assert is_coordinate((1, 2)) is True + assert is_coordinate((1,)) is True + + +def test_is_coordinate_not_composite_coordinates() -> None: + assert is_coordinate([(1, 2)]) is False + assert is_coordinate(((1, 2), )) is False + assert is_coordinate((((1, 2), ), )) is False + + +def test_is_coordinate_not_primitive() -> None: + assert is_coordinate(1) is False