地震火山月報のPDFから計測震度を抜き出す

この記事は [防災アプリ開発 Advent Calendar 2023](https://adventar.org/calendars/9301) 15日目の記事です。
こんにちは! iku55です。初めましての方は初めまして、お久しぶりの方はお久しぶりです。
2021年福島県沖地震にて防災に興味を持ち、そこからプログラムを書いたり自由に生きております。

この記事では僕が開発している、[計測震度データベース](https://iku55.github.io/shindodb/index.html)についての話をしたいと思います。記憶をたどりながら書いたので実際とは違う部分もあるかもしれませんが、読んでいただけたら幸いです。


# きっかけ
計測震度とは、震度計が観測した揺れの値であり、これを元に0~7までの震度が決められます。計測震度を確認するとその揺れが「4に近い震度5弱」「7に近い震度6強」といったことを読み取ることができます。
しかし、計測震度を見かけることはあまりありません。気象庁の会見等で聞くことはありますが、ほとんどの地震の計測震度は知らないでしょう。

気象庁は過去の有感地震の計測震度を[地震・火山月報（防災編）](https://www.data.jma.go.jp/eqev/data/gaikyo/index.html#monthly)と、[地震月報(カタログ編)](https://www.data.jma.go.jp/eqev/data/bulletin/index.html)の震度データにて発表しています。
震度データベースでは計測震度を見ることができないので、震度データベースのように計測震度を表示するアプリを開発したいと思いました。

地震月報(カタログ編)は不定期更新(おそらく)で、更新頻度もあまり高くないことから、地震・火山月報（防災編）から計測震度を抜き出すことにしました。
しかし、地震・火山月報（防災編）はPDFというプログラムでは読み取りが難しい形式のため苦労しました。


# PDFから計測震度を抜き出す
Node.jsを使って開発することにしました。苦労した部分も多かったので、皆様にお伝えできればと思います。
コード量はあまり多くないのですが、試行錯誤した点は多いです。それだけPDFはデータ抜き出しに向いてないです。


## 初期バージョン
2021年12月頃に開発しました。pdfreaderというライブラリを用いて、PDF上のテキストを順番に読み取っていきデータ化する方法です。これは`Node.js pdf 読み込み`等でググればすぐに出てくるでしょう。しかし、この方法には問題点がありました。

PDFのテキストはよくわからないところで途切れており、これらをつないで解析するのがとてもめんどくさかったのです。
`10   2  19 06` `能登半島沖` `37°31.1’` `Ｎ` `137°13.9’` `Ｅ` `13km` `Ｍ` `: 3.9`...

さらに別れ方は何パターンかあるため、その処理もめんどくさいのです。
`(` `注` `)   2` `19 06` `能登半島沖` `37°31.1’` `Ｎ` `137°13.9’` `Ｅ` `11km` `Ｍ` `: 3.4`...
`11   4  16` `01` `石川県能登地方` `37°31.3’` `Ｎ` `137°18.8’` `Ｅ` `12km` `Ｍ`...
`60` `13  07 12` `福島県沖` `37°35.5’` `Ｎ` `141°29.7’` `Ｅ` `53km` `Ｍ`...

---

https://x.com/iku55mc/status/1472504619607916545?s=20

![screenshot.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/7074fcac-78f3-17c1-6aae-127619c43943.png)
![screenshot.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/01a43af4-34ac-58e8-d36d-e7efd7b6d0f7.png)
![screenshot.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/c004240a-225f-6946-78ad-98ba2efb5937.png)
![screenshot.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/b221d06e-3c79-231f-b304-bd32a73a9d9a.png)
以上失敗例。データは地震火山月報（防災編）2021年11月より。

---

この方法だと結構な数の読み取りミスが生まれます。プログラムを実行後、30分程度手作業で修正していました。

https://x.com/iku55mc/status/1508735717257596929?s=20



さらに、コードが読みにくくなり(自分の技量のせいでもありますが)開発が大変になりました。PDFきらい。


## Tabulaとの出会い

https://x.com/iku55mc/status/1537799446008053760?s=20

PDFから表のデータを取り出す方法を模索していたところ、[Tabula](https://tabula.technology/)というソフトウェアに出会いました。TabulaはPDFの表をCSVに変換するソフトウェアです。結構精度良い。
そのCSVを元にデータ化することにしました。

Tabulaを使用してPDFをCSVに変換してみると、次のようになります。大分プログラムで読み取りやすくなったでしょう。
![screenshot.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/e06b8da8-63f5-91d7-2fc8-289dc996ce43.png)

しかし、まだ不十分な部分があるので、次のような処理を行います。手作業でもできるくらい簡単な作業です。
![screenshot.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497806/0037b8f8-62e2-cc0a-2b5e-ccb781fa5444.png)

読み取りミスはほとんどなくなりました。Tabula最高です。
この処理を自動化して生成されたものが現在、計測震度データベースに使われています。

PDFの表からデータを抜き出す際はぜひTabulaを使ってみてください。


# 計測震度データベースの開発
2022年7月頃に開発しました。PDFから抜き出した各地点の計測震度をLeaflet(現在はMapLibre)を使って表示するアプリです。
Leafletについては詳しい解説記事がたくさんあると思うので書きません。

抜き出したデータと[気象庁 震度データベース検索](https://www.data.jma.go.jp/svd/eqdb/data/shindo/index.html)のIDとを紐づけて震度データベースに簡単に移動できるようにしました。
機能については、震度データベースを~~パクった~~参考にさせていただきました。

https://x.com/iku55mc/status/1551085316177805313?s=20

いいですね。PDFの表を見るよりもわかりやすくなったと思います。

今後は検索機能の追加やデータ抜き出しの完全自動化を目指して開発したいです。

# 最後に
今回紹介した震度データや計測震度データベースについてはGitHubにて公開しています。
- [計測震度データベース (https://iku55.github.io/shindodb/index.html)](https://iku55.github.io/shindodb/index.html)
- [GitHubリポジトリ iku55/shindodb](https://github.com/iku55/shindodb)(ソースコード・データ)

簡単な記事でしたが最後までお読みいただきありがとうございました。少しでもPDFを解析する際の参考になれば幸いです。
実はこの話は今年の話ではないのですが...まあいいでしょう。

翌16日目は、あめうまさんの「[これまでの地震ソフト制作をまとめてみる](https://ameuma773.hatenablog.com/entry/2023/12/15/233602)」です。