Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions pydantic_geojson/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
),
]

AltField = Annotated[
Union[float, int],
Field(
title="Coordinate altitude",
),
]

PointFieldType = Annotated[Literal[POINT], Field(POINT, title="Point")] # type: ignore

MultiPointFieldType = Annotated[
Expand Down Expand Up @@ -104,10 +111,22 @@
class Coordinates(NamedTuple):
lon: LonField
lat: LatField
alt: Optional[AltField] = None

def __eq__(self, other):
# Note that +180 and -180 are not considered equal here
return math.isclose(self.lon, other.lon) and math.isclose(self.lat, other.lat)
# Note that +180 and -180 are not considered equal latitude here
lon_equal = math.isclose(self.lon, other.lon)
lat_equal = math.isclose(self.lat, other.lat)
alt_equal = (
self.alt is None
and other.alt is None
or (
self.alt is not None
and other.alt is not None
and math.isclose(self.alt, other.alt)
)
)
return lon_equal and lat_equal and alt_equal


def check_linear_ring(linear_ring: List[Coordinates]) -> List[Coordinates]:
Expand Down
44 changes: 44 additions & 0 deletions tests/test_coordinates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest
from pydantic_geojson._base import Coordinates


@pytest.mark.parametrize(
"coord_one,coord_two,is_equal",
[
(
Coordinates(0, 0, None),
Coordinates(0, 0, None),
True,
), # None and None are equivalent
(
Coordinates(0, 0, 0),
Coordinates(0, 0, 0),
True,
), # Zero and Zero are equivalent
(
Coordinates(0, 0, None),
Coordinates(0, 0, 0),
False,
), # Altiture not specified for coord_one
(Coordinates(1, 0, None), Coordinates(0, 0, None), False), # Latitude not equal
(
Coordinates(0, 1, None),
Coordinates(0, 0, None),
False,
), # Longitude not equal
(
Coordinates(0, 0, 1),
Coordinates(0, 0, 0),
False,
), # Altitude specified but not equal
(
Coordinates(180, 0, None),
Coordinates(-180, 0, None),
False,
), # Plus and minus 180 latitude are not considered equal
],
)
def test_coordinate_equality(coord_one, coord_two, is_equal):
assert (
coord_one == coord_two
) == is_equal, f"Result of {coord_one} == {coord_two} should be {is_equal}"
2 changes: 1 addition & 1 deletion tests/test_feature_on_lat_lon_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_loads_model_linestring(self):
coordinates = ls_model.coordinates

for lsi_key, ls_item in enumerate(coordinates):
lon, lat = ls_item
lon, lat, _ = ls_item
assert data_linestring["coordinates"][lsi_key] == [lon, lat]

assert ls_model.type == data_linestring["type"]
Expand Down
2 changes: 1 addition & 1 deletion tests/test_line_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_loads_model(self, valid_linestring_data):
coordinates = ls_model.coordinates

for lsi_key, ls_item in enumerate(coordinates):
lon, lat = ls_item
lon, lat, _ = ls_item
assert valid_linestring_data["coordinates"][lsi_key] == [lon, lat]

assert ls_model.type == valid_linestring_data["type"]
Expand Down