feat: improve planning engine travel handling, itinerary reordering, and scenario planners

Add TravelInfo initializers and city normalization helpers to fix repeat
city-pair disambiguation. Improve drag-and-drop reordering with segment
index tracking and source-row-aware zone calculation. Enhance all five
scenario planners with better next-day departure handling and travel
segment placement. Add comprehensive tests across all planners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-13 08:55:23 -06:00
parent 1c97f35754
commit 9736773475
19 changed files with 928 additions and 171 deletions

View File

@@ -58,8 +58,8 @@ enum TravelEstimator {
let distanceMiles = calculateDistanceMiles(from: from, to: to)
let drivingHours = distanceMiles / averageSpeedMph
// Maximum allowed: 5 days of driving (matches GameDAGRouter.maxDayLookahead)
// This allows multi-day cross-country segments like Chicago Anaheim
// Maximum allowed: 5 days of driving as a conservative hard cap.
// This allows multi-day cross-country segments like Chicago Anaheim.
let maxAllowedHours = constraints.maxDailyDrivingHours * 5.0
if drivingHours > maxAllowedHours {
return nil
@@ -103,8 +103,8 @@ enum TravelEstimator {
let distanceMiles = distanceMeters * 0.000621371 * roadRoutingFactor
let drivingHours = distanceMiles / averageSpeedMph
// Maximum allowed: 5 days of driving (matches GameDAGRouter.maxDayLookahead)
// This allows multi-day cross-country segments like Chicago Anaheim
// Maximum allowed: 5 days of driving as a conservative hard cap.
// This allows multi-day cross-country segments like Chicago Anaheim.
let maxAllowedHours = constraints.maxDailyDrivingHours * 5.0
if drivingHours > maxAllowedHours {
return nil