Search by

jmaxml / earthquake

shimomo

Unofficial earthquake event aggregation for JMA (Japan Meteorological Agency) XML

0.1.1 2026-11-04 17:21 UTC

This package is auto-updated.

Last update: 2026-11-04 17:22:23 UTC


README

気象庁防災情報XMLの地震の電文を地震イベントにまとめ、「登録した市町村のうち、震度いくつ以上だったのはどこか」「取り消されたか」を判定する 非公式 PHP ライブラリです。気象庁とは関係ありません。

An unofficial PHP library that groups JMA (Japan Meteorological Agency) earthquake telegrams into events and tells you which registered cities may have reached a given seismic intensity, and whether the event was cancelled. Not affiliated with JMA.

  • 対象の電文:震度速報(VXSE51)、震源に関する情報(VXSE52)、震源・震度に関する情報(VXSE53)
  • jmaxml/core で読んだ Report を使い、市町村と細分区域の対応は jmaxml/codes で引きます
  • 状態は持ちません。同じ地震の電文を保存しておき、新しい電文が届くたびにイベントを組み立て直します

インストール

composer require jmaxml/earthquake

PHP 8.3 以上が必要です。電文の取得には jmaxml/feed が使えます。

使い方

use JmaXml\Earthquake\EarthquakeEvent;
use JmaXml\Earthquake\EarthquakeEvents;
use JmaXml\Earthquake\SeismicIntensity;

// $reports:同じ地震の電文(JmaXml\Report)。feed から受け取ったものを保存しておき、届くたびに全部で組み立て直す
$event = EarthquakeEvent::fromReports($reports);

if ($event->isCancelled()) {
    // 取り消された地震。送った安否確認があれば、取消を知らせる
}

$result = $event->citiesAtLeast(SeismicIntensity::FiveLower, $registeredCityCodes);

foreach ($result->matches as $match) {
    // $match->cityCode の登録者に安否確認を送る
    // $match->intensity:市町村(または細分区域)の震度。$match->notYetReceived なら「5弱以上の可能性あり、観測値未着」
    // $match->basis:MatchBasis::City(市町村の震度)か MatchBasis::Area(震度速報の細分区域から当てはめた)
}

foreach ($result->unknownCityCodes as $code) {
    // コード表に無い市町村コード。どの段階でも照合できないので、登録を見直す(黙って見送らない)
}

いろいろな電文がまとめて届くときは、EarthquakeEvents::group($reports) で地震ごとに分けられます。地震の電文以外は無視し、既定では運用種別が「通常」の電文だけを使います(訓練も扱うときは EarthquakeEvents::group($reports, ['通常', '訓練']))。EarthquakeEvent::fromReports() は渡された電文をそのまま使うので、$event->status が「通常」かどうかは呼び出し側で確かめてください。

例:震度速報だけの段階

$event = EarthquakeEvent::fromReports($shindoSokuhoReports);   // 震度速報 3 通(32-35_08 の地震 A)
$event->stage;                                                  // EventStage::IntensityOnly
$event->maxIntensity;                                           // SeismicIntensity::Four

$event->citiesAtLeast(SeismicIntensity::Four, ['0320100', '0110100'])->matches;
// [CityMatch('0320100', Four, false, MatchBasis::Area)]  盛岡市は細分区域「岩手県内陸北部」が震度 4

地域ごとの震度と取消の状況

