OTENKI Data Science

TechBlog

K.Sakurai

Slackを用いた防災情報タイムライン(Pythonで防災情報XMLを扱う)

はじめに

気象庁は、気象警報や地震・津波・火山、天気予報などの防災情報を発表しています。これらは、既定のフォーマットで記述された文字列や文章の「電文形式」で、多くはXML形式フォーマットで提供されています。最近は防災情報の種類が増えていますが、とるべき行動を直感的に理解しやすいよう警戒レベルで対応させており(参考:「防災気象情報と警戒レベルとの対応について」気象庁HP)、自らの判断で安全確保行動をとることが重要になっています。台風や線状降水帯による集中豪雨等により、時々刻々と変化する状況を防災情報で把握することに関して、情報を見るユーザーも、情報を伝達する事業者も、できる限り読み取りやすい・伝えやすい方法を常々考えていますね。
今回の記事では、気象庁防災情報XMLを処理して時系列に表示する「防災情報タイムライン」という使い方を紹介します。防災情報を時系列に表示すると、リアルタイムな状況の変化を把握しやすくなるのでお勧めの方法です。表示するサービスには一例としてSlackを用いますが、同様のことはTwitter等でも可能です。また、XML形式ファイルの処理にはPython(ver.3系)を用います。Pythonで防災情報XMLを扱う方法としてもご参考になればと思います。

※注意事項
「Slack」はSlack Technologies, Inc.の登録商標あるいは商標です。ここで紹介するアプリケーションの作成方法、スクリーンショットは記事作成時のものであり、動作は保証できません。記事を参考に利用される場合は、自己の判断でお願いします。
防災情報の扱いは気象業務法に従ってください。例えば、警報は編集してはいけません。また、気象庁が発表した予報内容と異なる予報を発表するには予報業務許可が必要です。

防災情報タイムライン

「防災情報タイムライン」は、防災情報を時系列に表示するコンテンツです。下のスクリーンショットは、気象庁防災情報XMLから情報文を抜き出して、Slackチャンネルに表示(POST)した例です。
この方法の一番のメリットは情報履歴が一目でわかることです。状況が悪く(良く)なっているのか、つまり、警戒レベルが上がっている(下がっている)のか、警報が発表(解除)されたのか等が、いつ発表されて、今とこれからの状況がどうなるのかをすぐに理解することができます。
設定すれば通知音やポップアップでお知らせすることもできますね。コンテンツのアプリケーションを開発しなくて良いのも便利なところです。
表示のタイトルやテキストのデザイン(太字、色など)も変更することができます。あまり文字数が多いと見づらくなるので、見出し文等ぱっと見でわかる短文で確認できるようにするのがコツです。
Slackの無料プランでは閲覧できる履歴が制限されます。防災情報は配信数が多くなりがちなので、あっという間に制限に達するかもしれません。

Slackの設定・投稿方法

事前準備として、Slackのアカウント、Workspaceを作成しておきます。
https://api.slack.com/にアクセスして、新しいSlackアプリケーション(Slack App)を作成します。
App Nameを入力して、先に作成しておいたWorkspaceを選びます。

Slack Appを作成できたら、Appの設定画面で「Incoming Webhooks」を開きます。
「Incoming Webhooks」では、指定するチャンネルにPOSTするAPIを発行します。「Activate Incoming Webhooks」をOnにします。

次に、チャンネルを作成します。チャンネルは、例えば、「地震情報を表示するチャンネル」など、種類に応じて作成すると便利だと思います。
チャンネルを作成したら、先ほどの「Incoming Webhooks」の設定ページから「Add New Webhooks to Workspace」でそのチャンネルを選び、APIを発行します。このとき、AppからWorkspaceにアクセスする権限を許可します。
APIが発行されると、「Incoming Webhooks」の設定ページに追加されます。curlコマンドによるPOSTの例があるので、参考にしてみてください。
これで準備は整いました。

投稿(メッセージをPOST)する際は以下のようにjsonファイル(message.json)を作成すると便利だと思います。
    $ curl -X POST -H 'Content-type: application/json' --data @${yourpath}/message.json ${webhook_URL}
フォーマットはReferenceを参考にしてください。
例えば、基本的なフォーマットは以下のように書きます。
    {
      "attachments": [
       {
        “title”: “タイトル",
        “text”: “本文",
        “color”: ”投稿の色(サイドライン)"
       }
      ]
    }
colorはカラーコードを指定するか、good(green)、warning(yellow)、danger(red)で指定します。警報や警戒レベルの危険度で色を変化させるとわかりやすいですね。凝ったデザインも可能なのでいろいろ試してみてください。

Pythonによる情報文の抜き出し

Slackで防災情報タイムラインの準備ができたら、表示させる情報文を防災情報XMLから抜き出すプログラムを作ります。
XML形式ファイルの処理に慣れている方は、この節を読まなくても防災情報タイムラインにすぐに投稿できるかと思います。初めての方は、このXML形式ファイルの処理方法の解説を参考にしてみてください。防災情報タイムラインだけでなく、様々な用途で活用できると思います。ソースコードは実用性を重視してなるべくわかりやすく解説しますが、Pythonのリファレンス等で理解を深めて頂くと良いと思います。

まず、防災情報XMLのフォーマットについて頭に入れておきましょう。下の例(震度速報VXSE51)のように、たいていは管理部(Control)、ヘッダ部(Head)、内容部(Body)の構造になっています。
以下、この電文例を基に解説します。
抜き出す候補としては、ヘッダ部の標題(Head/Title)、情報形態(Head/InfoType)、見出し文(Head/Headline/Text)、防災気象情報要素(Head/Headline/Information/Item)が考えられます。標題を防災情報タイムラインのタイトルに、見出し文と防災気象情報要素(観測された震度3以上の最大震度と地域)を本文に、といった感じですね。
見出し文(Text内)はフリーフォーマットです。防災気象情報要素(Item)は複数の場合があります。
情報形態は、発表・訂正・取消が入ることがあり、取消は内容が変わるため注意が必要です。また、管理部の運用種別(Control/Status)は、通常・訓練・試験があり、通常以外は業務利用しないようにしなければなりません。
電文の種類によって異なる部分があるので、各電文の技術資料を参照するようにしてください。

XML形式ファイルをPythonで読み込むには、xml.etree.ElementTreeモジュールを使用します。
    import xml.etree.ElementTree as ET
XML形式ファイルを指定して読み込みます。
    # xmlファイルの読み込み
    tree = ET.parse('data.xml')
root階層(Control, Head, Body)をインポートします。
    root = tree.getroot()
ヘッダ部の標題(Head/Title)から要素を抜き出すには以下のように書きます。
    Title=root.find("{http://xml.kishou.go.jp/jmaxml1/informationBasis1/}Head/{http://xml.kishou.go.jp/jmaxml1/informationBasis1/}Title")
    print(Title.text)
findメソッドはタグの階層から要素を1つ抽出します。textメソッドは、要素のうち、タグの中身を指定します。
ヘッダ部の見出し防災気象情報事項(Head/Headline/Information)の属性@typeを抜き出すには以下のように書きます。
    Information=root.find("{http://xml.kishou.go.jp/jmaxml1/informationBasis1/}Head/{http://xml.kishou.go.jp/jmaxml1/informationBasis1/}Headline/{http://xml.kishou.go.jp/jmaxml1/informationBasis1/}Information")
    print(Information.attrib[“type”])
attribメソッドが、要素のうち、属性の中身を指定します。
電文によっては属性を条件にして処理する場合もあると思います。
findの中に{}で囲まれたURLがありますが、これは名前空間(namespace)と呼ばれるものです。Headタグのxmlns等を参照するか、tagメソッドで出力して調べます。
防災気象情報要素(Head/Headline/Information/Item)のように複数のデータを抽出したい場合は、findallメソッドを使います。
    Items=root.findall("{.*}Head/{.*}Headline/{.*}Information/ {.*}Item")
    for Item in Items:
        Shindo=Item.find("{.*}Kind/{.*}Name”)
        print(Shindo.text)
(名前空間は省略しています)
震度(Kind/Name)は震度3,4,5-,5+,6-,6+,7のいずれかになります。震度?以上等の条件を処理することができますね。
地域(Areas/Area/NameもしくはCode)を限定したい場合にも使えますね。

あとは読み込んだ要素から防災情報タイムラインに投稿するメッセージ(jsonファイル)を作成します。作成したjsonファイルは前節で説明したように、curlコマンド等でPOSTすれば防災情報タイムラインに表示されます。

おわりに

今回はSlackを用いた防災情報タイムラインの作り方について、PythonでXML形式ファイルを扱う方法を解説しながらご紹介しました。
いかがでしょうか。実際にタイムラインとして表示してみて、その便利さに気づいて頂けると嬉しいです。
個人的には、指定河川洪水予報は河川の水位レベルの変化がわかり、大雨危険度通知は警戒レベルの変化した地域や時刻がわかるので便利だと思います。
また、防災情報ではないのですが、虹情報は通知が来たら実際に虹が見えたりして面白いです。

冒頭でもお話したように、今の防災は自らの判断で安全確保行動をとることが求められており、データを扱うことに関しては、より分かりやすい防災情報の伝え方を極めていかなければなりません。防災情報タイムラインが、大切な人を守るためのツールとして活用されればと思います。

この記事を書いた人

K.Sakurai

気象予報士/技術士(応用理学)/防災士 
総合気象数値計算システムSACRA、データ提供システムCOSMOS及びお天気データサイエンスの開発に一から携わる。
WRF-5kmモデル、虹予報、虹ナウキャスト、1㎞メッシュ雨雪判別予測データ、2kmメッシュ推計日射量を開発。
趣味はバドミントンと登山。

前の記事へ 【データ解説】図形式気象情報の活用について
記事一覧へ
次の記事へ 【データ解説】2kmメッシュ推計日射量
  1. お天気データサイエンスHOME
  2. 技術情報
  3. 技術ブログ
  4. Slackを用いた防災情報タイムライン(Pythonで防災情報XMLを扱う)