public void Recalculate()
{
this.etas.Clear();
foreach (Shuttle s in this.world.Shuttles.Values)
{
Route r = s.CurrentRoute;
foreach (Stop st in r.Stops.Values)
{
int i = s.NextRouteCoordinate;
int j;
double distance;
int stopPrecedingCoordinate = st.PrecedingCoordinate[r.Id];
// If the shuttle and stop are between the same two route points, the distance is
// simply the distance from the shuttle to the stop
if ((s.NextRouteCoordinate == 0 && stopPrecedingCoordinate == r.Coordinates.Count - 1) ||
(s.NextRouteCoordinate == stopPrecedingCoordinate + 1))
{
distance = s.Location.DistanceTo(s.Location);
}
else
{
// Start with the distance from the shuttle to the next route point
distance = s.Location.DistanceTo(r.Coordinates[s.NextRouteCoordinate]);
// Go through each route point until we reach the one just before
// the stop and sum the distances
while (i != stopPrecedingCoordinate)
{
if (i == r.Coordinates.Count)
j = 0;
else
j = i + 1;
// TODO: use the nextStopDistance map to remove the need to recalculate
// the distance each time. Check execution times for both. Dictionary lookup
// may actually be slower than recalculating
distance += r.Coordinates[i].DistanceTo(r.Coordinates[j]);
i++;
if (i == r.Coordinates.Count)
i = 0;
}
// Finish by adding the distance from the stop to the last route point that the shuttle
// will go through
distance += st.PrecedingCoordinateDistance[r.Id];
}
this.etas.Add(new Eta(s.Id, s.CurrentRoute.Id, st.Id, (int)(distance / s.AverageSpeed)));
}
}
}