Skip to content

Track import: keep handovers as indices into the recording - #103

Merged
aquasolterra merged 1 commit into
mainfrom
fix/track-import-handover-snap
Oct 4, 2026
Merged

aquasolterra merged 1 commit into
mainfrom
fix/track-import-handover-snap

Conversation

@aquasolterra

Copy link
Copy Markdown
Member

Problem

When a recording is divided among several entries, a handover that was read off an entry's own coordinates could not be moved. Tapping to move it threw it back to the recording's first point, and after that no tap moved it at all.

The trigger was a return trip by train with short walks at Malmö and Copenhagen. Every handover came from a leg's station coordinates, and the walk at each stop was a loop that started and ended at the station. The automatic division put the handovers on both sides of each walk five seconds apart, which is expected for a loop. The bug is that they then could not be corrected.

Cause

_place bounded a moved handover by its neighbours and found them again with indexOf(coordinate). A coordinate taken from an entry lies beside the line, not on it. So the lookup returned −1, the upper bound became −2, and the snap clamped to index 0.

Fix

  • The screen holds each handover as a cut index into the recording. It is resolved once when the screen opens (trackCutIndices, which also keeps room for open handovers), so moving one handover never moves another.
  • The bounds, the preview and the written division all come from those indices (splitTracksAt, snapIndexOnTrack). What is drawn is exactly what gets written.
  • The mark is drawn on the line where it cuts. The coordinate is kept only as what gets written onto an entry that had none.
  • The lower bound for the first handover is now 1, not 0, so the first stretch always keeps two points.

splitTracks and snapToTrack keep their signatures. trackIndexOf is removed.

The automatic proposal for a loop that starts and ends at one station is still ambiguous by position alone. That is out of scope here: it can now be corrected by hand, and using the GPX timestamps could improve it later.

Tests

  • track_import_screen_test: a handover read off an entry's coordinates moves to where it was tapped, can be moved again, and leaves the other handover in place. On the old code this test fails because the handover lands on the first point.
  • track_split_test: an open handover keeps its room, dividing by index equals dividing by point, and snapping on a there-and-back line picks the pass inside the bounds.

flutter analyze is clean and the full suite passes.

🤖 Generated with Claude Code

Moving a handover bounded the tap by its neighbours, which were looked
up again by coordinate with indexOf. A handover read off an entry's own
position lies beside the line rather than on it, so the lookup returned
-1, the upper bound became -2, and every tap snapped to the recording's
first point; after that no tap could move it again.

The import screen now holds each handover as a cut index, resolved once
when it opens (trackCutIndices, which also keeps room for open ones), and
derives the bounds, the preview and the written division from those
indices (splitTracksAt). The mark is drawn on the line where it cuts; the
coordinate is kept only as what gets written onto an entry that had none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aquasolterra
aquasolterra merged commit 18281bd into main Oct 4, 2026
4 checks passed
@aquasolterra
aquasolterra deleted the fix/track-import-handover-snap branch October 4, 2026 22:45
@codecov

codecov Bot commented Oct 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.66667% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...features/map/presentation/track_import_screen.dart 82.60% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant