Skip to content

Commit

Permalink
Added the Position class
Browse files Browse the repository at this point in the history
  • Loading branch information
felix-zenk committed Sep 5, 2022
1 parent 3b4d3b5 commit 8ec0723
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 10 deletions.
10 changes: 5 additions & 5 deletions onboardapis/trains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .. import Vehicle
from ..exceptions import DataInvalidError, APIConnectionError, InitialConnectionError
from ..utils.conversions import coordinates_to_distance
from ..utils.data import StaticDataConnector, DynamicDataConnector, ScheduledEvent
from ..utils.data import StaticDataConnector, DynamicDataConnector, ScheduledEvent, Position


class Station(object):
Expand All @@ -22,7 +22,7 @@ class Station(object):

def __init__(self, station_id: Any, name: str, platform: ScheduledEvent[str] = None,
arrival: ScheduledEvent[datetime.datetime] = None, departure: ScheduledEvent[datetime.datetime] = None,
position: Tuple[float, float] = None, distance: float = None,
position: Position = None, distance: float = None,
connections: List["ConnectingTrain"] = None):
"""
Initialize a new :class:`Station`
Expand All @@ -38,7 +38,7 @@ def __init__(self, station_id: Any, name: str, platform: ScheduledEvent[str] = N
:param departure: The departure time from this station
:type departure: ScheduledEvent[datetime.datetime]
:param position: The geographic position of the station
:type position: Tuple[float, float]
:type position: Position
:param distance: The distance from the start to this station
:type distance: float
:param connections: The connecting services departing from this station
Expand Down Expand Up @@ -124,12 +124,12 @@ def distance(self) -> float:
return self._distance

@property
def position(self) -> Tuple[float, float]:
def position(self) -> Position:
"""
The geographic position of the station
:return: The coordinates of the station
:rtype: Tuple[float, float]
:rtype: Position
"""
return self._position

Expand Down
15 changes: 10 additions & 5 deletions onboardapis/trains/austria/oebb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from .. import Train, Station, ConnectingTrain
from ...exceptions import DataInvalidError
from ...utils.conversions import kmh_to_ms
from ...utils.data import StaticDataConnector, DynamicDataConnector, JSONDataConnector, some_or_default, ScheduledEvent
from ...utils.data import StaticDataConnector, DynamicDataConnector, JSONDataConnector, some_or_default, ScheduledEvent, \
Position

API_BASE_URL_RAILNET_REGIO = "railnet.oebb.at"

Expand Down Expand Up @@ -162,11 +163,15 @@ def distance(self) -> float:
raise DataInvalidError("No base station found for distance") from e

@property
def position(self) -> Tuple[float, float]:
def position(self) -> Position:
map_info = self._dynamic_data.load('combined', {}).get('mapInfo', {})
return (
float(map_info.get('latitude')) if some_or_default(map_info.get('latitude')) is not None else None,
float(map_info.get('longitude')) if some_or_default(map_info.get('longitude')) is not None else None
return Position(
latitude=(
float(map_info.get('latitude')) if some_or_default(map_info.get('latitude')) is not None else None
),
longitude=(
float(map_info.get('longitude')) if some_or_default(map_info.get('longitude')) is not None else None
)
)

@property
Expand Down
93 changes: 93 additions & 0 deletions onboardapis/utils/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from requests import Response

from .conversions import coordinates_decimal_to_dms
from ..exceptions import DataInvalidError, APIConnectionError, InitialConnectionError
from .. import __version__

Expand Down Expand Up @@ -78,6 +79,98 @@ def __str__(self):
return f"{self.actual}"


class Position(object):
"""
A position requires at least a latitude and longitude,
but can also provide data on altitude and the current compass heading.
"""

__slots__ = ["_latitude", "_longitude", "_altitude", "_heading"]

def __init__(self, latitude: float, longitude: float, altitude: float = None, bearing: float = None):
"""
Initialize a new :class:`Position`.
:param latitude: The latitude in decimal degrees
:type latitude: float
:param longitude: The longitude in decimal degrees
:type longitude: float
:param altitude: The altitude in meters
:type altitude: float
:param bearing: The compass heading in degrees
:type bearing: float
"""
self._latitude = latitude
self._longitude = longitude
self._altitude = altitude
self._heading = bearing

def __str__(self) -> str:
(lat_deg, lat_min, lat_sec), (lon_deg, lon_min, lon_sec) = coordinates_decimal_to_dms(
(self.latitude, self.longitude)
)
coordinates = (
f"{abs(lat_deg)}°{lat_min}'{lat_sec:.3f}\"{'N' if lat_deg >= 0 else 'S'} "
f"{abs(lon_deg)}°{lon_min}'{lon_sec:.3f}\"{'E' if lon_deg >= 0 else 'W'}"
)
return coordinates

def __getitem__(self, item):
return list([self.latitude, self.longitude])[item]

@property
def latitude(self) -> float:
"""
The latitude in decimal degrees.
:return: The latitude
:rtype: float
"""
return self._latitude

@property
def longitude(self) -> float:
"""
The longitude in decimal degrees.
:return: The longitude
:rtype: float
"""
return self._longitude

@property
def altitude(self) -> float:
"""
The altitude in meters.
:return: The altitude
:rtype: float
"""
return self._altitude

@property
def heading(self) -> float:
"""
The compass heading in degrees.
0 is north, 90 is east, 180 is south, 270 is west.
:return: The heading
:rtype: float
"""
return self._heading

def calculate_distance(self, other: "Position") -> float:
"""
Calculate the distance (in meters) between this position and another position.
:param other: The other position
:return: The distance in meters
"""
raise NotImplementedError()
# return coordinates_to_distance((self.latitude, self.longitude), (other.latitude, other.longitude))


class DataStorage:
"""
A storage class that can be used to store data and retrieve it later.
Expand Down

0 comments on commit 8ec0723

Please sign in to comment.