国土数値情報「海岸線」データ(全国版 Shapefile)

国土数値情報「海岸線」データ(全国版 Shapefile)のURL
を調べたが全国版はない

都道府県別に Shapefile 形式や GML 形式で取得可能な国土数値情報「海岸線」データのダウンロードページがある

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-C23.html?utm_source=chatgpt.com
が海岸線データのリンクだけど
最新のデータは2006年度(平成18年度)版

他を調べてみると

の情報があった
https://nlftp.mlit.go.jp/ksj/index.html

これらを元にGPTで調べてみる

📊 スクショにあるデータの役割
* 津波浸水想定区域データ
→ 津波が来た場合の浸水範囲(自治体がハザードマップで使う)。
* 洪水浸水想定区域データ
→ 河川ごと、メッシュごとの洪水想定範囲。
* 高潮・雨水出水・多段階浸水データ
→ 津波以外の沿岸・豪雨災害関連のリスク領域。
* 避難所・避難道路系(行政区、緊急輸送道路など)
→ 避難経路や防災拠点の把握に必須。

🌊 あなたの用途別の適材適所
1. 「海岸線」データ(国土数値情報 2006年版)
* 海と陸の境界を決める基盤。
* 最新ではないが行政基準値。
* → 基準線として使う。
2. スクショの「津波浸水想定区域データ」
* シミュレーション済みの「どこまで水が来るか」。
* → 津波到達後の浸水エリア算出に必須。
3. スクショの「洪水・高潮データ」
* 津波以外のリスクも扱える。
* → 家族の防災マップを広くカバー。
4. 避難所・緊急輸送道路データ
* 実際の「どこに逃げるか」「どう行くか」。
* → GraphDBの避難所ノード・道路ノードに登録。

✅ 推奨データ利用の組み合わせ
* ベース地図:
* 国土数値情報「海岸線」 + OSM Coastlines(更新補完)
* リスク領域:
* 津波浸水想定区域データ(スクショにある)
* 洪水・高潮想定区域データ
* 地形:
* DEM(国土地理院/GEBCO)
* 避難系:
* 避難所・緊急輸送道路・行政区データ
* GraphDB:
* ノード:震源・海岸線・浸水想定区域・避難所・道路・家族
* リレーション:到達時間・避難経路・所要時間・備蓄品

🔑 結論:
スクショにある「津波浸水想定区域データ」や「洪水浸水想定区域データ」は 必ず併用すべきデータ です。
単なる「海岸線」だけでは津波到達範囲はわからないので、
* 海岸線 = 境界線
* 浸水想定区域 = 被害範囲
として 両方組み合わせるのがベスト

まずは居住区域のみで作成して動くようなら適用範囲を拡大していく

pip install geopandas shapely rtree pyproj osmnx networkx fiona

で必要なパッケージのインストール

📦 パッケージ解説
1. GeoPandas
* 役割: pandas の DataFrame に地理情報(ポリゴンやポイントなどのジオメトリ)を扱えるようにした拡張版。
* 特徴:
* shapefile や GeoJSON など GIS ファイルを直接読み書きできる。
* 空間結合(spatial join)、バッファリング(一定距離の範囲作成)、重なり判定などが簡単にできる。
* 用途例: 避難所の位置と自宅の位置から最寄り避難所を検索。

2. Shapely
* 役割: ジオメトリ(点、線、面)の作成・操作・解析を行うライブラリ。
* 特徴:
* ポリゴンの交差判定やバッファリング、距離計算が可能。
* GeoPandas 内部でも Shapely が使われている。
* 用途例: 津波の浸水範囲ポリゴンと建物の位置の交差判定。

3. Rtree
* 役割: 空間インデックスを構築して、高速に空間検索を行うためのライブラリ。
* 特徴:
* 例えば「ある点から半径 1km 以内の避難所を検索」といった処理が高速化できる。
* GeoPandas で .sindex を使うと裏で Rtree が動作。
* 用途例: 半径○km以内の避難場所を効率的に抽出。

4. PyProj
* 役割: 座標系(緯度経度、UTMなど)の変換を行うライブラリ。
* 特徴:
* EPSG コードを指定して座標変換ができる。
* GeoPandas で .to_crs() を使うと内部で PyProj が使われる。
* 用途例: 世界測地系(WGS84, EPSG:4326)から日本の平面直角座標系(EPSG:6677など)への変換。

5. OSMnx
* 役割: OpenStreetMap (OSM) データを Python で取得・解析するライブラリ。
* 特徴:
* 道路ネットワークや建物形状を簡単にダウンロード可能。
* networkx 形式で道路ネットワークを解析できる。
* 用途例: 自宅から避難所までの徒歩ルート検索。

6. NetworkX
* 役割: グラフ(ネットワーク)解析ライブラリ。
* 特徴:
* 最短経路探索、中心性、連結成分などのネットワーク理論を使った解析が可能。
* OSMnx が取得した道路データを解析するのに必須。
* 用途例: 最短避難経路の算出(Dijkstra アルゴリズムなど)。

7. Fiona
* 役割: 各種 GIS ファイルの入出力を行うためのライブラリ。
* 特徴:
* shapefile や GeoJSON を読み込むときに GeoPandas が内部で使用。
* GDAL(GIS の基盤ライブラリ)の Python バインディング的な存在。
* 用途例: 国土地理院の災害情報シェープファイルの読み込み。

🔗 関係性まとめ
* GeoPandas = GIS用 DataFrame(中心的存在)
* 内部で Shapely(ジオメトリ処理)、PyProj(座標変換)、Fiona(ファイルIO)、Rtree(高速検索)を利用。
* OSMnx = OpenStreetMap から道路や建物を取得 → NetworkX で解析。

✅ あなたの防災マップ用途との対応
* 津波浸水範囲と建物位置の判定 → Shapely / GeoPandas
* 避難所の検索(近い順) → Rtree / GeoPandas
* ルート案内 → OSMnx + NetworkX
* 座標変換(地図投影法の切り替え) → PyProj
* データの入出力(shapefile, GeoJSONなど) → Fiona

👉 この7つをまとめてインストールしておくと、ほぼ PythonでGIS + 避難経路システムを自作できる環境が揃います。

まずは全国ではなく居住区域の静岡県のみで作成して、テストして動くようなら適用範囲を拡大していく

まずは静岡県のみで最小セットを作って、表示・経路探索・レイヤ結合が全部通るか確認

「海岸線(KSJ)+津波浸水想定(KSJ)+道路(OSM)+避難所(自治体オープンデータがあれば)」をGeoPackage 1ファイルにまとめて、テスト用に「自宅→最寄り避難所の最短経路(浸水域は回避)」まで動かす

使うデータ(静岡県のみ)
* 海岸線:国土数値情報 C23 海岸線(Shapefile/GML)
※ページ:国土数値情報ダウンロード → C23(都道府県別を選択して「静岡県」をDL)
* 津波浸水想定区域:国土数値情報(都道府県別配布の「津波浸水想定」)
※静岡県のファイルをDL
* 道路:OSMnxでOSMから静岡県全域の道路グラフを取得(最新更新が反映されやすい)
* 避難所:静岡県/市町のオープンデータ(CSV/GeoJSON、なければ後で追加)
ポイント
* 最初は海岸線+津波浸水+道路の3つでOK。
* 経路探索やバッファ計算など**距離単位(m)**が必要になるので、計算時は **WGS84/UTM Zone 54N(EPSG:32654)**に投影して処理します(静岡は概ね54N)。

このために必要なファイルのダウンロード
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-C23.html?utm_source=chatgpt.com
から海岸線データのダウンロード
今回は静岡県のみ

次に
津波浸水想定区域データのダウンロード
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-A40-2024.html
からダウンロード
これもまずは静岡県のみ
ただし更新が2016年になっている
他の地域だと2024年まで更新されている

難所:静岡県/市町のオープンデータ(CSV/GeoJSON、なければ後で追加)
をやろうとしたけど
居住の市にCSVファイルがない…

https://www.city.fukuroi.shizuoka.jp/opendata/opendata/data/1490706118930.html

ふじのくにオープンデータカタログ
にあるらしいがリンクが違っているので検索する

https://opendata.pref.shizuoka.jp/dataset/

ふじのくにオープンデータカタログ

https://opendata.pref.shizuoka.jp/dataset/search/?s%5Barea_id%5D=36
に袋井市があった

指定緊急避難場所一覧
https://opendata.pref.shizuoka.jp/dataset/10246.html
最新版は
20250801_指定緊急避難場所一覧 (CSV 17.8KB)
なので
これをダウンロードする

次にプロジェクトフォルダの作成

mkdir FamilySafetyMap

名前を決めるのは苦手なので gemini を使った

源地から津波が到達するまでの時間と津波の高さを計算し GIS情報を使い避難するエリアを算出しルート案内できるようにしたい 家族の避難経路・地域防災マップをGraphDBで整理 避難所や重要連絡先も紐付け 使い方例: 「地震が来たら最寄りの避難所はどこ?」 「非常食の賞味期限が近いものは?」 など この用途で使うプロジェクトファイル名を決めたい。
使用するのは家族がメイン

実用・機能重視FamilySafetyMap家族の安全と地図(避難経路、GIS情報)という機能が明確。シンプルで覚えやすい。

が答え

cd FamilySafetyMap 
mkdir -p data/coastline_shizuoka/
mkdir -p data/tsunami_shizuoka/  

ファイルを設置しようとしたけど
どれを入れるかわからなくなったので

どっちが海岸線?どっちが津波浸水想定?
* C23-06_22_GML → 中に *_Coastline.* があり、これは 海岸線(C23)
例:C23-06_22-g_Coastline.shp ← これを 海岸線 として使う
* A40-16_22_GML → A40-16_22.* は 津波浸水想定区域(A40) のシェープ
つまり:
海岸線 = C23、津波浸水 = A40 です(認識を入れ替えてください)。