$event->city('1310100')?->maxIntensity;      // 市町村の震度(震源・震度に関する情報)
$event->area('350');                          // 細分区域
$event->prefecture('13');                     // 都道府県
$event->station('1310100');                   // 震度観測点
$event->cancelledKinds;                       // 例:['震源・震度に関する情報'](取り消された種類。一部だけ取り消されることもある)
$event->mayBeAtLeast(SeismicIntensity::FiveUpper);   // どこかが基準以上、または未入電の地域がある
  • areas・cities などの配列のキーは、'211' や '1310100' のようなコードが PHP によって整数に変わることがあります。キーを === で比べず、city()・area()・prefecture()・station() で引くか、各読み取りの code を使ってください
  • 震源・震度に関する情報より新しい震度速報があるときは、area()・prefecture() は両方の震度のうち強いほうを返します。どちらかが未入電なら notYetReceived は true です
  • maxIntensity は確定した震度だけを見ます。未入電の地域があると、実際の揺れはもっと強いかもしれません。地震を基準の震度で先に絞り込むときは mayBeAtLeast() を使ってください
  • 震度のデータが無い地震では、mayBeAtLeast() は false、citiesAtLeast() も一致なしです。遠地地震のほか、震源に関する情報だけを受け取ったときもそうなります。気象庁は震源に関する情報を震度 3 以上で発表するので、震度速報を受け取り損ねただけかもしれません。この時点で処理済みにせず、震度速報や震源・震度に関する情報が届いたら、地震を作り直して判定し直してください。見分けるには maxIntensity === null && !isCancelled() を使います(取り消された地震も maxIntensity は null です)

振る舞い

項目 振る舞い
地震のまとめ方 Control/Status(通常・訓練など)と Head/EventID が同じ電文を 1 つの地震にします。訓練の電文は別の地震になります
情報の単位 「運用種別 + EventID + 電文の種類(Control/Title)」です。気象庁の仕様の単位には編集官署(Control/EditorialOffice)も入りますが、同じ地震でも電文の種類によって官署が違う(震度速報は大阪管区気象台、震源・震度に関する情報は気象庁本庁など)ため、地震のまとめには使いません。同じ種類の電文は同じ官署から出る前提です
最新の決め方 電文の種類(Control/Title)ごとに、Head/ReportDateTime、同じなら Control/DateTime が最も新しいものを使います。Serial は使いません。「訂正」は最新を置き換えるだけです
取消 最新が「取消」の種類は使いません。すべての種類が取り消されたら EventStage::Cancelled で、どの市町村も一致しません
段階 IntensityOnly(震度速報だけ)、WithHypocenter(震源あり)、WithHypocenterAndIntensity(震源・震度あり)、Cancelled
市町村の判定 震源・震度に関する情報があれば、市町村の震度で判定します。震度速報しか無ければ、細分区域の震度をその細分区域の市町村に当てはめます
あとから届いた震度速報 震源・震度に関する情報より新しい震度速報があれば、その細分区域も当てはめて判定に加えます(追加入電で震度が上がった細分区域を見落とさないため)
未入電 「震度5弱以上未入電」の市町村は、どの基準の震度でも一致として返します(notYetReceived === true)。市町村の確定した震度が 5 弱以上でも、観測点のどれかが未入電なら同じ扱いです(実際の揺れは確定した震度より強いことがあるため)。intensity ではなく notYetReceived を見てください
コード表に無い市町村 どの段階でも unknownCityCodes に入れます
別の EventID の地震 1 つにまとめません。小さな地震が大きな地震の揺れで震度速報の基準に達すると、気象庁は別の EventID で震度速報を出すことがあります。$a->isPossiblyRelatedTo($b)(既定は検知時刻の差が 5 分以内で、震度 3 以上の細分区域が重なる)で関連の可能性を知らせるだけです。まとめるかどうかはアプリで決めてください

注意

  • 震度速報の段階の判定は細分区域単位なので、実際の市町村の震度より強めに出ることがあります(MatchBasis::Area)
  • 遠くの地震(震源・震度に関する情報に国内の震度が無いもの)は、どの市町村も一致しません
  • このライブラリは気象庁の公式ソフトウェアではありません。内容の正確性や即時性は保証しません。実際の防災行動は、気象庁や自治体などの公式の発表に従ってください

出典

出典:気象庁ホームページ「気象庁防災情報XMLフォーマット」

ライセンス

MIT