public static void GoToNextCheckpoint(BusOnRoad bor) { var svc = BusHelper.BusSvcs [bor.routeName]; if (bor.nextCheckpointEnumerator == null) { bor.nextCheckpointEnumerator = svc.checkpoints.GetEnumerator(); } double longitude = BusHelper.BusStops [svc.firstStop].longitude; double latitude = BusHelper.BusStops [svc.firstStop].latitude; // update position based on checkpoint if (bor.nextCheckpointEnumerator.MoveNext()) { longitude = (double)bor.nextCheckpointEnumerator.Current; } else { BusHelper.RemoveBusOnRoad(bor.vehiclePlate); return; } if (bor.nextCheckpointEnumerator.MoveNext()) { latitude = (double)bor.nextCheckpointEnumerator.Current; } bor.longitude = longitude; bor.latitude = latitude; }
public App() { // load bus data BusHelper.LoadBusData(); // Display the main page of your application MainPage = new NUSBusMap.MainPage(); }
private async void UpdatePublicBusPins() { while (true) { // skip update pins if map is freezed (user clicks on pin) if (!FreezeMap) { // remove all bus pins foreach (CustomPin p in map.PublicBusPins) { map.Pins.Remove(p.Pin); } map.PublicBusPins.Clear(); // get list of bus stops to call based on enabled public bus svcs on map List <string> busStopCodes = new List <string> (); foreach (string serviceNo in BusHelper.PublicBusSvcOnMap) { busStopCodes = busStopCodes.Union(BusHelper.PublicBusSvcStops [serviceNo]).ToList(); } // get public bus real-time location (by calling API) List <PublicBusOnRoad> publicBuses = new List <PublicBusOnRoad> (); foreach (string busStopCode in busStopCodes) { // get buses passing by bus stop (ignore same bus) var thisPublicBuses = await BusHelper.GetPublicBuses(busStopCode); publicBuses.AddRange(thisPublicBuses.Where(b1 => !publicBuses.Any(b2 => b2.IsSameBus(b1, MARGIN_OF_ERROR)))); } // add pin if bus has location foreach (PublicBusOnRoad bus in publicBuses.Where(bus => (bus.Latitude.HasValue && !bus.Latitude.Value.Equals(0)) && (bus.Longitude.HasValue && !bus.Longitude.Value.Equals(0)))) { var description = "Start: " + BusHelper.PublicBusStopCodeName[bus.OriginatingID] + "\n" + "End: " + BusHelper.PublicBusStopCodeName[bus.TerminatingID] + "\n"; var pin = new Pin { Type = PinType.Place, Position = new Xamarin.Forms.Maps.Position(bus.Latitude.Value, bus.Longitude.Value), Label = bus.ServiceNo, Address = description }; var busPin = new CustomPin { Pin = pin, Id = bus.ServiceNo, Url = bus.ServiceNo + ".png" }; map.Pins.Add(pin); map.PublicBusPins.Add(busPin); } } // continue after interval await Task.Delay(TimeSpan.FromSeconds(SettingsVars.Variables ["REFRESH_PUBLIC_BUS_INTERVAL"].value)); } }
private static async void DispatchBasedOnTime(BusSvc bs) { while (BusHelper.IsWithinServiceTiming(bs.routeName)) { BusHelper.AddBusOnRoad(bs.routeName + "-" + BusHelper.ActiveBuses.Count, bs.routeName); // dispatch again after freq await Task.Delay(TimeSpan.FromMinutes(bs.freq [BusHelper.GetTimeOfDay(bs.routeName)])); } }
private async void UpdateBusPins() { while (true) { // skip update pins if map is freezed (user clicks on pin) if (!FreezeMap) { // remove all bus pins foreach (CustomPin p in map.BusPins) { map.Pins.Remove(p.Pin); } map.BusPins.Clear(); foreach (BusOnRoad bor in BusHelper.ActiveBuses.Values) { // move bus to next checkpoint on the route for simulation // actual deployment: get real-time position of bus BusSimulator.GoToNextCheckpoint(bor); // add pin to map if service is to be shown on map if (BusHelper.BusSvcs [bor.routeName].showOnMap) { var description = "Start: " + BusHelper.BusStops [bor.firstStop].name + "\n" + "End: " + BusHelper.BusStops [bor.lastStop].name + "\n" + "Approaching: " + BusHelper.BusStops [(string)bor.nextStopEnumerator.Current].name + "\n" + "In: " + BusHelper.GetArrivalTiming(bor.vehiclePlate) + "\n"; var pin = new Pin { Type = PinType.Place, Position = new Xamarin.Forms.Maps.Position(bor.latitude, bor.longitude), Label = bor.routeName, Address = description }; var bus = new CustomPin { Pin = pin, Id = bor.routeName, Url = bor.routeName + ".png" }; map.Pins.Add(pin); map.BusPins.Add(bus); } } // remove buses which has finished plying List <BusOnRoad> finishedBuses = BusHelper.ActiveBuses.Values.Where(bor => bor.finished).ToList(); foreach (BusOnRoad bor in finishedBuses) { BusHelper.RemoveBusOnRoad(bor.vehiclePlate); } } // continue after interval await Task.Delay(TimeSpan.FromSeconds(SettingsVars.Variables ["REFRESH_BUS_INTERVAL"].value)); } }
// private static double avgSpeedPeak = 4.0; // in m/s // private static double avgSpeedNonPeak = 5.0; // in m/s // private static double avgBoardingTimePeak = 30; // in secs // private static double avgBoardingTimeNonPeak = 15; // in secs public static void DispatchBuses() { // set timer for each bus service to dispatch bus at freq (if within service timing) foreach (BusSvc bs in BusHelper.BusSvcs.Values) { Device.StartTimer(TimeSpan.FromMinutes(bs.freq [(int)Days.WEEKDAY]), () => { BusHelper.AddBusOnRoad(bs.routeName + "-" + BusHelper.ActiveBuses.Count, bs.routeName); return(IsWithinServiceTiming(bs.routeName)); }); } }
private bool UpdatePositions() { // skip update pins if map is freezed if (FreezeMap) { return(true); } // remove all bus pins foreach (CustomPin p in map.BusPins) { map.Pins.Remove(p.Pin); } map.BusPins.Clear(); foreach (BusOnRoad bor in BusHelper.ActiveBuses.Values) { // temp change position randomly for test // bor.latitude += rand.NextDouble () * 0.0001 - 0.00005; // bor.longitude += rand.NextDouble () * 0.0001 - 0.00005; // move bus to next checkpoint on the route for simulation BusSimulator.GoToNextCheckpoint(bor); // add pin to map if svc show on map if (BusHelper.BusSvcs [bor.routeName].showOnMap) { var description = "Start: " + BusHelper.BusStops [bor.firstStop].name + "\n" + "End: " + BusHelper.BusStops [bor.lastStop].name + "\n" + "Approaching: " + BusHelper.BusStops [(string)bor.nextStopEnumerator.Current].name + "\n" + "In: " + BusHelper.GetArrivalTiming((string)bor.nextStopEnumerator.Current, bor.routeName); var pin = new Pin { Type = PinType.Place, Position = new Xamarin.Forms.Maps.Position(bor.latitude, bor.longitude), Label = bor.routeName, Address = description }; var bus = new CustomPin { Pin = pin, Id = bor.routeName, Url = bor.routeName + ".png" }; map.Pins.Add(pin); map.BusPins.Add(bus); } } return(true); }
public SvcInfoPage(string busSvcName) { Title = busSvcName + " Route Information"; // show only for nus buses if (!BusHelper.IsPublic(busSvcName)) { Label header = new Label { Text = busSvcName, FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Center }; var view = new TableView() { Intent = TableIntent.Data }; var root = new TableRoot(); var section = new TableSection(); foreach (string busStopCode in BusHelper.BusSvcs[busSvcName].stops) { section.Add(new BusStopCell(busStopCode)); } root.Add(section); view.Root = root; Content = new StackLayout { Children = { header, view } }; } else { Content = new Label { Text = "Page under construction" }; } }
private async void CheckAlertTiming() { while (true) { // check each stop and each svc that are enabled // incl public bus foreach (string busStopCode in enabledStops) { foreach (string routeName in enabledSvcs) { var stop = BusHelper.BusStops [busStopCode]; if (stop.services.Union(stop.publicServices).Contains(routeName)) { // get arrival timing of svc in stop and display alert if below alert minutes var arrivalTimingStr = (stop.services.Contains(routeName)) ? BusHelper.GetArrivalTiming(busStopCode, routeName) : await BusHelper.GetPublicBusesArrivalTiming(busStopCode, routeName); var nextTimingStr = Regex.Match(arrivalTimingStr, @"\d+").Value; if (!nextTimingStr.Equals(String.Empty)) { var nextTiming = Int32.Parse(nextTimingStr); if (nextTiming == 0) { await DisplayAlert("Bus Alert", routeName + " is arriving " + stop.name + "!", "OK", "Cancel"); } else if (nextTiming <= SettingsVars.Variables ["ALERT_MINUTES"].value) { await DisplayAlert("Bus Alert", routeName + " is arriving " + stop.name + " at " + nextTiming + " min.", "OK", "Cancel"); } } else if (arrivalTimingStr.Contains("Arr")) { await DisplayAlert("Bus Alert", routeName + " is arriving " + stop.name + "!", "OK", "Cancel"); } } } } // continue after interval await Task.Delay(TimeSpan.FromSeconds(SettingsVars.Variables ["REFRESH_ALERT_INTERVAL"].value)); } }
private void OnClickRoute(object sender, EventArgs e) { var routeName = ((Button)sender).StyleId; // take the correct list for public/nus bus var busSvcStops = (BusHelper.IsPublic(routeName)) ? BusHelper.PublicBusSvcStops[routeName] : BusHelper.BusSvcs [routeName].stops; if (((Button)sender).Opacity.Equals(0.3)) { // activate bus service // add all stops from bus service into list if list does not contains bus stop ((Button)sender).Opacity = 1; enabledSvcs.Add(routeName); foreach (string busStopCode in busSvcStops) { if (!stops.Contains(BusHelper.BusStops[busStopCode])) { stops.Add(BusHelper.BusStops[busStopCode]); } } } else { // deactivate bus service // remove bus stop of bus service from list if no other enabled bus service shares the same bus stop // incl public bus ((Button)sender).Opacity = 0.3; enabledSvcs.Remove(routeName); foreach (string busStopCode in busSvcStops) { var stop = BusHelper.BusStops [busStopCode]; var otherEnabledSvcsInStop = enabledSvcs.Intersect(stop.services.Union(stop.publicServices)).ToList(); if (otherEnabledSvcsInStop.Count == 0) { stops.Remove(stop); } } } }
public MapPage() { // map with default centre at NUS var NUSCenter = new Xamarin.Forms.Maps.Position(1.2966, 103.7764); map = new BusMap( MapSpan.FromCenterAndRadius(NUSCenter, Distance.FromKilometers(DEFAULT_RADIUS))) { IsShowingUser = true, HeightRequest = 100, WidthRequest = 960, VerticalOptions = LayoutOptions.FillAndExpand }; // shift to current location if possible (activate only for device testing) // ShiftToCurrentLocation (); // add pins for each bus stops foreach (BusStop busStop in BusHelper.BusStops.Values) { var description = ""; foreach (string svc in busStop.services) { description += svc + ": " + BusHelper.GetArrivalTiming(busStop.busStopCode, svc) + "\n"; } var pin = new Pin { Type = PinType.Place, Position = new Xamarin.Forms.Maps.Position(busStop.latitude, busStop.longitude), Label = busStop.name + " - " + busStop.busStopCode, Address = description }; var stop = new CustomPin { Pin = pin, Id = "stop", Url = "stop.png" }; map.Pins.Add(pin); map.StopPins.Add(stop); } // slider to change radius from 0.1 - 0.9 km var slider = new Slider(1, 9, 5); slider.ValueChanged += (sender, e) => { var zoomLevel = e.NewValue; // between 1 and 9 currRadius = 1.0 - (zoomLevel / 10.0); map.MoveToRegion(MapSpan.FromCenterAndRadius( map.VisibleRegion.Center, Distance.FromKilometers(currRadius))); }; // add map and slider to stack layout var stack = new StackLayout { Spacing = 0 }; stack.Children.Add(map); stack.Children.Add(slider); Icon = "MapTabIcon.png"; Title = "Map"; Content = stack; // add random buses for testing BusSimulator.DispatchBuses(); // set timer to update bus and current location Device.StartTimer(TimeSpan.FromSeconds(REFRESH_INTERVAL), UpdatePositions); }
private async void UpdateStopPins() { while (true) { // skip update pins if map is freezed (user clicks on pin) if (!FreezeMap) { // remove all stop pins foreach (CustomPin p in map.StopPins) { map.Pins.Remove(p.Pin); } map.StopPins.Clear(); // add stop pins, with change in arrival timing foreach (BusStop busStop in BusHelper.BusStops.Values) { var description = ""; foreach (string svc in busStop.services) { // handle repeated service in bus stop case // show timing for both directions if (busStop.repeatedServices != null && busStop.repeatedServices.Contains(svc)) { description += svc + "(to " + BusHelper.BusStops [BusHelper.BusSvcs [svc].loopStop].name + "): "; description += BusHelper.GetArrivalTiming(busStop.busStopCode, svc, "BEFORE") + "\n"; description += svc + "(to " + BusHelper.BusStops [BusHelper.BusSvcs [svc].lastStop].name + "): "; description += BusHelper.GetArrivalTiming(busStop.busStopCode, svc, "AFTER") + "\n"; } else { description += svc + ": " + BusHelper.GetArrivalTiming(busStop.busStopCode, svc) + "\n"; } } // get public bus arrival timing for bus stop (if public buses pass by) // busStopCode with all digits -> public bus will pass by if (BusHelper.IsPublic(busStop.busStopCode)) { description += await BusHelper.GetPublicBusesArrivalTiming(busStop.busStopCode); } var pin = new Pin { Type = PinType.Place, Position = new Xamarin.Forms.Maps.Position(busStop.latitude, busStop.longitude), Label = busStop.name + " - " + busStop.busStopCode, Address = description }; var stop = new CustomPin { Pin = pin, Id = "stop", Url = "stop.png" }; map.Pins.Add(pin); map.StopPins.Add(stop); } } // continue after interval await Task.Delay(TimeSpan.FromSeconds(SettingsVars.Variables ["REFRESH_STOP_INTERVAL"].value)); } }