置くべきファイル(Shapefileの必須構成)
各フォルダに、少なくとも下記が同じ名前で揃っていればOK:
* *.shp(本体)
* *.shx(インデックス)
* *.dbf(属性)
* *.prj(座標系:あると良い・ほぼ入ってます)
*.xml(メタデータ)はあって良い(無くても読み込みは可能)。

あなたの手元の例
* 海岸線フォルダ(C23-06_22_GML)
* C23-06_22-g_Coastline.shp / .shx / .dbf / .prj … 使用するのはこれ
* C23-06_22-g.xml, KS-META-*.xml … メタデータ(任意)
* 津波浸水フォルダ(A40-16_22_GML)
* A40-16_22.shp / .shx / .dbf / .prj … これを使う
* A40-16_22.xml, KS-META-*.xml … メタデータ(任意)

スクリプトに設定するパス(例)

COAST_SHP   = "data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp"
TSUNAMI_SHP = "data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp"

あと
20250801_指定緊急避難場所一覧.CSV
の文字コードを調べる

file -I 20250801_指定緊急避難場所一覧.CSV
20250801_指定緊急避難場所一覧.CSV: text/csv; charset=unknown-8bit

となるので

brew install nkf uchardet

としたが

Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
    arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.

となる
久々で忘れていたけど
M1Mac の場合は

arch -arm64 brew install nkf uchardet

となる

uchardet 20250801_指定緊急避難場所一覧.CSV
SHIFT_JIS
 nkf -g 20250801_指定緊急避難場所一覧.CSV
CP932

このため

import pandas as pd
df = pd.read_csv("20250801_指定緊急避難場所一覧.CSV", encoding="cp932")

の文字コードはそのままにする

これらを元に

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
import osmnx as ox
import networkx as nx
import folium
import numpy as np
import os

# =========================
# 0) 入力(あなたの実ファイルに合わせて修正)
# =========================
COAST_SHP   = "data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp"  # C23=海岸線
TSUNAMI_SHP = "data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp"                # A40=津波浸水想定
SHELTER_CSV = "data/20250801_指定緊急避難場所一覧.CSV"                            # cp932想定

OUT_GPKG = "outputs/shizuoka_hazard.gpkg"
os.makedirs(os.path.dirname(OUT_GPKG), exist_ok=True)

# 自宅の位置(WGS84)※必ずあなたの座標に置換(lat, lon)
home_wgs = (34.728, 137.978)  # 例: 袋井市周辺

# OSM道路グラフ取得範囲(自宅中心 半径[m])
GRAPH_RADIUS_M = 10000  # 10km程度で様子見。広げたければ 15000~20000


# =========================
# 1) データ読み込み・CRS整備
# =========================
# 海岸線(C23)/ 津波浸水想定(A40)をWGS84に
coast = gpd.read_file(COAST_SHP)
if coast.crs is None:
    raise ValueError("海岸線ShapefileにCRSがありません(.prjが同フォルダにあるか確認)")
coast = coast.to_crs(4326)

tsunami = gpd.read_file(TSUNAMI_SHP)
if tsunami.crs is None:
    raise ValueError("津波浸水想定ShapefileにCRSがありません(.prjが同フォルダにあるか確認)")
tsunami = tsunami.to_crs(4326)
tsunami_union = tsunami.unary_union  # 高速化用

# 避難所CSV(cp932想定)→ 可能な列名を自動検出して点に
df = pd.read_csv(SHELTER_CSV, encoding="cp932")
# 緯度・経度列の候補(大小・日本語をカバー)
lat_candidates = 
lon_candidates = 

if not lat_candidates or not lon_candidates:
    raise ValueError("CSV内に緯度/経度の列が見つかりません。列名を教えてください。")

lat_col = lat_candidates[0]
lon_col = lon_candidates[0]

# 数値に変換(欠損/文字混入対策)
df[lat_col] = pd.to_numeric(df[lat_col], errors="coerce")
df[lon_col] = pd.to_numeric(df[lon_col], errors="coerce")
df = df.dropna(subset=[lat_col, lon_col])

shelters = gpd.GeoDataFrame(
    df.copy(),
    geometry=gpd.points_from_xy(df[lon_col], df[lat_col], crs="EPSG:4326")
)

# 浸水域外の避難所のみを「安全」とする
safe_shelters = shelters.loc[~shelters.intersects(tsunami_union)].copy()


# =========================
# 2) 道路グラフ(OSMnx)
# =========================
# 自宅中心の徒歩グラフ(避難行動向け)。範囲広すぎると重いので半径で制限
G = ox.graph_from_point(home_wgs, dist=GRAPH_RADIUS_M, network_type="walk", simplify=True, retain_all=False)
nodes, edges = ox.graph_to_gdfs(G, nodes=True, edges=True)
# 以降WGS84で統一
if edges.crs is None:
    edges.set_crs(4326, inplace=True)
elif edges.crs.to_epsg() != 4326:
    edges = edges.to_crs(4326)

# 浸水域と交差する道路エッジを除去(形状は切らず、そのまま抜く)
bad = edges.intersects(tsunami_union)
edges_keep = edges.loc[~bad].copy()

# 使われるノードだけに絞る
used_node_ids = pd.unique(edges_keep[["u", "v"]].values.ravel())
nodes_keep = nodes.loc[nodes.index.isin(used_node_ids)].copy()

# サブグラフ再構築
G2 = ox.utils_graph.graph_from_gdfs(nodes_keep, edges_keep, graph_attrs=G.graph)

# =========================
# 3) 出発・目的地ノード
# =========================
home_point = Point(home_wgs[1], home_wgs[0])

# 目的地:安全な避難所のうち「自宅に最も近い」1つ(直線距離)
if len(safe_shelters) == 0:
    # もし全て浸水域なら、とりあえず最も近い避難所を使う(要検討)
    target_shelters = shelters.copy()
else:
    target_shelters = safe_shelters.copy()

# 距離計算はメートル系CRSで
METRIC_CRS = "EPSG:32654"  # 静岡周辺
tp = target_shelters.to_crs(METRIC_CRS)
hp = gpd.GeoSeries([home_point], crs=4326).to_crs(METRIC_CRS).iloc[0]
tp["__dist_m__"] = tp.geometry.distance(hp)
dest_pt = target_shelters.loc[tp["__dist_m__"].idxmin(), "geometry"]

# 近傍ノード
orig = ox.distance.nearest_nodes(G2, X=home_point.x, Y=home_point.y)
dest = ox.distance.nearest_nodes(G2, X=dest_pt.x, Y=dest_pt.y)

# =========================
# 4) 最短経路(浸水域エッジを除去済みグラフ)
# =========================
try:
    route = nx.shortest_path(G2, orig, dest, weight="length")
except nx.NetworkXNoPath:
    # 到達不能の場合は半径を増やす or 車道(network_type="drive")に切替など検討
    raise RuntimeError("安全な避難所へ到達するパスが見つかりません。半径を増やす/目的地を変更してください。")

# ルート形状(LineString)を作成
route_coords = [(G2.nodes[n]["x"], G2.nodes[n]["y"]) for n in route]
# GeoDataFrame化(WGS84)
route_gdf = gpd.GeoDataFrame(geometry=[gpd.GeoSeries([Point(xy) for xy in route_coords]).unary_union.convex_hull], crs=4326)
# ↑簡易化:見た目重視ならPolylineをFoliumへ直接渡す(下でやります)

# =========================
# 5) 出力(GeoPackage)& Folium 可視化
# =========================
# GPKGへ保存(必要なら既存を削除)
if os.path.exists(OUT_GPKG):
    os.remove(OUT_GPKG)

coast.to_file(OUT_GPKG, layer="coastline", driver="GPKG")
tsunami.to_file(OUT_GPKG, layer="tsunami_inundation", driver="GPKG")
shelters.to_file(OUT_GPKG, layer="shelters_all", driver="GPKG")
safe_shelters.to_file(OUT_GPKG, layer="shelters_safe", driver="GPKG")

# 走行可能エッジ(浸水交差なし)だけ保存
edges_keep.to_file(OUT_GPKG, layer="roads_safe", driver="GPKG")

# ルートはFolium用に直接線で描くので、GPKGは省略してもOK
# 保存したいなら下のようにLineStringを作って保存
from shapely.geometry import LineString
route_line = LineString(route_coords)
gpd.GeoDataFrame(geometry=[route_line], crs=4326).to_file(OUT_GPKG, layer="route", driver="GPKG")

print(f"✓ 出力: {OUT_GPKG}")

# Folium地図
m = folium.Map(location=[home_wgs[0], home_wgs[1]], zoom_start=12, control_scale=True)

# 津波浸水想定
folium.GeoJson(tsunami.__geo_interface__, name="津波浸水想定(A40)", tooltip=None).add_to(m)

# 海岸線
folium.GeoJson(coast.__geo_interface__, name="海岸線(C23)", tooltip=None).add_to(m)

# 避難所(安全/全体)
folium.GeoJson(safe_shelters.__geo_interface__, name="安全な避難所", 
               marker=folium.CircleMarker(radius=4),
               tooltip=folium.GeoJsonTooltip(fields=[:5])
               ).add_to(m)
folium.GeoJson(shelters.__geo_interface__, name="避難所(全体・灰)", 
               marker=folium.CircleMarker(radius=3, color="gray", fill=True),
               tooltip=folium.GeoJsonTooltip(fields=[:3])
               ).add_to(m)

# ルート線(G2ノード列から)
route_latlon = [(G2.nodes[n]["y"], G2.nodes[n]["x"]) for n in route]
folium.PolyLine(route_latlon, weight=5, opacity=0.9, tooltip="避難経路").add_to(m)

# 出発/目的地
folium.Marker(location=[home_wgs[0], home_wgs[1]], popup="現在地", icon=folium.Icon(color="green")).add_to(m)
folium.Marker(location=[dest_pt.y, dest_pt.x], popup="避難所", icon=folium.Icon(color="blue")).add_to(m)

