Skip to content

Commit

Permalink
KML support unnamed locations as input (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xierumeng authored Nov 13, 2024
1 parent b737ef8 commit a0aac8c
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 88 deletions.
38 changes: 34 additions & 4 deletions modules/kml/locations_to_kml.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@
from .. import location_global


def locations_to_kml(
locations: list[location_global.LocationGlobal],
document_name_prefix: str,
save_directory: pathlib.Path,
) -> "tuple[bool, pathlib.Path | None]":
"""
Converts locations to named locations with empty name and calls named_locations_to_kml.
locations: Locations without names.
document_name_prefix: Name of the KML file to save (without the timestamp or .kml extension).
save_directory: Parent directory to save the KML file to.
Return: Success, path to the KML file.
"""
named_locations = []
for i, location in enumerate(locations):
result, named_location = location_global.NamedLocationGlobal.create(
str(i), location.latitude, location.longitude
)
if not result:
return False, None

# Get Pylance to stop complaining
assert named_location is not None

named_locations.append(named_location)

return named_locations_to_kml(named_locations, document_name_prefix, save_directory)


def named_locations_to_kml(
named_locations: list[location_global.NamedLocationGlobal],
document_name_prefix: str,
Expand All @@ -18,21 +48,21 @@ def named_locations_to_kml(
"""
Generates a KML file from a list of ground locations.
ground_locations: Ground locations.
named_locations: Locations with names.
document_name_prefix: Name of the KML file to save (without the timestamp or .kml extension).
save_directory: Parent directory to save the KML file to.
Return: Success, path to the KML file.
"""
kml = simplekml.Kml()

for i, named_location in enumerate(named_locations):
ground_location_name = f"Point {i + 1}: {named_location.name}"
for named_location in named_locations:
name = 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)])
kml.newpoint(name=name, coords=[(longitude, latitude)])

current_time = time.time()
kml_file_path = pathlib.Path(save_directory, f"{document_name_prefix}_{int(current_time)}.kml")
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/kml_documents/expected_enumerated.kml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document id="9">
<Placemark id="11">
<name>0</name>
<Point id="10">
<coordinates>-122.4194,37.7749,0.0</coordinates>
</Point>
</Placemark>
<Placemark id="13">
<name>1</name>
<Point id="12">
<coordinates>-118.2437,34.0522,0.0</coordinates>
</Point>
</Placemark>
<Placemark id="15">
<name>2</name>
<Point id="14">
<coordinates>-74.006,40.7128,0.0</coordinates>
</Point>
</Placemark>
</Document>
</kml>
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document id="1">
<Placemark id="3">
<name>Point 1: San Francisco</name>
<name>San Francisco</name>
<Point id="2">
<coordinates>-122.4194,37.7749,0.0</coordinates>
</Point>
</Placemark>
<Placemark id="5">
<name>Point 2: Los Angeles</name>
<name>Los Angeles</name>
<Point id="4">
<coordinates>-118.2437,34.0522,0.0</coordinates>
</Point>
</Placemark>
<Placemark id="7">
<name>Point 3: New York City</name>
<name>New York City</name>
<Point id="6">
<coordinates>-74.006,40.7128,0.0</coordinates>
</Point>
Expand Down
81 changes: 0 additions & 81 deletions tests/unit/test_ground_locations_to_kml.py

This file was deleted.

134 changes: 134 additions & 0 deletions tests/unit/test_locations_to_kml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"""
Test Process.
"""

import pathlib

import pytest

from modules import location_global
from modules.kml import locations_to_kml


PARENT_DIRECTORY = pathlib.Path("tests", "unit", "kml_documents")
KML_SUFFIX = ".kml"


# Test functions use test fixture signature names and access class privates
# No enable
# pylint: disable=protected-access,redefined-outer-name


@pytest.fixture
def locations() -> list[location_global.LocationGlobal]: # type: ignore
"""
List of locations.
"""
result, san_francisco = location_global.LocationGlobal.create(37.7749, -122.4194)
assert result
assert san_francisco is not None

result, los_angeles = location_global.LocationGlobal.create(34.0522, -118.2437)
assert result
assert los_angeles is not None

result, new_york_city = location_global.LocationGlobal.create(40.7128, -74.0060)
assert result
assert new_york_city is not None

yield [
san_francisco,
los_angeles,
new_york_city,
]


@pytest.fixture
def named_locations() -> list[location_global.NamedLocationGlobal]: # type: ignore
"""
List of named locations.
"""
result, san_francisco = location_global.NamedLocationGlobal.create(
"San Francisco", 37.7749, -122.4194
)
assert result
assert san_francisco is not None

result, los_angeles = location_global.NamedLocationGlobal.create(
"Los Angeles", 34.0522, -118.2437
)
assert result
assert los_angeles is not None

result, new_york_city = location_global.NamedLocationGlobal.create(
"New York City", 40.7128, -74.0060
)
assert result
assert new_york_city is not None

yield [
san_francisco,
los_angeles,
new_york_city,
]


def test_named_locations_to_kml_with_save_path(
named_locations: list[location_global.NamedLocationGlobal], tmp_path: pathlib.Path
) -> None:
"""
Basic test case to save KML to the correct path when provided.
"""
# Setup
expected_kml_document_path = pathlib.Path(PARENT_DIRECTORY, "expected_named.kml")
actual_kml_document_name = "actual"

tmp_path.mkdir(parents=True, exist_ok=True)

# Run
result, actual_kml_file_path = locations_to_kml.named_locations_to_kml(
named_locations,
actual_kml_document_name,
tmp_path,
)

# Check
assert result
assert actual_kml_file_path is not None

assert actual_kml_file_path.exists()
assert actual_kml_file_path.suffix == KML_SUFFIX

assert actual_kml_file_path.read_text(encoding="utf-8") == expected_kml_document_path.read_text(
encoding="utf-8"
)


def test_locations_to_kml(
locations: list[location_global.LocationGlobal], tmp_path: pathlib.Path
) -> None:
"""
Basic test case for locations without names.
"""
expected_kml_document_path = pathlib.Path(PARENT_DIRECTORY, "expected_enumerated.kml")
actual_kml_document_name = "actual_kml_document"

tmp_path.mkdir(parents=True, exist_ok=True)

# Run
result, actual_kml_file_path = locations_to_kml.locations_to_kml(
locations,
actual_kml_document_name,
tmp_path,
)

# Check
assert result
assert actual_kml_file_path is not None

assert actual_kml_file_path.exists()
assert actual_kml_file_path.suffix == KML_SUFFIX

assert actual_kml_file_path.read_text(encoding="utf-8") == expected_kml_document_path.read_text(
encoding="utf-8"
)

0 comments on commit a0aac8c

Please sign in to comment.