『openframeworks』天气预报查询

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

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

可以参考这片文章,对这个接口的介绍还蛮全面的: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){			//解析字符串,把数据存入vector
	wstring::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转wstring

	int 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;
}
最后还是一样,我们依次将它们画出来!效果如下,凑合看吧。


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


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值