folium.LayerControl().add_to(m)
m  # Jupyterならこれで表示。スクリプトなら m.save("evac.html")

としたが

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 33
     31 coast = gpd.read_file(COAST_SHP)
     32 if coast.crs is None:
---> 33     raise ValueError("海岸線ShapefileにCRSがありません(.prjが同フォルダにあるか確認)")
     34 coast = coast.to_crs(4326)
     36 tsunami = gpd.read_file(TSUNAMI_SHP)

ValueError: 海岸線ShapefileにCRSがありません(.prjが同フォルダにあるか確認)

対処としては
海岸線(C23)の .prj が無いため CRS が未設定になっています。
C23 の公式仕様は JGD2000(経緯度) です。つまり EPSG:4612 を与えればOK。

対処方法は
A40(津波浸水想定)は配布物に .prj が入っていることが多いので、そのまま読める想定です。データ仕様の説明はここ(CRSは配布年度によりJGD2000/2011ですが、多くは .prj に記載あり)

coast = gpd.read_file(COAST_SHP)
if coast.crs is None:
    # C23 海岸線は JGD2000 (経緯度) → EPSG:4612
    coast = coast.set_crs(epsg=4612)
coast = coast.to_crs(4326)  # Folium等で扱いやすいWGS84へ

もしくは
コマンドで WKT を出して .prj として保存

# EPSG:4612 のWKTを出力(どちらか)
gdalsrsinfo EPSG:4612 -o wkt > C23-06_22-g_Coastline.prj
# または
projinfo EPSG:4612 --wkt2=EPSG > C23-06_22-g_Coastline.prj

念のための確認ポイント
* coast.total_bounds を見て、経度 ~122–154、緯度 ~20–46 の範囲に収まっていれば経緯度(度)の座標と判断可。
* メタデータXML(C23-06_22-g.xml など)に「座標系: JGD2000 / (B,L)」の記述があります。国土数値情報
これで ValueError は解消できます。次に進めて、浸水域クリップや経路探索を回してみてください

GPTで
対処(最短)と代替(.prj を作ってしまう) どちらが良い? その根拠は?
と調べてみる

結論:.prj を作って“直す”方(恒久対処)がオススメ。
理由は下記のとおりです。
どちらが良い?(要点)
* .prj を作成(恒久対処)
* 一度直せば QGIS/GeoPandas/同僚PC すべてで自動認識。再発しない。
* 将来の再利用・共有・配布に強い(ミスの温床を潰せる)。
* 前提:正しいCRSが確定していること(C23=JGD2000)。国土数値情報
* コード内で set_crs(暫定対処)
* いま手元のスクリプトをすぐ動かすなら最短。
* ただし、毎回コード側で設定を忘れるリスク、他ツール(QGIS等)を使うたびに同じエラーが再発。
このC23「海岸線」は仕様上 JGD2000(緯度経度)= EPSG:4612。
一方、A40「津波浸水想定」は JGD2011(緯度経度) が明記されています(年度によるが少なくとも2020版でJGD2011)。
→ どのみち最終的に同一CRS(例:WGS84=EPSG:4326)へ統一してから解析・可視化します。

これを実行するためのコマンドをインストール

arch -arm64 brew install gdal proj

🧭 1. PROJ(座標変換ライブラリ)
概要
PROJ は、地理座標系(緯度・経度など)と投影座標系(メートル単位の平面座標など)を相互変換するためのオープンソースライブラリです。
* URL: https://proj.org/
* 開発元: OSGeo Foundation
* 最新バージョン例: PROJ 9.x(2025年現在)
主な機能
機能 説明
座標変換 緯度経度(WGS84など)↔ 平面直角座標(UTM、EPSG:2451など)の変換
測地計算 2点間距離、方位角などを地球楕円体上で計算
EPSG対応 EPSGコード(例: 4326, 6674, 2451など)を使って簡単に座標系を指定可能
datum変換 世界測地系(WGS84)↔ 日本測地系(Tokyo Datum)などの変換
WKT/WKT2対応 座標系定義をWKT形式で入出力できる
利用例(コマンドライン)

projinfo EPSG:4326

→ WGS84の詳細を表示します。

🌍 2. GDAL(Geospatial Data Abstraction Library)
概要
GDAL は、地理空間データ(ラスタ・ベクタ形式)を読み書き・変換するためのライブラリ群です。
* URL: https://gdal.org/
* 開発元: OSGeo Foundation
* Pythonから利用するときは import gdal または from osgeo import gdal として使用可能。
主な機能
分類 説明
ファイル形式サポート GeoTIFF, Shapefile, GPKG, KML, GML, CSV, NetCDF など300以上
座標変換 内部的にPROJを使用して座標系を変換
ベクタ操作 属性情報付きの地理データ(例: Shapefile)を読み書き
ラスタ操作 画像や地形データ(DEMなど)の切り出し、リサンプリング、投影変換
コマンドツール ogr2ogr, gdalinfo, gdalwarp, gdalsrsinfo など多機能CLIツールを提供
利用例

gdalinfo sample.tif

→ GeoTIFFファイルのメタデータ(座標系・範囲など)を表示。

ogr2ogr -f "GPKG" output.gpkg input.shp

→ ShapefileをGeoPackage形式に変換。

🧠 まとめ
項目 内容
PROJ 座標変換ライブラリ(EPSGコード、測地変換)
GDAL 地理空間データ入出力ライブラリ(ShapefileやGeoTIFFの変換)
arch -arm64 Apple SiliconでARMネイティブ実行を強制
主な用途 GeoPandas, Rasterio, QGIS, OSMnx, PyProjなどのPython地理ライブラリの基盤

インストール完了後

==> Running `brew cleanup gdal`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Running `brew cleanup proj`...
==> No outdated dependents to upgrade!

となるので
バージョンを確認

 gdalinfo --version

を実行するとGPTで書いてあったが

GDAL 3.11.4 "Eganville", released 2025/09/04

 projinfo --version
Unrecognized option: --version
usage: projinfo [-o formats] [-k crs|operation|datum|ensemble|ellipsoid] [--summary] [-q]
                ([--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]) 
                [--spatial-test contains|intersects]
                [--crs-extent-use none|both|intersection|smallest]
                [--grid-check none|discard_missing|sort|known_available] 
                [--pivot-crs always|if_no_direct_transformation|never|{auth:code[,auth:code]*}]
                [--show-superseded] [--hide-ballpark] [--accuracy {accuracy}]
                [--allow-ellipsoidal-height-as-vertical-crs]
                [--boundcrs-to-wgs84]
                [--authority name]
                [--main-db-path path] [--aux-db-path path]*
                [--identify] [--3d]
                [--output-id AUTH:CODE]
                [--c-ify] [--single-line]
                --searchpaths | --remote-data |
                --list-crs [list-crs-filter] |
                --dump-db-structure [{object_definition} | {object_reference}] |
                {object_definition} | {object_reference} |
                (-s {srs_def} [--s_epoch {epoch}] -t {srs_def} [--t_epoch {epoch}]) |
                ({srs_def} {srs_def})

-o: formats is a comma separated combination of: all,default,PROJ,WKT_ALL,WKT2:2015,WKT2:2019,WKT1:GDAL,WKT1:ESRI,PROJJSON,SQL
    Except 'all' and 'default', other format can be preceded by '-' to disable them

list-crs-filter is a comma separated combination of: allow_deprecated,geodetic,geocentric,
geographic,geographic_2d,geographic_3d,vertical,projected,compound

{object_definition} might be a PROJ string, a WKT string, a AUTHORITY:CODE, or urn:ogc:def:OBJECT_TYPE:AUTHORITY::CODE

となる

正確には

proj          

を実行

Rel. 9.7.0, September 1st, 2025
usage: proj [-bdeEfiIlmorsStTvVwW [args]] [+opt[=arg] ...] [file ...]

これで準備ができたので
.prj を作成
海岸線の .shp と同じフォルダ(= data/coastline_shizuoka/C23-06_22_GML)で、同じベース名の .prj を作ればOKです。
(津波浸水想定 A40 側は既に A40-16_22.prj があるので不要)

とのことなので

cd data/coastline_shizuoka/C23-06_22_GML

次にコマンドの実行だが
提案されたコマンドは2つ

# どちらか一方でOK(ESRI形式のほうがShapefileと相性が良い)
gdalsrsinfo EPSG:4612 -o wkt_esri > C23-06_22-g_Coastline.prj

# または

projinfo EPSG:4612 --wkt2=EPSG > C23-06_22-g_Coastline.prj

どちらが良い?

結論:gdalsrsinfo -o wkt_esri を推奨です。
理由(短く)
* Shapefile は ESRI 由来なので、.prj は ESRI 方言(wkt_esri)が最も相性◎。
* 互換性が広い(ArcGIS/QGIS/古いツールでもズレにくい)。
* EPSG WKT2 でも動きますが、古いツールで軸順やデータム解釈の差がまれに出ます。

ということなので

gdalsrsinfo EPSG:4612 -o wkt_esri > C23-06_22-g_Coastline.prj

を実行

結果は

head -n 3 data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.prj

で確認

