今いる場所の天気予報 [2012-03-25 追記]

今いる場所の天気予報 [2012-03-25 追記] #

空を見上げよう
風を感じよう

ってのが正解なんだろうけど、やってみたくなったので、やってみよう
いろんな WEB API が公開されているので、それを使う

スマートフォン + HTML + JavaScript でやればいいかなぁと思ったんだけど、XMLHttpRequest の制限があったり、途中で手こずったりしたので、もう結論だけ書く

以上。

以下、書きかけて整理するのがしんどくなったけど消すのももったいないしなぁ、という理由で放置する文章

2012-03-25 追記
探してみたが、やっぱり Yahoo! Weather のきれいな api はみつからん。無念
仕方ないのでこれでいったんあきらめて、HeartRails のところをちょっと書きなおして終了ー

位置情報を取得 #

位置情報使おうと思ったら「navigator.geolocation」。昔は位置情報遊びがしたいために携帯電話機種変更したり色々ありましたが、今は W3C が「Geolocation API 」とか策定してるので、あまり気にしなくていいんでしょうね、多分

では、まずは現在値の緯度と経度を取得してみましょう

«実行 >

<script>
  navigator.geolocation.getCurrentPosition(
    function (g) {
      var lat = g.coords.latitude;
      var lon = g.coords.longitude;
      alert( 'lat: ' + lat +   lon: ' + lon );
    },
    function (e) {
      switch (e.code) {
      case 1:
        alert('Permission denied. Plz check settings.');
        break;
      case 2:
        alert('Location info is unavailable.');
        break;
      case 3:
        alert('Timeout.');
        break;
      default:
        alert('Sorry, but unknown error is available.');
      break;
      };
    },
    {
      enableHighAccuracy: true
    }
  );
</script>

位置情報から、地域情報を取得 #

緯度・経度からそのまま天気予報を取得できればいいんですが、よさげな API も見当たらなかったので、都市名とか郵便番号とか、そういう「地域」を特定できる情報を取得してみましょう
HeartRails Geo API 」を使います
jsonp 関連は、jquery を使って楽をするってことで

  navigator.geolocation.getCurrentPosition(
    function (g) {
      var lat = g.coords.latitude;
      var lon = g.coords.longitude;
      alert( 'lat: ' + lat + '  lon: ' + lon );

      //HeartRails Geo API で、緯度経度情報→地域情報
      var uri = 'http://geoapi.heartrails.com/api/json';
      $.getJSON(uri+'?method=searchByGeoLocation&x='+lon+'&y='+lat+'&jsonp=?',
        function(area){
          alert( JSON.stringify(area) );
        });

    },
    function (e) {
      switch (e.code) {
      case 1:
        alert('Permission denied. Plz check settings.');
        break;
      case 2:
        alert('Location info is unavailable.');
        break;
      case 3:
        alert('Timeout.');
        break;
      default:
        alert('Sorry, but unknown error is available.');
      break;
      };
    },
    {
      enableHighAccuracy: true
    }
  );

こんな感じのデータが取得できる

{
  "response":{
    "location":[
      {"city":"大阪市","city_kana":"おおさかし","town":"ホゲホゲ","town_kana":"ほげほげ","x":"135","y":"34","distance":672,"prefecture":"大阪府","postal":"5610000"},
      {"city":"大阪市","city_kana":"おおさかし","town":"フガフガ","town_kana":"ふがふが","x":"135","y":"34","distance":672,"prefecture":"大阪府","postal":"5610001"}
    ]}}

«サンプル »

地域情報から天気予報を取得 #

地域情報として、いくつか候補が取得できました。次は「Yahoo! Weather 」が、郵便番号から天気予報を取得できるので、そこを使いましょうそうしましょう
地域情報はいくつか取得できましたが、こんなものは大体でいいので、配列の一個目の postal を使います

。。。で、だ
「Yahoo! Weather」では、郵便番号で検索すると天気予報が表示されるのは確かなんだけど、

  1. 郵便番号: 5300001
  2. 天気予報ページ: http://weather.yahoo.com/japan/osaka-prefecture/osaka-shi-26281340/
  3. 天気予報 RSS: http://weather.yahooapis.com/forecastrss?p=JAXX0071&u=f
    みたいになっているので、なんとかして 1. と 2. もしくは 3. とを結び付けたい。簡単そうなのは 1. → 3. なので、そっちにチャレンジ。5300001 から JAXX0071 を取得したいな、と

ここの過程は 1 時間くらいかかったので、間のもろもろは省略して、結論だけ書きます

http://weather.yahoo.com/locationWidget/widget/htdocs/locationWidget.php?location=5300001&appId=us_weather

JSON っぽいものが返ってきます

{
  "status":"0",
  "locations":{
    "id" : "26281340",
    "city" : "大阪市",
    "state" : "大阪府",
    "country" : "JP"
  },
  "html":"..."}
<!-- fe3.weather.sp2.yahoo.com compressed/chunked Sat Mar 17 22:44:36 PDT 2012 -->
  • Yahoo 的には「html: 」のところの html をそのまま使って欲しいんだろうけど、今回欲しいのは locations.id=26281340 の部分
  • お尻にコメントとかついてるので、これを除去しないと JSON として扱えない

で、取得した id を使って

http://weather.yahooapis.com/forecastjson?w=26281340

今度はちゃんと JSON が返ってくる。やっと使える!

{
  "units": {
    "temperature":"F",
    "speed":"mph",
    "distance":"mi",
    "pressure":"in"
  },
  "location": {
    "location_id":"JAXX0071",
    "city":"Osaka",
    "state_abbreviation":"*",
    "country_abbreviation":"JA",
    "elevation":33,
    "latitude":34.78000000000000,
    "longitude":135.44999999999999
  },
  "wind": {
    "speed":12.00000000000000,
    "direction":"NNW"
  },
  "atmosphere": {
    "humidity":"75",
    "visibility":"6.21",
    "pressure":"30.09",
    "rising":"steady"
  },
  "url":"http:\\/\\/weather.yahoo.com\\/forecast\\/JAXX0071.html",
  "logo":"http:\\/\\/l.yimg.com\\/a\\/i\\/us\\/nt\\/ma\\/ma_nws-we_1.gif",
  "astronomy": {
    "sunrise":"06:16",
    "sunset":"18:01"
  },
  "condition": {
    "text":"Partly Cloudy",
    "code":"29",
    "image":"http:\\/\\/l.yimg.com\\/a\\/i\\/us\\/we\\/52\\/29.gif",
    "temperature":39.00000000000000
  },
  "forecast": [
    {
      "day":"Today",
      "condition":"Clear",
      "high_temperature":"47",
      "low_temperature":"38"
    },{
      "day":"Tomorrow",
      "condition":"Showers",
      "high_temperature":"49",
      "low_temperature":"39"
    }
  ]
}

See Also

Copyright © 髭。/ Hugo + hugo-book