public static async Task <BusStop[]> GetBusStopsForArea(GeoboundingBox bounds, Action <BusStop[], GeoboundingBox> stopsLoadedCallback, CancellationToken cancellationToken, bool offlineOnly) { List <BusStop> totalFoundStops = new List <BusStop>(); try { var offlineStops = await FileManager.GetStopsForArea(bounds.NorthwestCorner, bounds.SoutheastCorner, cancellationToken); totalFoundStops.AddRange(offlineStops); foreach (var stop in offlineStops) { if (!CachedStops.ContainsKey(stop.ID)) { CachedStops.Add(stop.ID, stop); } } if (stopsLoadedCallback != null) { stopsLoadedCallback(offlineStops, null); } cancellationToken.ThrowIfCancellationRequested(); if (!offlineOnly) { double latRange = bounds.NorthwestCorner.Latitude - bounds.SoutheastCorner.Latitude; double lonRange = bounds.SoutheastCorner.Longitude - bounds.NorthwestCorner.Longitude; int latPieces = (int)Math.Ceiling(latRange / MAX_LAT_RANGE); int lonPieces = (int)Math.Ceiling(lonRange / MAX_LON_RANGE); double smallLatRange = latRange / (double)latPieces; double smallLonRange = lonRange / (double)lonPieces; for (int i = 0; i < latPieces; i++) { for (int j = 0; j < lonPieces; j++) { BusStop[] foundStops = await ApiLayer.GetBusStopsForArea(new BasicGeoposition() { Latitude = bounds.SoutheastCorner.Latitude + (i + .5) * smallLatRange, Longitude = bounds.NorthwestCorner.Longitude + (j + .5) * smallLonRange }, smallLatRange, smallLonRange, cancellationToken); foreach (var item in foundStops ?? new BusStop[0]) { if (!totalFoundStops.Contains(item)) { totalFoundStops.Add(item); } if (!CachedStops.ContainsKey(item.ID)) { CachedStops.Add(item.ID, item); } } if (stopsLoadedCallback != null) { stopsLoadedCallback(foundStops, null); } } } } } catch (OperationCanceledException) { } return(totalFoundStops.ToArray()); }
public static async Task <DownloadManager> Create(RouteListing listing, CancellationToken cancellationToken) { listing.Progress = 0; listing.ShowProgress = true; DownloadManager result = new DownloadManager(); result.Listing = listing; result._Route = result.Listing.Route; var stopsAndShapes = await ApiLayer.GetStopsAndShapesForRoute(result.Listing.Route.ID, cancellationToken); result._Shapes = stopsAndShapes.Item2; result._StopsPending = new ObservableCollection <BusStop>(stopsAndShapes.Item1); if (cancellationToken.IsCancellationRequested) { return(null); } result.Initialize(); result._TotalStops = result.StopsPending.Count; DownloadsInProgress.Add(result); if (!FileManager.PendingDownloads.Any(item => item.First() == result.Route.ID)) { List <string> pend = new List <string>() { result.Route.ID }; pend.AddRange(result.StopsPending.Select(stop => stop.ID)); FileManager.PendingDownloads.Add(pend); await listing.RefreshIsDownloaded(); await FileManager.SavePendingDownloads(); } return(result); }
public static async Task <Tuple <RealtimeArrival[], DataRetrievalMessage> > GetArrivals(string stopId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal( () => ApiLayer.GetBusArrivals(stopId, cancellationToken) , () => FileManager.GetScheduledArrivals(stopId) , options, typeof(OperationCanceledException) )); }
public static async Task <BusRoute?> GetRoute(string id, CancellationToken cancellationToken) { if (CachedRoutes.ContainsKey(id)) { return(CachedRoutes[id]); } var result = await CloudOrLocal(() => ApiLayer.GetBusRoute(id, cancellationToken), () => FileManager.GetRouteFromCache(id), new DataRetrievalOptions(DataSourceDescriptor.Local), typeof(OperationCanceledException)); if (!CachedRoutes.ContainsKey(id) && result.Item2.FinalSource != null) { CachedRoutes.Add(id, result.Item1.Value); } return(result.Item1); }
public static async Task <WeekSchedule> GetScheduleForStop(string id, CancellationToken cancellationToken) { WeekSchedule result = new WeekSchedule(); for (int i = 0; i < 8; i++) { DaySchedule daySched = new DaySchedule(); ServiceDay day = (ServiceDay)(int)Math.Pow(2, i); DateTime? date = HelperFunctions.DateForServiceDay(day); if (date.HasValue) { daySched.LoadFromVerboseString(await ApiLayer.SendRequest("schedule-for-stop/" + id, new Dictionary <string, string>() { ["date"] = date.Value.ToString("yyyy-MM-dd") }, false, cancellationToken), id); result.AddServiceDay(day, daySched); } } return(result); }
public static async Task <Tuple <BusRoute[], DataRetrievalMessage> > GetBusRoutesForAgency(string agencyId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetBusRoutesForAgency(agencyId, cancellationToken), () => FileManager.GetBusRoutesForAgencyFromCache(agencyId), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <TransitAgency[], DataRetrievalMessage> > GetTransitAgencies(DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetTransitAgencies(cancellationToken), () => FileManager.GetAgenciesFromCache(), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <Tuple <BusStop[], string[]>, DataRetrievalMessage> > GetStopsAndShapesForRoute(string routeId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetStopsAndShapesForRoute(routeId, cancellationToken), () => FileManager.GetStopsAndShapesForRouteFromCache(routeId), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <WeekSchedule, DataRetrievalMessage> > GetScheduleForStop(string id, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetScheduleForStop(id, cancellationToken), () => FileManager.LoadSchedule(id), options, typeof(OperationCanceledException))); }
public static async Task <TransitAgency?> GetTransitAgency(string id, CancellationToken cancellationToken) { return((await ApiLayer.GetTransitAgencies(cancellationToken)).First(agency => agency.ID == id)); }
public static async Task <RouteListing[]> DownloadAll(Action <double, string> statusChangedCallback, CancellationToken cancellationToken, params RouteListing[] routeListings) { List <RouteListing> errorList = new List <RouteListing>(); List <BusStop> allStops = new List <BusStop>(); await FileManager.LoadPendingDownloads(); try { for (int i = 0; i < routeListings.Length; i++) { statusChangedCallback(0.15 * i / routeListings.Length, "Getting stops (" + (i + 1).ToString() + " of " + routeListings.Length.ToString() + ")" + " " + (routeListings[i].Name.All(chr => char.IsDigit(chr)) ? "Route " : "") + routeListings[i].Name); try { var manager = await DownloadManager.Create(routeListings[i], cancellationToken); await FileManager.SaveRoute(manager.Route, manager.StopsPending.Select(item => item.ID).ToArray(), manager.Shapes); foreach (var stop in manager.StopsPending) { if (!allStops.Contains(stop)) { allStops.Add(stop); } } } catch (Exception ex) { cancellationToken.ThrowIfCancellationRequested(); errorList.Add(routeListings[i]); ex.ToString(); } } WeekSchedule schedule; string[] routeFilters = DownloadsInProgress.Select(download => download.Listing.Route.ID).ToArray(); for (int i = 0; i < allStops.Count; i++) { statusChangedCallback(0.15 + 0.85 * i / allStops.Count, "Downloading schedules (" + (i + 1).ToString() + " of " + allStops.Count.ToString() + ") " + allStops[i].Name); try { var pend = FileManager.PendingDownloads.Where(item => routeFilters.Contains(item.First())).ToArray(); if (pend.Any(item => item.Contains(allStops[i].ID))) { schedule = await ApiLayer.GetScheduleForStop(allStops[i].ID, cancellationToken); schedule.FilterByRoutes(routeFilters); await FileManager.SaveScheduleAsync(schedule, allStops[i]); foreach (var item in pend) { if (item.Contains(allStops[i].ID)) { item.Remove(allStops[i].ID); } if (item.Count == 1) { FileManager.PendingDownloads.Remove(item); } } await FileManager.SavePendingDownloads(); } foreach (var manager in DownloadsInProgress.ToArray()) { if (manager.StopsPending.Contains(allStops[i])) { manager.StopsPending.Remove(allStops[i]); } } } catch (Exception ex) { cancellationToken.ThrowIfCancellationRequested(); foreach (var download in DownloadsInProgress.Where(item => item.StopsPending.Contains(allStops[i]))) { if (!errorList.Contains(download.Listing)) { errorList.Add(download.Listing); } } ex.ToString(); } } statusChangedCallback(1, "Download complete."); } catch (OperationCanceledException) { statusChangedCallback(1, "Download cancelled."); while (DownloadsInProgress.Count > 0) { DownloadsInProgress[0].StopsPending.Clear(); } } return(errorList.ToArray()); }