GEOGCS["GCS_JGD_2000",
DATUM["D_JGD_2000",

しかし

python - <<'PY'
import geopandas as gpd
gdf = gpd.read_file("data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp")
print(gdf.crs) # → EPSG:4612 と出ればOK
PY
None

となる

ベース名が1文字でも違う(拡張子以外が完全一致でない)
GDAL/FionaがESRI方言(wkt_esri)をうまく読めない環境
.prjは正しいが、別の場所の同名SHPを読んでいる/パス違い
まれに .prj はあるが内容が空/壊れている
が主な原因らしい

ls data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.*
data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.dbf
data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.prj
data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp
data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shx

次に

ogrinfo -so data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp C23-06_22-g_Coastline


OGRがSRSを認識しているか

ogrinfo -so data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp C23-06_22-g_Coastline
INFO: Open of `data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp'
      using driver `ESRI Shapefile' successful.

Layer name: C23-06_22-g_Coastline
Metadata:
  DBF_DATE_LAST_UPDATE=1941-11-24
Geometry: Line String
Feature Count: 1141
Extent: (137.484966, 34.572136) - (139.176559, 35.144928)
Layer SRS WKT:
(unknown)
C23_001: String (5.0)
C23_002: String (1.0)
C23_003: String (4.0)
C23_004: String (46.0)
C23_005: String (1.0)
C23_006: String (10.0)
C23_007: String (5.0)

これらにより
.prj を置いたのに GDAL が Layer SRS WKT: (unknown)。
これは その環境の GDAL/Fiona が WKT をうまく解釈できていない ケース

ogr2ogr -a_srs で“CRS付きの新ファイル”を作るのが一番おすすめです。
理由:
* その場しのぎではなく恒久対処(QGIS/GeoPandas/他PCでも確実に認識)。
* .prj の方言差や環境差に左右されにくい(今回まさに .prj を置いても読まれなかった)。
* 元データを壊さず安全に複製できる。

ということで
CRSを付与した“新しい”SHPを作成(EPSG:4612 = JGD2000)

cd data/coastline_shizuoka/C23-06_22_GML

で移動

ogr2ogr -a_srs EPSG:4612 C23_4612.shp C23-06_22-g_Coastline.shp

しかし

Warning 1: One or several characters couldn't be converted correctly from UTF-8 to ISO-8859-1.  This warning will not be emitted anymore.

となる

この警告は属性の文字エンコード(日本語)が
Shapefile の既定(ISO-8859-1)に合わず、
変換できない文字があったという意味で
幾何やCRS付与は完了しているが、属性が文字化けする可能性がある

解決策は
1) Shapefileのエンコーディングを指定して作り直す(手早い)
2) いっそ GeoPackage にする(おすすめ:今後楽)

どの方法が良いかを相談

コンセプトが

使用する用途のコンセプト また震源地から津波が到達するまでの時間と津波の高さを計算し 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でノード/リレーションを整理して「質問に答えられる防災知識ベース」を構築
なら、どの方法を推奨する?

