使用する用途のコンセプト また震源地から津波が到達するまでの時間と津波の高さを計算し GIS情報を使い避難するエリアを算出しルート案内できるようにしたい 家族の避難経路・地域防災マップをGraphDBで整理 避難所や重要連絡先も紐付け 使い方例: 「地震が来たら最寄りの避難所はどこ?」 「非常食の賞味期限が近いものは?」 など この用途で使うならどれを推奨する?
✅ あなたの用途の要件
* 精度:震源→沿岸までの到達時間・波高推定の入力に使うので、誤差が大きすぎると危険。
* 範囲:主に日本周辺で十分。全球は必須ではない。
* 更新頻度:将来的に OSM/防災機関の最新データと連携したい。
* GraphDB連携:避難所・道路・避難経路・浸水域をノード/リレーションで管理。
* 利用イメージ:
* 「地震が来たら最寄りの避難所はどこ?」 → 避難所ノード+道路グラフ
* 「非常食の賞味期限が近いものは?」 → 在庫管理ノード
* 「津波到達までに何分ある?」 → 震源ノード→海岸ノードのコスト距離
✅ データセットごとの特徴
1. 国土数値情報「海岸線データ」
* 日本限定。行政データとして信頼性が高い。
* GML/Shapefile 提供。
* 避難計画(住民向け防災マップ)に最も適する。
➡ 推奨(基準データにする)
2. OSM Coastlines / Land polygons
* 更新頻度が高い(週次〜月次)。
* 最新の人工改変(埋立地・護岸)も比較的反映。
* 避難経路や実際の生活圏との整合性が良い。
➡ 補助データ(現況把握用)
3. Natural Earth
* 全球対応、軽量。
* 精度は粗い(1:10mでも数百 m〜km の誤差)。
* 可視化や概念実証には便利。
➡ プロトタイプ用のみ
4. GSHHG
* 全球対応、高解像度あり。
* ファイルが大きく、取り回しに手間。
* 学術研究向き。
➡ 専門シミュレーション以外では過剰
✅ 推奨構成(防災マップ+GraphDB向け)
1. 海岸線:
* 基本 → 国土数値情報(海岸線)
* 最新の現況補正 → OSM Coastlines
2. 標高/地形:
* 陸域 DEM → 国土地理院 DEM / ALOS / SRTM
* 海域 DEM → GEBCO
3. 避難所・道路:
* 避難所 → 自治体オープンデータ(CSV/GeoJSON)
* 道路 → OSMnx で抽出
4. GraphDBに格納:
* ノード:震源・海岸・浸水域・避難所・家庭・在庫
* リレーション:到達時間・避難経路・所要時間・備蓄品管理
✅ まとめ
ご提示の用途(家族避難+地域防災+GraphDB管理)なら:
* **国土数値情報(海岸線)**をメイン
* OSM Coastlinesで現況更新
* DEM(陸域+海域)+道路+避難所を組み合わせ
* GraphDBでノード/リレーションを整理して「質問に答えられる防災知識ベース」を構築
これらを考慮して次に作る機能は?
いいね、その前提なら“すぐ効く順”でこれを作るのが最短です。各項目は**完成定義(DoD)**と**最小コード断片**まで落とし込みました。
# 1) 震源→到達時間v0(安全側近似)
**目的**: 「あと何分?」に即答(まずは簡易モデル)。
**DoD**: `route_latest` に `arrival_time_min`, `height_class`, `confidence` を追記して保存。
**やること**
* 震源点(緯度経度)と自宅最寄り海岸線点の距離`D`を計算
* 代表水深`h_rep`で c≈√(g·h_rep)(保守的に**遅め**で見積り)
* `arrival_time_min = D / c / 60`(分)
* 波高は「不明なら ‘unknown’」、速報値が入手できたら `height_class` に格納
def arrival_time_min_km(d_km, h_rep=3000): # m
import math
g=9.81; c=math.sqrt(g*h_rep) # m/s
return (d_km*1000)/c/60
# 保存時に route_latest の属性へ追記
route_gdf["arrival_time_min"] = [arrival_time_min_km(D_km)]
route_gdf["height_class"] = ["unknown"]
route_gdf["confidence"] = ["low"] # v0は保守的
```
# 2) 「安全エリア」ポリゴン生成(反転×等時間到達圏)
**目的**: 地図で「今向かうべき範囲」を1枚で示す。
**DoD**: `safe_area_now` と `isochrone_walk_
**やること**
* 浸水想定を反転(`safe = study_area – tsunami_inundation`)
* 歩行速度4.8km/hで `Y = min(arrival_time*0.7, 20)` 分の等時間到達圏(graph isochrone)
* `safe_area_now = safe ∩ isochrone`
(等時間到達圏は既存グラフ`G2`から到達ノード抽出→凸包/マルチポリゴン化でOK)
—
# 3) 自動実行パイプライン(CLI化)
**目的**: トリガーが来たら無人で回る。
**DoD**: `python evac_pipeline.py –home 34.728,137.978 –quake 33.0,138.5 –radius 12000` で
`roads_safe`,`shelters_safe`,`route_latest`,`safe_area_now` が更新され、LINE/音声に通知。
**雛形**
# evac_pipeline.py
import argparse
def main():
ap=argparse.ArgumentParser()
ap.add_argument("--home", required=True) # "lat,lon"
ap.add_argument("--quake", required=True) # "lat,lon"
ap.add_argument("--radius", type=int, default=12000)
ap.add_argument("--notify", default="line,voice")
args=ap.parse_args()
# 1) データ更新→ 2) ルート再計算→ 3) 到達時間→ 4) 安全エリア→ 5) 保存→ 6) 通知
# (既存コードを関数化して順番に呼ぶ)
if __name__=="__main__":
main()
—
# 4) GraphDB(Neo4j) スキーマ初期化
**目的**: 「質問に答えられる」グラフへ。
**DoD**: `Schema v1` が作成され、`Route(latest=true)` が常に1本だけ存在。
**Cypher(最小)**
CREATE CONSTRAINT shelter_id IF NOT EXISTS FOR (s:Shelter) REQUIRE s.sid IS UNIQUE;
CREATE CONSTRAINT route_id IF NOT EXISTS FOR (r:Route) REQUIRE r.rid IS UNIQUE;
UNWIND $shelters AS s
MERGE (sh:Shelter {sid:s.sid})
SET sh.name=s.name, sh.lat=s.lat, sh.lon=s.lon, sh.safe=s.safe;
MERGE (h:Home {hid:'home-1'}) SET h.lat=$home.lat, h.lon=$home.lon;
WITH $route AS r
MERGE (rt:Route {rid:r.rid})
SET rt.meters=r.meters, rt.eta_walk=r.eta_walk, rt.eta_walk_safe=r.eta_walk_safe,
rt.arrival_time_min=r.arrival_time_min, rt.height_class=r.height_class,
rt.created_at=r.created_at, rt.latest=true;
MATCH (h:Home {hid:'home-1'}), (best:Shelter {sid:$best_sid})
MERGE (h)-[:SAFE_PATH_TO {mode:'walk'}]->(best);
MATCH (x:Route {latest:true}) WHERE x.rid <> $route.rid
SET x.latest=false;
—
# 5) 緊急ダッシュボード(Folium MVP)
**目的**: 家族が1枚で把握。
**DoD**: `outputs/evac.html` に以下が出る。
* `route_latest`(距離/徒歩ETA/安全係数/推定到達までX分)
* `safe_area_now`(半透明塗り)
* 「Googleマップで開く」直リンク
**追加断片**
folium.GeoJson(safe_area_now.__geo_interface__, name="安全エリア", style_function=lambda x: {
"fillOpacity":0.25, "weight":0
}).add_to(m)
gmap_url=f"https://www.google.com/maps/dir/?api=1&destination={dest_pt.y},{dest_pt.x}&travelmode=walking"
folium.Marker([dest_pt.y, dest_pt.x],
popup=f"<a href='{gmap_url}' target='_blank'>Googleマップで開く</a>",
icon=folium.Icon(color='blue')).add_to(m)
—
# 6) 期限ウォッチャ(非常食)
**目的**: 「切れてた」を無くす。
**DoD**: SQLite(またはNeo4j)から**14日以内期限**を抽出し、朝9時にLINE/音声通知。
**SQL 例**
SELECT name, qty, expiry_date
FROM supplies
WHERE DATE(expiry_date) <= DATE('now','+14 day')
ORDER BY expiry_date ASC;
—
# 7) イベントトリガー(擬似EEW→本番)
**目的**: 自動化の完成。
**DoD**: ダミーの震源JSONを受けて③のCLIを起動→将来EEW/津波情報に差し替え。
**擬似Webhook**
curl -X POST http://localhost:8080/quake \
-H "Content-Type: application/json" \
-d '{"lat":33.0,"lon":138.5,"mag":7.6,"depth_km":20}'
—
## 実装順(2スプリント想定)
1. **③ CLI化** → 既存処理の関数化・引数化
2. **1) 到達時間v0** → `route_latest` 属性追加
3. **2) 安全エリア** → 反転×等時間到達圏を保存&Folium表示
4. **5) ダッシュボード** → GMapリンク・要点表示
5. **4) GraphDB投入** → Route/Shelter/関係だけ先行
6. **6) 期限ウォッチャ** → 朝9時通知
7. **7) 擬似EEWトリガー** → 自動化通し
必要なら、上記の**等時間到達圏(isochrone)生成関数**と**Neo4j投入用の具体的なPythonコード**をすぐ出します。どこから書くか一言くれたら、その部分を一気に仕上げます。
ということでまずは
上記の等時間到達圏(isochrone)生成関数から作成