/// <summary> /// Makes a request against RSS Weather service and add update the layer's table /// </summary> /// <param name="zipCode"></param> /// <param name="Lat"></param> /// <param name="Lon"></param> private void AddWeatherItem(long zipCode, double Lat, double Lon) { try { string cityName; double lat, lon; int temp; string condition; string desc; string iconPath; string day; string date; int low; int high; int iconCode; int iconWidth = 52; //default values int iconHeight = 52; Bitmap bitmap = null; DataRow dbr = m_table.Rows.Find(zipCode); if (dbr != null) { // get the date DateTime updateDate = Convert.ToDateTime(dbr[14]); TimeSpan ts = DateTime.Now - updateDate; // if the item had been updated in the past 15 minutes, simply bail out. if (ts.TotalMinutes < 15) return; } //the base URL for the service string url = "http://xml.weather.yahoo.com/forecastrss?p="; //the RegEx used to extract the icon path from the HTML tag string regxQry = "(http://(\\\")?(.*?\\.gif))"; XmlTextReader reader = null; XmlDocument doc; XmlNode node; try { //make the request and get the result back into XmlReader reader = new XmlTextReader(url + zipCode.ToString()); } catch(Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); return; } //load the XmlReader to an xml doc doc = new XmlDocument(); doc.Load(reader); //set an XmlNamespaceManager since we have to make explicit namespace searches XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable); //Add the namespaces used in the xml doc to the XmlNamespaceManager. xmlnsManager.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0"); xmlnsManager.AddNamespace("geo", "http://www.w3.org/2003/01/geo/wgs84_pos#"); //make sure that the node exists node = doc.DocumentElement.SelectSingleNode("/rss/channel/yweather:location/@city", xmlnsManager); if(null == node) return; //get the cityname cityName = doc.DocumentElement.SelectSingleNode("/rss/channel/yweather:location/@city", xmlnsManager).InnerXml; if(Lat == 0.0 && Lon == 0.0) { //in case that the caller did not specify a coordinate, get the default coordinate from the service lat = Convert.ToDouble(doc.DocumentElement.SelectSingleNode("/rss/channel/item/geo:lat", xmlnsManager).InnerXml); lon = Convert.ToDouble(doc.DocumentElement.SelectSingleNode("/rss/channel/item/geo:long", xmlnsManager).InnerXml); } else { lat = Lat; lon = Lon; } //extract the rest of the information from the RSS response condition = doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:condition/@text", xmlnsManager).InnerXml; iconCode = Convert.ToInt32(doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:condition/@code", xmlnsManager).InnerXml); temp = Convert.ToInt32(doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:condition/@temp", xmlnsManager).InnerXml); desc = doc.DocumentElement.SelectSingleNode("/rss/channel/item/description").InnerXml; day = doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:forecast/@day", xmlnsManager).InnerXml; date = doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:forecast/@date", xmlnsManager).InnerXml; low = Convert.ToInt32(doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:forecast/@low", xmlnsManager).InnerXml); high = Convert.ToInt32(doc.DocumentElement.SelectSingleNode("/rss/channel/item/yweather:forecast/@high", xmlnsManager).InnerXml); //use regex in order to extract the icon name from the html script Match m = Regex.Match(desc,regxQry); if(m.Success) { iconPath = m.Value; //add the icon ID to the symbology table DataRow tr = m_symbolTable.Rows.Find(iconCode); if(null == tr) { //get the icon from the website bitmap = DownloadIcon(iconPath, out iconWidth, out iconHeight); //create a new record tr = m_symbolTable.NewRow(); tr[1] = iconCode; tr[3] = iconWidth; tr[4] = iconHeight; tr[6] = bitmap; //update the symbol table. The initialization of the symbol cannot take place in here, since //this code gets executed on a background thread. lock(m_symbolTable) { m_symbolTable.Rows.Add(tr); } } else //get the icon's dimensions from the table { //get the icon's dimensions from the table iconWidth = Convert.ToInt32(tr[3]); iconHeight = Convert.ToInt32(tr[4]); } } else { iconPath = ""; } //test whether the record already exists in the layer's table. if(null == dbr) //in case that the record does not exist { //create a new record dbr = m_table.NewRow(); if (!m_table.Columns[0].AutoIncrement) dbr[0] = Convert.ToInt32(DateTime.Now.Millisecond); //add the item to the table lock (m_table) { dbr[1] = zipCode; dbr[2] = cityName; dbr[3] = lat; dbr[4] = lon; dbr[5] = temp; dbr[6] = condition; dbr[7] = iconPath; dbr[8] = iconCode; dbr[9] = day; dbr[10] = date; dbr[11] = low; dbr[12] = high; dbr[13] = false; dbr[14] = DateTime.Now; m_table.Rows.Add(dbr); } } else //in case that the record exists, just update it { //update the record lock (m_table) { dbr[5] = temp; dbr[6] = condition; dbr[7] = iconPath; dbr[8] = iconCode; dbr[9] = day; dbr[10] = date; dbr[11] = low; dbr[12] = high; dbr[14] = DateTime.Now; dbr.AcceptChanges(); } } base.m_bIsCompiledDirty = true; //fire an event to notify the user that the item has been updated if (OnWeatherItemAdded != null) { WeatherItemEventArgs weatherItemEventArgs = new WeatherItemEventArgs(Convert.ToInt32(dbr[0]), zipCode, lon, lat, iconWidth, iconHeight); OnWeatherItemAdded(this, weatherItemEventArgs); } } catch(Exception ex) { System.Diagnostics.Trace.WriteLine("AddWeatherItem: " + ex.Message); } }
private void RefreshWeatherItemInvoked(WeatherItemEventArgs weatherItemInfo) { ITransformation transform = m_activeView.ScreenDisplay.DisplayTransformation as ITransformation; if (transform == null) return; double[] iconDimensions = new double[2]; iconDimensions[0] = (double)weatherItemInfo.IconWidth; iconDimensions[1] = (double)weatherItemInfo.IconHeight; double[] iconDimensionsMap = new double[2]; transform.TransformMeasuresFF(esriTransformDirection.esriTransformReverse, 1, ref iconDimensionsMap[0], ref iconDimensions[0]); m_invalidateExtent.PutCoords(0, 0, iconDimensionsMap[0], iconDimensionsMap[0]); m_point.PutCoords(weatherItemInfo.mapX, weatherItemInfo.mapY); m_invalidateExtent.CenterAt(m_point); m_activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography, m_weatherLayer, m_invalidateExtent); m_activeView.ScreenDisplay.UpdateWindow(); }
/// <summary> /// weather layer ItemAdded event handler /// </summary> /// <param name="sender"></param> /// <param name="args"></param> /// <remarks>gets fired when an item is added to the table</remarks> private void OnWeatherItemAdded(object sender, WeatherItemEventArgs args) { // use the invoke helper since this event gets fired on a different thread m_invokeHelper.RefreshWeatherItem(args); }
public void RefreshWeatherItem(WeatherItemEventArgs weatherItemInfo) { try { // Invoke the RefreshInternal through its delegate if (!this.IsDisposed && this.IsHandleCreated) Invoke(new RefreshWeatherItemHelper(RefreshWeatherItemInvoked), new object[] { weatherItemInfo }); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); } }