結論:公的データ優先の“ハイブリッド型”を強く推奨します。
「浸水範囲は公式シミュ結果(A40)」「到達時刻・高さは公的速報を取り込む」「経路はOSM+浸水域回避」で組むのが、安全・現実的・拡張容易です。
推奨アーキテクチャ(段階導入)
フェーズ1:静岡・オフライン基盤(最小成功)
* 海岸線:KSJ C23(CRS整備済み)
* 津波浸水想定:KSJ A40(静岡)を絶対基準に採用
* 道路:OSMnx(walk/drive)取得 → A40と交差するエッジを除去
* 避難所:自治体CSV(cp932)→ GeoDataFrame(WGS84)
* 結果:
* 「自宅 → 最寄り“安全な”避難所」の最短経路
* 到達圏(isochrone):歩行/車速で10分・20分…を事前計算
* 保存:1つの GeoPackage(coastline / tsunami / roads_safe / shelters_safe / routes / isochrones)
ここまでで、「地震が来たら最寄りの避難所は?」に即答できます。
高度な波高計算はまだ入れず、安全サイドの浸水域回避を徹底。
フェーズ2:リアルタイム連携(到達“時刻”の提示)
* 到達時刻・津波高の“情報源”は公的速報(気象庁の津波警報・到達予想)。
* ワークフロー:
1. 速報の沿岸予報区ごとの到達見込み時刻/高さを取得
2. 県内の該当海岸セグメントへ付与(C23を海岸線ノードに分割)
3. 自宅の最短海岸ノードまでの**“海→陸の到達時刻”を速報値**で表示
4. ルート案内UIに「残り時間(ETA)」を明示(保守的に短めに表示)
物理モデルでの即時計算は難度・不確実性が高いので、公式速報を真に受ける方が安全かつ信用性◎。
どうしても“目安”を補うなら、深海平均水深での線形速波
c
=
g
h
c=gh による暫定下限ETAを併記(保守的に短く)。
フェーズ3:GraphDB連携(質問に答える防災知識ベース)
* ノード:Home / Shelter / RoadNode|RoadEdge / TsunamiPolygon(A40) / CoastNode / Item(備蓄) / Contact
* リレーション:ROUTE_TO(time,length) / INTERSECTS / AVOIDS / NEAREST / EXPIRING_SOON
* QA例:
* 「津波到達まで何分?」→ 最近接 CoastNode の公式ETA(フェーズ2)
* 「最短でどの避難所?」→ ROUTE_TO の最小 time を返す
* 「非常食の賞味期限近い?」→ EXPIRING_SOON <= 14d の Item 列挙 この方式を推す理由 * 安全性:浸水範囲は公式A40で担保。到達時刻・高さも公的速報準拠。独自計算の誤差リスクを避ける。 * 実装容易 & 拡張性:いまのPython+OSMnxコードの発展で実装可能。将来は別県や別ハザード(洪水・高潮)も流用可。 * 運用:GeoPackageに集約→QGIS/GeoPandas両対応。GraphDBで家族向けの質問応答が作りやすい。 実装メモ(最短でやるなら) * まずはフェーズ1を静岡で完成:A40で道路遮断 → 最短経路 & isochrone 出力。 * フェーズ2は速報取り込みのI/Oだけ追加し、海岸ノードにETA属性を付与。UIで「残り時間」を表示。 * すべて保守的(安全側)に倒す:ETAは短め、通行可能性に不確実があれば通れない扱い。 要約:
あなたの要求(精度・安全・拡張性)に最も合うのは、A40×OSM×公的速報のハイブリッド。
先に静岡でフェーズ1を完成させ、問題なければ**速報連携(フェーズ2)→GraphDB化(フェーズ3)**へ進めましょう。 となる つまり、今回なら 1) Shapefileのエンコーディングを指定して作り直す(手早い) 2) いっそ GeoPackage にする(おすすめ:今後楽) はどちらにする? それとも別の方法をとる? 結論:② GeoPackage(GPKG)に統一するのがベストです。 理由:文字化け・.prj問題・属性名10文字制限・2GB制限など Shapefileの弱点を一掃でき、今後の拡張(複数レイヤ管理、QGIS/GeoPandas/GraphDB連携)が安定します やることは 出力は一つの outputs/shizuoka_hazard.gpkg にレイヤ分けして格納 らしいが # 1) 海岸線(C23):CRS未付与なので付けてから WGS84 へ投影して GPKG へ を実行する前に気になるので確認しておく 現在 # 1) 海岸線(C23):CRS未付与なので付けてから WGS84 へ投影して GPKG へ[shell] ogr2ogr -a_srs EPSG:4612 -t_srs EPSG:4326 \ -f GPKG outputs/shizuoka_hazard.gpkg \ data/coastline_shizuoka/C23-06_22_GML/C23-06_22-g_Coastline.shp \ -nln coastline [/shell] # 2) 津波浸水想定(A40):.prj あり → そのCRSから WGS84 へ投影して同じ GPKG に追加[shell] ogr2ogr -t_srs EPSG:4326 \ -f GPKG -update outputs/shizuoka_hazard.gpkg \ data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp \ -nln tsunami_inundation[/shell] を実行する前のフォルダ構成として [shell] data/coastline_shizuoka/C23-06_22_GML C23-06_22-g.xml C23_4612.dbf C23-06_22-g_Coastline.dbf C23_4612.prj C23-06_22-g_Coastline.prj C23_4612.shp C23-06_22-g_Coastline.shp C23_4612.shx C23-06_22-g_Coastline.shx KS-META-C23-06_22-g.xml[/shell] となっているが .prj ファイルは一度削除した方が良いか? 結論:消さなくてOKです。 大事なのは「どのSHPを入力に使うか」と「source SRS を明示して出力する」こと。GPKGを作るときに正しく指定すれば、フォルダ内に .prj が残っていても問題ありません 既にCRS付きコピーを作ってあるので、それを入力にして WGS84 で GPKG に出力すればOK 先に outputsフォルダの作成が必要なので [shell] cd -[/shell] で移動しておく ~/aw10s/FamilySafetyMap へ移動して [shell] mkdir -p outputs[/shell] でフォルダ作成し[shell] ogr2ogr -t_srs EPSG:4326 \ -f GPKG outputs/shizuoka_hazard.gpkg \ data/coastline_shizuoka/C23-06_22_GML/C23_4612.shp \ -nln coastline[/shell] で 既にCRS付きコピーを作ってあるので、それを入力にして WGS84 で GPKG に出力。 動作確認[shell] ogrinfo -so outputs/shizuoka_hazard.gpkg coastline INFO: Open of `outputs/shizuoka_hazard.gpkg' using driver `GPKG' successful. Layer name: coastline Metadata: DBF_DATE_LAST_UPDATE=2025-10-10 Geometry: Line String Feature Count: 1141 Extent: (137.484966, 34.572136) - (139.176559, 35.144928) Layer SRS WKT: GEOGCRS["WGS 84", ENSEMBLE["World Geodetic System 1984 ensemble", MEMBER["World Geodetic System 1984 (Transit)"], MEMBER["World Geodetic System 1984 (G730)"], MEMBER["World Geodetic System 1984 (G873)"], MEMBER["World Geodetic System 1984 (G1150)"], MEMBER["World Geodetic System 1984 (G1674)"], MEMBER["World Geodetic System 1984 (G1762)"], MEMBER["World Geodetic System 1984 (G2139)"], MEMBER["World Geodetic System 1984 (G2296)"], ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]], ENSEMBLEACCURACY[2.0]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], USAGE[ SCOPE["Horizontal component of 3D system."], AREA["World."], BBOX[-90,-180,90,180]], ID["EPSG",4326]] Data axis to CRS axis mapping: 2,1 FID Column = fid Geometry Column = geom C23_001: String (5.0) C23_002: String (1.0) C23_003: String (4.0) C23_004: String (46.0) C23_005: String (1.0) C23_006: String (10.0) C23_007: String (5.0) ogrinfo -so outputs/shizuoka_hazard.gpkg tsunami_inundation INFO: Open of `outputs/shizuoka_hazard.gpkg' using driver `GPKG' successful. ERROR 1: Couldn't fetch requested layer tsunami_inundation. [/shell] となった tsunami_inundation レイヤが GPKGに存在していない いま入っているレイヤ一覧を確認[shell] ogrinfo outputs/shizuoka_hazard.gpkg INFO: Open of `outputs/shizuoka_hazard.gpkg' using driver `GPKG' successful. 1: coastline (Line String) [/shell] A40 のソースCRSを確認[shell] ogrinfo -so data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp A40-16_22 INFO: Open of `data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp' using driver `ESRI Shapefile' successful. Layer name: A40-16_22 Metadata: DBF_DATE_LAST_UPDATE=2016-12-08 Geometry: Polygon Feature Count: 113272 Extent: (137.483132, 34.594813) - (139.176599, 35.163526) Layer SRS WKT: GEOGCRS["JGD2011", DATUM["Japanese Geodetic Datum 2011", ELLIPSOID["GRS 1980",6378137,298.257222101, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], USAGE[ SCOPE["Horizontal component of 3D system."], AREA["Japan - onshore and offshore."], BBOX[17.09,122.38,46.05,157.65]], ID["EPSG",6668]] Data axis to CRS axis mapping: 2,1 A40_001: String (10.0) A40_002: String (2.0) A40_003: String (40.0) [/shell] この結果から A40 はちゃんと EPSG:6668 (JGD2011) で読めています。あとは GPKG に “追記” できればOK 進捗表示・無効ジオメトリを自動修復・マルチ化・空間インデックス作成する [shell] ogr2ogr -progress -t_srs EPSG:4326 \ -makevalid -nlt PROMOTE_TO_MULTI \ -f GPKG -update -lco SPATIAL_INDEX=YES -lco GEOMETRY_NAME=geom \ outputs/shizuoka_hazard.gpkg \ data/tsunami_shizuoka/A40-16_22_GML/A40-16_22.shp \ -nln tsunami_inundation [/shell] を実行 補足(なぜこのオプション?) * -update:既存 GPKG に 追記 * -nln tsunami_inundation:レイヤ名を固定 * -t_srs EPSG:4326:WGS84 に統一(Folium/QGISで扱いやすい) * -makevalid:自己交差などの 無効ポリゴンを自動修復(A40は件数多く、稀に必要) * -nlt PROMOTE_TO_MULTI:MultiPolygon に正規化(後段の処理が安定) * -lco SPATIAL_INDEX=YES:高速化のための 空間インデックス 付与 次に動作確認 [shell] ogrinfo -so outputs/shizuoka_hazard.gpkg tsunami_inundation INFO: Open of `outputs/shizuoka_hazard.gpkg' using driver `GPKG' successful. Layer name: tsunami_inundation Metadata: DBF_DATE_LAST_UPDATE=2016-12-08 Geometry: Multi Polygon Feature Count: 113272 Extent: (137.483133, 34.594813) - (139.176599, 35.163526) Layer SRS WKT: GEOGCRS["WGS 84", ENSEMBLE["World Geodetic System 1984 ensemble", MEMBER["World Geodetic System 1984 (Transit)"], MEMBER["World Geodetic System 1984 (G730)"], MEMBER["World Geodetic System 1984 (G873)"], MEMBER["World Geodetic System 1984 (G1150)"], MEMBER["World Geodetic System 1984 (G1674)"], MEMBER["World Geodetic System 1984 (G1762)"], MEMBER["World Geodetic System 1984 (G2139)"], MEMBER["World Geodetic System 1984 (G2296)"], ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]], ENSEMBLEACCURACY[2.0]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], USAGE[ SCOPE["Horizontal component of 3D system."], AREA["World."], BBOX[-90,-180,90,180]], ID["EPSG",4326]] Data axis to CRS axis mapping: 2,1 FID Column = fid Geometry Column = geom A40_001: String (10.0) A40_002: String (2.0) A40_003: String (40.0) [/shell] これだけだとわからないのでGPTで解説を依頼 これは `ogrinfo -so` コマンド(GDALのツール)で、 GeoPackage ファイル(`outputs/shizuoka_hazard.gpkg`)のレイヤー `tsunami_inundation`(津波浸水想定区域)に関する**メタデータと構造情報**を表示した結果です。 以下に各項目の意味を解説します👇 --- ## 🗂 基本情報 | 項目 | 内容 | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | **Open of ... using driver 'GPKG' successful** | GeoPackage 形式(`.gpkg`)のファイルを正常に開けたことを示します。GDALドライバ `GPKG`(GeoPackageフォーマット)を使用しています。 | | **Layer name: tsunami_inundation** | レイヤー名(地理データの層の名前)。ここでは津波浸水区域を示すレイヤーです。 | | **Geometry: Multi Polygon** | 地物のジオメトリ(形状)が「複数ポリゴン」で構成されていることを示します。津波の浸水区域など、面(エリア)を表現するために使われます。 | | **Feature Count: 113272** | 含まれる地物(フィーチャー)の総数。ここでは 113,272 個の津波浸水ポリゴンが含まれています。 | | **Extent: (137.483133, 34.594813) - (139.176599, 35.163526)** | データがカバーしている範囲の外接矩形(最小緯度経度と最大緯度経度)。静岡県の東西南北の境界座標です。 | | **Layer SRS WKT** | 空間参照系(Spatial Reference System)の詳細情報。ここでは世界測地系(WGS84 / EPSG:4326)です。 | --- ## 🌍 空間参照系(SRS: Spatial Reference System) ``` GEOGCRS["WGS 84", ... ID["EPSG",4326]] ``` これは座標系の定義で、簡単に言うと: * **EPSG:4326** → 世界測地系(WGS 84)。 GPSなどで使われる緯度経度座標系。 * **CS[ellipsoidal,2]** → 2次元の楕円体座標系(緯度・経度)。 * **PRIMEM["Greenwich",0]** → 基準子午線はグリニッジ子午線。 * **ANGLEUNIT["degree",...]** → 度単位で表されている。 つまり、データは**緯度経度(度単位)**で表現されており、地図投影(メートル単位の平面座標変換)はまだ行われていません。 --- ## 📊 属性カラム(テーブル構造) | カラム名 | データ型 | 意味(推定) | | ----------- | ------------- | -------------------- | | **A40_001** | String (10.0) | コードやID(市区町村や地域コードなど) | | **A40_002** | String (2.0) | 区分や種別(例:津波の想定区分など) | | **A40_003** | String (40.0) | 名称(例:「静岡県○○市△△地区」など) | これらのフィールド名は国土数値情報(国交省が公開する津波浸水想定データ)と一致しています。 具体的な意味はデータ仕様書により異なりますが、概ね以下の通りです: | フィールド名 | 意味(国交省仕様例) | | ------- | --------------------- | | A40_001 | 行政コード(市区町村コード) | | A40_002 | 津波区分(1:想定, 2:最大クラスなど) | | A40_003 | 地域名・想定名などのラベル | --- ## 🧭 Data axis to CRS axis mapping: 2,1 これは軸の並び順を示します。 * 通常は **(緯度, 経度)** の順ですが、 * このデータでは **(経度, 緯度)** の順に格納されていることを意味します。 GDALで処理する際、軸の順序に注意が必要です(例:FoliumやGeoPandasで描画する際に位置がズレる場合があります)。 --- ## 🔍 FID / Geometry Column | 項目 | 内容 | | -------------------------- | -------------------------- | | **FID Column = fid** | 各地物を識別する一意のID(Feature ID)。 | | **Geometry Column = geom** | ポリゴン形状が格納されているカラム名。 | --- ## 🧩 まとめ このGeoPackageは、 **「静岡県内の津波浸水想定区域」**をWGS84座標で格納したもので、 113,272件のポリゴンが `geom` フィールドに保存されています。 主な使い方の例: [shell] import geopandas as gpd gdf = gpd.read_file("outputs/shizuoka_hazard.gpkg", layer="tsunami_inundation") print(gdf.head()) ``` 出力例: | fid | A40_001 | A40_002 | A40_003 | geometry | | --- | ------- | ------- | ------- | ----------------- | | 1 | 22210 | 1 | 静岡市駿河区 | MULTIPOLYGON(...) | [/shell] ご希望であれば、このデータを **Folium地図上に可視化するコード例** や **GeoPandasでの属性抽出・座標変換(EPSG:4326 → EPSG:6677など)** の実例も示せます

震源地から津波が到達するまでの時間と津波の高さを計算

震源地から津波が到達するまでの時間と津波の高さを計算

✅ 津波の到達時間の基本式
津波は浅水波近似で速度が次の式で表されます:
v=√g⋅h

v:津波の速度 (m/s)
g:重力加速度 (9.81 m/s²)
h:海の水深 (m)


水深 4000 m → 速度 ≈ 200 m/s (720 km/h)
水深 100 m → 速度 ≈ 31 m/s (110 km/h)

✅ 津波の高さ(沿岸での増幅)
震源での初期波高
H
0
H0 は断層変位や地殻変動から推定されます。
沿岸での津波高さ
H
H は「グリーンの法則」によって水深比に応じて増幅します:

h0 :沖合の水深
h:沿岸の水深

つまり、水深が浅くなるにつれて波高は増大します。

✅ Pythonでの計算イメージ

import math

def tsunami_travel_time(distance_km, depth_m):
    g = 9.81
    v = math.sqrt(g * depth_m)  # m/s
    t_sec = (distance_km*1000) / v
    return t_sec / 60  # 分

def tsunami_height(H0, h0, h):
    return H0 * ((h0 / h) ** 0.25)

