54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
from haversine import haversine, Unit
|
|
|
|
from lap_detection.api import Coordinate
|
|
|
|
|
|
def dist(a: Coordinate, b: Coordinate):
|
|
return haversine((a.lat, a.lon), (b.lat, b.lon), Unit.METERS)
|
|
|
|
|
|
def count_laps(coords: list[Coordinate], start_coord: Coordinate, radius: int) -> int:
|
|
"""Count the number of laps completed
|
|
by tracking the number of times that the starting coordinate was passed by the given coordinate list
|
|
Args:
|
|
coords (list[Coordinate]): the list of coordinates
|
|
start_coord (Coordinate): the coordinate to compare to
|
|
radius (int): the radius around the starting coordinate
|
|
Returns:
|
|
int: the number of laps completed
|
|
"""
|
|
if not coords:
|
|
return 0
|
|
|
|
laps = 0
|
|
|
|
distance_since_last = 0
|
|
|
|
# Do we start inside or outside the start/finish area?
|
|
d_to_first = dist(coords[0], start_coord)
|
|
inside = d_to_first < radius
|
|
|
|
for i in range(1, len(coords)):
|
|
prev = coords[i - 1]
|
|
curr = coords[i]
|
|
|
|
# Don't compare the starting coordinate with itself
|
|
if curr == start_coord:
|
|
continue
|
|
|
|
d = dist(prev, curr)
|
|
distance_since_last += d
|
|
|
|
# Did we enter the start/finish area?
|
|
d_to_start = dist(curr, start_coord)
|
|
now_inside = d_to_start < radius
|
|
if not inside and now_inside:
|
|
# Ignore possible gps stutters with minimum lap distance threshold
|
|
if distance_since_last > 100:
|
|
laps += 1
|
|
distance_since_last = 0
|
|
|
|
inside = now_inside
|
|
|
|
return laps
|