/// <summary> /// Gets the cameras. /// </summary> /// <param name="cameraType">Type of the camera.</param> /// <param name="name">The name.</param> /// <returns></returns> public IObservable<Camera> GetCameras(CameraType cameraType, string name) { var cachedCameras = new CachedEntity<List<Camera>>(string.Format("Services.Camera.{0}.{1}", cameraType, name)); return new AnonymousObservable<Camera>(observer => { if (!cachedCameras.Value.Any() || !cachedCameras.CachedDateTime.HasValue || cachedCameras.CachedDateTime.Value <= DateTime.Now.AddDays(-1)) { Uri cameraListUri = null; if (cameraType == CameraType.Regional) { cameraListUri = new Uri(string.Format("{0}?roadway={1}", DfwTranstarUri.CamerasRegionalUri, name.Replace(' ', '_'))); } else { cameraListUri = new Uri(string.Format("{0}?list={1}&roadway={2}", DfwTranstarUri.CamerasUri, cameraType.ToString().ToLower(), name.Replace(' ', '_'))); } IObservable<string> observable = ObservableHelper.TextFromUri(cameraListUri); var svc = observable.Subscribe(result => { int tableStart = result.IndexOf("<table id=\"ListTable\""); int tableEnd = result.IndexOf("</table>", tableStart); XElement xmlDoc = XElement.Parse(result.Substring(tableStart, (tableEnd + 8) - tableStart)); var cameras = from item in xmlDoc.Element("tr").Element("td").Element("ul").Elements("li") select new Camera { ID = this.GetCameraID(cameraType, item.Element("a").Attribute("href").Value), Name = item.Value, EnableThumbnails = ProfileCommon.UserSettings.ShowCameraThumbnails, ImageUri = cameraType == CameraType.Regional ? string.Format(DfwTranstarUri.CameraDetailRegionalUri, name.ToLower() .Replace(" north", "") .Replace(" south", "") .Replace(" east", "") .Replace(" west", ""), this.GetCameraID(cameraType, item.Element("a").Attribute("href").Value)) : string.Format(DfwTranstarUri.CameraDetailUri, this.GetCameraID(cameraType, item.Element("a").Attribute("href").Value)) }; cachedCameras.Value = cameras.ToList(); cachedCameras.Cache(); cachedCameras.Value.ToList().ForEach(c => observer.OnNext(c)); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }); } else { cachedCameras.Value.ToList().ForEach(c => observer.OnNext(c)); observer.OnCompleted(); } return Disposable.Empty; }); }
/// <summary> /// Gets the roadway cameras. /// </summary> /// <param name="cameraType">Type of the camera.</param> /// <returns></returns> public IObservable<Roadway> GetRoadwayCameras(CameraType cameraType) { var cachedRoadways = new CachedEntity<List<Roadway>>("Services.RoadwayCameras." + cameraType.ToString()); return new AnonymousObservable<Roadway>(observer => { if (!cachedRoadways.Value.Any() || cachedRoadways.CachedDateTime <= DateTime.Now.AddDays(-1)) { Uri uri = null; switch (cameraType) { case CameraType.Freeway: uri = new Uri(DfwTranstarUri.CamerasUri); break; case CameraType.Street: uri = new Uri(DfwTranstarUri.CamerasUri + "?list=street"); break; case CameraType.Regional: uri = new Uri(DfwTranstarUri.CamerasRegionalUri); break; } IObservable<string> observable = ObservableHelper.TextFromUri(uri); var svc = observable.Subscribe(result => { int tableStart = result.IndexOf("<table id=\"ListTable\""); int tableEnd = result.IndexOf("</table>", tableStart); XElement xmlDoc = XElement.Parse(result.Substring(tableStart, (tableEnd + 8) - tableStart)); var roadways = from item in xmlDoc.Element("tr").Element("td").Element("ul").Elements("li") select new Roadway { Name = item.Value, IconUri = cameraType == CameraType.Freeway ? this.GetRoadwayIconUri(item.Value) : "/Resources/Images/empty_svg_small.png" }; cachedRoadways.Value = roadways.ToList(); cachedRoadways.Cache(); cachedRoadways.Value.ToList().ForEach(r => observer.OnNext(r)); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }); } else { cachedRoadways.Value.ToList().ForEach(r => observer.OnNext(r)); observer.OnCompleted(); } return Disposable.Empty; }); }
/// <summary> /// Gets the road closures. /// </summary> /// <param name="refreshData">if set to <c>true</c> [refresh data].</param> /// <returns></returns> public IObservable<RoadClosure> GetRoadClosures(bool refreshData) { var cachedRoadClosures = new CachedEntity<RoadClosure>("Services.RoadClosures"); return new AnonymousObservable<RoadClosure>(observer => { if (refreshData || !cachedRoadClosures.CachedDateTime.HasValue || cachedRoadClosures.CachedDateTime.Value <= DateTime.Now.AddMinutes(-15)) { IObservable<string> observable = ObservableHelper.TextFromUri(new Uri(DfwTranstarUri.BaseUri + "/mobile/roadclosures.aspx")); observable.Subscribe(result => { RoadClosure roadClosure = new RoadClosure(); if (result != null) { int spanStart = result.IndexOf("<span id=\"RCMessage\""); int spanEnd = result.IndexOf("</span>", spanStart); string message = string.Empty; if (spanStart > 0) { message = result.Substring(spanStart + 21, spanEnd - spanStart - 21).Trim() .Replace("<br/>", "\n") .Replace("<br />", "\n") .Replace("</br>", "") .Replace("<b>", "") .Replace("</b>", ""); } roadClosure.Closure = message; } cachedRoadClosures.Value = roadClosure; cachedRoadClosures.Cache(); observer.OnNext(roadClosure); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }, () => { }); } else { observer.OnNext(cachedRoadClosures.Value); observer.OnCompleted(); } return Disposable.Empty; }); }
/// <summary> /// Gets the incidents. /// </summary> /// <param name="refreshData">if set to <c>true</c> [refresh data].</param> /// <returns></returns> public IObservable<Incident> GetIncidents(bool refreshData) { var cachedIncidents = new CachedEntity<List<Incident>>("Services.Incidents"); return new AnonymousObservable<Incident>(observer => { if (refreshData || !cachedIncidents.Value.Any() || cachedIncidents.CachedDateTime <= DateTime.Now.AddMinutes(-10)) { IObservable<string> observable = ObservableHelper.TextFromUri(new Uri(string.Format("{0}?CenterId={1}", DfwTranstarUri.IncidentsUri, TrafficCenter.DalTrans))); var svc = observable.Subscribe(result => { List<Incident> incidents; int indexStart = result.IndexOf("<span id=\"LabelTime\""); int indexEnd = result.IndexOf("</span>", indexStart); var incidentTime = result.Substring(indexStart + 21, indexEnd - indexStart - 21); indexStart = result.IndexOf("<ul id=\"IncidentList\""); if (indexStart > 0) { indexEnd = result.IndexOf("</ul>", indexStart); XElement xmlDoc = XElement.Parse(result.Substring(indexStart, (indexEnd + 5) - indexStart)); incidents = (from item in xmlDoc.Elements("li") select new Incident { Title = item.Value, PublishedDate = DateTime.Parse(string.Format("{0:d} {1}", DateTime.Today, incidentTime)) }).ToList(); } else { incidents = new List<Incident>(); incidents.Add(new Incident() { Title = "No incidents found", PublishedDate = DateTime.Parse(string.Format("{0:d} {1}", DateTime.Today, incidentTime)) }); } cachedIncidents.Value = incidents.ToList(); cachedIncidents.Cache(); incidents.ToList().ForEach(i => observer.OnNext(i)); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }); } else { cachedIncidents.Value.ToList().ForEach(i => observer.OnNext(i)); observer.OnCompleted(); } return Disposable.Empty; }); }
/// <summary> /// Gets the construction closures. /// </summary> /// <param name="roadway">The roadway.</param> /// <returns></returns> public IObservable<ConstructionClosure> GetConstructionClosures(string roadway) { var cachedConstructionClosures = new CachedEntity<ConstructionClosure>("Services.ConstructionClosures." + roadway.Replace(" ", ".")); return new AnonymousObservable<ConstructionClosure>(observer => { if (!cachedConstructionClosures.CachedDateTime.HasValue || cachedConstructionClosures.CachedDateTime.Value <= DateTime.Now.AddDays(-1)) { IObservable<string> observable = ObservableHelper.TextFromUri(new Uri(string.Format("{0}?roadway={1}", DfwTranstarUri.ConstructionClosure, roadway.Replace(" ", "_")))); observable.Subscribe(result => { ConstructionClosure constructionClosure = new ConstructionClosure() { Roadway = roadway }; if (result != null) { int spanStart = result.IndexOf("<span id=\"CurrentConstruction\""); int spanEnd = result.IndexOf("</span>", spanStart); string message = string.Empty; if (spanStart > 0) { message = result.Substring(spanStart + 31, spanEnd - spanStart - 31).Trim() .Replace("<br/>", "\n") .Replace("<br />", "\n") .Replace("</br>", ""); ; } constructionClosure.Message = message; } cachedConstructionClosures.Value = constructionClosure; cachedConstructionClosures.Cache(); observer.OnNext(constructionClosure); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }, () => { }); } else { observer.OnNext(cachedConstructionClosures.Value); observer.OnCompleted(); } return Disposable.Empty; }); }
/// <summary> /// Gets the incidents. /// </summary> /// <param name="refreshData">if set to <c>true</c> [refresh data].</param> /// <returns></returns> public IObservable<Incident> GetIncidents(bool refreshData) { var cachedIncidents = new CachedEntity<List<Incident>>("Services.Incidents"); return new AnonymousObservable<Incident>(observer => { if (refreshData || !cachedIncidents.Value.Any() || cachedIncidents.CachedDateTime <= DateTime.Now.AddMinutes(-10)) { IObservable<string> observable = ObservableHelper.TextFromUri(new Uri(HoustonTranstarUri.IncidentsUri)); var svc = observable.Subscribe(result => { XElement xmlDoc = XElement.Parse(result); string title = (string)xmlDoc.Element("channel").Element("title"); var incidents = from item in xmlDoc.Element("channel").Elements("item") select new Incident { Title = (string)item.Element("title"), PublishedDate = item.Element("pubDate") != null ? ((DateTime)item.Element("pubDate")).ToLocalTime() : DateTime.MinValue }; cachedIncidents.Value = incidents.ToList(); cachedIncidents.Cache(); incidents.ToList().ForEach(i => observer.OnNext(i)); observer.OnCompleted(); }, ex => { observer.OnError(new Exception("Unable to retrieve traffic data.", ex)); }); } else { cachedIncidents.Value.ToList().ForEach(i => observer.OnNext(i)); observer.OnCompleted(); } return Disposable.Empty; }); }