diff --git a/src/ssoss/process_road_objects.py b/src/ssoss/process_road_objects.py index 2dc46f2..41337b4 100644 --- a/src/ssoss/process_road_objects.py +++ b/src/ssoss/process_road_objects.py @@ -677,6 +677,36 @@ def get_speed_at_timestamp(self, ts): break return speed + def get_location_at_timestamp(self, ts): + """Return interpolated :class:`geopy.Point` for a timestamp.""" + + point_list = self.gpx_listDF + last_point = len(point_list) - 1 + + if ts < point_list.loc[0][0].get_timestamp(): + return None + if ts > point_list.loc[last_point][0].get_timestamp(): + return None + + for i in range(len(point_list) - 1): + p_curr = point_list.loc[i][0] + p_next = point_list.loc[i + 1][0] + t0 = p_curr.get_timestamp() + t1 = p_next.get_timestamp() + if t0 <= ts <= t1: + if t1 == t0: + return p_curr.get_location() + ratio = (ts - t0) / (t1 - t0) + lat = p_curr.get_location().latitude + ratio * ( + p_next.get_location().latitude - p_curr.get_location().latitude + ) + lon = p_curr.get_location().longitude + ratio * ( + p_next.get_location().longitude - p_curr.get_location().longitude + ) + return geopy.Point(lat, lon) + + return None + diff --git a/tests/test_process_road_objects.py b/tests/test_process_road_objects.py new file mode 100644 index 0000000..5ce40d6 --- /dev/null +++ b/tests/test_process_road_objects.py @@ -0,0 +1,29 @@ +import sys +import pathlib +import unittest +from datetime import datetime, timezone + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / "src")) + +from ssoss.process_road_objects import ProcessRoadObjects +from ssoss.motion_road_object import GPXPoint +import pandas as pd + + +class TestLocationInterpolation(unittest.TestCase): + def setUp(self): + p0 = GPXPoint(0, datetime.fromtimestamp(0, tz=timezone.utc).isoformat(), (0.0, 0.0), 0) + p1 = GPXPoint(1, datetime.fromtimestamp(10, tz=timezone.utc).isoformat(), (0.0, 1.0), 0) + self.proc = ProcessRoadObjects() + self.proc.gpx_listDF = pd.DataFrame({"gpx_pt": [p0, p1]}) + + def test_midpoint_interpolation(self): + ts = 5.0 + location = self.proc.get_location_at_timestamp(ts) + self.assertIsNotNone(location) + self.assertAlmostEqual(location.latitude, 0.0, places=6) + self.assertAlmostEqual(location.longitude, 0.5, places=6) + + +if __name__ == "__main__": + unittest.main()