PHPで地図で指定した場所の天気予報を求める

(1/1)
PHPで天気予報を求める」で紹介した気象庁の「気象庁防災情報XML」を利用し、地図サービスをクラウド連携することで、住所やランドマークから週間天気予報を表示するPHPプログラムを作ってみる。

(2024年11月9日)予報地点情報ファイルを更新
(2024年4月22日)京都市,熱海市など3日間しか表示されなくなった地点があり,予報地点情報ファイルを更新した.
(2023年12月30日)予報地点情報ファイルを更新
(2023年8月27日)予報地点情報ファイルを更新
(2023年8月12日)国土地理院ジオコーディングAPIを利用できるようにした.検索キーの最小・最大長が指定できるようにした.

サンプル・プログラムの実行例

PHPで地図で指定した場所の天気予報を求める
Googleマップ表示

目次

サンプル・プログラムのダウンロード

圧縮ファイルの内容
myWeather.phpサンプル・プログラム本体
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。
pahooWeather.php気象情報に関わるクラス pahooWeather。
気象情報に関わるクラスの使い方は「PHPで天気予報を求める」を参照。include_path が通ったディレクトリに配置すること。
pahooCache.phpキャッシュ処理に関わるクラス pahooCache。
キャッシュ処理に関わるクラスの使い方は「PHPで天気予報を求める」を参照。include_path が通ったディレクトリに配置すること。
jmaweatherspots.xml予報地点情報ファイル。「PHPで天気予報を求める」参照。
jmaWeatherInit.php予報地点情報ファイル作成プログラム。「PHPで天気予報を求める」参照。
myWeather.php 更新履歴
バージョン 更新日 内容
3.5.0 2023/08/12 検索キーの最小・最大長の指定
3.4.0 2023/08/12 国土地理院ジオコーディングAPIを追加
3.3 2021/04/10 キャッシュ・システム導入:pahooCacheクラス
3.2 2021/03/07 天気予報情報を気象庁防災情報XMLから取得に変更
3.1 2020/12/13 PHP8対応
jmaWeatherInit.php 更新履歴
バージョン 更新日 内容
3.1.0 2023/03/18 地域気象観測所一覧のフォーマット変更に対応
3.0.0 2023/02/11 アメダスのページから自動ダウンロード対応
2.2 2022/03/12 気象庁防災情報XMLのhttps化に対応, キャッシュ・システム導入:pahooCacheクラス
2.11 2021/03/23 bug-fix,地域観測所一覧(アメダス)を最新に
2.1 2021/03/03 天気予報(2~3日予報)に対応
pahooGeoCode.php 更新履歴
バージョン 更新日 内容
6.3.3 2024/09/14 $this->NOMINATIM_EMAIL 追加
6.3.2 2024/02/14 getStaticMap() -- bug-fix
6.3.1 2023/07/09 bug-fix
6.3.0 2023/07/02 getPointsGSI()追加
6.2.0 2023/07/02 ip2address()追加
pahooWeather.php 更新履歴
バージョン 更新日 内容
5.4.1 2023/08/12 __construct() -- 不具合修正
5.4 2023/02/11 FILE_VERSION = 2.2 に更新
5.3 2022/03/10 気象庁防災情報XMLのhttps化に対応
5.2 2021/04/08 pahoo_simplexml_loadをpahooCache::simplexml_loadへ
5.1 2021/04/02 キャッシュ・システム導入:pahooCacheクラス
pahooCache.php 更新履歴
バージョン 更新日 内容
1.1.1 2023/02/11 コメント追記
1.1 2021/04/08 simplexml_load()メソッド追加
1.0 2021/04/02 初版
pahooInputData.php 更新履歴
バージョン 更新日 内容
1.7.0 2024/10/09 validURL() validEmail() 追加
1.6.0 2024/10/07 isButton() -- buttonタグに対応
1.5.0 2024/01/28 exitIfExceedVersion() 追加
1.4.2 2024/01/28 exitIfLessVersion() メッセージ修正
1.4.1 2023/09/30 コメントの訂正

サンプル・プログラムの流れ

PHPで地図で指定した場所の天気予報を求める
プログラムの流れは「PHPで最寄り駅を求める」の時と同じで、緯度・経度から施設情報を求める部分を、「PHPで天気予報を求める」に差し替えただけである。

準備:pahooGeoCode クラス

