63 lines
2.2 KiB
Python

"""This module asserts correct runtime behaviour of the :mod:`pyrate.plan.geometry.helpers` functions
for calculating distances.
"""
# Python standard library
from datetime import timedelta
from math import radians
# Testing
from unittest import TestCase
# Hypothesis testing
from hypothesis import given
from hypothesis import settings
import hypothesis.strategies as st
# Scientific (testing)
import numpy.testing
# Module under test
from pyrate.plan.geometry.helpers import fast_distance_geo
from pyrate.plan.geometry.helpers import haversine_numpy
# Own geometry
from pyrate.plan.geometry.geospatial import MEAN_EARTH_CIRCUMFERENCE
from pyrate.plan.geometry import PolarLocation
# Test helpers
from pyrate.common.testing.strategies.geometry import geo_bearings
from pyrate.common.testing.strategies.geometry import polar_locations
class TestDistanceCalculation(TestCase):
"""Tests the geographic helper methods."""
@given(polar_locations(), polar_locations())
def test_haversine_formula(self, location_1: PolarLocation, location_2: PolarLocation) -> None:
"""Test the correctness of the haversine formula."""
dist = haversine_numpy(
radians(location_1.latitude),
radians(location_1.longitude),
radians(location_2.latitude),
radians(location_2.longitude),
)
self.assertLessEqual(dist, MEAN_EARTH_CIRCUMFERENCE / 2)
numpy.testing.assert_allclose(location_1.distance(location_2), dist, atol=5.0, rtol=0.01)
@given(polar_locations(), geo_bearings(), st.floats(min_value=0.0, max_value=250_000.0))
@settings(deadline=timedelta(seconds=1.0))
# pylint: disable=no-self-use
def test_fast_distance_geo(self, center: PolarLocation, direction: float, distance: float) -> None:
"""Test the correctness of the fast great-circle approximation."""
other, _ = center.translate(direction, distance)
distance_calculated = fast_distance_geo(
radians(other.latitude),
radians(other.longitude),
radians(center.latitude),
radians(center.longitude),
)
numpy.testing.assert_allclose(distance, distance_calculated, atol=0.5, rtol=0.05)