added segments
This commit is contained in:
108
FitnessSync/scratch/auto_create_segments.py
Normal file
108
FitnessSync/scratch/auto_create_segments.py
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
# Add backend to path
|
||||
sys.path.append(os.path.join(os.getcwd(), 'backend'))
|
||||
|
||||
from src.models.activity import Activity
|
||||
from src.models.segment import Segment
|
||||
from src.services.segment_matcher import SegmentMatcher
|
||||
from src.services.parsers import extract_points_from_file
|
||||
from src.utils.geo import haversine_distance, calculate_bounds, ramer_douglas_peucker
|
||||
from src.utils.config import config
|
||||
|
||||
# Setup DB
|
||||
engine = create_engine(config.DATABASE_URL)
|
||||
Session = sessionmaker(bind=engine)
|
||||
db = Session()
|
||||
|
||||
def auto_create_segments(garmin_activity_id, split_dist_meters=1000):
|
||||
print(f"\n--- Auto Creating Segments for {garmin_activity_id} (Split: {split_dist_meters}m) ---")
|
||||
|
||||
activity = db.query(Activity).filter(Activity.garmin_activity_id == garmin_activity_id).first()
|
||||
if not activity:
|
||||
print(f"Activity {garmin_activity_id} not found in DB.")
|
||||
return
|
||||
|
||||
# Extract points
|
||||
points = extract_points_from_file(activity.file_content, activity.file_type)
|
||||
if not points or len(points) < 2:
|
||||
print("No points found in activity.")
|
||||
return
|
||||
|
||||
print(f"Total Points: {len(points)}")
|
||||
|
||||
accum_dist = 0.0
|
||||
split_start_idx = 0
|
||||
split_count = 1
|
||||
|
||||
segments_created = []
|
||||
|
||||
for i in range(1, len(points)):
|
||||
p1 = points[i-1]
|
||||
p2 = points[i]
|
||||
|
||||
# dist between p1 and p2
|
||||
d = haversine_distance(p1[1], p1[0], p2[1], p2[0])
|
||||
accum_dist += d
|
||||
|
||||
if accum_dist >= split_dist_meters:
|
||||
# Create segment
|
||||
split_end_idx = i
|
||||
|
||||
seg_points = points[split_start_idx : split_end_idx + 1]
|
||||
|
||||
# Simplify
|
||||
simple_points = ramer_douglas_peucker(seg_points, epsilon=5.0)
|
||||
bounds = calculate_bounds(seg_points)
|
||||
|
||||
# Calc actual distance & elevation
|
||||
seg_dist = 0.0
|
||||
seg_elev_gain = 0.0
|
||||
for k in range(len(seg_points)-1):
|
||||
sp1 = seg_points[k]
|
||||
sp2 = seg_points[k+1]
|
||||
seg_dist += haversine_distance(sp1[1], sp1[0], sp2[1], sp2[0])
|
||||
if len(sp1) > 2 and len(sp2) > 2 and sp1[2] is not None and sp2[2] is not None:
|
||||
diff = sp2[2] - sp1[2]
|
||||
if diff > 0:
|
||||
seg_elev_gain += diff
|
||||
|
||||
name = f"AutoSplit #{split_count} ({garmin_activity_id})"
|
||||
|
||||
print(f"Creating Segment: {name} | Dist: {seg_dist:.1f}m | Elev: {seg_elev_gain:.1f}m | Indices: {split_start_idx}-{split_end_idx}")
|
||||
|
||||
segment = Segment(
|
||||
name=name,
|
||||
description=f"Auto-generated {split_dist_meters}m split",
|
||||
distance=seg_dist,
|
||||
elevation_gain=seg_elev_gain,
|
||||
activity_type=activity.activity_type or 'cycling',
|
||||
points=json.dumps(simple_points),
|
||||
bounds=json.dumps(bounds)
|
||||
)
|
||||
db.add(segment)
|
||||
segments_created.append(segment)
|
||||
|
||||
# Reset for next split
|
||||
accum_dist = 0.0
|
||||
split_start_idx = i
|
||||
split_count += 1
|
||||
|
||||
db.commit()
|
||||
print(f"\nCreated {len(segments_created)} segments.")
|
||||
|
||||
# Trigger Matching
|
||||
if segments_created:
|
||||
print("\nTriggering Segment Matcher...")
|
||||
matcher = SegmentMatcher(db)
|
||||
matcher.match_activity(activity, points)
|
||||
print("Matching complete.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
auto_create_segments("21249259141", 1000)
|
||||
Reference in New Issue
Block a user