many updates

This commit is contained in:
2026-01-11 06:06:43 -08:00
parent 67357b5038
commit 4bb86b603e
73 changed files with 2881 additions and 59 deletions

View File

@@ -0,0 +1,138 @@
import logging
from sqlalchemy.orm import Session
from src.services.postgresql_manager import PostgreSQLManager
from src.utils.config import config
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
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def debug_matching():
db_manager = PostgreSQLManager(config.DATABASE_URL)
with db_manager.get_db_session() as db:
# 1. Fetch Segment
segment = db.query(Segment).filter(Segment.name.like("%Etiwanda%")).first()
if not segment:
print("ERROR: Segment 'Etiwanda Climb' not found.")
return
print(f"DEBUG: Found Segment ID {segment.id}: {segment.name}")
print(f"DEBUG: Segment Distance: {segment.distance}")
# 2. Fetch Activity
# Try finding by ID or Garmin ID
act_id = 21072264737
activity = db.query(Activity).filter(Activity.id == act_id).first()
if not activity:
activity = db.query(Activity).filter(Activity.garmin_activity_id == str(act_id)).first()
if not activity:
print(f"ERROR: Activity {act_id} not found.")
return
print(f"DEBUG: Found Activity ID {activity.id} (Garmin: {activity.garmin_activity_id})")
# 3. Extract Points
if not activity.file_content:
print("ERROR: Activity has no file content")
return
points = extract_points_from_file(activity.file_content, activity.file_type)
print(f"DEBUG: Extracted {len(points)} points from activity.")
# 4. Trigger Match
matcher = SegmentMatcher(db)
# Manually invoke match parts to trace
# (Copying logic from match_activity wrapper)
import json
seg_points = json.loads(segment.points) if isinstance(segment.points, str) else segment.points
print(f"DEBUG: Segment has {len(seg_points)} points.")
print(f"DEBUG: Segment has {len(seg_points)} points.")
efforts = matcher.match_activity(activity, points)
if efforts:
print(f"SUCCESS: match_activity returned {len(efforts)} efforts.")
for e in efforts:
print(f" - Segment {e.segment_id} (Duration: {e.elapsed_time}s)")
else:
print("FAILURE: match_activity returned NO efforts.")
# --- Deep Trace ---
print("\n--- DEEP TRACE ---")
ENTRY_RADIUS = 25.0
CORRIDOR_RADIUS = 35.0
from src.utils.geo import haversine_distance, perpendicular_distance
start_node = seg_points[0]
end_node = seg_points[-1]
# Check Start Proximity
start_candidates = []
min_start_dist = float('inf')
for i, p in enumerate(points):
dist = haversine_distance(p[1], p[0], start_node[1], start_node[0])
if dist < min_start_dist: min_start_dist = dist
if dist <= ENTRY_RADIUS:
start_candidates.append(i)
print(f"Min distance to Start Node: {min_start_dist:.2f}m")
print(f"Start Candidates: {start_candidates}")
if not start_candidates:
print("FAIL: Start node never reached within 25m.")
return
# Trace Candidate 0 (or all)
for start_idx in start_candidates:
print(f"\nChecking candidate starting at index {start_idx}...")
effort_accum_dist = 0.0
deviated = False
completed = False
max_deviation = 0.0
for j in range(start_idx + 1, len(points)):
p = points[j]
prev_p = points[j-1]
# Accumulate distance
step_dist = haversine_distance(p[1], p[0], prev_p[1], prev_p[0])
effort_accum_dist += step_dist
# Check deviation
dev = matcher._min_dist_to_segment_path(p, seg_points)
if dev > max_deviation: max_deviation = dev
if dev > CORRIDOR_RADIUS:
print(f" DEVIATION at index {j}! Dist {dev:.2f}m > {CORRIDOR_RADIUS}m. AccumDist: {effort_accum_dist:.2f}m")
deviated = True
break
# Check completion
d_end = haversine_distance(p[1], p[0], end_node[1], end_node[0])
if d_end <= ENTRY_RADIUS:
if effort_accum_dist >= 0.8 * segment.distance:
print(f" COMPLETION possible at index {j}. d_end={d_end:.2f}m, dist={effort_accum_dist:.2f}m")
completed = True
# Don't break immediately, could get closer?
# But logic breaks on completion check?
# Logic: returns first valid end.
if not completed:
print(f" Candidate ended without completion. Max Deviation: {max_deviation:.2f}m. Total Dist: {effort_accum_dist:.2f}m vs Target {segment.distance:.2f}m")
if __name__ == "__main__":
debug_matching()