diff --git a/src/gpsclean.egg-info/PKG-INFO b/src/gpsclean.egg-info/PKG-INFO
index ba4421a..dc4c204 100644
--- a/src/gpsclean.egg-info/PKG-INFO
+++ b/src/gpsclean.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: gpsclean
-Version: 1.0.2
+Version: 1.0.3
Summary: An application to correct a GPS trace using machine learning techniques
Home-page: https://github.com/sbettid/GPSClean
Author: Davide Sbetti
diff --git a/src/gpsclean.egg-info/SOURCES.txt b/src/gpsclean.egg-info/SOURCES.txt
index d0ad5da..9e275a6 100644
--- a/src/gpsclean.egg-info/SOURCES.txt
+++ b/src/gpsclean.egg-info/SOURCES.txt
@@ -3,10 +3,12 @@ README.md
pyproject.toml
setup.py
src/gpsclean/Correction.py
+src/gpsclean/DateTimeUtil.py
src/gpsclean/FullTraining.py
+src/gpsclean/KalmanFilterFactory.py
+src/gpsclean/PointsUtil.py
src/gpsclean/__init__.py
src/gpsclean/_version.py
-src/gpsclean/gpsclean_transform.py
src/gpsclean/main.py
src/gpsclean.egg-info/PKG-INFO
src/gpsclean.egg-info/SOURCES.txt
diff --git a/src/gpsclean/Correction.py b/src/gpsclean/Correction.py
index b539dd7..34686ea 100644
--- a/src/gpsclean/Correction.py
+++ b/src/gpsclean/Correction.py
@@ -1,21 +1,8 @@
#this file contains the functions used to correct a trace based on the generated predictions
import numpy as np
-from pyproj import Transformer
-from filterpy.kalman import KalmanFilter
-from filterpy.common import Q_discrete_white_noise
-from scipy.linalg import block_diag
-from datetime import datetime
-
-
-#defining conversions between the two used coordinates systems
-ecef = {"proj": 'geocent', "ellps": 'WGS84', "datum": 'WGS84'}
-lla = {"proj": 'latlong', "ellps": 'WGS84', "datum": 'WGS84'}
-
-lla_to_ecef_transformer = Transformer.from_crs(lla, ecef)
-ecef_to_lla_transform = Transformer.from_crs(ecef, lla)
-
-#value used for clipping the deltas correction of each epoch applied to outliers
-EPS = 0.1
+from . import PointsUtil as gt
+from . import DateTimeUtil as date_util
+from . import KalmanFilterFactory as kalman_factory
#function used to remove pauses from the original trace based on the predictions,
#since in case of pauses no extra correction is needed besides removing them
@@ -80,62 +67,15 @@ def remove_pauses(all_coords, all_coordtimes, predictions, deltas):
#correct the trace by applying a Kalman Filter (https://en.wikipedia.org/wiki/Kalman_filter) over the entire trace
#Kalman filters are created and manages using the Filterpy library (https://filterpy.readthedocs.io/en/latest/)
def full_kalman_smoothing(points, times):
-
- print("Points shape: ", points.shape)
-
+
#convert everything to ecef
- data = []
-
- for i in range(points.shape[0]):
- #get point
- point = points[i]
- #convert to ECEF
- lon, lat, alt = point[0], point[1], point[2]
- x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
- #append to data
- data.append(np.array([x,y,z]))
-
- data = np.array(data)
-
+ data = gt.convert_lla_points_to_ecef(points)
#calculate also time deltas to adjust state transition matrix of the Kalman Filter based on the measured delta
- datetimes = []
- if not (type(times[0]) == datetime):
- for dt in times:
- datetimes.append(datetime.fromisoformat(dt.replace("Z", "")))
- else:
- datetimes = times
-
-
- time_deltas = []
- for i in range(1, len(datetimes)):
- time_deltas.append((datetimes[i] - datetimes[i-1]).total_seconds())
-
-
+ time_deltas = date_util.calculate_timedeltas(times)
# create kalman filter
- dt = 2. #time delta
-
- f1 = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
-
- f1.F = np.array ([[1, dt, 0, 0, 0, 0], #kalman transition matrix
- [0, 1, 0, 0, 0, 0],
- [0, 0, 1, dt, 0, 0],
- [0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 1, dt],
- [0, 0, 0, 0, 0, 1]], dtype=float)
-
- f1.R *= 4.9
- f1.Q *= .1
-
- f1.x = np.array([[data[0][0], 0, data[0][1], 0, data[0][2], 0]], dtype=float).T #starting position, assuming it is correct
- f1.P = np.eye(6) * 500.
- f1.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
- [0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]])
-
- q = Q_discrete_white_noise(dim=3, dt=dt, var=0.001) #white noise
- f1.Q = block_diag(q, q)
+ kalman_filter = kalman_factory.get_kalman_filter_config_from_data(data)
#correction process
filterpy_data = []
@@ -152,33 +92,22 @@ def full_kalman_smoothing(points, times):
cur_dt = time_deltas[i-1]
#update time delta in state transition matrix with the measured one
- f1.F[0][1] = cur_dt
- f1.F[2][3] = cur_dt
- f1.F[4][5] = cur_dt
+ kalman_filter.F[0][1] = cur_dt
+ kalman_filter.F[2][3] = cur_dt
+ kalman_filter.F[4][5] = cur_dt
#predict next point
- f1.predict()
+ kalman_filter.predict()
#update prediction based on measured value
- f1.update(np.array([long, lat, alt]).T)
+ kalman_filter.update(np.array([long, lat, alt]).T)
#add updated version to array
- filterpy_data.append(np.array([f1.x[0][0], f1.x[2][0], f1.x[4][0]]))
+ filterpy_data.append(np.array([kalman_filter.x[0][0], kalman_filter.x[2][0], kalman_filter.x[4][0]]))
filterpy_data = np.array(filterpy_data)
#now convert adjusted points back to lat lang
- corrected_points = []
-
- for i in range(filterpy_data.shape[0]): #for each point
- #get data
- x = filterpy_data[i][0]
- y = filterpy_data[i][1]
- z = filterpy_data[i][2]
- #convert to lat long and append
- lon, lat, alt = ecef_to_lla_transform.transform(x, y, z, radians=False)
- corrected_points.append(np.array([lon, lat, alt]))
-
- corrected_points = np.array(corrected_points)
+ corrected_points = gt.convert_ecef_points_to_lla(filterpy_data)
return corrected_points, times
@@ -187,55 +116,13 @@ def full_kalman_smoothing(points, times):
def kalman_smoothing(points, times, predictions):
#convert everything to ecef
- data = []
-
- for i in range(points.shape[0]): #for each point
-
- point = points[i] #get it
-
- #convert values to ECEF
- lon, lat, alt = point[0], point[1], point[2]
- x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
-
- data.append(np.array([x,y,z]))
-
- data = np.array(data)
+ data = gt.convert_lla_points_to_ecef(points)
#calculate also time deltas to adjust state transition matrix of the Kalman Filter
- datetimes = []
- if not (type(times[0]) == datetime):
- for dt in times:
- datetimes.append(datetime.fromisoformat(dt.replace("Z", "")))
- else:
- datetimes = times
-
- time_deltas = []
- for i in range(1, len(datetimes)):
- time_deltas.append((datetimes[i] - datetimes[i-1]).total_seconds())
+ time_deltas = date_util.calculate_timedeltas(times)
# create kalman filter
- dt = 2. #time delta
-
- f1 = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
-
- f1.F = np.array ([[1, dt, 0, 0, 0, 0], #kalman transition matrix
- [0, 1, 0, 0, 0, 0],
- [0, 0, 1, dt, 0, 0],
- [0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 1, dt],
- [0, 0, 0, 0, 0, 1]], dtype=float)
-
- f1.R *= 4.9
- f1.Q *= .1
-
- f1.x = np.array([[data[0][0], 0, data[0][1], 0, data[0][2], 0]], dtype=float).T #starting position, assuming it is correct
- f1.P = np.eye(6) * 500.
- f1.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
- [0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]])
-
- q = Q_discrete_white_noise(dim=3, dt=dt, var=0.001) #white noise
- f1.Q = block_diag(q, q)
+ kalman_filter = kalman_factory.get_kalman_filter_config_from_data(data)
#correction
filterpy_data = []
@@ -252,41 +139,29 @@ def kalman_smoothing(points, times, predictions):
cur_dt = time_deltas[i-1]
#update time delta in state transition matrix
- f1.F[0][1] = cur_dt
- f1.F[2][3] = cur_dt
- f1.F[4][5] = cur_dt
+ kalman_filter.F[0][1] = cur_dt
+ kalman_filter.F[2][3] = cur_dt
+ kalman_filter.F[4][5] = cur_dt
#predict next point
- f1.predict()
+ kalman_filter.predict()
#update predicted value using the measurement
- f1.update(np.array([long, lat, alt]).T)
+ kalman_filter.update(np.array([long, lat, alt]).T)
#if it is an outlier
if predictions[i] >= 2:
#append the corrected version
- filterpy_data.append(np.array([f1.x[0][0], f1.x[2][0], f1.x[4][0]]))
+ filterpy_data.append(np.array([kalman_filter.x[0][0], kalman_filter.x[2][0], kalman_filter.x[4][0]]))
else:
#otherwise keep the original one
filterpy_data.append(np.array([data[i][0], data[i][1], data[i][2]]))
- #f1.x = np.array([[long, f1.x[0][1], lat, f1.x[0][3], alt, f1.x[0][4]]], dtype=float).T
- f1.x = np.array([[long, 0, lat, 0, alt, 0]], dtype=float).T
+ kalman_filter.x = np.array([[long, 0, lat, 0, alt, 0]], dtype=float).T
filterpy_data = np.array(filterpy_data)
#now convert back to lat lang
- corrected_points = []
-
- for i in range(filterpy_data.shape[0]):
- #convert each point back to lat long
- x = filterpy_data[i][0]
- y = filterpy_data[i][1]
- #z = filtered_state_means[i][2]
- z = filterpy_data[i][2]
- lon, lat, alt = ecef_to_lla_transform.transform(x, y, z, radians=False)
- corrected_points.append(np.array([lon, lat, alt]))
-
- corrected_points = np.array(corrected_points)
+ corrected_points = gt.convert_ecef_points_to_lla(filterpy_data)
return corrected_points, times
@@ -296,33 +171,10 @@ def kalman_smoothing(points, times, predictions):
def separate_kalman_smoothing(points, times, predictions):
#convert everything to ecef
- data = []
-
- for i in range(points.shape[0]): #for each point
-
- point = points[i] #get it
-
- #convert values to ECEF
- lon, lat, alt = point[0], point[1], point[2]
- x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
-
- data.append(np.array([x,y,z]))
-
- data = np.array(data)
+ data = gt.convert_lla_points_to_ecef(points)
#calculate also time deltas to adjust state transition matrix of the Kalman Filter
- datetimes = []
- if not (type(times[0]) == datetime):
- for dt in times:
- datetimes.append(datetime.fromisoformat(dt.replace("Z", "")))
- else:
- datetimes = times
-
- time_deltas = []
- for i in range(1, len(datetimes)):
- time_deltas.append((datetimes[i] - datetimes[i-1]).total_seconds())
-
-
+ time_deltas = date_util.calculate_timedeltas(times)
#control variables to be used
isIncorrect = False
@@ -345,49 +197,28 @@ def separate_kalman_smoothing(points, times, predictions):
#if the point is wrong
if predictions[i] >= 2:
if not isIncorrect: #if the previous point was correct we need to instantiate a Kalman filter
- f1 = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
-
- f1.F = np.array ([[1, cur_dt, 0, 0, 0, 0], #kalman transition matrix
- [0, 1, 0, 0, 0, 0],
- [0, 0, 1, cur_dt, 0, 0],
- [0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 1, cur_dt],
- [0, 0, 0, 0, 0, 1]], dtype=float)
-
- f1.R *= 4.9
- f1.Q *= .1
-
- f1.x = np.array([[filterpy_data[indexStart][0], 0, filterpy_data[indexStart][1], 0, filterpy_data[indexStart][2], 0]], dtype=float).T #starting position, assuming it is correct
-
-
- f1.P = np.eye(6) * 500.
- f1.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
- [0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]])
-
- q = Q_discrete_white_noise(dim=3, dt=cur_dt, var=0.001) #white noise
- f1.Q = block_diag(q, q)
+ kalman_filter = kalman_factory.get_kalman_filter_config_from_data(data, dt = cur_dt, starting_index= indexStart)
#do some predict and update to learn parameters
for j in range(indexStart + 1, i):
- f1.predict()
+ kalman_filter.predict()
- f1.update(np.array([filterpy_data[j][0], filterpy_data[j][1], filterpy_data[j][2]]).T)
+ kalman_filter.update(np.array([filterpy_data[j][0], filterpy_data[j][1], filterpy_data[j][2]]).T)
- f1.x = np.array([[filterpy_data[j][0], 0, filterpy_data[j][1], 0, filterpy_data[j][2], 0]], dtype=float).T
+ kalman_filter.x = np.array([[filterpy_data[j][0], 0, filterpy_data[j][1], 0, filterpy_data[j][2], 0]], dtype=float).T
#update time delta
- f1.F[0][1] = cur_dt
- f1.F[2][3] = cur_dt
- f1.F[4][5] = cur_dt
+ kalman_filter.F[0][1] = cur_dt
+ kalman_filter.F[2][3] = cur_dt
+ kalman_filter.F[4][5] = cur_dt
#predict next point
- f1.predict()
+ kalman_filter.predict()
#update predicted value using the measurement
- f1.update(np.array([long, lat, alt]).T)
+ kalman_filter.update(np.array([long, lat, alt]).T)
- filterpy_data.append(np.array([f1.x[0][0], f1.x[2][0], f1.x[4][0]])) #append filtered data
+ filterpy_data.append(np.array([kalman_filter.x[0][0], kalman_filter.x[2][0], kalman_filter.x[4][0]])) #append filtered data
isIncorrect = True
@@ -404,18 +235,7 @@ def separate_kalman_smoothing(points, times, predictions):
filterpy_data = np.array(filterpy_data)
#now convert back to lat lang
- corrected_points = []
-
- for i in range(filterpy_data.shape[0]):
- #convert each point back to lat long
- x = filterpy_data[i][0]
- y = filterpy_data[i][1]
- #z = filtered_state_means[i][2]
- z = filterpy_data[i][2]
- lon, lat, alt = ecef_to_lla_transform.transform(x, y, z, radians=False)
- corrected_points.append(np.array([lon, lat, alt]))
-
- corrected_points = np.array(corrected_points)
+ corrected_points = gt.convert_ecef_points_to_lla(filterpy_data)
return corrected_points, times
@@ -424,32 +244,10 @@ def separate_kalman_smoothing(points, times, predictions):
def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9):
#convert everything to ecef
- data = []
-
- for i in range(points.shape[0]): #for each point
-
- point = points[i] #get it
-
- #convert values to ECEF
- lon, lat, alt = point[0], point[1], point[2]
- x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
-
- data.append(np.array([x,y,z]))
-
- data = np.array(data)
+ data = gt.convert_lla_points_to_ecef(points)
#calculate also time deltas to adjust state transition matrix of the Kalman Filter
- datetimes = []
- if not (type(times[0]) == datetime):
- for dt in times:
- datetimes.append(datetime.fromisoformat(dt.replace("Z", "")))
- else:
- datetimes = times
-
- time_deltas = []
- for i in range(1, len(datetimes)):
- time_deltas.append((datetimes[i] - datetimes[i-1]).total_seconds())
-
+ time_deltas = date_util.calculate_timedeltas(times)
#for each point but the first one
outliers = []
@@ -487,7 +285,6 @@ def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9)
outliers.append({'start' : cur_start, 'end' : cur_end})
#for each outlying area
- corrected_areas = []
for cur_outlier in outliers:
cur_outlier_corrected = []
@@ -502,25 +299,8 @@ def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9)
else:
break
- #initialise filter
- cur_dt = 2.
-
- f1 = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
- f1.F = np.array ([[1, cur_dt, 0, 0, 0, 0], #kalman transition matrix
- [0, 1, 0, 0, 0, 0],
- [0, 0, 1, cur_dt, 0, 0],
- [0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 1, cur_dt],
- [0, 0, 0, 0, 0, 1]], dtype=float)
- f1.R *= R
- f1.Q *= .1
- f1.x = np.array([[data[cur_start][0], 0, data[cur_start][1], 0, data[cur_start][2], 0]], dtype=float).T #starting position
- f1.P = np.eye(6) * 500.
- f1.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
- [0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]])
- q = Q_discrete_white_noise(dim=3, dt=cur_dt, var=0.001) #white noise
- f1.Q = block_diag(q, q)
+ #initialise filter
+ kalman_filter = kalman_factory.get_kalman_filter_config_from_data(data, starting_index = cur_start, R=R)
#apply to points and store correction
for i in range(cur_start, cur_outlier['end'] + 1):
@@ -530,21 +310,21 @@ def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9)
cur_dt = time_deltas[i-1]
#update time delta
- f1.F[0][1] = cur_dt
- f1.F[2][3] = cur_dt
- f1.F[4][5] = cur_dt
+ kalman_filter.F[0][1] = cur_dt
+ kalman_filter.F[2][3] = cur_dt
+ kalman_filter.F[4][5] = cur_dt
#predict
- f1.predict()
+ kalman_filter.predict()
#update
- f1.update(np.array([data[i][0], data[i][1], data[i][2]]).T)
+ kalman_filter.update(np.array([data[i][0], data[i][1], data[i][2]]).T)
#append to list if point is incorrect
if predictions[i] >= 2:
- cur_outlier_corrected.append(np.array([f1.x[0][0], f1.x[2][0], f1.x[4][0]]))
+ cur_outlier_corrected.append(np.array([kalman_filter.x[0][0], kalman_filter.x[2][0], kalman_filter.x[4][0]]))
else:
- f1.x = np.array([[data[i][0], 0, data[i][1], 0, data[i][2], 0]], dtype=float).T
+ kalman_filter.x = np.array([[data[i][0], 0, data[i][1], 0, data[i][2], 0]], dtype=float).T
#now initialise filter again and
@@ -558,24 +338,8 @@ def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9)
break
- #initialise filter
- cur_dt = 2.
- f1 = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
- f1.F = np.array ([[1, cur_dt, 0, 0, 0, 0], #kalman transition matrix
- [0, 1, 0, 0, 0, 0],
- [0, 0, 1, cur_dt, 0, 0],
- [0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 1, cur_dt],
- [0, 0, 0, 0, 0, 1]], dtype=float)
- f1.R *= R
- f1.Q *= .1
- f1.x = np.array([[data[cur_end][0], 0, data[cur_end][1], 0, data[cur_end][2], 0]], dtype=float).T #starting position
- f1.P = np.eye(6) * 500.
- f1.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
- [0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]])
- q = Q_discrete_white_noise(dim=3, dt=cur_dt, var=0.001) #white noise
- f1.Q = block_diag(q, q)
+ #initialise filter
+ kalman_filter = kalman_factory.get_kalman_filter_config_from_data(data, starting_index = cur_end, R=R)
#now apply it backward
cur_item = len(cur_outlier_corrected) - 1
@@ -585,41 +349,30 @@ def separate_bidirectional_kalman_smoothing(points, times, predictions, R = 4.9)
cur_dt = time_deltas[i-1]
#update time delta
- f1.F[0][1] = cur_dt
- f1.F[2][3] = cur_dt
- f1.F[4][5] = cur_dt
+ kalman_filter.F[0][1] = cur_dt
+ kalman_filter.F[2][3] = cur_dt
+ kalman_filter.F[4][5] = cur_dt
#predict
- f1.predict()
+ kalman_filter.predict()
#update
- f1.update(np.array([data[i][0], data[i][1], data[i][2]]).T)
+ kalman_filter.update(np.array([data[i][0], data[i][1], data[i][2]]).T)
#append to list if point is incorrect
if predictions[i] >= 2:
- cur_outlier_corrected[cur_item] += np.array([f1.x[0][0], f1.x[2][0], f1.x[4][0]])
+ cur_outlier_corrected[cur_item] += np.array([kalman_filter.x[0][0], kalman_filter.x[2][0], kalman_filter.x[4][0]])
cur_outlier_corrected[cur_item] /= 2
cur_item -= 1
else:
- f1.x = np.array([[data[i][0], 0, data[i][1], 0, data[i][2], 0]], dtype=float).T
+ kalman_filter.x = np.array([[data[i][0], 0, data[i][1], 0, data[i][2], 0]], dtype=float).T
#now apply correction
cur_outlier_corrected = np.array(cur_outlier_corrected)
data[cur_outlier['start'] : cur_outlier['end'] + 1][:] = cur_outlier_corrected
#now convert back to lat lang
- corrected_points = []
-
- for i in range(data.shape[0]):
- #convert each point back to lat long
- x = data[i][0]
- y = data[i][1]
- #z = filtered_state_means[i][2]
- z = data[i][2]
- lon, lat, alt = ecef_to_lla_transform.transform(x, y, z, radians=False)
- corrected_points.append(np.array([lon, lat, alt]))
-
- corrected_points = np.array(corrected_points)
+ corrected_points = gt.convert_ecef_points_to_lla(data)
return corrected_points, times
\ No newline at end of file
diff --git a/src/gpsclean/DateTimeUtil.py b/src/gpsclean/DateTimeUtil.py
new file mode 100644
index 0000000..8fdb315
--- /dev/null
+++ b/src/gpsclean/DateTimeUtil.py
@@ -0,0 +1,16 @@
+from datetime import datetime
+
+def calculate_timedeltas(timestamps):
+ #calculate also time deltas to adjust state transition matrix of the Kalman Filter based on the measured delta
+ datetimes = []
+ if not (type(timestamps[0]) == datetime):
+ for dt in timestamps:
+ datetimes.append(datetime.fromisoformat(dt.replace("Z", "")))
+ else:
+ datetimes = timestamps
+
+ time_deltas = []
+ for i in range(1, len(datetimes)):
+ time_deltas.append((datetimes[i] - datetimes[i-1]).total_seconds())
+
+ return time_deltas
\ No newline at end of file
diff --git a/src/gpsclean/FullTraining.py b/src/gpsclean/FullTraining.py
index c330e49..c3ba9d4 100644
--- a/src/gpsclean/FullTraining.py
+++ b/src/gpsclean/FullTraining.py
@@ -1,15 +1,10 @@
#This file contains functions used to perform the training on an entire dataset
#and to predict a newly acquired trace
import numpy as np
-import pyproj
import sys
#setting max int used for masking
-max_int = sys.maxsize
-
-ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
-lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
-
+max_int = sys.maxsize
#this function takes the generated segments and keeps those that
#contain at least an annotated point. Points annotated as correct are then
@@ -44,11 +39,6 @@ def predict_trace(interpreter, trace, window_size, step):
segments = []
indices = []
- annotatedIDs = set([])
- notAnnotatedIDs = set([])
-
- act_counter = 1
-
#first, we need to generate segments
for point_index in range(0,len(trace),step):
@@ -76,9 +66,7 @@ def predict_trace(interpreter, trace, window_size, step):
cur_ind = np.concatenate((np.arange(point_index,point_index+len(trace[point_index:])), ind_pad))
segments.append(cur_segment)
- indices.append(cur_ind)
-
-
+ indices.append(cur_ind)
#convert to Numpy arrays
@@ -188,17 +176,3 @@ def compress_trace_predictions(predictions, indices, n_classes):
trace_mean_prediction.append(means[key]) #... and the mean prediction
return np.array(trace_predictions), np.array(trace_mean_prediction)
-
-
-def convert_to_ECEF(points):
-
- ecef_points = []
-
- for point in points:
- cur_lon, cur_lat, cur_alt = point[0], point[1], point[2]
- x, y, z = pyproj.transform(lla, ecef, cur_lon, cur_lat, cur_alt, radians=False)
-
- ecef_points.append(np.array([x, y, z]))
-
-
- return np.array(ecef_points)
diff --git a/src/gpsclean/KalmanFilterFactory.py b/src/gpsclean/KalmanFilterFactory.py
new file mode 100644
index 0000000..874a424
--- /dev/null
+++ b/src/gpsclean/KalmanFilterFactory.py
@@ -0,0 +1,29 @@
+from filterpy.kalman import KalmanFilter
+from filterpy.common import Q_discrete_white_noise
+from scipy.linalg import block_diag
+import numpy as np
+
+def get_kalman_filter_config_from_data(data, dt = 2., starting_index = 0, R = 4.9):
+
+ kalman_filter = KalmanFilter(dim_x=6, dim_z=3)# 6 state variables, 3 observed
+
+ kalman_filter.F = np.array ([[1, dt, 0, 0, 0, 0], #kalman transition matrix
+ [0, 1, 0, 0, 0, 0],
+ [0, 0, 1, dt, 0, 0],
+ [0, 0, 0, 1, 0, 0],
+ [0, 0, 0, 0, 1, dt],
+ [0, 0, 0, 0, 0, 1]], dtype=float)
+
+ kalman_filter.R *= R
+ kalman_filter.Q *= .1
+
+ kalman_filter.x = np.array([[data[starting_index][0], 0, data[starting_index][1], 0, data[starting_index][2], 0]], dtype=float).T #starting position, assuming it is correct
+ kalman_filter.P = np.eye(6) * 500.
+ kalman_filter.H = np.array([[1, 0, 0, 0, 0, 0], #how do we pass from measurement to position?
+ [0, 0, 1, 0, 0, 0],
+ [0, 0, 0, 0, 1, 0]])
+
+ q = Q_discrete_white_noise(dim=3, dt=dt, var=0.001) #white noise
+ kalman_filter.Q = block_diag(q, q)
+
+ return kalman_filter
\ No newline at end of file
diff --git a/src/gpsclean/gpsclean_transform.py b/src/gpsclean/PointsUtil.py
similarity index 50%
rename from src/gpsclean/gpsclean_transform.py
rename to src/gpsclean/PointsUtil.py
index 0d4d503..e76d582 100644
--- a/src/gpsclean/gpsclean_transform.py
+++ b/src/gpsclean/PointsUtil.py
@@ -8,7 +8,8 @@
ecef = {"proj": 'geocent', "ellps": 'WGS84', "datum": 'WGS84'}
lla = {"proj": 'latlong', "ellps": 'WGS84', "datum": 'WGS84'}
-transformer = Transformer.from_crs(lla, ecef)
+lla_to_ecef_transformer = Transformer.from_crs(lla, ecef)
+ecef_to_lla_transform = Transformer.from_crs(ecef, lla)
def create_deltas(points, times):
@@ -23,7 +24,7 @@ def create_deltas(points, times):
if alt is not None:
- x, y, z = transformer.transform(lon, lat, alt, radians=False)
+ x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
#append
features.append([x,y,z])
@@ -47,3 +48,42 @@ def create_deltas(points, times):
return np.array(deltas)
+def lla_to_ecef(lon, lat, alt):
+ x, y, z = lla_to_ecef_transformer.transform(lon, lat, alt, radians=False)
+
+ return x, y, z
+
+def ecef_to_lla(x, y, z):
+ lon, lat, alt = ecef_to_lla_transform.transform(x, y, z, radians=False)
+
+ return lon, lat, alt
+
+def convert_lla_points_to_ecef(points):
+
+ #convert everything to ecef
+ ecef_points = []
+
+ for i in range(points.shape[0]):
+ #get point
+ point = points[i]
+ #convert to ECEF
+ lon, lat, alt = point[0], point[1], point[2]
+ x, y, z = lla_to_ecef(lon, lat, alt)
+ #append to data
+ ecef_points.append(np.array([x,y,z]))
+
+ return np.array(ecef_points)
+
+def convert_ecef_points_to_lla(points):
+ lla_points = []
+
+ for i in range(points.shape[0]): #for each point
+ #get data
+ x = points[i][0]
+ y = points[i][1]
+ z = points[i][2]
+ #convert to lat long and append
+ lon, lat, alt = ecef_to_lla(x, y, z)
+ lla_points.append(np.array([lon, lat, alt]))
+
+ return np.array(lla_points)
\ No newline at end of file
diff --git a/src/gpsclean/_version.py b/src/gpsclean/_version.py
index bb35ee1..679362c 100644
--- a/src/gpsclean/_version.py
+++ b/src/gpsclean/_version.py
@@ -1 +1 @@
-__version__ = "1.0.2"
\ No newline at end of file
+__version__ = "1.0.3"
\ No newline at end of file
diff --git a/src/gpsclean/main.py b/src/gpsclean/main.py
index d94f000..86e9e71 100644
--- a/src/gpsclean/main.py
+++ b/src/gpsclean/main.py
@@ -2,7 +2,7 @@
import gpxpy
import gpxpy.gpx
import numpy as np
-from . import gpsclean_transform as gt
+from . import PointsUtil as gt
from . import FullTraining as ft
from . import _version as v
import tflite_runtime.interpreter as tflite
diff --git a/src/tests/integration/inputs/test_input_trace_outliers.gpx b/src/tests/integration/inputs/test_input_trace_outliers.gpx
new file mode 100644
index 0000000..d26f3a5
--- /dev/null
+++ b/src/tests/integration/inputs/test_input_trace_outliers.gpx
@@ -0,0 +1,7179 @@
+
+
+
+
+ Garmin Connect
+
+
+
+
+ Bolzano Corsa
+ running
+
+
+ 265
+
+
+
+ 87
+ 52
+
+
+
+
+ 265
+
+
+
+ 87
+ 55
+
+
+
+
+ 265
+
+
+
+ 86
+ 0
+
+
+
+
+ 265
+
+
+
+ 90
+ 80
+
+
+
+
+ 265
+
+
+
+ 94
+ 81
+
+
+
+
+ 265
+
+
+
+ 97
+ 81
+
+
+
+
+ 265.20001220703125
+
+
+
+ 100
+ 80
+
+
+
+
+ 265.600006103515625
+
+
+
+ 103
+ 80
+
+
+
+
+ 265.600006103515625
+
+
+
+ 105
+ 80
+
+
+
+
+ 265.600006103515625
+
+
+
+ 106
+ 81
+
+
+
+
+ 266
+
+
+
+ 109
+ 80
+
+
+
+
+ 266
+
+
+
+ 110
+ 80
+
+
+
+
+ 266
+
+
+
+ 112
+ 81
+
+
+
+
+ 266.600006103515625
+
+
+
+ 115
+ 81
+
+
+
+
+ 267
+
+
+
+ 117
+ 80
+
+
+
+
+ 266.399993896484375
+
+
+
+ 121
+ 81
+
+
+
+
+ 266.600006103515625
+
+
+
+ 121
+ 81
+
+
+
+
+ 266.600006103515625
+
+
+
+ 125
+ 80
+
+
+
+
+ 267.20001220703125
+
+
+
+ 124
+ 82
+
+
+
+
+ 267.399993896484375
+
+
+
+ 127
+ 82
+
+
+
+
+ 267.79998779296875
+
+
+
+ 128
+ 82
+
+
+
+
+ 268.600006103515625
+
+
+
+ 131
+ 80
+
+
+
+
+ 271.399993896484375
+
+
+
+ 132
+ 82
+
+
+
+
+ 271.600006103515625
+
+
+
+ 132
+ 81
+
+
+
+
+ 271.600006103515625
+
+
+
+ 133
+ 80
+
+
+
+
+ 271.79998779296875
+
+
+
+ 133
+ 80
+
+
+
+
+ 271.600006103515625
+
+
+
+ 133
+ 80
+
+
+
+
+ 271.20001220703125
+
+
+
+ 133
+ 81
+
+
+
+
+ 271
+
+
+
+ 134
+ 81
+
+
+
+
+ 271
+
+
+
+ 134
+ 81
+
+
+
+
+ 269.600006103515625
+
+
+
+ 134
+ 80
+
+
+
+
+ 268.79998779296875
+
+
+
+ 135
+ 81
+
+
+
+
+ 267.399993896484375
+
+
+
+ 133
+ 82
+
+
+
+
+ 265.399993896484375
+
+
+
+ 132
+ 82
+
+
+
+
+ 264.79998779296875
+
+
+
+ 132
+ 82
+
+
+
+
+ 264
+
+
+
+ 131
+ 81
+
+
+
+
+ 264
+
+
+
+ 132
+ 81
+
+
+
+
+ 264
+
+
+
+ 132
+ 82
+
+
+
+
+ 264
+
+
+
+ 132
+ 80
+
+
+
+
+ 264.20001220703125
+
+
+
+ 133
+ 81
+
+
+
+
+ 264.600006103515625
+
+
+
+ 137
+ 82
+
+
+
+
+ 264.79998779296875
+
+
+
+ 139
+ 82
+
+
+
+
+ 264.79998779296875
+
+
+
+ 136
+ 82
+
+
+
+
+ 264.399993896484375
+
+
+
+ 137
+ 81
+
+
+
+
+ 264.399993896484375
+
+
+
+ 135
+ 80
+
+
+
+
+ 264.399993896484375
+
+
+
+ 132
+ 80
+
+
+
+
+ 265.20001220703125
+
+
+
+ 130
+ 81
+
+
+
+
+ 268.399993896484375
+
+
+
+ 133
+ 80
+
+
+
+
+ 270.600006103515625
+
+
+
+ 134
+ 80
+
+
+
+
+ 272
+
+
+
+ 135
+ 81
+
+
+
+
+ 272.600006103515625
+
+
+
+ 136
+ 80
+
+
+
+
+ 273.600006103515625
+
+
+
+ 136
+ 81
+
+
+
+
+ 274.20001220703125
+
+
+
+ 137
+ 81
+
+
+
+
+ 274.20001220703125
+
+
+
+ 137
+ 81
+
+
+
+
+ 274.20001220703125
+
+
+
+ 137
+ 81
+
+
+
+
+ 274
+
+
+
+ 137
+ 81
+
+
+
+
+ 274
+
+
+
+ 137
+ 82
+
+
+
+
+ 274
+
+
+
+ 137
+ 81
+
+
+
+
+ 274
+
+
+
+ 137
+ 81
+
+
+
+
+ 274.600006103515625
+
+
+
+ 137
+ 80
+
+
+
+
+ 274.79998779296875
+
+
+
+ 137
+ 81
+
+
+
+
+ 275.79998779296875
+
+
+
+ 137
+ 81
+
+
+
+
+ 276.79998779296875
+
+
+
+ 137
+ 82
+
+
+
+
+ 276.79998779296875
+
+
+
+ 137
+ 81
+
+
+
+
+ 277
+
+
+
+ 138
+ 81
+
+
+
+
+ 277
+
+
+
+ 138
+ 81
+
+
+
+
+ 277
+
+
+
+ 138
+ 81
+
+
+
+
+ 277.20001220703125
+
+
+
+ 139
+ 81
+
+
+
+
+ 277.79998779296875
+
+
+
+ 140
+ 81
+
+
+
+
+ 278.399993896484375
+
+
+
+ 140
+ 81
+
+
+
+
+ 279.600006103515625
+
+
+
+ 140
+ 81
+
+
+
+
+ 279.79998779296875
+
+
+
+ 140
+ 81
+
+
+
+
+ 280
+
+
+
+ 141
+ 80
+
+
+
+
+ 280.399993896484375
+
+
+
+ 141
+ 81
+
+
+
+
+ 280.399993896484375
+
+
+
+ 142
+ 81
+
+
+
+
+ 280.79998779296875
+
+
+
+ 142
+ 81
+
+
+
+
+ 281.399993896484375
+
+
+
+ 141
+ 80
+
+
+
+
+ 282
+
+
+
+ 140
+ 81
+
+
+
+
+ 282
+
+
+
+ 139
+ 80
+
+
+
+
+ 282
+
+
+
+ 137
+ 80
+
+
+
+
+ 282
+
+
+
+ 139
+ 82
+
+
+
+
+ 282
+
+
+
+ 143
+ 81
+
+
+
+
+ 282
+
+
+
+ 139
+ 81
+
+
+
+
+ 282.20001220703125
+
+
+
+ 139
+ 81
+
+
+
+
+ 282.79998779296875
+
+
+
+ 141
+ 82
+
+
+
+
+ 283.600006103515625
+
+
+
+ 140
+ 82
+
+
+
+
+ 284
+
+
+
+ 143
+ 82
+
+
+
+
+ 284.20001220703125
+
+
+
+ 142
+ 83
+
+
+
+
+ 284.399993896484375
+
+
+
+ 142
+ 82
+
+
+
+
+ 284.600006103515625
+
+
+
+ 141
+ 82
+
+
+
+
+ 284.399993896484375
+
+
+
+ 141
+ 81
+
+
+
+
+ 284.20001220703125
+
+
+
+ 142
+ 81
+
+
+
+
+ 284.20001220703125
+
+
+
+ 142
+ 80
+
+
+
+
+ 283.600006103515625
+
+
+
+ 142
+ 81
+
+
+
+
+ 283.399993896484375
+
+
+
+ 144
+ 83
+
+
+
+
+ 283.20001220703125
+
+
+
+ 143
+ 82
+
+
+
+
+ 283.79998779296875
+
+
+
+ 147
+ 81
+
+
+
+
+ 284
+
+
+
+ 148
+ 81
+
+
+
+
+ 284.20001220703125
+
+
+
+ 151
+ 81
+
+
+
+
+ 286.79998779296875
+
+
+
+ 155
+ 81
+
+
+
+
+ 287.399993896484375
+
+
+
+ 156
+ 81
+
+
+
+
+ 289.600006103515625
+
+
+
+ 160
+ 81
+
+
+
+
+ 292
+
+
+
+ 166
+ 81
+
+
+
+
+ 292.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 294.600006103515625
+
+
+
+ 171
+ 81
+
+
+
+
+ 295.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 295.399993896484375
+
+
+
+ 172
+ 80
+
+
+
+
+ 294
+
+
+
+ 171
+ 82
+
+
+
+
+ 292.20001220703125
+
+
+
+ 170
+ 81
+
+
+
+
+ 292
+
+
+
+ 169
+ 82
+
+
+
+
+ 291.20001220703125
+
+
+
+ 170
+ 83
+
+
+
+
+ 290.600006103515625
+
+
+
+ 170
+ 82
+
+
+
+
+ 290.600006103515625
+
+
+
+ 169
+ 82
+
+
+
+
+ 290.79998779296875
+
+
+
+ 169
+ 80
+
+
+
+
+ 291
+
+
+
+ 168
+ 82
+
+
+
+
+ 291.20001220703125
+
+
+
+ 168
+ 82
+
+
+
+
+ 292
+
+
+
+ 170
+ 81
+
+
+
+
+ 292.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 293
+
+
+
+ 173
+ 81
+
+
+
+
+ 293
+
+
+
+ 174
+ 80
+
+
+
+
+ 293
+
+
+
+ 174
+ 81
+
+
+
+
+ 292.79998779296875
+
+
+
+ 175
+ 75
+
+
+
+
+ 292.79998779296875
+
+
+
+ 174
+ 75
+
+
+
+
+ 292.600006103515625
+
+
+
+ 174
+ 0
+
+
+
+
+ 292
+
+
+
+ 174
+ 83
+
+
+
+
+ 289.79998779296875
+
+
+
+ 173
+ 81
+
+
+
+
+ 288.20001220703125
+
+
+
+ 171
+ 82
+
+
+
+
+ 287.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 287.79998779296875
+
+
+
+ 170
+ 81
+
+
+
+
+ 287.79998779296875
+
+
+
+ 169
+ 80
+
+
+
+
+ 288
+
+
+
+ 169
+ 81
+
+
+
+
+ 287.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 286.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 286.20001220703125
+
+
+
+ 171
+ 82
+
+
+
+
+ 286.600006103515625
+
+
+
+ 172
+ 82
+
+
+
+
+ 287.20001220703125
+
+
+
+ 172
+ 82
+
+
+
+
+ 288.600006103515625
+
+
+
+ 172
+ 82
+
+
+
+
+ 288.79998779296875
+
+
+
+ 173
+ 82
+
+
+
+
+ 290.20001220703125
+
+
+
+ 173
+ 82
+
+
+
+
+ 290.600006103515625
+
+
+
+ 174
+ 82
+
+
+
+
+ 292
+
+
+
+ 175
+ 80
+
+
+
+
+ 293.399993896484375
+
+
+
+ 175
+ 82
+
+
+
+
+ 293.600006103515625
+
+
+
+ 175
+ 82
+
+
+
+
+ 293.79998779296875
+
+
+
+ 175
+ 82
+
+
+
+
+ 294.600006103515625
+
+
+
+ 175
+ 81
+
+
+
+
+ 295.20001220703125
+
+
+
+ 175
+ 82
+
+
+
+
+ 296
+
+
+
+ 175
+ 80
+
+
+
+
+ 296
+
+
+
+ 175
+ 80
+
+
+
+
+ 295.399993896484375
+
+
+
+ 175
+ 81
+
+
+
+
+ 295.20001220703125
+
+
+
+ 175
+ 81
+
+
+
+
+ 295.20001220703125
+
+
+
+ 175
+ 80
+
+
+
+
+ 295
+
+
+
+ 175
+ 80
+
+
+
+
+ 294.399993896484375
+
+
+
+ 173
+ 81
+
+
+
+
+ 294
+
+
+
+ 172
+ 81
+
+
+
+
+ 294
+
+
+
+ 173
+ 81
+
+
+
+
+ 293.79998779296875
+
+
+
+ 173
+ 81
+
+
+
+
+ 294
+
+
+
+ 173
+ 81
+
+
+
+
+ 295
+
+
+
+ 174
+ 80
+
+
+
+
+ 296
+
+
+
+ 173
+ 81
+
+
+
+
+ 296
+
+
+
+ 174
+ 82
+
+
+
+
+ 296
+
+
+
+ 174
+ 82
+
+
+
+
+ 294.79998779296875
+
+
+
+ 174
+ 83
+
+
+
+
+ 294.600006103515625
+
+
+
+ 174
+ 83
+
+
+
+
+ 293.79998779296875
+
+
+
+ 174
+ 82
+
+
+
+
+ 293.399993896484375
+
+
+
+ 173
+ 81
+
+
+
+
+ 293.20001220703125
+
+
+
+ 173
+ 81
+
+
+
+
+ 293.399993896484375
+
+
+
+ 173
+ 81
+
+
+
+
+ 294.20001220703125
+
+
+
+ 172
+ 82
+
+
+
+
+ 295.20001220703125
+
+
+
+ 173
+ 82
+
+
+
+
+ 296.79998779296875
+
+
+
+ 173
+ 82
+
+
+
+
+ 297.20001220703125
+
+
+
+ 174
+ 82
+
+
+
+
+ 298.79998779296875
+
+
+
+ 174
+ 82
+
+
+
+
+ 300.399993896484375
+
+
+
+ 174
+ 81
+
+
+
+
+ 301.79998779296875
+
+
+
+ 173
+ 80
+
+
+
+
+ 302.399993896484375
+
+
+
+ 173
+ 81
+
+
+
+
+ 303.600006103515625
+
+
+
+ 173
+ 80
+
+
+
+
+ 303.79998779296875
+
+
+
+ 173
+ 81
+
+
+
+
+ 303.79998779296875
+
+
+
+ 172
+ 81
+
+
+
+
+ 301.399993896484375
+
+
+
+ 172
+ 82
+
+
+
+
+ 300.399993896484375
+
+
+
+ 172
+ 82
+
+
+
+
+ 299.20001220703125
+
+
+
+ 173
+ 83
+
+
+
+
+ 300.20001220703125
+
+
+
+ 173
+ 81
+
+
+
+
+ 301
+
+
+
+ 173
+ 82
+
+
+
+
+ 303.399993896484375
+
+
+
+ 174
+ 83
+
+
+
+
+ 304
+
+
+
+ 175
+ 83
+
+
+
+
+ 304.399993896484375
+
+
+
+ 174
+ 84
+
+
+
+
+ 304.79998779296875
+
+
+
+ 175
+ 82
+
+
+
+
+ 306.600006103515625
+
+
+
+ 175
+ 81
+
+
+
+
+ 307.20001220703125
+
+
+
+ 175
+ 81
+
+
+
+
+ 308
+
+
+
+ 175
+ 82
+
+
+
+
+ 307.79998779296875
+
+
+
+ 175
+ 80
+
+
+
+
+ 307.600006103515625
+
+
+
+ 174
+ 80
+
+
+
+
+ 306.399993896484375
+
+
+
+ 174
+ 81
+
+
+
+
+ 306
+
+
+
+ 174
+ 82
+
+
+
+
+ 306.20001220703125
+
+
+
+ 175
+ 81
+
+
+
+
+ 307.600006103515625
+
+
+
+ 175
+ 82
+
+
+
+
+ 309
+
+
+
+ 175
+ 82
+
+
+
+
+ 309.20001220703125
+
+
+
+ 176
+ 82
+
+
+
+
+ 310.600006103515625
+
+
+
+ 176
+ 82
+
+
+
+
+ 310.79998779296875
+
+
+
+ 176
+ 83
+
+
+
+
+ 312
+
+
+
+ 176
+ 83
+
+
+
+
+ 312
+
+
+
+ 176
+ 83
+
+
+
+
+ 311.79998779296875
+
+
+
+ 177
+ 83
+
+
+
+
+ 311.600006103515625
+
+
+
+ 177
+ 82
+
+
+
+
+ 311
+
+
+
+ 178
+ 83
+
+
+
+
+ 311.79998779296875
+
+
+
+ 178
+ 82
+
+
+
+
+ 312.600006103515625
+
+
+
+ 178
+ 83
+
+
+
+
+ 313.20001220703125
+
+
+
+ 178
+ 82
+
+
+
+
+ 314.399993896484375
+
+
+
+ 177
+ 83
+
+
+
+
+ 315.20001220703125
+
+
+
+ 178
+ 82
+
+
+
+
+ 315.399993896484375
+
+
+
+ 178
+ 82
+
+
+
+
+ 315.79998779296875
+
+
+
+ 177
+ 82
+
+
+
+
+ 315.79998779296875
+
+
+
+ 179
+ 82
+
+
+
+
+ 315.600006103515625
+
+
+
+ 178
+ 82
+
+
+
+
+ 315.600006103515625
+
+
+
+ 178
+ 82
+
+
+
+
+ 314.79998779296875
+
+
+
+ 177
+ 82
+
+
+
+
+ 314
+
+
+
+ 178
+ 83
+
+
+
+
+ 314
+
+
+
+ 178
+ 83
+
+
+
+
+ 314
+
+
+
+ 178
+ 82
+
+
+
+
+ 314
+
+
+
+ 178
+ 83
+
+
+
+
+ 316.20001220703125
+
+
+
+ 176
+ 84
+
+
+
+
+ 320
+
+
+
+ 176
+ 82
+
+
+
+
+ 321.79998779296875
+
+
+
+ 176
+ 82
+
+
+
+
+ 327.79998779296875
+
+
+
+ 175
+ 80
+
+
+
+
+ 328
+
+
+
+ 175
+ 80
+
+
+
+
+ 327.399993896484375
+
+
+
+ 176
+ 78
+
+
+
+
+ 322.600006103515625
+
+
+
+ 176
+ 81
+
+
+
+
+ 320
+
+
+
+ 176
+ 81
+
+
+
+
+ 317.600006103515625
+
+
+
+ 175
+ 81
+
+
+
+
+ 314.79998779296875
+
+
+
+ 174
+ 80
+
+
+
+
+ 314.399993896484375
+
+
+
+ 174
+ 79
+
+
+
+
+ 314
+
+
+
+ 174
+ 79
+
+
+
+
+ 314
+
+
+
+ 173
+ 79
+
+
+
+
+ 314.399993896484375
+
+
+
+ 173
+ 79
+
+
+
+
+ 315.79998779296875
+
+
+
+ 171
+ 82
+
+
+
+
+ 316
+
+
+
+ 171
+ 82
+
+
+
+
+ 316.20001220703125
+
+
+
+ 169
+ 80
+
+
+
+
+ 316.20001220703125
+
+
+
+ 169
+ 81
+
+
+
+
+ 315.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 315.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 314.600006103515625
+
+
+
+ 167
+ 82
+
+
+
+
+ 314.20001220703125
+
+
+
+ 167
+ 82
+
+
+
+
+ 312.399993896484375
+
+
+
+ 164
+ 82
+
+
+
+
+ 312.399993896484375
+
+
+
+ 164
+ 81
+
+
+
+
+ 311
+
+
+
+ 163
+ 82
+
+
+
+
+ 311
+
+
+
+ 163
+ 82
+
+
+
+
+ 311.399993896484375
+
+
+
+ 162
+ 81
+
+
+
+
+ 312
+
+
+
+ 162
+ 81
+
+
+
+
+ 312
+
+
+
+ 162
+ 82
+
+
+
+
+ 312
+
+
+
+ 162
+ 82
+
+
+
+
+ 311.20001220703125
+
+
+
+ 163
+ 81
+
+
+
+
+ 310.79998779296875
+
+
+
+ 163
+ 81
+
+
+
+
+ 309.20001220703125
+
+
+
+ 163
+ 82
+
+
+
+
+ 309
+
+
+
+ 163
+ 82
+
+
+
+
+ 307.399993896484375
+
+
+
+ 162
+ 82
+
+
+
+
+ 307
+
+
+
+ 160
+ 82
+
+
+
+
+ 306
+
+
+
+ 159
+ 81
+
+
+
+
+ 306
+
+
+
+ 160
+ 82
+
+
+
+
+ 306.20001220703125
+
+
+
+ 158
+ 80
+
+
+
+
+ 306.20001220703125
+
+
+
+ 161
+ 80
+
+
+
+
+ 306.79998779296875
+
+
+
+ 163
+ 80
+
+
+
+
+ 306.79998779296875
+
+
+
+ 163
+ 80
+
+
+
+
+ 306
+
+
+
+ 165
+ 80
+
+
+
+
+ 305.600006103515625
+
+
+
+ 166
+ 79
+
+
+
+
+ 304.399993896484375
+
+
+
+ 166
+ 80
+
+
+
+
+ 303.79998779296875
+
+
+
+ 165
+ 80
+
+
+
+
+ 302.79998779296875
+
+
+
+ 161
+ 81
+
+
+
+
+ 301.79998779296875
+
+
+
+ 161
+ 81
+
+
+
+
+ 301.600006103515625
+
+
+
+ 161
+ 81
+
+
+
+
+ 300.20001220703125
+
+
+
+ 163
+ 82
+
+
+
+
+ 299.20001220703125
+
+
+
+ 163
+ 81
+
+
+
+
+ 300.600006103515625
+
+
+
+ 162
+ 82
+
+
+
+
+ 301.79998779296875
+
+
+
+ 162
+ 82
+
+
+
+
+ 303
+
+
+
+ 163
+ 82
+
+
+
+
+ 303
+
+
+
+ 163
+ 82
+
+
+
+
+ 302.20001220703125
+
+
+
+ 163
+ 82
+
+
+
+
+ 301
+
+
+
+ 163
+ 80
+
+
+
+
+ 300.79998779296875
+
+
+
+ 163
+ 81
+
+
+
+
+ 300
+
+
+
+ 163
+ 81
+
+
+
+
+ 299.399993896484375
+
+
+
+ 163
+ 81
+
+
+
+
+ 299.600006103515625
+
+
+
+ 163
+ 81
+
+
+
+
+ 299.79998779296875
+
+
+
+ 163
+ 80
+
+
+
+
+ 300.399993896484375
+
+
+
+ 162
+ 79
+
+
+
+
+ 302
+
+
+
+ 161
+ 81
+
+
+
+
+ 302.399993896484375
+
+
+
+ 161
+ 81
+
+
+
+
+ 304
+
+
+
+ 161
+ 82
+
+
+
+
+ 304.20001220703125
+
+
+
+ 161
+ 81
+
+
+
+
+ 303.79998779296875
+
+
+
+ 161
+ 80
+
+
+
+
+ 302.600006103515625
+
+
+
+ 164
+ 79
+
+
+
+
+ 298.600006103515625
+
+
+
+ 166
+ 80
+
+
+
+
+ 297.600006103515625
+
+
+
+ 165
+ 80
+
+
+
+
+ 297.600006103515625
+
+
+
+ 165
+ 81
+
+
+
+
+ 299.20001220703125
+
+
+
+ 166
+ 81
+
+
+
+
+ 299.79998779296875
+
+
+
+ 166
+ 81
+
+
+
+
+ 303.20001220703125
+
+
+
+ 165
+ 80
+
+
+
+
+ 304
+
+
+
+ 165
+ 81
+
+
+
+
+ 307
+
+
+
+ 165
+ 81
+
+
+
+
+ 308.20001220703125
+
+
+
+ 166
+ 83
+
+
+
+
+ 309.20001220703125
+
+
+
+ 167
+ 81
+
+
+
+
+ 309
+
+
+
+ 168
+ 81
+
+
+
+
+ 306.399993896484375
+
+
+
+ 169
+ 79
+
+
+
+
+ 304.79998779296875
+
+
+
+ 170
+ 79
+
+
+
+
+ 302.79998779296875
+
+
+
+ 171
+ 80
+
+
+
+
+ 300.79998779296875
+
+
+
+ 170
+ 80
+
+
+
+
+ 300.20001220703125
+
+
+
+ 171
+ 80
+
+
+
+
+ 299.399993896484375
+
+
+
+ 175
+ 81
+
+
+
+
+ 299.20001220703125
+
+
+
+ 173
+ 81
+
+
+
+
+ 297.79998779296875
+
+
+
+ 171
+ 81
+
+
+
+
+ 295.399993896484375
+
+
+
+ 170
+ 80
+
+
+
+
+ 294.399993896484375
+
+
+
+ 170
+ 81
+
+
+
+
+ 294
+
+
+
+ 167
+ 82
+
+
+
+
+ 294
+
+
+
+ 166
+ 82
+
+
+
+
+ 294.20001220703125
+
+
+
+ 168
+ 81
+
+
+
+
+ 294.399993896484375
+
+
+
+ 168
+ 82
+
+
+
+
+ 295.399993896484375
+
+
+
+ 167
+ 82
+
+
+
+
+ 296.20001220703125
+
+
+
+ 167
+ 81
+
+
+
+
+ 297.20001220703125
+
+
+
+ 169
+ 81
+
+
+
+
+ 297.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 297.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 297.600006103515625
+
+
+
+ 167
+ 81
+
+
+
+
+ 297
+
+
+
+ 167
+ 82
+
+
+
+
+ 296.79998779296875
+
+
+
+ 167
+ 82
+
+
+
+
+ 296.20001220703125
+
+
+
+ 167
+ 81
+
+
+
+
+ 296
+
+
+
+ 167
+ 81
+
+
+
+
+ 296
+
+
+
+ 167
+ 80
+
+
+
+
+ 296
+
+
+
+ 166
+ 81
+
+
+
+
+ 294.79998779296875
+
+
+
+ 166
+ 81
+
+
+
+
+ 294.600006103515625
+
+
+
+ 166
+ 81
+
+
+
+
+ 293
+
+
+
+ 166
+ 81
+
+
+
+
+ 292.600006103515625
+
+
+
+ 166
+ 80
+
+
+
+
+ 291.79998779296875
+
+
+
+ 163
+ 81
+
+
+
+
+ 291
+
+
+
+ 165
+ 81
+
+
+
+
+ 291
+
+
+
+ 168
+ 83
+
+
+
+
+ 291
+
+
+
+ 168
+ 82
+
+
+
+
+ 291.79998779296875
+
+
+
+ 167
+ 82
+
+
+
+
+ 291.600006103515625
+
+
+
+ 168
+ 82
+
+
+
+
+ 291
+
+
+
+ 167
+ 81
+
+
+
+
+ 290.399993896484375
+
+
+
+ 167
+ 81
+
+
+
+
+ 289
+
+
+
+ 167
+ 81
+
+
+
+
+ 288.79998779296875
+
+
+
+ 167
+ 80
+
+
+
+
+ 288.399993896484375
+
+
+
+ 165
+ 81
+
+
+
+
+ 288.20001220703125
+
+
+
+ 165
+ 81
+
+
+
+
+ 289.600006103515625
+
+
+
+ 166
+ 81
+
+
+
+
+ 290.399993896484375
+
+
+
+ 166
+ 82
+
+
+
+
+ 292.399993896484375
+
+
+
+ 166
+ 81
+
+
+
+
+ 292.79998779296875
+
+
+
+ 166
+ 81
+
+
+
+
+ 293.20001220703125
+
+
+
+ 164
+ 82
+
+
+
+
+ 292.79998779296875
+
+
+
+ 164
+ 82
+
+
+
+
+ 291.20001220703125
+
+
+
+ 166
+ 80
+
+
+
+
+ 290.600006103515625
+
+
+
+ 167
+ 81
+
+
+
+
+ 288.600006103515625
+
+
+
+ 167
+ 82
+
+
+
+
+ 287.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 286
+
+
+
+ 167
+ 81
+
+
+
+
+ 285.79998779296875
+
+
+
+ 168
+ 82
+
+
+
+
+ 285
+
+
+
+ 168
+ 82
+
+
+
+
+ 285
+
+
+
+ 169
+ 82
+
+
+
+
+ 285.399993896484375
+
+
+
+ 167
+ 81
+
+
+
+
+ 285.20001220703125
+
+
+
+ 164
+ 83
+
+
+
+
+ 284.79998779296875
+
+
+
+ 164
+ 83
+
+
+
+
+ 284
+
+
+
+ 166
+ 83
+
+
+
+
+ 283.79998779296875
+
+
+
+ 165
+ 82
+
+
+
+
+ 283.600006103515625
+
+
+
+ 167
+ 82
+
+
+
+
+ 283.600006103515625
+
+
+
+ 166
+ 80
+
+
+
+
+ 283.20001220703125
+
+
+
+ 165
+ 80
+
+
+
+
+ 282
+
+
+
+ 162
+ 81
+
+
+
+
+ 281.600006103515625
+
+
+
+ 160
+ 82
+
+
+
+
+ 279.600006103515625
+
+
+
+ 163
+ 82
+
+
+
+
+ 279.399993896484375
+
+
+
+ 163
+ 82
+
+
+
+
+ 278
+
+
+
+ 165
+ 82
+
+
+
+
+ 278.399993896484375
+
+
+
+ 163
+ 83
+
+
+
+
+ 278.399993896484375
+
+
+
+ 163
+ 82
+
+
+
+
+ 279.79998779296875
+
+
+
+ 163
+ 81
+
+
+
+
+ 280
+
+
+
+ 163
+ 81
+
+
+
+
+ 281
+
+
+
+ 163
+ 81
+
+
+
+
+ 281
+
+
+
+ 163
+ 81
+
+
+
+
+ 280.600006103515625
+
+
+
+ 163
+ 80
+
+
+
+
+ 280.399993896484375
+
+
+
+ 163
+ 81
+
+
+
+
+ 280
+
+
+
+ 162
+ 81
+
+
+
+
+ 280.399993896484375
+
+
+
+ 164
+ 81
+
+
+
+
+ 281.20001220703125
+
+
+
+ 165
+ 82
+
+
+
+
+ 281.600006103515625
+
+
+
+ 165
+ 82
+
+
+
+
+ 282.79998779296875
+
+
+
+ 165
+ 82
+
+
+
+
+ 284.20001220703125
+
+
+
+ 166
+ 81
+
+
+
+
+ 284.79998779296875
+
+
+
+ 166
+ 82
+
+
+
+
+ 285.79998779296875
+
+
+
+ 167
+ 83
+
+
+
+
+ 285.600006103515625
+
+
+
+ 167
+ 83
+
+
+
+
+ 284.20001220703125
+
+
+
+ 168
+ 84
+
+
+
+
+ 283.79998779296875
+
+
+
+ 168
+ 84
+
+
+
+
+ 282.79998779296875
+
+
+
+ 169
+ 82
+
+
+
+
+ 279.600006103515625
+
+
+
+ 169
+ 80
+
+
+
+
+ 278.20001220703125
+
+
+
+ 168
+ 80
+
+
+
+
+ 275.399993896484375
+
+
+
+ 168
+ 82
+
+
+
+
+ 274
+
+
+
+ 169
+ 81
+
+
+
+
+ 272
+
+
+
+ 170
+ 80
+
+
+
+
+ 272
+
+
+
+ 172
+ 81
+
+
+
+
+ 272.399993896484375
+
+
+
+ 170
+ 82
+
+
+
+
+ 273
+
+
+
+ 170
+ 81
+
+
+
+
+ 274.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 274.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 274.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 274.399993896484375
+
+
+
+ 170
+ 80
+
+
+
+
+ 275.20001220703125
+
+
+
+ 170
+ 80
+
+
+
+
+ 275.600006103515625
+
+
+
+ 170
+ 81
+
+
+
+
+ 276.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 276
+
+
+
+ 168
+ 81
+
+
+
+
+ 276
+
+
+
+ 168
+ 81
+
+
+
+
+ 275
+
+
+
+ 169
+ 80
+
+
+
+
+ 274.399993896484375
+
+
+
+ 169
+ 82
+
+
+
+
+ 272.79998779296875
+
+
+
+ 168
+ 82
+
+
+
+
+ 272.600006103515625
+
+
+
+ 169
+ 81
+
+
+
+
+ 271.79998779296875
+
+
+
+ 168
+ 76
+
+
+
+
+ 271.399993896484375
+
+
+
+ 168
+ 79
+
+
+
+
+ 271
+
+
+
+ 165
+ 81
+
+
+
+
+ 270.79998779296875
+
+
+
+ 164
+ 81
+
+
+
+
+ 271.399993896484375
+
+
+
+ 162
+ 80
+
+
+
+
+ 271.399993896484375
+
+
+
+ 163
+ 81
+
+
+
+
+ 271
+
+
+
+ 161
+ 81
+
+
+
+
+ 271
+
+
+
+ 161
+ 81
+
+
+
+
+ 270.79998779296875
+
+
+
+ 164
+ 81
+
+
+
+
+ 270.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 271
+
+
+
+ 168
+ 81
+
+
+
+
+ 270.399993896484375
+
+
+
+ 167
+ 82
+
+
+
+
+ 270.20001220703125
+
+
+
+ 166
+ 82
+
+
+
+
+ 270
+
+
+
+ 168
+ 83
+
+
+
+
+ 270
+
+
+
+ 168
+ 82
+
+
+
+
+ 270
+
+
+
+ 168
+ 82
+
+
+
+
+ 270.399993896484375
+
+
+
+ 168
+ 82
+
+
+
+
+ 271.399993896484375
+
+
+
+ 169
+ 81
+
+
+
+
+ 271.399993896484375
+
+
+
+ 167
+ 82
+
+
+
+
+ 271.20001220703125
+
+
+
+ 169
+ 83
+
+
+
+
+ 271
+
+
+
+ 169
+ 83
+
+
+
+
+ 270.399993896484375
+
+
+
+ 170
+ 82
+
+
+
+
+ 270.399993896484375
+
+
+
+ 169
+ 83
+
+
+
+
+ 270.600006103515625
+
+
+
+ 168
+ 82
+
+
+
+
+ 270.399993896484375
+
+
+
+ 169
+ 81
+
+
+
+
+ 270.20001220703125
+
+
+
+ 168
+ 82
+
+
+
+
+ 269.600006103515625
+
+
+
+ 169
+ 82
+
+
+
+
+ 267.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 268
+
+
+
+ 169
+ 82
+
+
+
+
+ 266.79998779296875
+
+
+
+ 169
+ 82
+
+
+
+
+ 266.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 266.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 266.79998779296875
+
+
+
+ 169
+ 81
+
+
+
+
+ 265.79998779296875
+
+
+
+ 170
+ 80
+
+
+
+
+ 265.399993896484375
+
+
+
+ 170
+ 80
+
+
+
+
+ 265
+
+
+
+ 170
+ 78
+
+
+
+
+ 265
+
+
+
+ 171
+ 78
+
+
+
+
+ 264.79998779296875
+
+
+
+ 174
+ 81
+
+
+
+
+ 264
+
+
+
+ 173
+ 80
+
+
+
+
+ 264.20001220703125
+
+
+
+ 170
+ 82
+
+
+
+
+ 264.20001220703125
+
+
+
+ 166
+ 82
+
+
+
+
+ 264.20001220703125
+
+
+
+ 166
+ 81
+
+
+
+
+ 264.20001220703125
+
+
+
+ 169
+ 81
+
+
+
+
+ 263.79998779296875
+
+
+
+ 168
+ 81
+
+
+
+
+ 263.399993896484375
+
+
+
+ 167
+ 81
+
+
+
+
+ 263
+
+
+
+ 167
+ 81
+
+
+
+
+ 261.600006103515625
+
+
+
+ 166
+ 81
+
+
+
+
+ 261.20001220703125
+
+
+
+ 166
+ 80
+
+
+
+
+ 260.20001220703125
+
+
+
+ 168
+ 82
+
+
+
+
+ 259.20001220703125
+
+
+
+ 170
+ 82
+
+
+
+
+ 258.79998779296875
+
+
+
+ 169
+ 82
+
+
+
+
+ 258.79998779296875
+
+
+
+ 169
+ 82
+
+
+
+
+ 258.79998779296875
+
+
+
+ 168
+ 82
+
+
+
+
+ 258.20001220703125
+
+
+
+ 168
+ 80
+
+
+
+
+ 257.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 258.600006103515625
+
+
+
+ 166
+ 80
+
+
+
+
+ 258.600006103515625
+
+
+
+ 167
+ 80
+
+
+
+
+ 259.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 260.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 261
+
+
+
+ 169
+ 81
+
+
+
+
+ 261
+
+
+
+ 168
+ 81
+
+
+
+
+ 261
+
+
+
+ 170
+ 81
+
+
+
+
+ 261
+
+
+
+ 170
+ 82
+
+
+
+
+ 261
+
+
+
+ 170
+ 81
+
+
+
+
+ 261
+
+
+
+ 170
+ 82
+
+
+
+
+ 261
+
+
+
+ 170
+ 82
+
+
+
+
+ 261
+
+
+
+ 172
+ 81
+
+
+
+
+ 261
+
+
+
+ 172
+ 83
+
+
+
+
+ 261.20001220703125
+
+
+
+ 172
+ 81
+
+
+
+
+ 261.20001220703125
+
+
+
+ 172
+ 81
+
+
+
+
+ 261.79998779296875
+
+
+
+ 171
+ 82
+
+
+
+
+ 261.79998779296875
+
+
+
+ 170
+ 82
+
+
+
+
+ 261
+
+
+
+ 170
+ 82
+
+
+
+
+ 260.600006103515625
+
+
+
+ 171
+ 83
+
+
+
+
+ 259.20001220703125
+
+
+
+ 172
+ 82
+
+
+
+
+ 259
+
+
+
+ 172
+ 82
+
+
+
+
+ 258.20001220703125
+
+
+
+ 171
+ 83
+
+
+
+
+ 258.20001220703125
+
+
+
+ 172
+ 83
+
+
+
+
+ 258
+
+
+
+ 171
+ 81
+
+
+
+
+ 257.79998779296875
+
+
+
+ 173
+ 81
+
+
+
+
+ 257.79998779296875
+
+
+
+ 174
+ 82
+
+
+
+
+ 257.79998779296875
+
+
+
+ 174
+ 81
+
+
+
+
+ 257.600006103515625
+
+
+
+ 173
+ 80
+
+
+
+
+ 257.600006103515625
+
+
+
+ 173
+ 80
+
+
+
+
+ 258
+
+
+
+ 173
+ 81
+
+
+
+
+ 258.399993896484375
+
+
+
+ 174
+ 81
+
+
+
+
+ 259.79998779296875
+
+
+
+ 173
+ 80
+
+
+
+
+ 261.20001220703125
+
+
+
+ 172
+ 81
+
+
+
+
+ 261.600006103515625
+
+
+
+ 172
+ 82
+
+
+
+
+ 262.399993896484375
+
+
+
+ 173
+ 83
+
+
+
+
+ 262.20001220703125
+
+
+
+ 172
+ 83
+
+
+
+
+ 261.600006103515625
+
+
+
+ 172
+ 83
+
+
+
+
+ 261.600006103515625
+
+
+
+ 168
+ 82
+
+
+
+
+ 261.600006103515625
+
+
+
+ 171
+ 81
+
+
+
+
+ 261.600006103515625
+
+
+
+ 171
+ 81
+
+
+
+
+ 261.399993896484375
+
+
+
+ 172
+ 82
+
+
+
+
+ 261.399993896484375
+
+
+
+ 173
+ 83
+
+
+
+
+ 261
+
+
+
+ 173
+ 82
+
+
+
+
+ 261
+
+
+
+ 173
+ 83
+
+
+
+
+ 261
+
+
+
+ 172
+ 83
+
+
+
+
+ 261
+
+
+
+ 173
+ 83
+
+
+
+
+ 260.79998779296875
+
+
+
+ 174
+ 80
+
+
+
+
+ 260.600006103515625
+
+
+
+ 174
+ 78
+
+
+
+
+ 259.399993896484375
+
+
+
+ 175
+ 79
+
+
+
+
+ 259
+
+
+
+ 175
+ 80
+
+
+
+
+ 258.399993896484375
+
+
+
+ 174
+ 82
+
+
+
+
+ 258.399993896484375
+
+
+
+ 174
+ 81
+
+
+
+
+ 259.399993896484375
+
+
+
+ 174
+ 82
+
+
+
+
+ 259.600006103515625
+
+
+
+ 173
+ 82
+
+
+
+
+ 259.399993896484375
+
+
+
+ 171
+ 83
+
+
+
+
+ 259.600006103515625
+
+
+
+ 173
+ 83
+
+
+
+
+ 260.399993896484375
+
+
+
+ 173
+ 82
+
+
+
+
+ 262
+
+
+
+ 173
+ 81
+
+
+
+
+ 263.600006103515625
+
+
+
+ 175
+ 82
+
+
+
+
+ 265.20001220703125
+
+
+
+ 175
+ 82
+
+
+
+
+ 265.20001220703125
+
+
+
+ 175
+ 82
+
+
+
+
+ 265
+
+
+
+ 175
+ 82
+
+
+
+
+ 264.600006103515625
+
+
+
+ 176
+ 82
+
+
+
+
+ 264.600006103515625
+
+
+
+ 175
+ 82
+
+
+
+
+ 265.20001220703125
+
+
+
+ 176
+ 80
+
+
+
+
+ 266
+
+
+
+ 175
+ 82
+
+
+
+
+ 266
+
+
+
+ 176
+ 81
+
+
+
+
+ 267.20001220703125
+
+
+
+ 177
+ 81
+
+
+
+
+ 267.600006103515625
+
+
+
+ 177
+ 81
+
+
+
+
+ 268.399993896484375
+
+
+
+ 176
+ 80
+
+
+
+
+ 269
+
+
+
+ 176
+ 80
+
+
+
+
+ 270
+
+
+
+ 177
+ 80
+
+
+
+
+ 270.20001220703125
+
+
+
+ 177
+ 79
+
+
+
+
+ 270
+
+
+
+ 177
+ 81
+
+
+
+
+ 269.600006103515625
+
+
+
+ 178
+ 82
+
+
+
+
+ 269.399993896484375
+
+
+
+ 176
+ 81
+
+
+
+
+ 269.399993896484375
+
+
+
+ 176
+ 81
+
+
+
+
+ 269.79998779296875
+
+
+
+ 179
+ 83
+
+
+
+
+ 270
+
+
+
+ 176
+ 83
+
+
+
+
+ 270.79998779296875
+
+
+
+ 178
+ 83
+
+
+
+
+ 271
+
+
+
+ 181
+ 81
+
+
+
+
+ 271
+
+
+
+ 182
+ 82
+
+
+
+
+ 271.600006103515625
+
+
+
+ 181
+ 82
+
+
+
+
+ 272
+
+
+
+ 179
+ 83
+
+
+
+
+ 272.79998779296875
+
+
+
+ 176
+ 82
+
+
+
+
+ 272.79998779296875
+
+
+
+ 176
+ 82
+
+
+
+
+ 272.399993896484375
+
+
+
+ 176
+ 82
+
+
+
+
+ 272.20001220703125
+
+
+
+ 176
+ 82
+
+
+
+
+ 271
+
+
+
+ 176
+ 82
+
+
+
+
+ 270.79998779296875
+
+
+
+ 176
+ 82
+
+
+
+
+ 270.79998779296875
+
+
+
+ 178
+ 83
+
+
+
+
+ 270.20001220703125
+
+
+
+ 177
+ 83
+
+
+
+
+ 270.20001220703125
+
+
+
+ 177
+ 84
+
+
+
+
+ 270.399993896484375
+
+
+
+ 176
+ 84
+
+
+
+
+ 271
+
+
+
+ 177
+ 85
+
+
+
+
+ 271.20001220703125
+
+
+
+ 177
+ 84
+
+
+
+
+ 271.600006103515625
+
+
+
+ 177
+ 82
+
+
+
+
+ 271.79998779296875
+
+
+
+ 177
+ 82
+
+
+
+
+ 271.79998779296875
+
+
+
+ 177
+ 83
+
+
+
+
+ 272
+
+
+
+ 177
+ 83
+
+
+
+
+ 273
+
+
+
+ 177
+ 82
+
+
+
+
+ 273.20001220703125
+
+
+
+ 178
+ 82
+
+
+
+
+ 273.79998779296875
+
+
+
+ 178
+ 82
+
+
+
+
+ 275.600006103515625
+
+
+
+ 179
+ 83
+
+
+
+
+ 275.79998779296875
+
+
+
+ 179
+ 83
+
+
+
+
+ 276.79998779296875
+
+
+
+ 178
+ 83
+
+
+
+
+ 277
+
+
+
+ 178
+ 81
+
+
+
+
+ 276.600006103515625
+
+
+
+ 177
+ 82
+
+
+
+
+ 278
+
+
+
+ 177
+ 82
+
+
+
+
+ 278.399993896484375
+
+
+
+ 176
+ 80
+
+
+
+
+ 278.20001220703125
+
+
+
+ 176
+ 80
+
+
+
+
+ 277.79998779296875
+
+
+
+ 177
+ 79
+
+
+
+
+ 277.79998779296875
+
+
+
+ 178
+ 78
+
+
+
+
+ 277.79998779296875
+
+
+
+ 178
+ 80
+
+
+
+
+ 278
+
+
+
+ 180
+ 80
+
+
+
+
+ 278.399993896484375
+
+
+
+ 177
+ 82
+
+
+
+
+ 278.600006103515625
+
+
+
+ 177
+ 82
+
+
+
+
+ 278.79998779296875
+
+
+
+ 176
+ 81
+
+
+
+
+ 279.600006103515625
+
+
+
+ 178
+ 82
+
+
+
+
+ 280.399993896484375
+
+
+
+ 177
+ 81
+
+
+
+
+ 280.600006103515625
+
+
+
+ 177
+ 83
+
+
+
+
+ 281.20001220703125
+
+
+
+ 178
+ 82
+
+
+
+
+ 281.20001220703125
+
+
+
+ 178
+ 82
+
+
+
+
+ 281.79998779296875
+
+
+
+ 176
+ 80
+
+
+
+
+ 282
+
+
+
+ 176
+ 81
+
+
+
+
+ 281
+
+
+
+ 176
+ 81
+
+
+
+
+ 281
+
+
+
+ 176
+ 81
+
+
+
+
+ 281.20001220703125
+
+
+
+ 177
+ 82
+
+
+
+
+ 281.20001220703125
+
+
+
+ 176
+ 82
+
+
+
+
+ 281
+
+
+
+ 177
+ 82
+
+
+
+
+ 281.20001220703125
+
+
+
+ 178
+ 84
+
+
+
+
+ 281
+
+
+
+ 178
+ 84
+
+
+
+
+ 280.399993896484375
+
+
+
+ 176
+ 82
+
+
+
+
+ 280.600006103515625
+
+
+
+ 176
+ 83
+
+
+
+
+ 281
+
+
+
+ 178
+ 82
+
+
+
+
+ 282.20001220703125
+
+
+
+ 178
+ 81
+
+
+
+
+ 283.79998779296875
+
+
+
+ 177
+ 81
+
+
+
+
+ 284.20001220703125
+
+
+
+ 177
+ 81
+
+
+
+
+ 284.79998779296875
+
+
+
+ 177
+ 80
+
+
+
+
+ 285.600006103515625
+
+
+
+ 178
+ 81
+
+
+
+
+ 285.600006103515625
+
+
+
+ 177
+ 81
+
+
+
+
+ 285.399993896484375
+
+
+
+ 176
+ 81
+
+
+
+
+ 285.20001220703125
+
+
+
+ 176
+ 81
+
+
+
+
+ 285
+
+
+
+ 177
+ 81
+
+
+
+
+ 285
+
+
+
+ 177
+ 80
+
+
+
+
+ 285
+
+
+
+ 177
+ 81
+
+
+
+
+ 285
+
+
+
+ 177
+ 81
+
+
+
+
+ 284.79998779296875
+
+
+
+ 180
+ 82
+
+
+
+
+ 284.399993896484375
+
+
+
+ 182
+ 82
+
+
+
+
+ 284.20001220703125
+
+
+
+ 179
+ 82
+
+
+
+
+ 283.79998779296875
+
+
+
+ 178
+ 80
+
+
+
+
+ 283.600006103515625
+
+
+
+ 178
+ 80
+
+
+
+
+ 284.600006103515625
+
+
+
+ 178
+ 82
+
+
+
+
+ 284.79998779296875
+
+
+
+ 178
+ 81
+
+
+
+
+ 285.79998779296875
+
+
+
+ 178
+ 82
+
+
+
+
+ 286.79998779296875
+
+
+
+ 178
+ 82
+
+
+
+
+ 287.79998779296875
+
+
+
+ 181
+ 81
+
+
+
+
+ 288
+
+
+
+ 181
+ 80
+
+
+
+
+ 288.20001220703125
+
+
+
+ 179
+ 81
+
+
+
+
+ 288
+
+
+
+ 178
+ 81
+
+
+
+
+ 288.79998779296875
+
+
+
+ 179
+ 81
+
+
+
+
+ 289
+
+
+
+ 178
+ 80
+
+
+
+
+ 291.399993896484375
+
+
+
+ 177
+ 78
+
+
+
+
+ 292.20001220703125
+
+
+
+ 176
+ 80
+
+
+
+
+ 292.79998779296875
+
+
+
+ 172
+ 0
+
+
+
+
+ 293
+
+
+
+ 171
+ 0
+
+
+
+
+ 293
+
+
+
+ 168
+ 77
+
+
+
+
+ 293
+
+
+
+ 167
+ 78
+
+
+
+
+ 293
+
+
+
+ 165
+ 79
+
+
+
+
+ 292.20001220703125
+
+
+
+ 166
+ 80
+
+
+
+
+ 291.20001220703125
+
+
+
+ 165
+ 80
+
+
+
+
+ 290.79998779296875
+
+
+
+ 165
+ 81
+
+
+
+
+ 290.399993896484375
+
+
+
+ 166
+ 79
+
+
+
+
+ 290.399993896484375
+
+
+
+ 166
+ 80
+
+
+
+
+ 291
+
+
+
+ 166
+ 81
+
+
+
+
+ 291.399993896484375
+
+
+
+ 165
+ 81
+
+
+
+
+ 293.20001220703125
+
+
+
+ 165
+ 81
+
+
+
+
+ 294
+
+
+
+ 166
+ 81
+
+
+
+
+ 293.20001220703125
+
+
+
+ 166
+ 81
+
+
+
+
+ 292.399993896484375
+
+
+
+ 167
+ 82
+
+
+
+
+ 288.600006103515625
+
+
+
+ 167
+ 80
+
+
+
+
+ 288
+
+
+
+ 167
+ 80
+
+
+
+
+ 285.20001220703125
+
+
+
+ 167
+ 83
+
+
+
+
+ 284.79998779296875
+
+
+
+ 167
+ 82
+
+
+
+
+ 283
+
+
+
+ 167
+ 81
+
+
+
+
+ 282.600006103515625
+
+
+
+ 167
+ 80
+
+
+
+
+ 283.399993896484375
+
+
+
+ 166
+ 80
+
+
+
+
+ 283.600006103515625
+
+
+
+ 166
+ 79
+
+
+
+
+ 283.600006103515625
+
+
+
+ 166
+ 79
+
+
+
+
+ 283.79998779296875
+
+
+
+ 166
+ 80
+
+
+
+
+ 284
+
+
+
+ 167
+ 80
+
+
+
+
+ 284
+
+
+
+ 168
+ 81
+
+
+
+
+ 284
+
+
+
+ 168
+ 82
+
+
+
+
+ 283.600006103515625
+
+
+
+ 168
+ 82
+
+
+
+
+ 283.399993896484375
+
+
+
+ 168
+ 81
+
+
+
+
+ 283
+
+
+
+ 166
+ 81
+
+
+
+
+ 282.79998779296875
+
+
+
+ 169
+ 80
+
+
+
+
+ 282.399993896484375
+
+
+
+ 168
+ 80
+
+
+
+
+ 282.399993896484375
+
+
+
+ 165
+ 80
+
+
+
+
+ 282
+
+
+
+ 168
+ 80
+
+
+
+
+ 282
+
+
+
+ 168
+ 81
+
+
+
+
+ 282
+
+
+
+ 168
+ 80
+
+
+
+
+ 282
+
+
+
+ 168
+ 80
+
+
+
+
+ 281.79998779296875
+
+
+
+ 167
+ 81
+
+
+
+
+ 280.79998779296875
+
+
+
+ 167
+ 82
+
+
+
+
+ 279.79998779296875
+
+
+
+ 169
+ 84
+
+
+
+
+ 279.20001220703125
+
+
+
+ 168
+ 79
+
+
+
+
+ 277.79998779296875
+
+
+
+ 171
+ 80
+
+
+
+
+ 277.20001220703125
+
+
+
+ 173
+ 81
+
+
+
+
+ 277.20001220703125
+
+
+
+ 173
+ 81
+
+
+
+
+ 276.79998779296875
+
+
+
+ 175
+ 80
+
+
+
+
+ 276.399993896484375
+
+
+
+ 174
+ 72
+
+
+
+
+ 276.399993896484375
+
+
+
+ 173
+ 0
+
+
+
+
+ 276.20001220703125
+
+
+
+ 172
+ 81
+
+
+
+
+ 276.20001220703125
+
+
+
+ 171
+ 81
+
+
+
+
+ 276.20001220703125
+
+
+
+ 171
+ 81
+
+
+
+
+ 276
+
+
+
+ 169
+ 80
+
+
+
+
+ 275
+
+
+
+ 167
+ 83
+
+
+
+
+ 274
+
+
+
+ 167
+ 81
+
+
+
+
+ 274
+
+
+
+ 168
+ 83
+
+
+
+
+ 274
+
+
+
+ 169
+ 81
+
+
+
+
+ 274.399993896484375
+
+
+
+ 168
+ 80
+
+
+
+
+ 274.399993896484375
+
+
+
+ 169
+ 80
+
+
+
+
+ 274.600006103515625
+
+
+
+ 168
+ 81
+
+
+
+
+ 274.399993896484375
+
+
+
+ 170
+ 82
+
+
+
+
+ 273.600006103515625
+
+
+
+ 170
+ 82
+
+
+
+
+ 273.399993896484375
+
+
+
+ 170
+ 82
+
+
+
+
+ 272.399993896484375
+
+
+
+ 170
+ 82
+
+
+
+
+ 271
+
+
+
+ 170
+ 82
+
+
+
+
+ 268.20001220703125
+
+
+
+ 171
+ 82
+
+
+
+
+ 265.79998779296875
+
+
+
+ 170
+ 81
+
+
+
+
+ 265.20001220703125
+
+
+
+ 169
+ 83
+
+
+
+
+ 265.399993896484375
+
+
+
+ 169
+ 82
+
+
+
+
+ 265.399993896484375
+
+
+
+ 169
+ 81
+
+
+
+
+ 264.79998779296875
+
+
+
+ 171
+ 82
+
+
+
+
+ 264.600006103515625
+
+
+
+ 173
+ 83
+
+
+
+
+ 264
+
+
+
+ 173
+ 80
+
+
+
+
+ 264
+
+
+
+ 173
+ 81
+
+
+
+
+ 264
+
+
+
+ 173
+ 80
+
+
+
+
+ 265
+
+
+
+ 173
+ 84
+
+
+
+
+ 267
+
+
+
+ 174
+ 83
+
+
+
+
+ 267.600006103515625
+
+
+
+ 173
+ 83
+
+
+
+
+ 269
+
+
+
+ 172
+ 82
+
+
+
+
+ 270.399993896484375
+
+
+
+ 173
+ 83
+
+
+
+
+ 270.399993896484375
+
+
+
+ 173
+ 83
+
+
+
+
+ 270.20001220703125
+
+
+
+ 173
+ 82
+
+
+
+
+ 270
+
+
+
+ 173
+ 82
+
+
+
+
+ 269.600006103515625
+
+
+
+ 174
+ 81
+
+
+
+
+ 270
+
+
+
+ 174
+ 80
+
+
+
+
+ 270
+
+
+
+ 174
+ 81
+
+
+
+
+ 269.600006103515625
+
+
+
+ 174
+ 81
+
+
+
+
+
+
diff --git a/src/tests/integration/inputs/test_input_trace.gpx b/src/tests/integration/inputs/test_input_trace_pauses.gpx
similarity index 99%
rename from src/tests/integration/inputs/test_input_trace.gpx
rename to src/tests/integration/inputs/test_input_trace_pauses.gpx
index 76562dc..5ba30ff 100644
--- a/src/tests/integration/inputs/test_input_trace.gpx
+++ b/src/tests/integration/inputs/test_input_trace_pauses.gpx
@@ -11,7 +11,7 @@
- Test walking trace
+ Bolzano Walking
walking
diff --git a/src/tests/integration/trace_cleaning_test.py b/src/tests/integration/trace_cleaning_test.py
index 54dc6cc..5503050 100644
--- a/src/tests/integration/trace_cleaning_test.py
+++ b/src/tests/integration/trace_cleaning_test.py
@@ -2,14 +2,26 @@
import os
class TestTraceCleaning:
- # test input trace
- test_input_trace_basepath = "./src/tests/integration/inputs/test_input_trace"
- test_input_trace = f"{test_input_trace_basepath}.gpx"
+ # test input traces
+ test_input_trace_outliers_basepath = "./src/tests/integration/inputs/test_input_trace_outliers"
+ test_input_trace_pauses_basepath = "./src/tests/integration/inputs/test_input_trace_outliers"
+
+ test_input_trace_outliers = f"{test_input_trace_outliers_basepath}.gpx"
+ test_input_trace_pauses = f"{test_input_trace_pauses_basepath}.gpx"
- # expected outputs
- expected_cleaned_trace_path = f"{test_input_trace_basepath}_cleaned.gpx"
- expected_predictions_path = f"{test_input_trace_basepath}_predicted.geojson"
- expected_colored_predictions_path = f"{test_input_trace_basepath}_predictedColors.geojson"
+ # expected outputs pauses
+ expected_outputs_pauses = [
+ f"{test_input_trace_pauses_basepath}_cleaned.gpx",
+ f"{test_input_trace_pauses_basepath}_predicted.geojson",
+ f"{test_input_trace_pauses_basepath}_predictedColors.geojson"
+ ]
+
+ # expected outputs outliers
+ expected_outputs_outliers = [
+ f"{test_input_trace_outliers_basepath}_cleaned.gpx",
+ f"{test_input_trace_outliers_basepath}_predicted.geojson",
+ f"{test_input_trace_outliers_basepath}_predictedColors.geojson"
+ ]
@classmethod
def remove_file_if_exists(self, filepath):
@@ -17,18 +29,17 @@ def remove_file_if_exists(self, filepath):
os.remove(filepath)
@classmethod
- def teardown_class(self):
- # teardown: remove output files, if existing
- self.remove_file_if_exists(self.expected_cleaned_trace_path)
- self.remove_file_if_exists(self.expected_predictions_path)
- self.remove_file_if_exists(self.expected_colored_predictions_path)
-
- def test_cleaning_full_output(self):
-
+ def trace_cleaning(self, trace, expected_outputs):
# try to clean the test trace
- main([self.test_input_trace, "--outputPredictions", "--meanPredictionColored"])
+ main([trace, "--outputPredictions", "--meanPredictionColored"])
# check the cleaned trace, predictions files, and mean colored predictions file were created
- assert os.path.exists(self.expected_cleaned_trace_path) == True
- assert os.path.exists(self.expected_predictions_path) == True
- assert os.path.exists(self.expected_colored_predictions_path) == True
+ for expected_file in expected_outputs:
+ assert os.path.exists(expected_file) == True
+ self.remove_file_if_exists(expected_file)
+
+ def test_cleaning_pauses_full_output(self):
+ self.trace_cleaning(self.test_input_trace_pauses, self.expected_outputs_pauses)
+
+ def test_cleaning_outliers_full_output(self):
+ self.trace_cleaning(self.test_input_trace_outliers, self.expected_outputs_outliers)