PHPでオープンデータ・気象庁天気予報データを使ってみよう!

PHP
スポンサーリンク

気象庁天気予報データを使ってみよう!

気象庁のデータは、オープンデータとして商用利用も可能です。利用前には「気象庁のホームページについて」をご覧下さい。

関係者に気象予報士がいない場合は、「独自天気予報」は出来ません

オープンデータを利用した郵便番号検索サイトを作ってみました。
住所から郵便番号だけで無く地図の表示と気象庁からの天気予報データを表示するサイトになっています。
ZIP 郵便番号検索

郵便番号データと住所の緯度経度データは、csvファイルになっているのでデータベース化して利用出来ると思います。分からない方は、下記参照

PHPでCSVファイルの読み込み
CSVファイルの読み込み .csvファイルは、「,」等の区切り文字で区切られたデータファイルの事です。 リンゴ,バナナ,みかん 区切り文字は、一般的に半角カンマやスペース等が使われるが特に決まっていないので好きな物を指定出来ます。 ...
ConoHa+PHP+mysqlデータベース構築
ConoHaWINGデータベース作成 以前DockerでPHP+MySQL環境構築をしましたが レンタルサーバーのConoHaWINGのmysqlデータベースをPHPで使って見ました。 データベース作成 ①サイト管理をク...

今回は気象庁のデータを使って見たいと思います。天気予報データは、jsonファイルになっているのでPHP+jsonの扱い方を確認していきましょう。

エリア情報の取得

全て配列に入れる方法

