『原创』WM利用Google Weather API获取天气预报

  最近,项目忙得很,公司里杂事很多都跑到我这里,搞得我也不能专心的做项目,索性,今天抽空,玩了一玩谷歌的天气预报服务。相信通过这篇文章,能让大家了解在.net CF下如何发起一个http访问请求(WebRequest),以及处理请求到的数据,比如xml数据、图片数据等。当然,在此分享也是娱乐一把,边走边说吧!

  开始,我们需要了解一下,谷歌的这个服务API,通过也即你在浏览器输入http://www.google.com/ig/api?weather=Kunming,看看什么效果,哈哈,一个xml结构的数据显示在网页中,这就是今天的主角儿!其实,WM通常获取这类数据是通过Webservice,但是也有些信息是通过之前那种http方式提供的,所以,如果我们的WM程序要完成天气预报的获取,至少要完成如下几个步骤:

  • 发起一个http请求:HttpWebRequest
  • 处理这个请求返回的数据:HttpWebResponse
  • 把这些数据组织成可读性强的形式:UI

很幸运,.net CF提供了关于http请求和处理的相关类,当然,它对xml文档操作的支持也是非常的人性化了,在开动Coding之前,先来普及一下某些知识:

————http请求,看图!

并且,附上一篇好文:HTTP请求流程(一)----流程简介,希望大家能够耐心的去了解,毕竟待会儿的代码中就会涉及某些知识,哈哈。

好了,开始惊心动魄的Coding吧,嘿嘿!

 

首先,用vs2008建立一个以c#语言为基础的智能设备应用程序,模拟器用5.0 ppc即可,.net cf版本么,2.0吧~~~~~

然后我们来设计如下的一个用户界面:

几个lable,用来存放天气数据,一个pictureBox用来存放天气图标。两个按钮,一个用来开启主要功能,另一个退出,简单吧!哈哈。到此界面完成了。我们来看看具体的业务代码,双击获取信息按钮,加入如下代码:

 

GetWeather
private void GetWeatherItem_Click(object sender, EventArgs e)
{
int i = 0;
//开始从xml文件中提取天气信息到Lable
XmlNodeList ggNodeList = GoogleWeatherAPI_Parser(@"http://www.google.com/ig/api?weather=Kunming").SelectNodes("xml_api_reply/weather/current_conditions");
lblTempC.Text
= ggNodeList.Item(i).SelectSingleNode("temp_c").Attributes["data"].InnerText;//获取温度信息
lblHumidity.Text = ggNodeList.Item(i).SelectSingleNode("humidity").Attributes["data"].InnerText;//获取湿度信息
lblCurtWeather.Text = ggNodeList.Item(i).SelectSingleNode("condition").Attributes["data"].InnerText;//获取天气状况信息
lblwind_condition.Text = ggNodeList.Item(i).SelectSingleNode("wind_condition").Attributes["data"].InnerText;//获取风向信息
//获取远程图片的url地址,进行组装
string picPath = "http://www.google.com" + ggNodeList.Item(i).SelectSingleNode("icon").Attributes["data"].InnerText;//获取远程图片地址

picBoxWeather.Image
= GetPicImage(picPath);//通过GetPicImage方法,将远程图片转化为.net CF图片控件所能使用的Image对象!
}

 

代码很好理解,也看到.net cf对xml数据的操作还是比较方便的,我们读取了选定的节点数据,赋值给lable控件,应该是一目了然了吧。我就不再赘述,下面要说说两个地方,第一,那个GoogleWeatherAPI_Parser方法;第二,GetPicImage方法。

首先,GoogleWeatherAPI_Parser方法主要是进行一个HttpWebRequest的发起,并且相应这个请求的回应,接受xml数据,具体代码如下:

 

