見出し画像

Pythonで扱う地理情報データ! 面と点の内外判定で土砂災害警戒区域の「盲点」を探る

こんにちは。朝日新聞社メディア研究開発センターの石井奏人です。

突然ですが、みなさんは土砂災害警戒区域についてご存知でしょうか。
土砂災害が起こる危険性のある箇所を、各都道府県が土砂災害防止法に基づき指定したものです。

では、どれほどの土砂災害が実際に警戒区域の中で起きているのでしょうか。
朝日新聞社では、土砂災害警戒区域と、2021年、2022年に起きた土砂災害の発生箇所を分析し、「警戒区域の外」で起きた土砂災害を探しました。

分析の結果は、朝日新聞・朝日新聞デジタルの記事として公開されています。
取材と記事の執筆を社会部、分析をメディア研究開発センターが担当しました。記者とエンジニアによるデータジャーナリズムの成果となりますのでぜひご覧ください!

今回のテックブログでは、土砂災害警戒区域の分析を題材として、Pythonを用いた地理情報データの分析、特にポリゴンデータ(面)とポイントデータ(点)の内外判定についてお話しします。


どうすれば判定できるのか

土砂災害が警戒区域の中で起きているかどうかは、どのように判定できるでしょうか。

シンプルに、土砂災害警戒区域を「面」、土砂災害発生箇所を「点」として考えると、それぞれの「点」が「面」の中に入っているかどうかをひとつひとつ判定していけば、区域の内外を判定できそうです。

警戒区域の中か外を「面」と「点」で考える

しかし、データの数が大量にある場合はどうすればいいでしょうか。

国土交通省への情報公開請求により入手した土砂災害発生箇所のデータを見ると、日本では2年間で1700件を超える土砂災害が起きていました(2021年、2022年)。
この大量のデータを、土砂災害警戒区域のデータと手作業で照らし合わせるのはなかなか難しそうです。

ただ、このデータには、住所のみならず、緯度、経度が含まれていました。
また、土砂災害警戒区域のデータも、国土数値情報ダウンロードサイトから正確なデータがダウンロードできます。

これらの地理情報データを活用すれば、機械的に判定していくことができそうです。

今回は、Pythonで使える地理情報分析ライブラリGeoPandasを用いて、土砂災害警戒区域と、実際の発生箇所の内外判定を行います。

1. 土砂災害警戒区域のデータを読み込む

まずは土砂災害警戒区域のデータを読み込みます。
こちらは「面」のデータで、ポリゴンデータと呼ばれます。

記事では全国の警戒区域に対する分析結果を紹介していますが、今回は、サンプルとして神奈川県のデータのみを使います。

GeoPandasをimportし、ファイルを読み込みます。
警戒区域は現象の種類(急傾斜地の崩壊、土石流、地すべり)ごとに設定されています。こちらも記事に用いた分析では全ての現象に対して分析しましたが、ここではシンプルに急傾斜地の崩壊に絞って分析します。

読み込みができたら、そのまま簡単にplotしてみます。

import geopandas as gpd

# geojsonデータの読み込み(パスは適宜書き換えてください)
gdf_polygon = gpd.read_file("../data/geojson/A33-22_14Polygon.geojson")

# 急傾斜地の崩壊に絞る
gdf_polygon = gdf_polygon[gdf_polygon["A33_001"]==1]

gdf_polygon.plot()
神奈川県の土砂災害警戒区域

背景の地図などもなく、警戒区域をプロットするだけで神奈川県のシルエットが浮かび上がりました。神奈川県内の広い範囲に土砂災害のリスクがあることがわかります。

これで、土砂災害警戒区域のデータを読み込むことができました。

2. 土砂災害発生箇所のデータを読み込む

次に、土砂災害発生箇所のデータを読み込みます。
こちらは「点」のデータで、ポイントデータと呼ばれます。
今回は、急傾斜地の崩壊が起きた箇所を想定した、3件のサンプルデータを用います。

住所,緯度,経度
神奈川県Axxx,35.58273,139.60755
神奈川県Bxxx,35.46240,139.53478
神奈川県Cxxx,35.45484,139.29259

緯度と経度を含むデータをcsvなどの形式にすることで、地理情報のポイントデータとして読み込むことができます。

import pandas as pd
from shapely.geometry import Point

# CSVデータの読み込み(パスは適宜書き換えてください)
point_df = pd.read_csv("../data/csv/sample_point.csv")

# GeoDataFrameの作成
geometry = [Point(xy) for xy in zip(point_df['経度'], point_df['緯度'])]

# geometryが緯度経度であることを指定
gdf_point = gpd.GeoDataFrame(point_df, geometry=geometry)
gdf_point

ここまででデータの読み込みは完了です。
試しに、先ほどの警戒区域のデータと重ねてplotしてみます。

import matplotlib.pyplot as plt

# ポリゴンとポイントを重ねてプロット
fig, ax = plt.subplots()
gdf_polygon.plot(ax=ax) # 警戒区域(ポリゴン)
gdf_point.plot(ax=ax) # 発生箇所(ポイント)
plt.show()
土砂災害警戒区域と土砂災害発生箇所(サンプル)

先ほどの警戒区域のデータと重ねて、土砂災害発生箇所のデータを表示できました。
ただ、これが警戒区域の中か外かは、このままではわかりません。

3. 警戒区域の内外判定

データを読み込むことができたので、それぞれの土砂災害発生箇所が警戒区域の中で起きているかどうかを判定しましょう。
ポイントデータが、ポリゴンの中に含まれるかどうかはwithinメソッドを使って判定できます。

警戒区域は細かく分割されたポリゴンデータとなっており、ひとつひとつに対して判定するのは非効率なので、はじめに結合した上で、判定します。

# ポリゴンを結合
gdf_polygon_union = gdf_polygon.union_all()

# ポイントごとに内外判定
gdf_point["区域内"] = gdf_point.apply(lambda row: row.geometry.within(gdf_polygon_union), axis=1)
gdf_point[["住所", "区域内"]]


# 以下のような出力となる
# 住所	区域内
# 0	神奈川県A市xxx	False
# 1	神奈川県B市xxx	True
# 2	神奈川県C市xxx	True

これで、この例では最初のデータのみが、区域の外で起きた災害であることがわかりました!
このように、地理情報データ同士の内外判定により、「土砂災害警戒区域の外」で起きた土砂災害を分析できます。

おわりに

今回は、土砂災害警戒区域に対する分析を題材に、Pythonを用いてポリゴンデータ(面)とポイントデータ(点)の内外判定をする方法を紹介しました。

災害はいつ起きるかわかりません。
土砂災害に限らず、日頃から備えておきたいと思います。
今回の分析と取材によって書き上げられた記事もあらためて読んでいただければ幸いです。

(メディア研究開発センター・石井奏人)