天気情報を取得できる目途がたったので、今度は天気情報をゲームに反映するための取得ルーチンを作る。
テスト用に作ったプログラムがあるので、それを整えつつ使う。
メインのソースにコピーしてもよかったのだが、長くなるし見づらいので、#includeで読み込んでおき、gosubでルーチンとして呼び出すようにした。
流れはこんな感じ。
- 天気予報を取得する国をランダムに決める
- 国情報DBから、wttr.inにリクエストするクエリ文字列を取得する
- wttr.inからJSONフォーマットで天気情報を取得する
- 取得したJSONから天気情報を、各変数に抽出する
- 天気コードをもとに、表示する天気名などを天気情報DBから取得する
1. 天気予報を取得する国をランダムに決める
はじめは、
国情報テーブルにあるレコード番号のMAX値をSELECT文で取得
→ 乱数で国番号を決める
→ 乱数で決めた国番号のレコードをSELECT文で取得
しようと思っていた。
2回SQLを実行するのは馬鹿らしいのと、国番号が将来的に連番にならない可能性もあった。
なので、簡単に乱数では決められない。
調べると、SQLite側でうまくできそうだった。
SQLの並べ替えを行うORDER BY句で、RANDOM()関数を使えるようだ。
こんなSQL文を実行すると、ランダムで一行だけ取得できる。これで一発解決♪
select * from CountryTable Where DelFlg=0 Order by RANDOM() LIMIT 1;
2. 国情報DBから、wttr.inにリクエストするクエリ文字列を取得する
国情報DBには、前回のエントリーで書いた通り、wttr.inにリクエストするクエリ文字列をあらかじめセットしているので、それを取得。
例えば日本は、ikebukuroにしている。この文字列を組み合わせて、URLにする。
3. wttr.inからJSONフォーマットで天気情報を取得する
https://wttr.in/ikebukuro?format=j2 という文字列を作って、リクエストする。
リクエストのプログラムは、hspinetのサンプルプログラムをほぼ借用。
リクエストに失敗することもあるので、失敗したときの処理にジャンプもしている。
; URLを指定 url="https://wttr.in/"+ReqText+"?format=j2" httpload url if stat : goto *bad ; 正しくリクエストができなかった *get_request ; 結果待ちのためのループ httpinfo res,HTTPINFO_MODE if res = HTTPMODE_READY { gosub *comp #if DEBUG=1 stop #else return #endif } if res <= HTTPMODE_NONE : goto *bad await 50 goto *get_request
4. 取得したJSONから天気情報を、各変数に抽出する
ここはすでにテストプログラムを作成済みだったので、仮で作った変数名などを整理して、終了。
;wttr.inのJSONフォーマットを読み込んで変数に代入 jsonopen JsonPtr,buf jsongetobj Ptr,"current_condition",JsonPtr jsonnext Ptr,Ptr,2 jsongets LocalTime,"localObsDateTime",Ptr jsongets WeatherCode,"weatherCode",Ptr jsongets AirTemp,"temp_C",Ptr jsongets Humidity,"humidity",Ptr jsongets CloudCover,"cloudcover",Ptr jsongets WindDir,"winddir16Point",Ptr jsongets WindSpeed,"windspeedKmph",Ptr
5. 天気コードをもとに、表示する天気名などを天気情報DBから取得する
wttr.inでは、天気名も日本語で取得できるのだが、どうもJSONの文字コードのせいか、文字化けしたり取得できなかった。
代わりに、weathercode(天気コード)が取得できることが分かった。
このコードに対応する日本語の天気名がwttr.inのGitHubにリストで転がっていたので拝借。天気情報テーブルを作って、SQLで取得するようにした。
sql_q "select * from WeatherTable where WeatherCode="+WeatherCode WeatherName=sql_v("WeatherName")
今は天気名だけだが、天気によって発生するギミック用のフラグも、後々設定してく。