pahooGeoCode.php

  37: class pahooGeoCode {
  38:     var $items;     //検索結果格納用
  39:     var $error;     //エラー・フラグ
  40:     var $errmsg;    //エラー・メッセージ
  41:     var $hits;      //検索ヒット件数
  42:     var $webapi;    //直前に呼び出したWebAPI URL
  43: 
  44:     //Google Cloud Platform APIキー
  45:     //https://cloud.google.com/maps-platform/
  46:     //※Google Maps APIを利用しないのなら登録不要
  47:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
  48:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
  49: 
  50:     //Yahoo! JAPAN Webサービス アプリケーションID
  51:     //https://e.developer.yahoo.co.jp/register
  52:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
  53:     var $YAHOO_APPLICATION_ID = '*****************************';

地図サービスを利用するために、クラスファイル "pahooGeoCode.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

地図や住所検索として Google を利用するのであれば、Google Cloud Platform APIキー が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、それぞれ参照されたい。

準備:地図サービスの選択

myWeather.php

  70: //地図描画サービスの選択
  71: //    0:Google
  72: //    2:地理院地図・OSM
  73: define('MAPSERVICE', 2);
  74: 
  75: //住所検索サービスの選択
  76: //    0:Google
  77: //    1:Yahoo!JAPAN
  78: //   11:HeartRails Geo API
  79: //   12:OSM Nominatim Search API
  80: //   13:国土地理院ジオコーディングAPI
  81: define('GEOSERVICE', 1);
  82: 
  83: //逆ジオコーディングサービスの選択
  84: //    0:Google
  85: //    1:Yahoo!JAPAN
  86: //   11:HeartRails Geo API
  87: //   21:簡易ジオコーディングサービス
  88: define('REVGEOSERVICE', 1);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。
住所検索サービスは、GoogleYahoo!JAPANHeartRails Geo APIOSM Nominatim Search API国土地理院ジオコーディングAPI から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、GoogleYahoo!JAPANHeartRails Geo API簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
PHPで地図で指定した場所の天気予報を求める
地理院地図表示
PHPで地図で指定した場所の天気予報を求める
オープンストリートマップ表示

準備:キャッシュ・システム

myWeather.php

 108: //キャッシュ保持時間(分) 0:キャッシュしない
 109: //気象庁へのアクセス負荷軽減のため,60分以上のキャッシュ保持をお勧めします.
 110: define('LIFE_CACHE', 120);
 111: 
 112: //キャッシュ・ディレクトリ
 113: //書き込み可能で,外部からアクセスされないディレクトリを指定してください.
 114: //最大150Mバイトを消費します.天気予報系プログラムは同じディレクトリで構わない.
 115: define('DIR_CACHE', './pcache/');

気象庁サイトへ負荷をかけないよう、キャッシュ・クラス pahooCache を導入した。使用方法については、「PHPで天気予報を求める - キャッシュ・システム」を参照いただきたい。
キャッシュ保持時間、キャッシュ・ディレクトリともに、自サイトの環境に応じて変更してほしい。天気予報系プログラム(「PHPで天気予報を求める」「PHPで地図で指定した場所の天気予報を求める」「PHPで地図で指定した場所の週間カレンダーを表示」)は全て同じディレクトリを指定することで、気象庁サイトへのアクセス回数がさらに減少する。

解説:最も近い予報地点

pahooWeather.php

 154: /**
 155:  * 指定した緯度・経度に最も近い予報地点コードを求める.
 156:  * 参考サイト https://www.pahoo.org/e-soul/webtech/php06/php06-52-01.shtm
 157:  * @param   object $pgc pahooGeoCodeオブジェクト
 158:  * @param   double $longitude 経度(世界測地系)
 159:  * @param   double $latitude  緯度(世界測地系)
 160:  * @param   int    $forecast  0:天気予報,1:週間天気予報(省略時:1)
 161:  * @return  string 予報地点コード/NULL:合致する予報地点がない
 162: */
 163: function getJmaNearSpot($pgc, $longitude, $latitude, $forecast=1) {
 164:     //電文コード
 165:     $code = ($forecast == 0? 'VPFD51' : 'VPFW50';
 166: 
 167:     $res = NULL;
 168:     $cnt = 0;
 169:     $d0  = 999999999;
 170:     //電文コードが一致する予報地点を選んで2地点間の距離を計算
 171:     while (1) {
 172:         if ($this->spots[$cnt]['code'] == $code
 173:             && isset($this->spots[$cnt]['stationCode'])
 174:             && isset($this->spots[$cnt]['longitude'])
 175:             && isset($this->spots[$cnt]['latitude'])) {
 176:             $d1 = $pgc->distance($this->spots[$cnt]['longitude'], $this->spots[$cnt]['latitude'], $longitude, $latitude);
 177:             //距離がより小さければ採用
 178:             if ($d1 < $d0) {
 179:                 $res = (string)$this->spots[$cnt]['stationCode'];
 180:                 $d0 = $d1;
 181:             }
 182:             $cnt++;
 183:         } else {
 184:             break;
 185:         }
 186:     }
 187:     return $res;
 188: }

Googleマップから取得した緯度・経度を取得できるが、一方、クラス "pahooWeather" では定められた都市の天気予報しか取得できない。そこで、マップ・サービスから取得した緯度・経度に最も近い予報地点の天気予報を表示することにした。
最も近い予報地点を取得するのがメソッド getJmaNearSpot である。
あらかじめ用意した予報地点情報 $spots とマップ・サービスから取得した緯度・経度の距離を計算し、それが最短になる予報地点を採用する。

なお、予報地点情報 $spots は、あらかじめXML形式ファイル "FILE_JMASPOTS" として用意しておく必要がある。
"FILE_JMASPOTS" は圧縮ファイルに同梱しているが、もし新規作成する場合は、「予報地点情報ファイル - PHPで天気予報を求める」をご覧いただきたい。

解説:表示とURLパラメータ

myWeather.php

 396: //各種パラメータを代入する.
 397: $items  = array();
 398: $errmsg = $url = $address = '';
 399: $id        = (int)getParam('id',          FALSE, 0);                //表示モード
 400: $query    = getValidString('query', $errmsg, '', QUERY_MIN_LEN, QUERY_MAX_LEN);
 401: if ($errmsg !'') {
 402:     $errmsg = '検索キーの長さが' . $errmsg;
 403: }
 404: $latitude  = (float)getParam('latitude',  FALSE, DEF_LATITUDE);     //緯度
 405: $longitude = (float)getParam('longitude', FALSE, DEF_LONGITUDE);    //経度
 406: $zoom      = (int)getParam('zoom',        FALSE, DEF_ZOOM);         //ズーム
 407: $type      = (string)getParam('type',     FALSE, DEF_TYPE);         //マップタイプ
 408: $category  = (string)getParam('category',    FALSE, DEF_CATEGORY);  //カテゴリ
 409: $outenc    = (string)getParam('charset',  FALSE, INTERNAL_ENCODING);

URLパラメータを使って
myWeather.php?id=1&query=%E6%9C%AD%E5%B9%8C%E5%B8%82
のようにすることで、query をキーワードにして検索した地点の天気予報のみを表示させることができる。つまり、このスクリプトをホームページやブログの一部として組み込むことで、週間天気予報を表示するパーツになる。
query はUTF-8をURLエンコードしたもの。Yahoo!JAPAN住所検索を使う場合は、category をあわせて指定すること。
また、出力はHTML文のみとなり、スタイルシートは本体ページの方で用意していただきたい。必要なclassは次の通り。

myWeather.php

 145: <style>
 146: /* エラー表示 */
 147: p.werror {
 148:     color: red;
 149: }
 150: /* 天気予報表 */
 151: table.weather {
 152:     width: {$width}px;
 153:     border:solid 1px #000000;
 154:     border-collapse:collapse;
 155:     margin-top:10px;
 156: 
 157: }
 158: /* 天気予報表:月日表示部 */
 159: table.weather td.dt {
 160:     width: {$width}px;
 161:     border:solid 1px #000000;
 162:     border-collapse: collapse;
 163:     padding:4px;
 164:     white-space:nowrap;
 165:     text-align:center;
 166: }
 167: /* 天気予報表:予報表示部 */
 168: table.weather td.info {
 169:     width: {$width}px;
 170:     border:solid 1px #000000;
 171:     border-collapse: collapse;
 172:     padding:4px;
 173:     white-space:nowrap;
 174:     text-align:center;
 175: }
 176: /* 天気予報表:予報アイコン */
 177: img.wicon {
 178:     width: 60px;
 179: }
 180: /* 天気予報表:小さい文字 */
 181: span.wsmall {
 182:     font-size: small;
 183: }
 184: </style>

また、親となるホームページやブログの文字コードセットにあわせ、charset 変数で出力文字コードを変更できるようにした。たとえば
myWeather.php?id=1&query=%E6%9C%AD%E5%B9%8C%E5%B8%82&charset=SJIS
とすると、シフトJISで出力することができる。
緯度・経度を直接、URLパラメータに渡すこともできる。
myWeather.php?id=1&latitude=26.591&longitude=127.977
のようにすることで、北緯26.591度、東経127.977度の天気予報のみを表示させることができる。

活用例

地図・地名で指定した場所の週間天気予報」(みんなの知識 ちょっと便利帳)では、このサンプル・プログラムを活用し、検索しやすく、また週間天気予報を見やすく表示している。ありがとうございます。

参考サイト

(この項おわり)
header