Skip to content
Snippets Groups Projects
Commit a489bfa5 authored by Raphael Sturgis's avatar Raphael Sturgis
Browse files

Ais trajectory shifting

parent aac48af1
Branches
Tags
2 merge requests!12version 0.2a,!10Resolve "Image creation bugs with 0 size windows"
......@@ -3,3 +3,6 @@ build/
skais.egg-info/
*.coverage
*__pycache__*
venv/
local.*
\ No newline at end of file
import random
import pandas as pd
import numpy as np
from numba import jit
from scipy.interpolate import interp1d
from skais.utils.geography import great_circle, position_from_distance
from skais.ais.ais_points import AISPoints
......@@ -154,3 +157,53 @@ class AISTrajectory(AISPoints):
index += i
return result
def shift_trajectory_to_coordinates(self, target_coordinate=(0, 0), point_index=None, in_place=False):
if point_index is None:
point_index = random.randint(0, len(self.df.index) - 1)
df = self.df.copy()
new_df = df.copy()
new_df['latitude'].iat[point_index] = target_coordinate[0]
new_df['longitude'].iat[point_index] = target_coordinate[1]
new_point = target_coordinate
for i in range(point_index, 0, -1):
current_point = (df.iloc[i]['latitude'], df.iloc[i]['longitude'])
lat_dist = great_circle(current_point[0], df.iloc[i - 1]['latitude'], current_point[1], current_point[1])
long_dist = great_circle(current_point[0], current_point[0], current_point[1], df.iloc[i - 1]['longitude'])
if current_point[0] > df.iloc[i - 1]['latitude']:
lat_dist *= -1
if current_point[1] > df.iloc[i - 1]['longitude']:
long_dist *= -1
new_point = position_from_distance(new_point, (lat_dist, long_dist))
new_df['latitude'].iat[i - 1] = new_point[0]
new_df['longitude'].iat[i - 1] = new_point[1]
new_point = target_coordinate
for i in range(point_index, len(df.index) - 1):
current_point = (df.iloc[i]['latitude'], df.iloc[i]['longitude'])
lat_dist = great_circle(current_point[0], df.iloc[i + 1]['latitude'], current_point[1], current_point[1])
long_dist = great_circle(current_point[0], current_point[0], current_point[1], df.iloc[i + 1]['longitude'])
if current_point[0] > df.iloc[i + 1]['latitude']:
lat_dist *= -1
if current_point[1] > df.iloc[i + 1]['longitude']:
long_dist *= -1
new_point = position_from_distance(new_point, (lat_dist, long_dist))
new_df['latitude'].iat[i + 1] = new_point[0]
new_df['longitude'].iat[i + 1] = new_point[1]
if in_place:
self.df = new_df
return self
else:
return AISTrajectory(new_df, mmsi=self.mmsi)
......@@ -320,3 +320,41 @@ class TestAISTrajectory(unittest.TestCase):
def test_apply_func_on_window(self):
self.assertRaises(ValueError, apply_func_on_window,np.arange(10), 0, 0, 'not valid string')
def test_shift_trajectory_to_coordinates_no_change(self):
trajectory = AISTrajectory(
pd.DataFrame(
{
"latitude": [0, 90, 0, -90],
"longitude": [0, 90, 180, -90],
"ts_sec": [i for i in range(4)]
}
)
)
result = trajectory.shift_trajectory_to_coordinates(point_index=0)
pd.testing.assert_frame_equal(trajectory.df.reset_index(drop=True), result.df.reset_index(drop=True))
def test_shift_trajectory_to_coordinates_change_1(self):
trajectory = AISTrajectory(
pd.DataFrame(
{
"latitude": [1, 2, 3, 4],
"longitude": [1, 2, 3, 4],
"ts_sec": [i for i in range(4)]
}
)
)
result = trajectory.shift_trajectory_to_coordinates(point_index=0).df
expected = pd.DataFrame(
{
"latitude": [0, 2, 3, 4], # TBD
"longitude": [0, 1, 2, 3],
"ts_sec": [i for i in range(4)]
}
)
pd.testing.assert_frame_equal(expected.reset_index(drop=True), result.reset_index(drop=True))
\ No newline at end of file
import unittest
import numpy as np
from skais.utils.geography import position_from_distance
tol = 0.005
class TestGeography(unittest.TestCase):
def test_position_from_distance_1(self):
position = (0, 0)
distance = (10000, 10000)
expected = (0.09, 0.09)
result = position_from_distance(position, distance)
np.testing.assert_allclose(expected, result, tol)
def test_position_from_distance_2(self):
position = (10, 10)
distance = (10000, 10000)
expected = (10.0636111, 10.064722222222223)
result = position_from_distance(position, distance)
np.testing.assert_allclose(expected, result, tol)
def test_position_from_distance_3(self):
position = (75, 75)
distance = (10000, -10000)
expected = (75.0633333, 74.75333333333333)
result = position_from_distance(position, distance)
np.testing.assert_allclose(expected, result, tol)
if __name__ == '__main__':
unittest.main()
File deleted
File deleted
......@@ -2,6 +2,9 @@ from sklearn.metrics.pairwise import haversine_distances
import numpy as np
from numba import jit
R = 6371000
@jit(nopython=True)
def great_circle(lat1, lat2, long1, long2):
x1 = np.radians(lat1)
......@@ -9,8 +12,6 @@ def great_circle(lat1, lat2, long1, long2):
x2 = np.radians(lat2)
y2 = np.radians(long2)
R = 6371000
delta_x = x2 - x1
delta_y = y2 - y1
......@@ -21,3 +22,16 @@ def great_circle(lat1, lat2, long1, long2):
d = R * c
return d
def position_from_distance(position, distances):
lat = np.arcsin(
np.sin(np.radians(position[0])) * np.cos(distances[0] / R) + np.cos(np.radians(position[0])) * np.sin(
distances[0] / R))
long = np.radians(position[1]) + np.arctan2(
np.sin(distances[1] / R) * np.cos(np.radians(position[0])),
np.cos(distances[1] / R) - (np.sin(np.radians(position[1])) * np.sin(lat))
)
return np.degrees(lat), np.degrees(long)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment