Commit 35e2ef8f authored by Joseph Siddons's avatar Joseph Siddons
Browse files

refactor(Record)!: Raises error if lat out of bounds, adds option to fix lon...

refactor(Record)!: Raises error if lat out of bounds, adds option to fix lon to -180, 180 (defaults to True)
parent 1a983768
from datetime import datetime, timedelta from datetime import datetime, timedelta
from .distance_metrics import haversine import datetime
from .distance_metrics import haversine, destination from .distance_metrics import haversine, destination
from .utils import LatitudeError
from math import degrees, sqrt from math import degrees, sqrt
...@@ -25,12 +26,14 @@ class SpaceTimeRecord: ...@@ -25,12 +26,14 @@ class SpaceTimeRecord:
Horizontal coordinate (longitude). Horizontal coordinate (longitude).
lat : float lat : float
Vertical coordinate (latitude). Vertical coordinate (latitude).
datetime : datetime datetime : datetime.datetime
Datetime of the record. Can also be a numeric value such as pentad. Datetime of the record. Can also be a numeric value such as pentad.
Comparisons between Records with datetime and Records with numeric Comparisons between Records with datetime and Records with numeric
datetime will fail. datetime will fail.
uid : str | None uid : str | None
Unique Identifier. Unique Identifier.
fix_lon : bool
Force longitude to -180, 180
**data **data
Additional data passed to the SpaceTimeRecord for use by other functions Additional data passed to the SpaceTimeRecord for use by other functions
or classes. or classes.
...@@ -40,11 +43,19 @@ class SpaceTimeRecord: ...@@ -40,11 +43,19 @@ class SpaceTimeRecord:
self, self,
lon: float, lon: float,
lat: float, lat: float,
datetime: datetime, datetime: datetime.datetime,
uid: str | None = None, uid: str | None = None,
fix_lon: bool = True,
**data, **data,
) -> None: ) -> None:
self.lon = lon self.lon = lon
if fix_lon:
# Move lon to -180, 180
self.lon = ((self.lon + 540) % 360) - 180
if lat < -90 or lat > 90:
raise LatitudeError(
"Expected latitude value to be between -90 and 90 degrees"
)
self.lat = lat self.lat = lat
self.datetime = datetime self.datetime = datetime
self.uid = uid self.uid = uid
...@@ -53,12 +64,15 @@ class SpaceTimeRecord: ...@@ -53,12 +64,15 @@ class SpaceTimeRecord:
return None return None
def __str__(self) -> str: def __str__(self) -> str:
return f"Record(x = {self.lon}, y = {self.lat}, datetime = {self.datetime}, uid = {self.uid})" return f"SpaceTimeRecord(x = {self.lon}, y = {self.lat}, datetime = {self.datetime}, uid = {self.uid})"
def __eq__(self, other: object) -> bool: def __eq__(self, other: object) -> bool:
if not isinstance(other, SpaceTimeRecord):
return False
if self.uid and other.uid:
return self.uid == other.uid
return ( return (
isinstance(other, SpaceTimeRecord) self.lon == other.lon
and self.lon == other.lon
and self.lat == other.lat and self.lat == other.lat
and self.datetime == other.datetime and self.datetime == other.datetime
and (not (self.uid or other.uid) or self.uid == other.uid) and (not (self.uid or other.uid) or self.uid == other.uid)
......
...@@ -5,6 +5,7 @@ for detecting nearby records for example ...@@ -5,6 +5,7 @@ for detecting nearby records for example
from datetime import datetime from datetime import datetime
from .distance_metrics import haversine, destination from .distance_metrics import haversine, destination
from .utils import LatitudeError
from math import degrees, sqrt from math import degrees, sqrt
...@@ -12,6 +13,12 @@ class Record: ...@@ -12,6 +13,12 @@ class Record:
""" """
ICOADS Record class ICOADS Record class
This is a simple instance of an ICOARDS record, it requires position data.
It can optionally include datetime, a UID, and extra data passed as
keyword arguments.
Equality is checked only on the required fields + UID if it is specified.
Parameters Parameters
---------- ----------
lon : float lon : float
...@@ -22,6 +29,11 @@ class Record: ...@@ -22,6 +29,11 @@ class Record:
Datetime of the record Datetime of the record
uid : str | None uid : str | None
Unique Identifier Unique Identifier
fix_lon : bool
Force longitude to -180, 180
**data
Additional data passed to the Record for use by other functions or
classes.
""" """
def __init__( def __init__(
...@@ -30,9 +42,17 @@ class Record: ...@@ -30,9 +42,17 @@ class Record:
lat: float, lat: float,
datetime: datetime | None = None, datetime: datetime | None = None,
uid: str | None = None, uid: str | None = None,
fix_lon: bool = True,
**data, **data,
) -> None: ) -> None:
self.lon = lon self.lon = lon
if fix_lon:
# Move lon to -180, 180
self.lon = ((self.lon + 540) % 360) - 180
if lat < -90 or lat > 90:
raise LatitudeError(
"Expected latitude value to be between -90 and 90 degrees"
)
self.lat = lat self.lat = lat
self.datetime = datetime self.datetime = datetime
self.uid = uid self.uid = uid
...@@ -44,9 +64,12 @@ class Record: ...@@ -44,9 +64,12 @@ class Record:
return f"Record(lon = {self.lon}, lat = {self.lat}, datetime = {self.datetime}, uid = {self.uid})" return f"Record(lon = {self.lon}, lat = {self.lat}, datetime = {self.datetime}, uid = {self.uid})"
def __eq__(self, other: object) -> bool: def __eq__(self, other: object) -> bool:
if not isinstance(other, Record):
return False
if self.uid and other.uid:
return self.uid == other.uid
return ( return (
isinstance(other, Record) self.lon == other.lon
and self.lon == other.lon
and self.lat == other.lat and self.lat == other.lat
and self.datetime == other.datetime and self.datetime == other.datetime
and (not (self.uid or other.uid) or self.uid == other.uid) and (not (self.uid or other.uid) or self.uid == other.uid)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment