Add matched training signals, daily recovery and performance analysis
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""Approximate same-start, same-direction full-course matching, without raw samples."""
|
||||
|
||||
import math
|
||||
from itertools import pairwise
|
||||
|
||||
from .analytics import numeric
|
||||
|
||||
|
||||
def distance(a, b):
|
||||
lat1, lat2 = math.radians(a[0]), math.radians(b[0])
|
||||
dlat, dlon = lat2 - lat1, math.radians(b[1] - a[1])
|
||||
h = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
|
||||
return 12742000 * math.asin(math.sqrt(min(1, h)))
|
||||
|
||||
|
||||
def resample(segments):
|
||||
# A recording break must not invent a connecting route.
|
||||
if not isinstance(segments, list) or len(segments) != 1:
|
||||
return None
|
||||
points = segments[0]
|
||||
if len(points) < 2 or any(not isinstance(p, list) or len(p) != 2 or
|
||||
not all(numeric(v) for v in p) or
|
||||
not -90 <= p[0] <= 90 or not -180 <= p[1] <= 180 for p in points):
|
||||
return None
|
||||
cumulative = [0.0]
|
||||
for a, b in pairwise(points):
|
||||
cumulative.append(cumulative[-1] + distance(a, b))
|
||||
total = cumulative[-1]
|
||||
if total < 500:
|
||||
return None
|
||||
result, cursor = [], 0
|
||||
for i in range(33):
|
||||
target = total * i / 32
|
||||
while cursor < len(points) - 2 and cumulative[cursor + 1] < target:
|
||||
cursor += 1
|
||||
span = cumulative[cursor + 1] - cumulative[cursor]
|
||||
fraction = (target - cumulative[cursor]) / span if span else 0
|
||||
result.append([a + (b - a) * fraction for a, b in zip(points[cursor], points[cursor + 1], strict=True)])
|
||||
return total, result
|
||||
|
||||
|
||||
def similar(reference, candidate):
|
||||
a, b = resample(reference), resample(candidate)
|
||||
if not a or not b or abs(b[0] / a[0] - 1) > .1:
|
||||
return False
|
||||
differences = sorted(distance(x, y) for x, y in zip(a[1], b[1], strict=True))
|
||||
return (distance(a[1][0], b[1][0]) <= 100 and distance(a[1][-1], b[1][-1]) <= 100
|
||||
and sum(differences) / len(differences) <= 100 and differences[29] <= 200)
|
||||
Reference in New Issue
Block a user