Commit 9ec0026f authored by Emma Fritzberg's avatar Emma Fritzberg
Browse files

store velocities

parent 2f2e201d
This diff is collapsed.
from datetime import datetime, timedelta
from geopy import distance
SOFAR_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
# Returns datetime object from the given timestamp string in the format used by Sofar, e.g. '2021-08-28T12:28:16.000Z'
def get_datetime(timestamp):
return datetime.strptime(timestamp, SOFAR_TIMESTAMP_FORMAT)
# Returns distance between two coordinate sets in kilometers, as a floating point number
def distance_travelled(start_location, end_location):
return distance.distance(start_location, end_location).km
# Returns time delta between two timestamps in hours
def time_elapsed(start_timestamp, end_timestamp):
return (get_datetime(end_timestamp) - get_datetime(start_timestamp)) / timedelta(hours=1)
import csv
import math
from ocean_drifters_utils import get_datetime, distance_travelled, time_elapsed
# Parse CSV data into global var spotters with a dict representing spotters and their paths.
#
......@@ -33,21 +35,37 @@ with open('data/raw_spotter_data.csv') as raw_data:
spotters[spotter_id] = path
with open('data/enriched_spotter_data.csv', 'w', newline='') as enriched_data:
fieldnames = ['spotter_id', 'timestamp', 'latitude', 'longitude', 'velocity', 'coastline_distance']
writer = csv.DictWriter(enriched_data, fieldnames=fieldnames)
writer = csv.DictWriter(
enriched_data,
fieldnames=['spotter_id', 'timestamp', 'latitude', 'longitude', 'velocity', 'coastline_distance'],
)
writer.writeheader()
for spotter_id in spotters.keys():
timestamps = spotters[spotter_id]
for timestamp in timestamps:
(latitude, longitude) = timestamps[timestamp]
path = spotters[spotter_id]
timestamps = list(path.keys())
timestamps.sort(key=(lambda e: get_datetime(e)))
def centered_in_time_velocity(timestamp_index):
mod_aware_timestamp_index = timestamp_index % len(timestamps)
if mod_aware_timestamp_index == 0 or mod_aware_timestamp_index == len(timestamps) - 1:
return math.nan
prev_timestamp = timestamps[timestamp_index - 1]
next_timestamp = timestamps[timestamp_index + 1]
dx = distance_travelled(path[prev_timestamp], path[next_timestamp])
dt = time_elapsed(prev_timestamp, next_timestamp)
if dt <= 0:
return math.nan
return dx / dt
for i in range(0, len(timestamps) - 1):
(latitude, longitude) = path[timestamps[i]]
writer.writerow({
'spotter_id': spotter_id,
'timestamp': timestamp,
'timestamp': timestamps[i],
'latitude': latitude,
'longitude': longitude,
# TODO: use velocity helper function to store velocity at each time
'velocity': 0,
'velocity': centered_in_time_velocity(timestamp_index=i),
# TODO: calculate distance from nearest coastline
'coastline_distance': 0,
'coastline_distance': math.nan,
})
from datetime import datetime, timedelta
from geopy import distance
from matplotlib import pyplot as plt
from cartopy import crs as ccrs
import math
TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
def get_datetime(timestamp):
return datetime.strptime(timestamp, TIMESTAMP_FORMAT)
# Returns time delta between two timestamps in hours
def time_elapsed(start_timestamp, end_timestamp):
return (get_datetime(end_timestamp) - get_datetime(start_timestamp)) / timedelta(hours=1)
# Returns distance between two coordinates in kilometers, as a floating point number
def distance_travelled(start_location, end_location):
return distance.distance(start_location, end_location).km
# Returns segment speed in kilometers per hour
def segment_speed(start, end):
start_timestamp, start_location = start
end_timestamp, end_location = end
return distance_travelled(start_location, end_location) / time_elapsed(start_timestamp, end_timestamp)
# Returns the average speed at which the spotter traveled its path, in kilometers per hour
def average_speed(spotters, spotter_id):
path = spotters[spotter_id]
total_distance = 0
total_time = 0
timestamps = list(path.keys())
timestamps.sort(key=(lambda e: get_datetime(e)))
for i in range(len(timestamps) - 1):
start_timestamp = timestamps[i]
end_timestamp = timestamps[i + 1]
total_time += time_elapsed(start_timestamp, end_timestamp)
total_distance += distance_travelled(path[start_timestamp], path[end_timestamp])
if total_time > 0:
return total_distance / total_time
# Returns the average velocity over a segment, in kilometers per hour
def average_segment_velocity(start_index, end_index, sorted_timestamps, path):
return distance_travelled(path[sorted_timestamps[start_index]], path[sorted_timestamps[end_index]]) / time_elapsed(sorted_timestamps[start_index], sorted_timestamps[end_index])
# Returns the velocity of the spotter at the given time
def time_resolved_velocity(spotters, spotter_id, time):
path = spotters[spotter_id]
timestamps = list(path.keys())
if len(timestamps) <= 1:
# Not enough data to calculate velocity
return math.nan
timestamps.sort(key=(lambda e: get_datetime(e)))
start_time = get_datetime(timestamps[0])
end_time = get_datetime(timestamps[-1])
if time < start_time or end_time < time:
# No data for given time
return math.nan
if time == start_time:
# TODO: At first timestamp, use forward Euler
return math.nan
if time == end_time:
# TODO: At last timestamp, use backward Euler
return math.nan
for i in range(len(timestamps)):
if time == get_datetime(timestamps[i]):
# At intermediary timestamp, use centered-in-time numerical differentiation
return average_segment_velocity(i - 1, i + 1, timestamps, path)
if get_datetime(timestamps[i]) < time and time < get_datetime(timestamps[i + 1]):
# Between timestamps, use segment average velocity
return average_segment_velocity(i, i + 1, timestamps, path)
return math.nan
def plot_single_trajectory(spotters, spotter_id):
path = spotters[spotter_id]
timestamps = list(path.keys())
timestamps.sort(key=(lambda e: get_datetime(e)))
(start_latitude, start_longitude) = path[timestamps[0]]
ax = plt.axes(projection=ccrs.Orthographic(central_longitude=start_longitude, central_latitude=start_latitude))
ax.set_global()
ax.coastlines()
for i in range(len(timestamps) - 1):
(start_latitude, start_longitude) = path[timestamps[i]]
print('start: lat: ', start_latitude, ' , long: ', start_longitude)
(end_latitude, end_longitude) = path[timestamps[i + 1]]
print('end: lat: ', end_latitude, ' , long: ', end_longitude)
velocity = average_segment_velocity(i, i + 1, timestamps, path)
print('velocity: ', velocity, 'km/h')
velocity_color = 'gray'
if not math.isnan(velocity):
if velocity < 0.5:
velocity_color = 'blue'
if velocity >= 0.5:
velocity_color = 'purple'
if velocity >= 1.0:
velocity_color = 'red'
plt.plot([start_longitude, end_longitude], [start_latitude, end_latitude], color=velocity_color, transform=ccrs.Geodetic())
plt.show()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment