『openframeworks』天气预报查询

来源:互联网 发布:剑灵杨幂捏脸数据 编辑:程序博客网 时间:2024/05/22 08:19

之前有需要要做一个天气预报查询的程序,在网上也找了很多别人的程序试了试,发现很多都不怎么好使。

最近研究了一下,发现也不是很难。首先,必须找到一个好一点的接口。在网上搜索发现,国家气象局提供的接口好像还不错。

可以参考这片文章,对这个接口的介绍还蛮全面的:http://www.weste.net/2012/8-23/84850.html

通过接口,我们试试打开武汉的链接,可以看到以下数据:

{"weatherinfo":{"city":"武汉","cityid":"101200101","temp":"23","WD":"东风","WS":"2级","SD":"52%","WSE":"2","time":"15:20","isRadar":"1","Radar":"JC_RADAR_AZ9270_JB"}}

可以发现他采用的是Json格式保存的信息。

这里我尝试用两种方法来进行处理。


1.自己来解析这些数据,这里我试了解析实时的简单的天气信息。效果如下:


首先,我们需要定义一个地址的查询接口URL:

以武汉为例,我们可以实时查询其信息,在update函数中实现如下:

void testApp::update(){if(ofGetElapsedTimef() - timeMark > 600.0f){//每10分钟更新一次数据string url = "http://www.weather.com.cn/data/sk/101200101.html";//武汉天气的接口地址ofHttpResponse response = ofLoadURL(url);if(response.status == 200) {char* pBuffer = response.data.getBinaryBuffer();//得到相关的天气信息保存到char*中wchar_t wPathname[512] = {0};int len = MultiByteToWideChar(CP_UTF8, NULL, pBuffer, -1, NULL, 0);MultiByteToWideChar(CP_UTF8, 0, pBuffer, -1, wPathname, len);//转换成wchar_t*if(wcscmp(wPathname, weatherInfo) != 0){memset(weatherInfo, 0, 512);memcpy(weatherInfo, wPathname, 512);if(wcscmp(weatherInfo, wPathname) == 0) {wcout<<L"天气信息更新!\n";//信息有变化,进行解析infoVec = splitWstring(weatherInfo);// string city, temp, WD, WS, SD, time;city = getInfo(L"city");temp = getInfo(L"temp");SD = getInfo(L"SD");wstring WD = getInfo(L"WD");wstring WS = getInfo(L"WS");time = getInfo(L"time");wind = wcscat(const_cast<wchar_t*>(WD.c_str()), WS.c_str());}}else{wcout<<L"天气信息无变化!\n";}}timeMark = ofGetElapsedTimef();}}
这里根据得到数据的格式,写的解析函数splitWstring,得到保存有数据的vector:

vector<wstring> testApp::splitWstring(wstring s){//解析字符串,把数据存入vectorwstring::size_type pos = 0, pre_pos = 0;wstring tmpWstring;vector<wstring> tmpVec;while( (pre_pos = s.find_first_of(L'\"', pre_pos)) != wstring::npos ){if( (pos = s.find_first_of(L'\"', pre_pos+1)) == wstring::npos ){break;}tmpWstring = s.substr(pre_pos+1, pos-pre_pos-1);tmpVec.push_back(tmpWstring);pre_pos = pos+1;}return tmpVec;}
<pre code_snippet_id="197469" snippet_file_name="blog_20140221_4_7379237" name="code" class="cpp">//得到相应的信息wstring testApp::getInfo(const wstring index){//由于相关的信息在key的下一个存储,所以直接取出来即可for(vector<wstring>::iterator iter = infoVec.begin(); iter != infoVec.end() - 1; iter++) {if(wcscmp(index.c_str(), (*iter).c_str()) == 0) {return *(iter+1);}}return NULL;}


最后,在得到数据后,我们直接画出来就OK了:
void testApp::draw(){bgImg.draw(0, 0, 240, 400);if(city.size() != 0) {//地点font_ado.drawString(city, 80, 300);//显示实时温度font.drawString(temp, 25, 150);font.drawString(L"℃", 105, 150);//显示风向,风力font_wind.drawString(wind, 30, 70);//显示湿度font_wind.drawString(L"湿度", 30, 85);font_wind.drawString(SD, 60, 85);//更新时间font_time.drawString(L"更新时间", 160, 390);font_time.drawString(time, 200, 390);}}wstring testApp::getInfo(const wstring index){//由于相关的信息在key的下一个存储,所以直接取出来即可for(vector<wstring>::iterator iter = infoVec.begin(); iter != infoVec.end() - 1; iter++) {if(wcscmp(index.c_str(), (*iter).c_str()) == 0) {return *(iter+1);}}return NULL;}


2.第二种方法,解析我用的别人封装好的Json解析方法。

就是这位大神的作品:https://github.com/jefftimesten/ofxJSON

OK,走起,先把它加到of中。

通过Json我们能容易的得到相关信息,如下:

string url_ = "http://m.weather.com.cn/data/101200101.html";bool parsingSuccessful = dateJson.open(url_);<span style="white-space:pre"></span>//Json解析if(parsingSuccessful) {date = dateJson["weatherinfo"]["date"].asString();<span style="white-space:pre"></span>//得到相关信息date_y = dateJson["weatherinfo"]["date_y"].asString();week = dateJson["weatherinfo"]["week"].asString();index = dateJson["weatherinfo"]["index"].asString();index_d = dateJson["weatherinfo"]["index_d"].asString();index_uv = dateJson["weatherinfo"]["index_uv"].asString();index_xc = dateJson["weatherinfo"]["index_xc"].asString();index_tr = dateJson["weatherinfo"]["index_tr"].asString();index_cl = dateJson["weatherinfo"]["index_cl"].asString();index_ls = dateJson["weatherinfo"]["index_ls"].asString();index_ag = dateJson["weatherinfo"]["index_ag"].asString();for(int i=1; i<=6; i++){string a, b, c;a = "temp" + ofToString(i);b = "weather" + ofToString(i);c = "wind" + ofToString(i);temps[i-1] = dateJson["weatherinfo"][a].asString();weatheres[i-1] = dateJson["weatherinfo"][b].asString();winds[i-1] = dateJson["weatherinfo"][c].asString();}}

最后把string转成wstring,我们就能正确的去显示中文的信息了:

//设置区域
std::wcout.imbue(std::locale("CHS"));

wchar_t* testApp::stringToWstring(string src) {  //string转wstringint len = src.size();int wcslen = ::MultiByteToWideChar(CP_UTF8, NULL, src.c_str(), len, NULL, 0);wchar_t* wszString = new wchar_t[wcslen + 1];::MultiByteToWideChar(CP_UTF8, NULL, src.c_str(), len, wszString, wcslen);wszString[wcslen] = L'\0';return wszString;}
最后还是一样,我们依次将它们画出来!效果如下,凑合看吧。


春雨惊春清谷天,
夏满芒夏暑相连。
秋处露秋寒霜降,
冬雪雪冬小大寒
上半年是六廿一,
下半年是八廿三。
每月两节日期定,
最多只差一两天。

	
				
		
原创粉丝点击