最近在做个项目,其中用到天气预报模块,如果自己在后台每天更新天气信息,必然存在更新不即时、花费大量人力等问题,因而,我采用yahoo提供的天气服务,通过解析yahoo的RSS数据,显示在PPC上,然而,如果在Windows Mobile上接卸RSS数据,对PPC的CPU是个很大的考验,因而,我设计通过WEB SERVICE的方式进行实现,在WEB SERVICE上调用YAHOO的服务,取得数据后,进行解析,将部分用户数据返回给客户端,这样大大减小了客户端的压力。
同时,如果用户每次进入该模块,都去WEB SERVICE上去取数据,WEB SERVICE到YAHOO去数据,这样,必然系统的运行速度会减慢,本人采用数据缓存的机制,当用户在一天之内第一次进入天气预报模块时,系统会到WEB SERVICE上去取数据,并将取得的数据保存到PPC 端的本地数据库中,在当日的其他次数进入模块时,直接从本地获取,大大增快了系统的运行速度和减少网络流量,PPC上本地数据库采用SQL LITE数据库。
下面,将几个关键模块代码贴出来,以供需要者参考!
WEB SERVICE服务:
/// <summary>
/// 获取三天内天气情况
/// </summary>
/// <param name="cityCode">城市编码</param>
/// <returns></returns>
[WebMethod(Description = "获取三天内天气情况")]
public WeatherList GetWeatherInfo(string cityCode)
{
try
{
XmlDocument xd = new XmlDocument();
xd.Load("http://xml.weather.yahoo.com/forecastrss?u=c&p=" + cityCode);
WeatherList result = new WeatherList();
result.TodayWeather = new WeatherInfo();
result.TomorrowWeather = new WeatherInfo();
result.AftertomorrowWeather = new WeatherInfo();
XPathNavigator xpn = xd.CreateNavigator();
XPathNodeIterator iterator;
XPathNavigator tmp;
iterator = xpn.Select("/rss/channel");
tmp = iterator.Current.Clone();
// to rss
if (tmp.MoveToFirstChild() == false)
{
return null;
}
// to channel
if (tmp.MoveToFirstChild() == false)
{
return null;
}
// to title detail
if (tmp.MoveToFirstChild() == false)
{
return null;
}
do
{
switch (tmp.Name.ToLower())
{
case "yweather:wind": //当日风向
result.TodayWeather.WindSpeed = tmp.GetAttribute("speed", "");
break;
case "yweather:atmosphere": //当日可建度
result.TodayWeather.Visibility = tmp.GetAttribute("visibility", "");
result.TodayWeather.Humidity = tmp.GetAttribute("humidity", "");
break;
case "yweather:astronomy": //当日升降旗时间
result.TodayWeather.Sunrise = tmp.GetAttribute("sunrise", "");
result.TodayWeather.Sunset = tmp.GetAttribute("sunset", "");
break;
case "item":
//XPathNavigator tmp2 = xpn.Select("/rss/channel/item").Current.Clone();
//tmp2.MoveToFirstChild();
//tmp2.MoveToFirstChild();
//tmp2.MoveToFirstChild();
tmp.MoveToFirstChild();
int i = 0;
do
{
switch (tmp.Name.ToLower())
{
case "description":
result.TodayWeather.ImageURL = this.DownImage(tmp.Value);
break;
case "yweather:forecast":
if (i == 0)
{
result.TodayWeather.Low = tmp.GetAttribute("low", "");
result.TodayWeather.High = tmp.GetAttribute("high", "");
result.TodayWeather.Code = tmp.GetAttribute("code", "");
}
else if (i == 1)
{
result.TomorrowWeather.Low = tmp.GetAttribute("low", "");
result.TomorrowWeather.High = tmp.GetAttribute("high", "");
result.TomorrowWeather.Code = tmp.GetAttribute("code", "");
}
else if (i == 2)
{
result.AftertomorrowWeather.Low = tmp.GetAttribute("low", "");
result.AftertomorrowWeather.High = tmp.GetAttribute("high", "");
result.AftertomorrowWeather.Code = tmp.GetAttribute("code", "");
}
i++;
break;
}
} while (tmp.MoveToNext());
tmp.MoveToParent();
break;
}
} while (tmp.MoveToNext());
return result;
}
catch
{
throw;
}
}
上面的方法是获取一个对象,该对象中包含三个数据,分别为最近三天的天气数据。
/// <summary>
/// 获取天气图标
/// </summary>
/// <param name="fileURL">图标所在服务器位置</param>
/// <returns></returns>
[WebMethod(Description = "获取天气图标")]
public byte[] GetWeatherImage(string fileURL)
{
try
{
string fileName = fileURL.Substring(fileURL.LastIndexOf("/") + 1);
if (!System.IO.File.Exists(ImageFolder + fileName))//如果文件不存在,则下载文件
{
// StreamReader rdr = null;
FileStream wrtr = null;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(fileURL);
req.Method = "GET";
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream respStream = resp.GetResponseStream();
wrtr = new FileStream(ImageFolder + fileName, FileMode.Create);
byte[] inData = new byte[4096];
int bytesRead = respStream.Read(inData, 0, inData.Length);
while (bytesRead > 0)
{
wrtr.Write(inData, 0, bytesRead);
bytesRead = respStream.Read(inData, 0, inData.Length);
}
resp.Close();
wrtr.Close();
respStream.Close();
}
//读取文件
FileStream fs = File.OpenRead(ImageFolder + fileName);
byte[] res = new byte[fs.Length];
fs.Read(res, 0, res.Length);
fs.Close();
return res;
}
catch
{
throw;
}
}
上面的方法实现了从YAHOO读取天气图标,在读取的过程中,为了增快系统运行速度,在每次获取之前,先检测本地是否存在该图片,如果存在,则直接通过IO流返回本地图片,否则先将YAHOO的图片保存到本地,在进行返回操作。
PPC端逻辑:
/// <summary>
/// 获取天气信息,并显示在页面上
/// </summary>
/// <param name="cityCode">城市编码</param>
public void GetWeatherData(string cityCode)
{
try
{
Cursor.Current = Cursors.WaitCursor;
this.label5.Text = DateTime.Now.ToString("yyyy年MM月dd日"); //日期
switch (DateTime.Now.DayOfWeek) //星期
{
case DayOfWeek.Friday:
this.label6.Text = "星期五";
break;
case DayOfWeek.Monday:
this.label6.Text = "星期一";
break;
case DayOfWeek.Saturday:
this.label6.Text = "星期六";
this.label6.ForeColor = Color.Blue;
break;
case DayOfWeek.Sunday:
this.label6.Text = "星期日";
this.label6.ForeColor = Color.Blue;
break;
case DayOfWeek.Thursday:
this.label6.Text = "星期四";
break;
case DayOfWeek.Tuesday:
this.label6.Text = "星期二";
break;
case DayOfWeek.Wednesday:
this.label6.Text = "星期三";
break;
}
CNCalendar.CNDate dt = new CNCalendar.CNDate(DateTime.Now.Date);
this.label8.Text = dt.GetLunarHolDay();//农历
WeatherList list = localLogic.GetWeatherList(cityCode);
if (list == null)
{
list = wslogic.GetWeatherInfo(cityCode);
localLogic.InsertNewWeatherInfo(list, cityCode);
}
if (list != null)
{
//今日天气
this.label1.Text = list.TodayWeather.Text;
this.label2.Text = list.TodayWeather.High + "℃";
this.label4.Text = list.TodayWeather.Low + "℃";
this.label23.Text = list.TodayWeather.WindSpeed;
this.label24.Text = list.TodayWeather.Visibility;
this.label25.Text = list.TodayWeather.Humidity;
this.label29.Text = list.TodayWeather.Sunrise;
this.label27.Text = list.TodayWeather.Sunset;
//明天天气
this.label12.Text = list.TomorrowWeather.Text;
this.label11.Text = list.TomorrowWeather.High + "℃";
this.label13.Text = list.TomorrowWeather.Low + "℃";
//后天天气
this.label17.Text = list.AftertomorrowWeather.Text;
this.label18.Text = list.AftertomorrowWeather.High + "℃";
this.label15.Text = list.AftertomorrowWeather.Low + "℃";
//今日图标
if (!System.IO.Directory.Exists(ImageFileFolder))
System.IO.Directory.CreateDirectory(ImageFileFolder);
if(!System.IO.File.Exists(ImageFileFolder+list.TodayWeather.ImageFileName))//不存在当前图标文件
{
FileStream wrtr = new FileStream(ImageFileFolder + list.TodayWeather.ImageFileName, FileMode.Create);
byte[] bts = wslogic.GetWeatherImage(list.TodayWeather.ImageURL);
wrtr.Write(bts, 0, bts.Length);
wrtr.Close();
}
this.pictureBox1.Image = new Bitmap(ImageFileFolder + list.TodayWeather.ImageFileName);
}
}
catch (Exception ep)
{
#if DEBUG
MessageBox.Show(ep.Message);
#endif
MessageBox.Show("读取天气信息失败,请检测网络连接!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
}
finally
{
Cursor.Current = Cursors.Default;
}
}