「いちばん近い避難所」を出すシステムは、危ない——避難所まで徒歩何分かを返すサービスを作って、災害種別で絞る設計にした話
名古屋でAIシステム開発の会社をやっています。
住所を入れると、最寄りの避難所まで道路をたどって徒歩何分かを返すサービスを公開しました。全国47都道府県・115,447件を収録しています。
Kurage 避難所マップ(無料で試せます)
先日公開した土砂災害ハザードマップの続編です。「その土地が警戒区域か」を調べたあとに来るのは「じゃあどこへ逃げるのか」なので、そこを埋めました。
ただ、この記事で書きたいのは機能の話ではありません。作りながら気づいた、危ない設計の話です。
「いちばん近い避難所」を返すと、危ない
最初に考えていた仕様は単純でした。住所を点にして、いちばん近い避難所を返す。それだけです。
データを見ていて、手が止まりました。
国土地理院が配布している指定緊急避難場所のデータには、施設ごとにこういう列が並んでいます。
| 列 | 意味 |
|---|---|
| flood | 洪水 |
| landslid | 崖崩れ・土石流・地すべり |
| surge | 高潮 |
| quake | 地震 |
| tsunami | 津波 |
| bigfire | 大規模な火事 |
| inlflood | 内水氾濫 |
| volcano | 火山現象 |
指定緊急避難場所は、災害種別ごとに指定されています。 全部の災害に使えるわけではありません。
言われてみれば当たり前です。崖のそばの広場は、地震のときには倒れてくる建物がないので安全です。しかし土砂災害のときは、まさにそこが危険です。川沿いの公園は地震では使えても、洪水では使えません。
収録件数を数えると、こうでした。
| 災害種別 | 件数 |
|---|---|
| 地震 | 88,177 |
| 洪水 | 71,783 |
| 崖崩れ・土石流・地すべり | 67,289 |
| 大規模な火事 | 43,105 |
| 津波 | 40,393 |
| 内水氾濫 | 38,621 |
| 高潮 | 25,157 |
| 火山現象 | 10,723 |
全体は115,447件です。地震で使えるのは76%、津波で使えるのは35%しかありません。
つまり「いちばん近い避難所はここです」と返すシステムは、その災害では使えない場所へ人を誘導する可能性があります。平時に使う分には気づきません。危ないのは、実際に災害が起きたときです。
そこで、災害種別を選ぶとその災害に対して指定されている場所だけを対象にする設計にしました。地図アプリの「近くの施設」とは別物にしたかった、というのが正直なところです。
実際に試すと、差が出ます
前回のハザードマップの記事で書いた住所(土砂災害警戒区域の縁から14mの場所)で試してみます。
土砂災害で絞ると、こうなりました。
旭支所(豊田市小渡町船戸) 徒歩49分・4,174m
串原福祉センター(恵那市串原) 徒歩66分・5,643m
徒歩49分です。2件目は県境を越えて岐阜県に入っています。
山間部ではこうなります。都市部だとまったく違って、名古屋駅なら徒歩6分・521mでした。この差自体が、知っておく価値のある情報だと思っています。
徒歩時間は直線距離では出せない
「何分」を出すのに直線距離を使うと嘘になります。川や線路や高速道路があると、実際には大きく迂回するからです。
道路網をたどった歩行経路で計算しています。オープンソースの経路探索エンジン Valhalla に、1地点から複数目的地への所要時間をまとめて問い合わせています。候補は先に20件へ絞ってから投げるので、応答は1秒前後です。
ここでひとつ決めたことがあります。Valhalla を使わない構成でも動くようにした上で、その場合は直線距離×徒歩80m/分で計算し、「直線距離で計算しました」と結果に明記するようにしました。
どちらで計算したか分からないまま数字だけ出すのは、精度を黙って落とすのと同じです。買い切り版を自社サーバーに置く方が Valhalla まで用意するとは限らないので、ここは譲れませんでした。
データの時点は、市町村ごとに違う
前回のハザードマップで「判定にはデータ時点を必ず添える」という原則を立てました。今回も同じですが、事情が少し違います。
このデータは市町村ごとに更新時期がバラバラです。国土地理院が市町村別の公開日・最終更新日を1,747件分公開しているので、それを取り込んで、判定結果にその市町村の時点を出しています。
豊田市 → 2025-11-22
名古屋市 → 2026-03-09
同じ画面でも、調べた住所によって表示される時点が変わります。全国一律で「2026-06-12のデータです」と出すほうが実装は簡単ですが、それだとその市町村の情報がいつのものかは分かりません。
時点が確認できないデータでは判定しない、という方針も引き継いでいます。
PostGIS をやめました
前回のハザードマップは PostGIS を使っています。土砂災害警戒区域は面なので、点が面の中に入るかを判定する必要があったからです。
今回、同じ構成にしようとして、やめました。避難所は点だからです。
必要なのは「近い順に並べる」だけで、面の包含判定は要りません。それなら SQLite の R-tree 索引で足ります。115,447点なら一瞬です。
結果として、買い切り版に Docker も PostgreSQL も要らなくなりました。 必要なのは Python と GDAL だけです。取り込み後のデータは30MBほどです。
技術的に高度なほうを選びたくなるのですが、要らないものを外すほうが製品としては強くなる、というのが今回の学びでした。設置でつまずく箇所が減ります。
つまずいた2点
同じことをやる方のために書いておきます。
1. .cpg が UTF-8 なのに変換指定を付けると壊れる
配布 Shapefile には .cpg ファイルが付いていて、UTF-8 と宣言されています。ここで ogr2ogr に -lco ENCODING=UTF-8 を付けると、二重変換で日本語が全滅します。付けないのが正解でした。
2. 元データに、途中で切れた日本語がある
取り込みが UnicodeDecodeError で止まりました。調べると、ファイルの後ろのほうに \xe3\x80 で終わっているバイト列がありました。「、」(\xe3\x80\x81)の3バイト目が欠けています。
254バイトのフィールド長で打ち切られた結果、日本語1文字の途中で切れていました。備考欄なので、施設名・住所・災害種別フラグには影響しません。エラーで止めるのではなく、置換して読み進める方針にして、なぜそうしたかをコードにコメントで残しました。
使ってほしい場面
不動産・建設の方が、物件や施工地の避難経路を当たり付けするのが本来の想定です。総務・防災の担当者が、事業所から避難所までの所要時間を把握するのにも使えます。
介護施設や保育園のように、自力で早く動けない人を預かっている施設では、徒歩何分かは避難計画そのものに関わります。
もちろん、ご自宅や実家で試すのも無料です。
最後に
出典は国土地理院の指定緊急避難場所データで、CC BY 4.0 のもとで利用しています。
本サービスの判定は参考情報で、公的な証明ではありません。このデータは最新でない場合や未掲載の場合があります。最終的な確認は必ず当該市町村の情報で行ってください。この注意書きは、国土地理院の利用規約でも第三者提供時に伝えるよう求められているものです。
自社サーバーに置ける買い切り版もKurage App Storeに出しました。ソースコードと設置手順書を同梱しています。
同じような「要らないものを外す」判断が、御社のシステムにもあるかもしれません。ご相談はお問い合わせからどうぞ。