예제 #1
0
        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;
        }
예제 #2
0
        public App()
        {
            // load bus data
            BusHelper.LoadBusData();

            // Display the main page of your application
            MainPage = new NUSBusMap.MainPage();
        }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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)]));
            }
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
//		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));
                });
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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"
                };
            }
        }
예제 #9
0
        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));
            }
        }
예제 #10
0
        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);
                    }
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        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));
            }
        }