# 例: 震源から200 km, 平均水深 3000 m
t = tsunami_travel_time(200, 3000)
print(f"到達時間 ≈ {t:.1f} 分")

# 例: 初期波高 1m, 沖合水深 3000 m, 沿岸水深 10 m
H = tsunami_height(1.0, 3000, 10)
print(f"沿岸波高 ≈ {H:.2f} m")

✅ データが必要になる部分
* 震源位置と震源から沿岸までの距離 → ジオデータ(緯度経度)を使って測る
* 海底地形(バソメトリー)データ → GEBCO や NOAA の水深データが必要
* 初期波高 → 地震断層モデルから計算(研究所や気象庁の速報値を利用するのが実務的)

✅ まとめ
* 津波高さは「水深比の1/4乗則(グリーンの法則)」で沿岸増幅を近似
* 実務では GEBCO の海底地形データを組み合わせて地図上で計算する


震源地から津波が到達するまでの時間と津波の高さを計算し GIS情報を使い避難するエリアを算出しルート案内できるようにしたい

精密な津波シミュレータではなく、GIS+簡易物理モデルで「到達時間」「想定浸水域」「安全エリア」「避難ルート」を一気通貫で出す手順と最小コード


※簡易近似。自治体ハザードマップがあればそれを優先
1. 想定浸水域の作成(簡易版)
陸域DEMから標高閾値(例:満潮+推定波高+α)以下の連結領域を抽出し、海から連結する部分を浸水ポリゴンとする。
(精密な遡上計算は専門コードが必要。ここでは避難計画用の予防的ゾーニング)
2. 安全エリアの抽出
浸水ポリゴン外かつ標高>閾値(例:5–10m以上)&避難所候補のある場所を安全エリアとする。
3. 避難ルート
OSMnxで道路グラフを取得し、浸水ポリゴン内のエッジを除外して、現在地→最寄り安全避難所までの最短路(距離 or 時間)を算出。Foliumで地図化。

必要なパッケージ

pip install geopandas rasterio shapely numpy scikit-image osmnx folium contextily networkx

でインストール

ミニマル実装(雛形)
ファイルパスはあなたの環境に合わせて置き換え。座標系は**投影座標(m単位)**に揃えるのがコツ(例:対象地域のUTM帯、または EPSG:3857)。日本なら JGD2011 の平面直角系でもOK。

import numpy as np
import geopandas as gpd
import rasterio
from rasterio import features
from shapely.geometry import Point
from skimage.graph import route_through_array  # 1対1のとき
import osmnx as ox
import networkx as nx
import folium

# --------------------
# 0) 入力
# --------------------
epicenter_wgs = (35.5, 142.0)  # 例: 緯度, 経度(仮)
gebco_tif = "data/gebco_bathymetry.tif"   # 海底地形(m, 海は正の深さ or 負の標高のことも)
dem_tif   = "data/dem_coast.tif"          # 陸域標高(m)
coastline = gpd.read_file("data/coastline.gpkg")  # 海岸線
shelters  = gpd.read_file("data/shelters.geojson")# 避難所点データ(WGS84想定)

# 便利関数:WGS84→ラスタ座標系へ
def to_crs_point(lat, lon, crs_epsg):
    g = gpd.GeoSeries([Point(lon, lat)], crs=4326).to_crs(crs_epsg)
    p = g.iloc[0]
    return p.y, p.x  # (Y, X) in projected CRS

# --------------------
# 1) 海上到達時間ラスタ(簡易)
# --------------------
with rasterio.open(gebco_tif) as src:
    bathy = src.read(1).astype("float32")
    prof  = src.profile
    # 海域の水深(m)に統一(負の標高なら反転)
    depth = np.where(bathy < 0, -bathy, bathy)  # 例:負値を深さに
    depth = np.where(depth<=0, np.nan, depth)

    g = 9.81
    v = np.sqrt(g * depth)  # m/s
    cost = 1.0 / v          # s/m(セル通過時間はこれ×セルサイズ)

    # 震源セル
    epic_y, epic_x = to_crs_point(epicenter_wgs[0], epicenter_wgs[1], src.crs.to_epsg())
    row, col = src.index(epic_x, epic_y)

    # coast マスク(海→陸境界の近傍)を後で使うためにベクタ→ラスタ化しておくのも可

# ここではデモとして「震源→任意の海岸点」1対1のrouteで travel time を出す例。
# 実際は multi-source 最短時間(fast marching/多点Dijkstra)が望ましい。
# skimage.graphの route_through_array はコスト配列にセルサイズを掛けて合計。
# セルサイズ(m):
pix_m = (prof["transform"][0])  # x解像度(m/px)。投影ラスタ前提
# 到達時間ラスタの厳密生成はここでは割愛(本格的には多源最短経路/コスト距離を実装)

# --------------------
# 2) 浸水域(閾値で簡易)
# --------------------
with rasterio.open(dem_tif) as demsrc:
    dem = demsrc.read(1).astype("float32")
    # 仮の沿岸波高 H(m)を設定(現実は断層モデルや公表想定を用いる)
    H0 = 1.0      # 沖合初期波高 1 m(例)
    h0 = 3000.0   # 沖合水深 3000 m(例)
    h_coast = 10.0# 沿岸水深(例)
    H_coast = H0*((h0/h_coast)**0.25)

    tide = 0.5    # 満潮加算(例)
    safety_margin = 0.5
    flood_threshold = H_coast + tide + safety_margin  # m

    # 海から連結する低地 = 浸水候補
    flood_mask = (dem <= flood_threshold).astype(np.uint8)

# flood_mask をポリゴン化(例)
shapes = features.shapes(flood_mask, transform=demsrc.transform)
flood_polys = [sh for sh, val in shapes if val == 1]
flood = gpd.GeoDataFrame(geometry=gpd.GeoSeries.from_iterable(flood_polys), crs=demsrc.crs)

# 海から連結していない内陸窪地は除外(簡易には海ポリゴンとの接触でフィルタ)
# coastlineを同一CRSへ
coastline_proj = coastline.to_crs(flood.crs)
flood = flood[flood.intersects(coastline_proj.unary_union)].buffer(0)

# --------------------
# 3) 安全エリア&避難所(浸水域の外)
# --------------------
shelters_proj = shelters.to_crs(flood.crs)
safe_shelters = shelters_proj[~shelters_proj.intersects(flood.unary_union)]

# --------------------
# 4) 避難ルート(浸水域の道路を除外)
# --------------------
place = "Sumida-ku, Tokyo, Japan"
G = ox.graph_from_place(place, network_type="walk")  # 徒歩網の方が避難向き

nodes, edges = ox.graph_to_gdfs(G)
edges_proj = edges.to_crs(flood.crs)

# 浸水と交差するエッジを除外
bad = edges_proj.intersects(flood.unary_union)
edges_keep = edges_proj.loc[~bad]

# サブグラフ再構築
G2 = ox.utils_graph.graph_from_gdfs(nodes.to_crs(edges_keep.crs), edges_keep)

# 出発地(例:現在地)と最寄り安全避難所
current_wgs = (35.71, 139.81)  # 例
cur_pt = gpd.GeoSeries([Point(current_wgs[1], current_wgs[0])], crs=4326).to_crs(edges_keep.crs).iloc[0]
dest_pt = safe_shelters.geometry.iloc[0] if len(safe_shelters) else shelters_proj.geometry.iloc[0]

orig = ox.distance.nearest_nodes(G2, X=cur_pt.x, Y=cur_pt.y)
dest = ox.distance.nearest_nodes(G2, X=dest_pt.x, Y=dest_pt.y)

route = nx.shortest_path(G2, orig, dest, weight="length")

# --------------------
# 5) Foliumで可視化
# --------------------
center = (current_wgs[0], current_wgs[1])
m = folium.Map(location=center, zoom_start=13)

# 浸水域
flood_wgs = flood.to_crs(4326)
folium.GeoJson(flood_wgs.__geo_interface__, name="Flood (simple)").add_to(m)

# ルート
route_latlon = [(G2.nodes[n]["y"], G2.nodes[n]["x"]) for n in route]
folium.PolyLine(route_latlon, color="red", weight=5, opacity=0.9, tooltip="Evacuation Route").add_to(m)

# 出発・目的地
folium.Marker(location=[cur_pt.y, cur_pt.x], popup="Start", icon=folium.Icon(color="green")).add_to(m)
folium.Marker(location=[dest_pt.to_crs(4326).y, dest_pt.to_crs(4326).x], popup="Shelter", icon=folium.Icon(color="blue")).add_to(m)

# 避難所レイヤ
folium.GeoJson(safe_shelters.to_crs(4326).__geo_interface__, name="Safe shelters",
               tooltip=folium.GeoJsonTooltip(fields=[:4])
               ).add_to(m)

folium.LayerControl().add_to(m)

# Jupyterなら m だけで表示
m  # もしくは m.save("evac.html")

実装のコツ
* CRSを徹底:ラスタ・ベクタ・OSMのCRSを揃える(距離・面積は投影座標)
* 閾値は保守的に:不確実性を考慮し安全側に(潮位・護岸・地形・内水氾濫は別論点)
* 道路グラフのカット:浸水ポリゴンだけでなく河川・橋梁も個別判定できると尚良
* 到達時間:本気でやるなら海上は1/vのコスト面で多源最短時間、陸上は時々刻々の浸水到達時刻 vs. 歩行速度で**到達可能圏(isochrone)**を比較

重要な注意(精度・安全)
* ここで示したのは教育・訓練用の簡易推定です。実運用や避難計画は、自治体のハザードマップ・気象庁/JMA・国研のモデル結果を最優先してください。
* グリーンの法則や低地抽出は大まかな上限見積に有効ですが、局所地形(湾形状、護岸、河口、運河)で大きな差が出ます。

次の拡張
海上到達時間:ラスタ全域での多源Dijkstra / Fast Marching(skfmm等)で全海岸の到達時刻マップを作る
公式ハザードデータ(津波浸水想定、指定緊急避難場所)との連携

