Skip to content

Commit

Permalink
Consolidate coordinate classes (#59)
Browse files Browse the repository at this point in the history
* Consolidate coordinate classes

* Linting and formatting
  • Loading branch information
Xierumeng authored Nov 12, 2024
1 parent a32385e commit 2880069
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

import simplekml

from . import named_location_global
from .. import location_global


def ground_locations_to_kml(
ground_locations: list[named_location_global.NamedLocationGlobal],
def named_locations_to_kml(
named_locations: list[location_global.NamedLocationGlobal],
document_name_prefix: str,
save_directory: pathlib.Path,
) -> "tuple[bool, pathlib.Path | None]":
) -> tuple[True, pathlib.Path] | tuple[False, None]:
"""
Generates a KML file from a list of ground locations.
Expand All @@ -26,10 +26,10 @@ def ground_locations_to_kml(
"""
kml = simplekml.Kml()

for i, ground_location in enumerate(ground_locations):
ground_location_name = f"Point {i + 1}: {ground_location.name}"
latitude = ground_location.location.latitude
longitude = ground_location.location.longitude
for i, named_location in enumerate(named_locations):
ground_location_name = f"Point {i + 1}: {named_location.name}"
latitude = named_location.latitude
longitude = named_location.longitude

# Coordinates are in the order: longitude, latitude, optional height
kml.newpoint(name=ground_location_name, coords=[(longitude, latitude)])
Expand All @@ -39,9 +39,10 @@ def ground_locations_to_kml(

try:
kml.save(str(kml_file_path))
return True, kml_file_path
# Required for catching library exceptions
# pylint: disable-next=broad-exception-caught
except Exception as exception:
print(f"Error while saving KML file: {exception}")
return False, None

return True, kml_file_path
56 changes: 0 additions & 56 deletions modules/kml/named_location_global.py

This file was deleted.

43 changes: 43 additions & 0 deletions modules/location_global.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""
Location on ground in WGS 84.
Class with name also available.
"""


Expand Down Expand Up @@ -42,3 +44,44 @@ def __repr__(self) -> str:
For collections (e.g. list).
"""
return str(self)


class NamedLocationGlobal(LocationGlobal):
"""
Named LocationGlobal.
"""

__create_key = object()

@classmethod
# Additional argument for name
# pylint: disable-next=arguments-differ
def create(
cls, name: str, latitude: float, longitude: float
) -> "tuple[True, NamedLocationGlobal] | tuple[False, None]":
"""
name: Can be empty.
latitude: Decimal degrees.
longitude: Decimal degrees.
Return: Success, object.
"""
return True, NamedLocationGlobal(cls.__create_key, name, latitude, longitude)

def __init__(
self, class_private_create_key: object, name: str, latitude: float, longitude: float
) -> None:
"""
Private constructor, use create() method.
"""
assert class_private_create_key is NamedLocationGlobal.__create_key, "Use create() method."

super().__init__(super()._LocationGlobal__create_key, latitude, longitude)

self.name = name

def __str__(self) -> str:
"""
To string.
"""
return f"{self.__class__}: name: {self.name}, latitude: {self.latitude}, longitude: {self.longitude}"
49 changes: 46 additions & 3 deletions modules/location_local.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
"""
Location on the ground in local Euclidean space (origin at home position global).
Class with name also available.
"""


class LocationLocal:
"""
Location in NED system, with down = 0.0 .
Location in NED system relative to home position, with down = 0.0 .
"""

__create_key = object()

@classmethod
def create(cls, north: float, east: float) -> "tuple[True, LocationLocal] | tuple[False, None]":
"""
North: Metres.
East: Metres.
north: Metres.
east: Metres.
Return: Success, object.
"""
Expand All @@ -40,3 +42,44 @@ def __repr__(self) -> str:
For collections (e.g. list).
"""
return str(self)


class NamedLocationLocal(LocationLocal):
"""
Named LocationLocal.
"""

__create_key = object()

@classmethod
# Additional argument for name
# pylint: disable-next=arguments-differ
def create(
cls, name: str, north: float, east: float
) -> "tuple[True, NamedLocationLocal] | tuple[False, None]":
"""
name: Can be empty.
north: Metres.
east: Metres.
Return: Success, object.
"""
return True, NamedLocationLocal(cls.__create_key, name, north, east)

def __init__(
self, class_private_create_key: object, name: str, north: float, east: float
) -> None:
"""
Private constructor, use create() method.
"""
assert class_private_create_key is NamedLocationLocal.__create_key, "Use create() method."

super().__init__(super()._LocationLocal__create_key, north, east)

self.name = name

def __str__(self) -> str:
"""
To string.
"""
return f"{self.__class__}: name: {self.name}, north: {self.north}, east: {self.east}"
53 changes: 53 additions & 0 deletions modules/position_global.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""
3D position in WGS 84.
Class with name also available.
"""


Expand Down Expand Up @@ -46,3 +48,54 @@ def __repr__(self) -> str:
For collections (e.g. list).
"""
return str(self)


class NamedPositionGlobal(PositionGlobal):
"""
Named PositionGlobal.
"""

__create_key = object()

@classmethod
# Additional argument for name
# pylint: disable-next=arguments-differ
def create(
cls,
name: str,
latitude: float,
longitude: float,
altitude: float,
) -> "tuple[True, NamedPositionGlobal] | tuple[False, None]":
"""
name: Can be empty.
latitude: Decimal degrees.
longitude: Decimal degrees.
altitude: Metres above mean sea level (MSL). Can be negative.
Return: Success, object.
"""
return True, NamedPositionGlobal(cls.__create_key, name, latitude, longitude, altitude)

def __init__(
self,
class_private_create_key: object,
name: str,
latitude: float,
longitude: float,
altitude: float,
) -> None:
"""
Private constructor, use create() method.
"""
assert class_private_create_key is NamedPositionGlobal.__create_key, "Use create() method."

super().__init__(super()._PositionGlobal__create_key, latitude, longitude, altitude)

self.name = name

def __str__(self) -> str:
"""
To string.
"""
return f"{self.__class__}: name: {self.name}, latitude: {self.latitude}, longitude: {self.longitude}, altitude: {self.altitude}"
Loading

0 comments on commit 2880069

Please sign in to comment.