無料天気予報APIのOpenWeatherMapを使ってみる


はじめに

プログラムから天気予報をとるために、無料で開発者用APIを提供しているOpenWeatherMapを使ってみました。

概要

OpenWeatherMapはAPIだけのサービスというわけではなくGUIでも天気を取得できます。トップページにデカデカ「Current weather and forecasts in your city」と書いてあり、地名を入れると天気予報を表示してくれます。

これは普通に便利ですね

とは言いつつもメインはAPIみたいです。APIを使うには登録してAPI Keyを取得する必要があります。

値段

無料プランを始めとして、いくつかプランがあります。

無料のFreeプランだと5日後までの3時間毎の天気予報を取得できて、1分間に60回までAPIコールできます。月180ドルのDeveloperプランでは3000 calls/分までOKで、16日後までの天気予報を取得することができます。

API Keyの取得

API Keyを取得するにはアカウントを作る必要があります。Sign Upページで必要な項目を入力して「Create Account」します。

そうすると次の画面でAPI Keyが表示されるはずです。

天気予報を取得する

Rubyで天気予報を取得してみます。単純にAPIを試してみたいだけなら全然まったくRubyである必要はなく、curlコマンドとかを使った方が簡単だと思います。

基本はapi.openweathermap.org/data/2.5/forecastというエンドポイントにパラメータを付け足してリクエストします。

都市名を指定する

まずは都市名を指定して天気予報を取得してみます。
都市はqというパラメータで指定します。API KeyはAPPIDというパラメータで指定します。

API_KEY = "YOUR API KEY"
BASE_URL = "http://api.openweathermap.org/data/2.5/forecast"

require "json"
require "open-uri"

response = open(BASE_URL + "?q=Akashi-shi,jp&APPID=#{API_KEY}")
puts JSON.pretty_generate(JSON.parse(response.read))

明石焼きが食べたい気分なので明石を指定してみました。実行結果は次のようになります。

{
  "city": {
    "id": 1850924,
    "name": "Takatorichō",
    "coord": {
      "lon": 135.133331,
      "lat": 34.650002
    },
    "country": "JP",
    "population": 0,
    "sys": {
      "population": 0
    }
  },
  "cod": "200",
  "message": 0.0272,
  "cnt": 34,
  "list": [
    {
      "dt": 1456941600,
      "main": {
        "temp": 277.58,
        "temp_min": 273.421,
        "temp_max": 277.58,
        "pressure": 1022.93,
        "sea_level": 1038.49,
        "grnd_level": 1022.93,
        "humidity": 71,
        "temp_kf": 4.15
      },
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "clear sky",
          "icon": "01n"
        }
      ],
      "clouds": {
        "all": 0
      },
      "wind": {
        "speed": 3.67,
        "deg": 239.002
      },
      "rain": {
      },
      "snow": {
      },
      "sys": {
        "pod": "n"
      },
      "dt_txt": "2016-03-02 18:00:00"
    },
    ...
  ]
}

Takatorichōってのがどこかわかりませんが、経度が135度になってるのでだいたい明石付近の天気はとれてるようです。多分。

listプロパティの値が配列になっていて、3時間ごとの天気予報が格納されています。
レスポンスの細かい内容はドキュメントを参照してください。

city IDを指定する

このようにqパラメータで都市名を指定すると曖昧性があるので、OpenWeatherMapはcity IDというものでリクエストすることを推奨しています。
city IDの一覧は次のURLからダウンロードできます。city.list.json.gzですね。3.8MBあります。

残念ながら明石のcity IDはないらしいので、かわりに神戸の天気予報をcity IDで取得してみます。神戸のcity IDは1859171です。

city IDはidパラメータで指定します。

# 省略
response = open(BASE_URL + "?id=1859171&APPID=#{API_KEY}")
puts JSON.pretty_generate(JSON.parse(response.read))

結果は載せませんが、うまく取得できてるみたいです。

緯度経度を指定する

明石の天気予報が取れないままでは悔しいので緯度と経度を指定して天気予報を取得してみます。

天文科学館の緯度と経度を指定します。天文科学館はWikipediaによると北緯34度、東経135度にあります。

緯度はlat、経度はlonパラメータで指定できます。

# 省略
response = open(BASE_URL + "?lat=34&lon=135&APPID=#{API_KEY}")
puts JSON.pretty_generate(JSON.parse(response.read))

さあどうでしょう。

{
  "city": {
    "id": 1848131,
    "name": "Yuasa",
    "coord": {
      "lon": 135.183334,
      "lat": 34.033329
    },
    "country": "JP",

うーーーん、どこやねん。

郵便番号を指定する

まだまだ諦められません。最後に郵便番号を指定してみます。これなら間違いないはず!

郵便番号はzipパラメータに郵便番号と国コードを指定します。

天文科学館がある人丸町の郵便番号である673-0877を指定します。

# 省略
response = open(BASE_URL + "?zip=673-0877,JP&APPID=#{API_KEY}")
puts JSON.pretty_generate(JSON.parse(response.read))

結果は…。

{
  "city": {
    "id": 1847966,
    "name": "Akashi",
    "coord": {
      "lon": 134.983337,
      "lat": 34.633331
    },
    "country": "JP",

やった!!ついに取れました!!
なんとcity IDもわかったのでこれからは苦労することなくcity IDで明石の天気予報を取得することができます。

おわりに

OpenWeatherMapを使うととても簡単に天気予報をとってくることができます。
天気を予報したいときにいかがでしょうか。