OpenWeatherMap JSON API v2.5(Androidからの利用方法メモ)

OpenWeatherMAP JSON API v2.5のAndroidからの利用方法メモ。

※ 2013/7/2 : API v2.5の情報に更新 
※ 2014/7/7 : APIキーについて追記
※ 2016/3/6 : 情報を更新, LibraryProjectを追記

本家：http://openweathermap.org/API
2016/3/6時点の最新はv2.5

OpenWeatherMapは世界中の天気情報（現在の天気、1週間分の天気予報等）を取得できるWebサービスです。

2012/8/末にGoogleの非公開APIだったGoogle Weather APIの稼働が停止したため、代わりのAPIを探していましたが、こちらのAPIが一番使い勝手がよさそうでした。

## 特徴
### APIキーを取得すれば無料で使用できる
※APIキーの取得が必須になったようです（2014/7/7）。

APIキーを取得することで無料で使用できますが、以下の注意があります。

*１つのデバイスからのリクエストは10分に１回に抑える
*リクエスに失敗したら10分間は再リクエストを控える（なるべく直前の情報を保持しておく）
http://openweathermap.org/appid#get

有料版との違いは以下を参照してください。
フリー版では１分間に60リクエストまでと制限があります。
http://openweathermap.org/price

また、日別の天気予報(最大16日分)もFreeでは制限されています。
（2016/3/6現在、FreeのAPIキーでも取得できていますが...)

#### APIキー（APPID）の取得
以下から、ユーザー名、パスワード、メールアドレスを入力後、「Create Account」ボタンを押下します。
ログイン先のページにキーが表示れます。
入力したアドレスへの登録確認等はありませんでした。
http://home.openweathermap.org/users/sign_up

### 経度・緯度で検索できる
Google Weather API同様に経度・緯度をパラメータとして天気情報を取得することができます。
その他、地名・地名ID・観測ステーションIDをもとに取得が可能です。

### 最大16日分の天気予報が取得できる
Google Weather APIでは4日分の予報でしたが16日分も取得できます。
しかも、5日分の予報であれば、3時間ごとの情報です。
(Freeプランでは5日分・3時間ごとの予報のみが有効となっていますが、
 2016/3/6現在は日別の予報も取得できています)

## 使い方
### 経度・緯度での取得
以下で札幌市役所付近の天気情報（現在の天気）を取得できます。
`http://api.openweathermap.org/data/2.5/find?lat=43.067885&lon=141.355539&cnt=1`

lat = 緯度
lng = 経度
cnt = 取得する情報数

cntを増やすことで指定した地点に近い順にcntに指定した分の地点情報が取得できます。

### Androidからの取得
取得方法

```java:
    String requestURL = "http://api.openweathermap.org/data/2.5/find?lat=43.067885&lon=141.355539&cnt=1";
    URL url = new URL(requestURL);
    InputStream is = url.openConnection().getInputStream();

    // JSON形式で結果が返るためパースのためにStringに変換する
    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    StringBuilder sb = new StringBuilder();
    String line;
    while (null != (line = reader.readLine())) {
        sb.append(line);
    }
    String data = sb.toString();

```

取得結果（JSON形式）

```json:
{"message":"Model=GFS-OWM, ","cod":"200","calctime":" mysql = 0.0041 mongo = 0.0006 center = 0.0232 total=0.0279","cnt":1,"list":[
    {"id":2128295,
     "name":"Sapporo-shi",
     "coord":{"lon":141.346939,"lat":43.064171},
     "distance":0.812,
     "main":{"temp":270.67,"humidity":19,"pressure":1016,"temp_min":269.82,"temp_max":271.48},
     "dt":1356758295,
     "wind":{"speed":0.51,"gust":1.03,"deg":61},
     "rain":{"1h":0,"24h":0,"today":0},
     "clouds":{"all":57},
     "weather":[
        {"id":803,
         "main":"Clouds",
         "description":"broken clouds",
         "icon":"04d"}
    ]}
]}
```

| パラメータ | 説明 |  
|:-------|:--------|
| id | 地点ID |
| name | 地点名 |
| main.temp | 現在の気温（単位：K（ケルビン）） |
| main.humnidity | 湿度（単位：％） |
| main.pressure | 気圧（単位：hPa） |
| main.temp_min | 最低気温（単位：K（ケルビン）） |
| main.temp_max | 最高気温（単位：K（ケルビン）） |
| dt | 取得時の時間（UNIX時間） |
| rain.today | 降水量（単位：mm） |
| snow.today | 降雪量（単位：mm） |
| clouds.all | 雲量（単位：％） |
| weather.id | 天気ID |
| weather.main | 天気 |
| weather.description | 詳細な天気 |
| weather.icon| 天気アイコンID |

### 結果のパース
結果はJSON形式で返るため、JSONObjectクラスを利用してパースします。

```java:
	try {
		JSONObject rootObj = new JSONObject(data);
		JSONArray listArray = rootObj.getJSONArray("list");
			
		JSONObject obj = listArray.getJSONObject(0);
			
		// 地点ID
		int id = obj.getInt("id");
			
		// 地点名
		String cityName = obj.getString("name");
			
		// 気温(Kから℃に変換)
		JSONObject mainObj = obj.getJSONObject("main");
		float currentTemp = (float) (mainObj.getDouble("temp") - 273.15f);
		
		float minTemp = (float) (mainObj.getDouble("temp_min") - 273.15f);
			
		float maxTemp = (float) (mainObj.getDouble("temp_max") - 273.15f);

		// 湿度
		if (mainObj.has("humidity")) {
			int humidity = mainObj.getInt("humidity");
		}
			
		// 取得時間
		long time = obj.getLong("dt");
			
		// 天気
		JSONArray weatherArray = obj.getJSONArray("weather");
		JSONObject weatherObj = weatherArray.getJSONObject(0);
		String iconId = weatherObj.getString("icon");
	} catch (JSONException e) {
		e.printStackTrace();
	}
```

### 天気アイコンの取得
天気アイコンも提供されているため、取得結果の天気アイコンIDのを使用して取得することができます。

以下のURLで取得できます。
`http://openweathermap.org/img/w/04d.png`
※04dは、取得したJSONのiconキーで取得した文字列に置き換えてください

Bitmapオブジェクトは以下で取得できます。

```java:
	try {
		String requestUrl = "http://openweathermap.org/img/w/04d.png";
		URL url = new URL(requestUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoInput(true);
		conn.connect();
		BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
		icon = BitmapFactory.decodeStream(in);
		in.close();
		conn.disconnect();
	} catch (IOException e) {
		e.printStackTrace();
	}
```

### APIキー（APPID）の使用

取得したAPIキーは、以下のように使用します。
`http://api.openweathermap.org/data/2.5/find?lat=43.067885&lon=141.355539&cnt=1&APPID=1111111111`
※1111111111を取得したキーに置き換えます

### ライブラリープロジェクト

OpenWeatherMapのAPIのラッパーを以下で公開しています。
https://github.com/kubotaku1119/OpenWeatherMapLib

AndroidStudioに依存関係を記載することで利用できますので、動作確認等にご利用下さい。
※ APIキーはご自分で取得してください。

```
repositories {
    maven { url 'http://raw.github.com/kubotaku1119/OpenWeatherMapLib/master/repository/' }
}

dependencies {
    compile 'com.kubotaku:openweathermap-lib:0.1.3'
}
```