GoogleWeatherAPI_Parser
/// <summary>
/// 从远程地址中,获取返回的xml文件结构体
/// </summary>
/// <param name="baseUrl">远程url</param>
/// <returns></returns>
private static XmlDocument GoogleWeatherAPI_Parser(string baseUrl)
{
HttpWebRequest gg_Request;
HttpWebResponse gg_Response
= null;
XmlDocument gg_XMLdoc
= null;
try
{
gg_Request
= (HttpWebRequest)WebRequest.Create(string.Format(baseUrl));
gg_Request.UserAgent
= @"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100413 Firefox/3.6.4";
gg_Response
= (HttpWebResponse)gg_Request.GetResponse();
gg_XMLdoc
= new XmlDocument();
gg_XMLdoc.Load(gg_Response.GetResponseStream());
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
gg_Response.Close();
return gg_XMLdoc;
}

 

哈,很简单吧,就是发起一个Http请求,把一些请求信息加入到Header中,比如地域性息、浏览器版本等……经过测试,如果你的地域是美国,那么返回的信息是英文的,当然,其他国家暂时没有测试哦……

下面,来看看GetPicImage方法,因为谷歌返回的那个xml数据中,天气图片是一个远程的url地址,对于PictureBox来说,不可能直接使用的,但是,经查,只要把这个图片地址进行HttpWebRequest一下,然后接受返回的Stream,再把此Stream通过Image的FromStream方法进行接收,就可以了。

实际上,.net CF下的Image类,只有FromHbitmap方法,看看此方法接受的参数,就知道杯具了,看来不能直接使用那个请求后返回的Stream,要做一个转换,如何转换呢,请看代码:

 

GetPicImage
/// <summary>
/// 从远程url地址,还原image对象
/// </summary>
/// <param name="picPath">远程图片地址</param>
/// <returns></returns>
private Image GetPicImage(string picPath)
{
Bitmap bit;
Image imagePic;
HttpWebRequest gg_Request;
HttpWebResponse gg_Response
= null;
gg_Request
= (HttpWebRequest)WebRequest.Create(picPath);
gg_Response
= (HttpWebResponse)gg_Request.GetResponse();

bit
= new Bitmap(gg_Response.GetResponseStream());
imagePic
= Image.FromHbitmap(bit.GetHbitmap());

gg_Response.Close();
return imagePic;
}

 

现在是不是明白很多了呢,我们先通过一个Bitmap对象,接受这个ResponseStream的内容,然后,再利用Bitmap的GetHbitmap方法,就得到了一个Hbitmap对象,刚好可以用来“填充”一个Image对象,而填充后的Image对象,就可以被PictureBox所使用。也许,这也是这篇文章中相对难度较大的地方,在此和大家分享一下。

Ok,说了这么多,系统主要功能模块代码和思路都有了,接下来要看看运行效果如何,如下图:

 

恩,风和日丽,湿度刚好!不愧是昆明啊~呵呵,好了,今天的文章就到此为止。谢谢!

参考文章:

Google Weather API调用说明

.NET Compact Framework下HttpWebRequest开发 

Windows mobile Emulator(模拟器)通过ActiveSync连接上网!

作者:Jack Fan初学博闻 of .NET CF/.Net
出处:http://longqi293.cnblogs.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看 [置顶]索引贴——移动开发(不断更新中)

知识共享许可协议
本篇博文 by Jack Fan is licensed under a Creative Commons 署名-非商业性使用-相同方式共享 2.5 中国大陆 License.
标签: c#, ppc, wm, .net cf, 天气, api
posted @ 2010-04-29 23:21 鸭梨山大同志 阅读(2943) 评论(22) 编辑 收藏

 回复 引用 查看   
#1楼 2010-04-30 07:00 施炯      
博主在昆明阿,好地方。
 回复 引用 查看   
#2楼[楼主] 2010-04-30 07:36 Jack Fan      
@施炯
早安!昆明天气的确很好!但就是工资收入和消费水平不成比例,辛苦>_<|||

 回复 引用 查看   
#3楼 2010-04-30 08:50 汉城      
刚开发网PDA程序。。 算是移动开发入门吧。。

以后请多多关照。

 回复 引用 查看   
#4楼 2010-04-30 09:01 egmkang      
你也用GoogleAPI啊,我也用过....
速度快,但是不稳定...

另外你DOM解析XML慢不慢?

 回复 引用 查看   
#5楼[楼主] 2010-04-30 09:14 Jack Fan      
@egmkang
恩,解析速度还好了,具体没有测量过,但是凭感觉来说呢,还好,能忍耐那个速度,呵呵。
@汉城
不敢担不敢担,大家多多交流!谢谢关注!

 回复 引用 查看   
#6楼 2010-04-30 09:34 燕之威      
留个脚印
 回复 引用 查看   
#7楼[楼主] 2010-04-30 10:29 Jack Fan      
@燕之威
哈哈,谢谢!

 回复 引用 查看   
#8楼 2010-04-30 11:22 Wuya      
昨天试了一下,发现google天气api有以下缺点:
1. 天气不准确;
2. 有些地名查询不到信息,例如:张家界
3. 地名只接受拼音,不支持汉字,编程实现较国内的一些天气查询麻烦。

 回复 引用 查看   
#9楼[楼主] 2010-04-30 13:11 Jack Fan      
@Wuya
恩,的确如此。不知道你能不能分享一些国内的天气查询API或者接口?呵呵
毕竟,以后大家都会用到,谢谢。

 回复 引用 查看   
#10楼 2010-04-30 17:50 Wuya      
@Jack Fan
国内似乎没有提供查询天气API的网站,
我看其他的介绍基本都是提交url,然后分析网页取结果的。

 回复 引用 查看   
#11楼 2010-04-30 18:32 Jake Lin      
做图片那个我也做过,.net compact framework真的很麻烦,一个图片需要一次请求,在.net framework一次搞定。
 回复 引用 查看   
#12楼[楼主] 2010-04-30 22:02 Jack Fan      
@Jake Lin
4242~~~~~~~~~

 回复 引用 查看   
#13楼 2010-05-01 10:04 egmkang      
Google天气的确不准确
中国只有大约400个比较大的城市,其他的都是比较小的,所以有些查不出来是有可能的.
而且Google的API还可以用GPS坐标查询

 回复 引用 查看   
#14楼 2010-05-01 10:05 egmkang      
其实图片不需要的啊
天气么,就那么几种,你可以把拿下来的天气保存在本地,以后先看本地有没有,速度也会快很多哈

 回复 引用 查看   
#15楼[楼主] 2010-05-01 12:00 Jack Fan      
@egmkang
对对,可以用坐标比较有意思,比如户外运动爱好者,就可以用坐标来查查,对于那个图片也是,只要在本地内建好相应的图片,直接调用即可。
谢谢关注!

 回复 引用 查看   
#16楼 2010-05-06 12:02 楊彬      
請問google.com被封了,這些API還是能用嗎?
 回复 引用 查看   
#17楼[楼主] 2010-05-06 12:35 Jack Fan      
@楊彬
能!文章中的例子就是使用它,但是具体是被重定向到哪个地方,就不得而知了。

 回复 引用 查看   
#18楼 2010-07-26 11:58 MichaelWu      
LZ,那个我返回的是us,怎么才能返回zh-CN啊
 回复 引用 查看   
#19楼 2010-08-29 14:40 Engineer      
新浪的不错。
 回复 引用 查看   
#20楼[楼主] 2010-08-29 17:06 Jack Fan      
@MichaelWu
你好,具体的我没有试过,不过有个思路就是,在UserAgent里面加入地理信息,也许会有用哦

 回复 引用 查看   
#21楼[楼主] 2010-08-29 17:07 Jack Fan      
@Engineer
恩是吗?我去看看吧,谢啦,嘿嘿

 回复 引用 查看   
#22楼 2010-09-02 12:24 Engineer      
楼主回复邮件会提示,这个不错