とりあえずコードを jupyter で実行してみる

PDFからGPTの連携

PDFからGPTの連携

chatGPT とPDFの連携
https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39774396?start=18#overview
を参考にする

ただしテキスト情報のみのPDFでの話

PDFと連携するには
まずPDFからテキスト情報を抽出する

PDFにはテキスト以外にも画像データがあるが
今回の講座は文字のみを想定

PDFから文字を抽出し
それが3000文字の場合
1000文字単位に分割すると3つの文章に分けることができる

ちなみにこっちは概要

https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39774404#overview

実践でllama index を使っている

https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39877052#overview
でPDFの差し替えが載っている

ただい、これだと画像の入っているPDFはできないので他を探す

graphDB graphRAG の他の用途

graphDB graphRAG の他の用途として
経済・金融データ分析
例: 経済指標・株価・商品価格・為替などの相関関係をグラフ構造に保存し、RAGで「現状と過去の類似パターン」を取得。
メリット:
価格・イベント・ニュースの因果関係を把握できる
RAGで時系列説明やリスク分析を生成可能
シナリオ:
質問:「過去10年間でWTIが急落したときの共通要因は?」
処理: GraphDBで急落イベントと関連経済指標を探索 → RAGが文章化

これを作成したい

GPTの答えを自分なりにまとめる

急落イベントの自動生成
閾値は2通り用意(どちらか一致でイベント化):
* 絶対閾値: return1d <= -0.05 * 統計的閾値: zscore <= -2.0 // 急落イベント生成 MATCH (a:Asset {symbol:"WTI"})-[:HAS_PRICE]->(p:Price)
WHERE p.return1d <= -0.05 OR p.zscore <= -2.0 MERGE (e:Event:PriceDrop {date:p.date, asset:"WTI"}) ON CREATE SET e.threshold = CASE WHEN p.return1d <= -0.05 THEN "ret<=-5%" ELSE "z<=-2" END MERGE (e)-[:ON_ASSET]->(a)
MERGE (e)-[:NEARBY_PRICE {lag:0}]->(p);

共起(要因候補)のひも付け
イベント±3営業日程度の窓で、関連しそうなファクトを CO_OCCURS_WITH で結ぶ。

// 経済指標サプライズと共起
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (ip:IndicatorPrint)
WHERE date(ip.date) >= date(e.date)-duration('P3D') AND date(ip.date) <= date(e.date)+duration('P3D')
MERGE (e)-[:CO_OCCURS_WITH {window:"±3d"}]->(ip);

// ドル指数(DXY)急騰など他資産の大変動
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (p:Price {asset:"DXY"})
WHERE date(p.date)=date(e.date) AND (p.return1d >= 0.01 OR p.zscore >= 2.0)
MERGE (e)-[:CO_OCCURS_WITH {window:"0d"}]->(p);

// ニュース(トピック抽出済み)も結ぶ
MATCH (e:Event:PriceDrop {asset:"WTI"}), (n:News)
WHERE date(n.date) >= date(e.date)-duration('P1D') AND date(n.date) <= date(e.date)+duration('P1D')
AND n.topic IN ["OPEC","在庫","中東地政学","需要見通し","景気後退懸念"]
MERGE (e)-[:CO_OCCURS_WITH {window:"±1d"}]->(n);

自動タグ付け(要因ノード化)
共起オブジェクトから 要因タグを抽出・集計して :Factor を作り、イベントと結ぶ。

// 例:DXY急騰なら「ドル高」を付与
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(p:Price {asset:"DXY"})
WHERE p.zscore >= 2.0 OR p.return1d >= 0.01
MERGE (f:Factor {name:"ドル高急伸"})
MERGE (e)-[:HAS_FACTOR {type:"market"}]->(f);

// 例:在庫サプライズ(EIA原油在庫が予想比+)
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(ip:IndicatorPrint)<-[:PUBLISHED_AS]-(:Indicator {code:"EIA_CRUDE_INV"})
WHERE ip.surprise > 0
MERGE (f:Factor {name:"EIA在庫予想超過(増)"})
MERGE (e)-[:HAS_FACTOR {type:"supply"}]->(f);

// 例:ニューストピックから
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(n:News)
WHERE n.topic IN ["OPEC","増産","協調減産不履行"]
MERGE (f:Factor {name:"OPEC供給ニュース"})
MERGE (e)-[:HAS_FACTOR {type:"policy"}]->(f);

回答から見ると
急落イベントの定義が必要

そして要員候補を定義し
Cyperで紐付け定義している
この要員候補が共起となるので

この共起をもとに
要因タグを抽出・集計して :Factor を作り、イベントと結ぶ

過去10年の共通要因」を求めるCypherを作成

ここまでできたら
GraphRAG(LlamaIndex例)
を作成

ゼロからやっていくとして やることの順番

0. 目的と範囲の固定(30分で決め切る)
目的:WTI急落の共通要因を、数値+ニュース根拠つきで説明・検知できる。
やること
* 期間:直近10年(例:2015-01-01〜)
* 対象:WTI, DXY, EIA原油在庫, 主要マクロ(CPI/NFP/ISM), ニュース見出し
* 急落定義:ret1d ≤ -5% または zscore ≤ -2
* 共起窓:±3日
完了条件:上記をREADMEに明文化。

1. 環境・リポジトリ準備
やること
* Gitリポジトリ作成:/graph-wti-poc
* Python 3.11系、仮想環境
* 依存:neo4j, pandas, numpy, python-dateutil, llama-index-graph-stores-neo4j, llama-index
* Neo4j(Docker可)起動、パスワード設定
完了条件:make setup && make testでimportなしのスモークテストが通る。

2. データの最小セットを落とす(まずはCSVでOK)
やること
* data/price_wti.csv(日次 Date, Close)
* data/price_dxy.csv
* data/eia_crude_inv.csv(週次 Date, actual, consensus)
* data/macro_{cpi,nfp,ism}.csv(Date, actual, consensus)
* data/news_titles.csv(Date, title, source, topic?)
完了条件:CSVが所定フォーマットで保存され、scripts/validate_csv.pyで列チェックOK。

3. グラフ・スキーマ定義
やること
* ノード:Asset, Price, Indicator, IndicatorPrint, News, Event:PriceDrop, Factor
* リレーション:HAS_PRICE, PUBLISHED_AS, ON_ASSET, NEARBY_PRICE, CO_OCCURS_WITH, HAS_FACTOR, MENTIONS
* インデックス/制約:Asset(symbol), Price(date,asset), Indicator(code), IndicatorPrint(date,code)
完了条件:scripts/init_schema.cypherを一発実行で作成される。

4. ETL(投入)——最小データ→Neo4j
やること
* scripts/load_assets.py(WTI/DXYなど)
* scripts/load_prices.py(ret1d/zscore計算込み)
* scripts/load_indicators.py(surprise = actual−consensus)
* scripts/load_news.py(topicは暫定でも可)
完了条件:Neo4j上でノード・関係の件数が期待範囲にある(簡易Cypherで確認)。

5. 急落イベント生成
やること
* jobs/mk_price_drop.cypher
* ルール① ret1d ≤ -0.05
* ルール② zscore ≤ -2.0
* イベント→資産・当日価格ノードへリンク
完了条件:MATCH (:Event:PriceDrop)で複数件が生成される。

6. 共起リンク付け(±3日)
やること
* jobs/link_cooccurrence.cypher
* Event ↔ IndicatorPrint(±3日)
* Event ↔ Price(DXY)(同日/±1日、急騰条件付き)
* Event ↔ News(±1日、topicフィルタ)
完了条件:各EventにCO_OCCURS_WITHが最低1件以上付く。

7. 要因タグ自動付与(Factor化)
やること
* ルールベースで開始(後でMLに発展)
* DXY急騰→「ドル高急伸」
* EIA在庫サプライズ>0→「在庫増サプライズ」
* News.topic in {OPEC, 需要減速, 地政学}→対応Factor
* jobs/mk_factors.cypher
完了条件:MATCH (e:Event)-[:HAS_FACTOR]->(f)がヒット、因子名の重複がない。

8. 集計クエリ(分析の芯)
やること
* TOP要因:頻度ランキング
* 事例リスト:各イベントと要因・信号の要約
* 反証:急落“でない”日との比較(同じ要因の出現率差)
完了条件:Cypher 3本がqueries/に保存され、結果がCSV/JSONで出力できる。

9. GraphRAG 接続(LlamaIndex最小構成)
やること
* Neo4j GraphStore接続
* ニュース本文(任意)をVector Index化
* 「イベント周辺サブグラフ抽出→要約」QueryEngine
完了条件:python rag_answer.py “過去10年のWTI急落の共通要因は?”が自然文で答えを返す。

10. 評価(人間の目で妥当性チェック)
やること
* ランダムに5〜10イベントを抽出し、当日の実ニュースと比較
* 誤検知/過検知の原因をメモ(topic付与・閾値調整など)
完了条件:改善ポイントのTODOが/docs/findings.mdにまとまる。

11. ルールのチューニング(再実行可能に)
やること
* 閾値・窓幅(±2/±3/±5日)、surpriseの標準化(z化)を切替可能に
* パラメタは.envやconfig.yamlへ
完了条件:make rebuild-with CONFIG=config.yamlで全処理が再実行できる。

12. アラート原型(将来の運用)
やること
* シンプルな条件2〜3本(例:WTI -3%以上&DXY +0.8%以上)
* 該当日の証跡(どの要因に引っかかったか)をテキスト生成
完了条件:CLIで日次スキャン→標準出力に最新ヒットを表示。

13. 可視化ミニUI(任意:後付け)
やること
* Streamlit or Dash
* タイムライン(急落イベント)
* ヒートマップ(要因×年)
* クリックで当日の共起ニュース・指標を展開
完了条件:ローカルで1ページ表示、スクリーンショット保存。

