/// <summary> /// Creates the region bounds. /// </summary> /// <param name="boundsElement">The bounds element</param> public RegionBounds(XElement boundsElement) { this.regionLatitude = boundsElement.GetFirstElementValue<double>("lat"); this.regionLatitudeSpan = boundsElement.GetFirstElementValue<double>("latSpan"); this.regionLongitude = boundsElement.GetFirstElementValue<double>("lon"); this.regionLongitudeSpan = boundsElement.GetFirstElementValue<double>("lonSpan"); }
/// <summary> /// Creates the trip stop. /// </summary> public TripStop(XElement tripStopElement, DateTime serverTime) { //<tripStopTime> //<arrivalTime>83942</arrivalTime> //<departureTime>83942</departureTime> //<stopId>1_35324</stopId> //<distanceAlongTrip>13566.594707177532</distanceAlongTrip> //</tripStopTime> // Note - this time is different from all the other times :) // from the documentation: // http://developer.onebusaway.org/modules/onebusaway-application-modules/current/api/where/elements/trip-details.html // "•arrivalTime - time, in seconds since the start of the service date, when the trip arrives at the specified stop" var timeSpan = new TimeSpan(0, 0, tripStopElement.GetFirstElementValue<int>("arrivalTime")); this.ArrivalTime = (new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day)).AddSeconds(timeSpan.TotalSeconds); // Try and find the stop in the owning document for this trip: string stopId = tripStopElement.GetFirstElementValue<string>("stopId"); XElement stopElement = (from currentStopElement in tripStopElement.Document.Descendants("stop") where string.Equals(stopId, currentStopElement.GetFirstElementValue<string>("id"), StringComparison.OrdinalIgnoreCase) select currentStopElement).FirstOrDefault(); if (stopElement != null) { base.ParseStopElement(stopElement); } }
public ScheduleStopTime(DateTime serverTime, XElement scheduleStopTimeElement) { //<scheduleStopTime> //<arrivalEnabled>true</arrivalEnabled> //<arrivalTime>1356615606000</arrivalTime> //<departureEnabled>true</departureEnabled> //<departureTime>1356615606000</departureTime> //<serviceId>1_WEEKDAY</serviceId> //<tripId>1_21912615</tripId></scheduleStopTime> //</scheduleStopTime> // IMPORTANT: the schedule time that we get from OBA is // relative to the time on the server. So for instance, the arrival // time may be 5:00pm, but that is relative to the server // time which may be 3:00pm. What that means is that the // bus' arrival time is actually 2 hours from now, so to // make the time relative to the client we take the difference // in minutes between the arrival time and the server time // and then add it to the current time. var arrivalTime = scheduleStopTimeElement.GetFirstElementValue<long>("arrivalTime").ToDateTime(); var arrivalTimeInMinutes = (arrivalTime - serverTime).TotalMinutes; this.ArrivalTime = DateTime.Now.AddMinutes(arrivalTimeInMinutes); this.TripId = scheduleStopTimeElement.GetFirstElementValue<string>("tripId"); }
/// <summary> /// Creates the region. /// </summary> /// <param name="regionElement">The region element.</param> public Region(XElement regionElement) { this.RegionName = regionElement.GetFirstElementValue<string>("regionName"); this.RegionUrl = regionElement.GetFirstElementValue<string>("obaBaseUrl"); this.SupportsObaRealtimeApis = regionElement.GetFirstElementValue<bool>("supportsObaRealtimeApis"); this.SupportsObaDiscoveryApis = regionElement.GetFirstElementValue<bool>("supportsObaDiscoveryApis"); this.IsActive = regionElement.GetFirstElementValue<bool>("active"); this.RegionBounds = new List<RegionBounds>(from boundsElement in regionElement.Descendants("bound") select new RegionBounds(boundsElement)); }
public Agency(XElement agencyElement) { // xml for agency: // <agency> // <id>1</id> // <name>Metro Transit</name> // <url>http://metro.kingcounty.gov</url> // <timezone>America/Los_Angeles</timezone> // <lang>en</lang> // <phone>206-553-3000</phone> // <disclaimer>Transit scheduling, geographic, and real-time data provided by permission of King County. Some real-time info provided by UW Intelligent Transportation Systems.</disclaimer> // <privateService>false</privateService> // </agency> this.Id = agencyElement.GetFirstElementValue<string>("id"); this.Name = agencyElement.GetFirstElementValue<string>("name"); this.WebsiteUri = agencyElement.GetFirstElementValue<string>("url"); this.PhoneNumber = agencyElement.GetFirstElementValue<string>("phone"); this.Disclaimer = agencyElement.GetFirstElementValue<string>("disclaimer"); }
protected void ParseStopElement(XElement stopElement) { // Xml for a stop: //<stop> // <id>3_3465</id> // <lat>47.610756</lat> // <lon>-122.337204</lon> // <direction>NW</direction> // <name>4th / Pike</name> // <code>3465</code> // <locationType>0</locationType> // <routeIds> // <string>40_590</string> // <string>40_592</string> // <string>40_594</string> // <string>40_595</string> // </routeIds> // </stop> this.StopId = stopElement.GetFirstElementValue<string>("id"); this.Latitude = stopElement.GetFirstElementValue<double>("lat"); this.Longitude = stopElement.GetFirstElementValue<double>("lon"); this.Direction = stopElement.GetFirstElementValue<string>("direction"); this.Name = stopElement.GetFirstElementValue<string>("name"); this.Code = stopElement.GetFirstElementValue<string>("code"); HashSet<string> routeIds = new HashSet<string>(from routeString in stopElement.Element("routeIds").Descendants("string") select routeString.Value); // The routes are stored at the begining of the document: this.Routes = (from routeElement in stopElement.Document.Descendants("route") where routeIds.Contains(routeElement.GetFirstElementValue<string>("id")) select new Route(routeElement)).ToArray(); }
public Route(XElement routeElement) { // Xml for route: // <route> // <id>1_43</id> // <shortName>43</shortName> // <description>cbd/u-district</description> // <type>3</type> // <url>http://metro.kingcounty.gov/tops/bus/schedules/s043_0_.html</url> // <agency> // <id>1</id> // <name>Metro Transit</name> // <url>http://metro.kingcounty.gov</url> // <timezone>America/Los_Angeles</timezone> // <lang>en</lang> // <phone>206-553-3000</phone> // <disclaimer>Transit scheduling, geographic, and real-time data provided by permission of King County. Some real-time info provided by UW Intelligent Transportation Systems.</disclaimer> // <privateService>false</privateService> // </agency> // </route> this.Id = routeElement.GetFirstElementValue<string>("id"); this.ShortName = routeElement.GetFirstElementValue<string>("shortName"); this.Description = routeElement.GetFirstElementValue<string>("description"); this.ScheduleUri = routeElement.GetFirstElementValue<string>("url"); if (string.IsNullOrEmpty(this.Description)) { this.Description = routeElement.GetFirstElementValue<string>("longName"); } // Throw if there is no agency. There should always be an agency: var agencyElement = routeElement.Descendants("agency").FirstOrDefault(); if (agencyElement != null) { this.Agency = new Agency(agencyElement); } }
/// <summary> /// Creates the region. /// </summary> /// <param name="regionElement">The region element.</param> public Region(XElement regionElement) { this.RegionName = regionElement.GetFirstElementValue<string>("regionName"); this.RegionUrl = regionElement.GetFirstElementValue<string>("obaBaseUrl"); this.SupportsObaRealtimeApis = regionElement.GetFirstElementValue<bool>("supportsObaRealtimeApis"); this.SupportsObaDiscoveryApis = regionElement.GetFirstElementValue<bool>("supportsObaDiscoveryApis"); this.IsActive = regionElement.GetFirstElementValue<bool>("active"); this.RegionBounds = new List<RegionBounds>(from boundsElement in regionElement.Descendants("bound") select new RegionBounds(boundsElement)); // Append api/where when neccessary: if (!this.RegionUrl.EndsWith("api/where/")) { // If the URI we get back is missing a backslash, add it first: if (!String.IsNullOrEmpty(this.RegionUrl) && !this.RegionUrl.EndsWith("/")) { this.RegionUrl += "/"; } this.RegionUrl += "api/where"; } }
/// <summary> /// Creates a shape out of a google encoded uri. This code was taken from the WP7 OneBusAway /// client - /// /// http://onebusawaywp7.codeplex.com/SourceControl/changeset/view/94877#1472108 /// /// Google documentation on polyline decoding: /// /// http://code.google.com/apis/maps/documentation/polylinealgorithm.html /// /// </summary> public Shape(XElement encodedPolylineElement) { string encoded = encodedPolylineElement.GetFirstElementValue<string>("points"); int index = 0; int latitude = 0; int longitude = 0; int length = encoded.Length; List<Point> pointList = new List<Point>(); while (index < length) { latitude += DecodePoint(encoded, index, out index); longitude += DecodePoint(encoded, index, out index); Point point = new Point(); point.Latitude = (latitude * 1e-5); point.Longitude = (longitude * 1e-5); pointList.Add(point); } this.Points = pointList.ToArray(); }
/// <summary> /// Creates the tracking data out of an arrival and departure element. /// </summary> public TrackingData(DateTime serverTime, string stopId, string stopName, XElement arrivalAndDepartureElement) { this.RouteId = arrivalAndDepartureElement.GetFirstElementValue<string>("routeId"); this.TripId = arrivalAndDepartureElement.GetFirstElementValue<string>("tripId"); this.TripHeadsign = arrivalAndDepartureElement.GetFirstElementValue<string>("tripHeadsign"); this.StopName = stopName; this.StopId = stopId; this.Context = OneStop; scheduledArrivalTime = arrivalAndDepartureElement.GetFirstElementValue<long>("scheduledArrivalTime").ToDateTime(); this.ScheduledArrivalInMinutes = (scheduledArrivalTime - serverTime).Minutes; long predictedTime = arrivalAndDepartureElement.GetFirstElementValue<long>("predictedArrivalTime"); if (predictedTime > 0) { DateTime predictedArrivalDateTime = predictedTime.ToDateTime(); this.PredictedArrivalInMinutes = (predictedArrivalDateTime - serverTime).Minutes; } else { this.PredictedArrivalInMinutes = this.scheduledArrivalInMinutes; } this.scheduledArrivalTime = DateTime.Now.AddMinutes(this.scheduledArrivalInMinutes); this.predictedArrivalTime = DateTime.Now.AddMinutes(this.predictedArrivalInMinutes); int difference = this.predictedArrivalInMinutes - this.scheduledArrivalInMinutes; if (difference > 0) { this.status = "DELAY"; } else { this.status = "ON TIME"; } // Grab the route element from the document and parse it into a Route object: var routeElements = (from routeElement in arrivalAndDepartureElement.Document.Descendants("route") where routeElement.GetFirstElementValue<string>("id") == this.RouteId select routeElement).ToList(); this.Route = new Route(routeElements[0]); this.stopAndRoute = new StopAndRoutePair(this); }
/// <summary> /// Creates a schedule out of a scheduleStopTimesElement. /// </summary> public StopRouteSchedule(DateTime serverTime, XElement stopRouteDirectionScheduleElement) { this.TripHeadsign = stopRouteDirectionScheduleElement.GetFirstElementValue<string>("tripHeadsign"); this.ScheduleStopTimes = (from scheduleStopTimeElement in stopRouteDirectionScheduleElement.Descendants("scheduleStopTime") select new ScheduleStopTime(serverTime, scheduleStopTimeElement)).ToArray(); }
/// <summary> /// Creates the trip details. /// </summary> public TripDetails(XElement entryElement, DateTime serverTime) { //<entry class="tripDetails"> // <tripId>40_21580184</tripId> // <serviceDate>1357113600000</serviceDate> // <status> // <activeTripId>40_21580184</activeTripId> // <blockTripSequence>0</blockTripSequence> // <serviceDate>1357113600000</serviceDate> // <scheduledDistanceAlongTrip>4200.542521894713</scheduledDistanceAlongTrip> // <totalDistanceAlongTrip>31368.062697873433</totalDistanceAlongTrip> // <position> // <lat>47.62131784992367</lat> // <lon>-122.32801704050095</lon> // </position> // <orientation>100.26638970466908</orientation> // <closestStop>1_1070</closestStop> // <closestStopTimeOffset>-98</closestStopTimeOffset> // <nextStop>1_71350</nextStop> // <nextStopTimeOffset>434</nextStopTimeOffset> // <status>default</status> // <predicted>true</predicted> // <lastUpdateTime>1357166368000</lastUpdateTime> // <lastKnownLocation> // <lat>47.61576461791992</lat> // <lon>-122.33000946044922</lon> // </lastKnownLocation> // <scheduleDeviation>660</scheduleDeviation> // <distanceAlongTrip>4200.542521894713</distanceAlongTrip> // <vehicleId>40_9616</vehicleId> // </status> //</entry> this.TripId = entryElement.GetFirstElementValue<string>("tripId"); this.VehicleId = entryElement.GetFirstElementValue<string>("vehicleId"); this.ClosestStopId = entryElement.GetFirstElementValue<string>("closestStop"); this.NextStopId = entryElement.GetFirstElementValue<string>("nextStop"); var lastKnownLocationElement = entryElement.Descendants("lastKnownLocation").FirstOrDefault(); if (lastKnownLocationElement != null) { this.KnownLatitude = lastKnownLocationElement.GetFirstElementValue<double>("lat"); this.KnownLongitude = lastKnownLocationElement.GetFirstElementValue<double>("lon"); } this.TripStops = (from tripStopElement in entryElement.Descendants("tripStopTime") select new TripStop(tripStopElement, serverTime)).ToArray(); // We need to mark the trip stops according to the real time data: bool hasReachedStop = true; foreach (var tripStop in this.TripStops) { if(string.Equals(tripStop.StopId, this.NextStopId, StringComparison.OrdinalIgnoreCase)) { hasReachedStop = false; } if (string.Equals(tripStop.StopId, this.ClosestStopId, StringComparison.OrdinalIgnoreCase)) { tripStop.IsClosestStop = true; } tripStop.HasReachedStop = hasReachedStop; } }