json_decodeの第2引数を「true」にする事で配列として取り込めます。
file_get_contentsは、バイナリデータも取り込めるので便利です。
・<pre></pre>タグで囲んでprint_rすると構造化されて見やすくなります。
$url = 'https://www.jma.go.jp/bosai/common/const/area.json';
$json = file_get_contents($url);
$jarr = json_decode($json, true);
echo '<pre>';
print_r($jarr);
echo '</pre>';
//実行結果
Array
(
    [centers] => Array
        (
            [010100] => Array
                (
                    [name] => 北海道地方
                    [enName] => Hokkaido
                    [officeName] => 札幌管区気象台
                    [children] => Array
                        (
                            [0] => 011000

全て配列に格納されるので「札幌管区気象台」を取得するには以下のようになります。

echo $jarr['centers']['010100']['officeName'];
連想配列になっているのでキー名を角括弧+シングルまたはダブルクォーテーションで囲います。
[children]の[0]の値「011000」は
echo $jarr['centers']['010100']['children'][0];
または、
echo $jarr['centers']['010100']['children']['0']
キーが単なる数字として扱える場合は、角括弧のみで結構です。
もちろん、シングルまたはダブルクォーテーションで囲ってもOKです。

オブジェクト(一部配列)として使う方法

json_decodeの第2引数を「false」又は省略する事でオブジェクトとして取り込めます。
file_get_contentsは、バイナリデータも取り込めるので便利です。
・<pre></pre>タグで囲んでprint_rすると構造化されて見やすくなります。
$url = 'https://www.jma.go.jp/bosai/common/const/area.json';
$json = file_get_contents($url);
$jobj = json_decode($json);
echo '<pre>';
print_r($jobj);
echo '</pre>';
//実行結果
stdClass Object
(
    [centers] => stdClass Object
        (
            [010100] => stdClass Object
                (
                    [name] => 北海道地方
                    [enName] => Hokkaido
                    [officeName] => 札幌管区気象台
                    [children] => Array
                        (
                            [0] => 011000

オブジェクトに格納されるので「札幌管区気象台」を取得するには以下のようになります。

echo $jobj->centers->{'010100'}->officeName;
オブジェクトの中にある、 PHP の命名規約では使えない文字 (ハイフンなど) を含む要素や数字から始まる要素名にアクセスするには、 要素名を波括弧+シングルまたはダブルクォーテーションで囲わ無ければならない。

ファイルとして保存してみる

・ファイルの読み込みは、file_get_contents
・ファイルの書き込みは、file_put_contentsで行っています。
$filename = 'area.json';
  if(file_exists($filename)){
  $json = file_get_contents($filename);
}else{
  $url = 'https://www.jma.go.jp/bosai/common/const/area.json';
  $json = file_get_contents($url);
  if($json !== false){
    file_put_contents($filename,$json);
  }
}
$jarr = json_decode($json, true);

CSVファイルとして保存してみる

・jsonファイルは、階層が深くなると見辛くなるのでcsvに変換
<?php
  //ini_set('display_errors', 0);
  $st = microtime(true);
  $url = file_get_contents('https://www.jma.go.jp/bosai/common/const/area.json');
  $jarr = json_decode($url, true);
  // echo '<pre>';
  // print_r($jarr);
  // echo '</pre>';
  $path = 'tenki.csv';
  $fhw = @fopen($path, "wb");
  foreach($jarr as $key1=>$arr1){
    foreach($arr1 as $key2=>$arr2){
      $csv=$key1.','.$key2;
      foreach($arr2 as $key3=>$arr3){
        if(is_array($arr3)){
          $csv .= ',';
          foreach($arr3 as $arr4){
            $csv .= $arr4.' ';
          }
          $csv = rtrim($csv);
        }else{
          $arr3 = str_replace(', ', ':', $arr3);
          $csv .= ','.$arr3;
        }
      }
      @fwrite($fhw, $csv . "\n");
      //echo $csv.'<br />';
    }
  }
  @fclose($fhw);
  $end = microtime(true);
  echo '処理時間:'.($end - $st)."秒<br />";
csvファイルにすると分かり易くなったと思います。
centers,offices,class10s,class15s,class20s
の5つのグループに分けられています。class20sから見ていくと分かりやすいと思います。

千代田区を例に見てみましょう。class20sの次の7桁の数字の上5桁が市区町村に付けられている行政コードです。天気予報データにはofficesの次の6桁の数字(エリアコード)が必要になります。

class20s,1310100,千代田区,Chiyoda City,ちよだく,130011

class15s,130011,23区西部,Western Region of 23 wards,130010,1310100 1310200 1310300 1310400 1310500 1310900 1311000 1311100 1311200 1311300 1311400 1311500 1311600 1311700 1311900 1312000

class10s,130010,東京地方,Tokyo Region,130000,130011 130012 130013 130014 130015

offices,130000,東京都,Tokyo,気象庁,010300,130010 130020 130030 130040

単に住所から天気予報を取得したい場合は、class20sの1310100の5桁とofficesの130000をデータベース化すれば良いだけです。

行政コード⇨エリアコード

・class20sの上5桁とofficesの6桁を対応させます。
<?php
 //ini_set('display_errors', 0);
 $st = microtime(true);
 $filename = 'area.json';
 $folder = './tenki/';
 $path = $folder.$filename;
 if(file_exists($path)){
  $json = file_get_contents($path);
 }else{
  $url = 'https://www.jma.go.jp/bosai/common/const/area.json';
  $json = file_get_contents($url);
  if($json !== false){
   file_put_contents($path,$json);
  }
 }
 $jarr = json_decode($json, true);
 //echo '<pre>';
 //print_r($jarr);
 //echo '</pre>';
 $c20 = $jarr['class20s'];
 $c15 = $jarr['class15s'];
 $c10 = $jarr['class10s'];
 $off = $jarr['offices'];
 $cen = $jarr['centers'];
 //print_r(array_keys($c20));
 $filename = 'gtoacode.csv';
 $path = $folder.$filename;
 $fhw = @fopen($path, "wb");
 $garry = array();
 foreach($c20 as $key => $value){
  $gcode = mb_substr($key,0,5);
  $pa20 = $value['parent'];
  $pa15 = $c15[$pa20]['parent'];
  $pa10 = $c10[$pa15]['parent'];
  if(!in_array($gcode,$garry)){
   array_push($garry,$gcode);
   //echo $gcode.','.$pa10."<br />";
   $csv = $gcode.','.$pa10."\n";
   @fwrite($fhw, $csv);
  }
 }
 @fclose($fhw);
 $end = microtime(true);
 echo '処理時間:'.($end - $st)."秒<br />";

天気予報(明後日までの)jsonの取得

東京の場合は、以下のようにエリアコードは’130000‘になります。
$acode = '130000';
$url = 'https://www.jma.go.jp/bosai/forecast/data/forecast/'.$acode.'.json';
$json = file_get_contents($url);
$jarr = json_decode($json, true);
echo '<pre>';
print_r($jarr);
echo '</pre>';
・offices 014030 ⇨ 014100
・offices 460040 ⇨ 460100
に変更します。(404NotFoundになってしまうので)

 

 

 

タイトルとURLをコピーしました