14. データ運用・再現性
やること
* Makefile:make all, make clean
* 週次/日次ジョブ(将来)向けに/jobs/を分離
* バックアップ手順(Neo4j dump, data/ バージョン付け)
完了条件:READMEに再現手順とバックアップ復元手順が記載。

まず動かす最短ルート(PoC 版)
1. 0→1→2(最小CSV)
2. 3(スキーマ)
3. 4(ETL投入)
4. 5(急落生成)
5. 6(共起リンク)
6. 8(要因TOP集計)
7. 9(RAG回答の骨格)
ここまでで**「数値+ニューストピックに基づく共通要因の説明」**が出ます。
その後、7(Factor強化)→11(チューニング)→12(アラート)→13(UI)で育てればOK。

分析に必要な各種経済指標のデータとの関連付け

分析に必要な各種経済指標のデータとの関連付け

AIによる時系列分析や予測において本当に必要なのは、
👉 「金価格(など予測対象)」と
👉 「各種経済指標との関連付け(=特徴量選定と因果仮説)」です。

✅ その理由(AIの本質に基づく)
AI(特にLSTMやProphetなどの時系列モデル)は、**「将来の値を予測するために、過去の関連データのパターンを学習」**します。
つまり:
* 単独の金価格系列では限界がある
→ 過去の金価格だけでは、政策変更・インフレ期待・為替変動に追いつけない
* 経済指標と結びつけてこそ「なぜ上がるか/下がるか」が予測できる
→ CPIの上昇やドル円の変動が金価格に与える影響など

✅ だから必要なのは「関連付け」=特徴量選定 + 時間的因果性
必要な処理 内容 例
📊 相関分析 金価格とCPI・WTI・ドル円の関係性を数値化 .corr() や ヒートマップ
🕒 ラグ特徴量 CPIやドル円の1日遅れ・1週間遅れの影響を追加 CPI_t-1, USDJPY_t-7
⛓ 因果関係の仮説 「インフレ率が上がると金が買われる」など CPI↑ → 金価格↑
⚙ 特徴量エンジニアリング 変化率、移動平均、ボラティリティなどの導入 ΔCPI, SMA_20

✅ 例:金価格を予測するための特徴量候補
特徴量 説明
CPI 消費者物価指数(インフレ期待)
WTI 原油価格(インフレ・景気指標)
USDJPY 為替(円安→金価格上昇しやすい)
金価格_t-1 前日終値
ΔCPI CPIの変化量(前月比)
SMA_20_gold 20日移動平均(トレンド)
金/CPI比 実質金価格(インフレ調整後価格)

✅ まとめ:分析に本当に必要なのは?
項目 必要性 補足
📈 チャート表示 ✅ 人間の理解に必要 傾向・異常・変動要因の発見
📊 指標との関連付け ✅ AI予測精度に不可欠 入力特徴量(多変量予測)
🧠 因果仮説 ✅ 分析の出発点 「何が影響しているか」をモデルに伝える

✅ 次にできること
* 🧠 特徴量エンジニアリングの開始(変化率・ラグ・差分)
* 📦 SQLiteやNeo4jで「日付→経済指標→金価格」の関連構造を保持
* 🔮 ProphetやLSTMにマルチ変数として入力して予測

ご希望あれば、次のステップとして:
* ✅ 「金価格予測用の学習データ(特徴量セット)」を自動生成するスクリプト
* ✅ 「影響度の高い特徴量ランキング」分析
* ✅ 「変化率・ラグ特徴量」を生成するコード
などご案内可能です。どこから進めたいですか?

ChatGPT に質問する
あなた:
FX、為替の分析をしたい場合、必要となる指標は? できるかぎり集めたいので、必要な指標を全て示して

ChatGPT:
素晴らしい取り組みです!
FX(外国為替)・為替レートの分析を本格的に行うために必要となる経済指標・市場指標・ポジションデータを、以下にカテゴリ別・優先度付きで網羅的に整理しました。

✅ 【最重要】中核となる経済指標(為替を動かす主要因)
カテゴリ 指標名 FREDコード / 取得元 内容
🧑‍💼 雇用 非農業部門雇用者数(NFP) PAYEMS(FRED) 米国雇用統計の中心指標、サプライズで為替が大きく動く
👷‍♂️ 失業率 失業率 UNRATE(FRED) 労働市場の健全性を反映
📈 インフレ CPI(消費者物価指数) CPIAUCSL(FRED) インフレ率(注目度高)
📊 物価 PCEコアデフレーター PCEPILFE(FRED) FRBが重視する物価指標
📦 生産 鉱工業生産 INDPRO(FRED) 経済活動の実態を示す
🛒 消費 小売売上高 RSXFS(FRED) 個人消費の強さを表す
🏛 金融政策 政策金利(FF金利) FEDFUNDS(FRED) FOMCの最終利上げ判断指標
📈 金利差 米・日本の10年債利回り差 DGS10 / JP10Y 長期金利差は為替の方向を決定

✅ 【重要】短期変動・投機を捉えるための指標
カテゴリ 指標名 取得先 内容
💼 ADP雇用統計 ADP民間雇用者数 ADP公式 NFPの先行指標(民間推計)
🏗 ISM製造業/非製造業 PMI指標 ISM公式 景気の加熱・冷え込みを評価
🌍 貿易 貿易収支 NETEXP(FRED) 国際収支・通貨需要を反映
🧾 財政 政府財政収支 FRED / 統計局 政策余地・財政リスクの判断
💬 FOMC発言 FOMCドットチャートや声明 FRB公式 将来の金利動向を織り込む判断材料

✅ 【ポジション系】センチメント分析に不可欠な指標
カテゴリ 指標名 取得先 内容
📊 IMMポジション 通貨先物建玉(Netポジ) CFTC(毎週金曜) 投機筋の動向を把握(過熱判断)
💹 リスク指標 VIX指数(恐怖指数) VIXCLS(FRED) リスクオン/オフの判定に重要
📈 株式指数 S&P500, NASDAQなど SP500(FRED)など リスク資産への流入・退避確認
🏦 金利先物 FedWatch、SOFR先物 CMEなど 金利の織り込みを可視化

✅ 【通貨ごとに重視される補足指標】
🇺🇸 米ドル(USD):
* GDP(GDPC1)
* フィラデルフィア連銀指数(PHIIND)
* シカゴ購買部協会指数
🇯🇵 円(JPY):
* 日銀政策金利(BoJ)
* コアCPI(日本)
* 実質実効為替レート(REER)
🇪🇺 ユーロ(EUR):
* ドイツIFO景況感指数
* ユーロ圏CPI
* ECB政策金利
🇨🇳 人民元(CNY):
* 中国GDP・CPI・製造業PMI
* 人民元中間値(CNH基準値)

✅ 【補足】その他考慮すべき指標
カテゴリ 指標名 内容
📊 景気動向指数 景気先行指数(USSLIND)
🏡 住宅関連 住宅着工件数(HOUST)、中古住宅販売
🏦 中央銀行バランスシート FRB、ECB、BoJなど
🛢 コモディティ 金価格(GC=F)、原油(CL=F)、銅など

✅ 分析に使えるデータソース一覧
データソース 内容 APIなど
FRED 米経済指標(無料) pandas_datareader
CFTC IMMポジション Excel or スクレイピング
TradingEconomics 世界の経済指標 REST API(有料もあり)
Yahoo Finance 為替・コモディティ yfinance
Quandl 金利・コモディティ・COT 一部無料・有料
Investing.com イベントカレンダー スクレイピング or 手動

✅ 次におすすめのステップ
1. ✅ 必要指標リストをCSVで保存 or 管理
2. ✅ FREDやYahooから取得スクリプトを一括作成
3. ✅ SQLiteやNeo4jに格納 → 分析&予測

必要であれば:
* ✅ 上記リストをCSVファイルにして渡す
* ✅ FREDなどから自動取得するスクリプト
* ✅ SQLiteへ連携するコード
など、あなたの分析基盤を整える形でサポート可能です。
次に進めたいステップを教えてください!

これで気になることは
* 🧠 特徴量エンジニアリングの開始(変化率・ラグ・差分)
* 📦 SQLiteやNeo4jで「日付→経済指標→金価格」の関連構造を保持 はこの順番で行う? それとも別の案件になる?

この2つは基本的に同じ分析プロジェクトの中で「役割が違うだけ」

✅ それぞれの役割の違い
ステップ 目的 主なツール タイミング
🧠 特徴量エンジニアリング モデルの精度を上げるために、学習用データを整備する pandas, numpy, scikit-learn モデル構築前に必須
📦 SQLite/Neo4jへの関連構造保存 人が理解・探索・説明するための構造化された関係表現 SQLite, Neo4j, cypher 可視化・レポート・RAG/LLM活用に有効

関係性は
[時系列データの取得]

[SQLiteで一元管理] ─────→ (RAGやLLMとの連携)

[特徴量エンジニアリング(差分・変化率・ラグ)]

[AIモデル構築(LSTM・Prophet・回帰など)]

[結果をNeo4jに格納して因果関係として見える化]

となる

📌 現実的な実行順はこうなります:
1. ✅ SQLiteに元データを格納する(データ基盤を整える)
2. ✅ 特徴量エンジニアリングを行う(モデル用データを整える)
3. ✅ モデルで予測・分析する
4. ✅ 分析や因果関係を人が探索するためにNeo4jへ登録

✅ まとめ:分けるべきか?
条件 同一案件でOK 分けたほうが良い
モデル精度を高めたい ✅
モデルとLLM/RAGの両方やる ✅(役割分担すればOK)
LLM用に知識構造をつくりたい ✅ Neo4j中心の別構造として

✅ 提案:以下のように分けて設計するとスムーズです
モジュール名 内容
feature_engineering.py 差分・ラグ・変化率などを作成してCSV/DF化
store_data_sqlite.py すべての指標をSQLiteに保存・更新
export_to_neo4j.py 分析結果や関係性をグラフDBに格納
train_model.py LSTMやProphetで予測モデル構築