導入
森林のデータを可視化したり分析を行う機会があったので、それを使って何かできないかな〜と考えて思いついたので投稿してみます。
やりたいこととしては宮城県の南三陸町を対象に、カブトムシが好むクヌギやコナラの木が生えている地点はどこかをマップ上に表示するところをpythonを使いつつやろうと思います。
もし他のクワガタなどを狙う場合は、データの抽出対象をクヌギやコナラではなくターゲットに合わせた樹木に変更してみると良いかもしれません。
オープンデータの収集
まずは地域ごとにどんな植生が生えているかどうかを調査するために、オープンデータを収集します。
今回は環境省の植生調査データ(宮城県)を使用しました。
shapeファイルのマッピング
zipファイルをダウンロードしてきて、取得してきたデータのうち南三陸町が地図上のどの範囲に収まるかをpythonを使ってvscode上で確認してみます。shapeファイルは次の3つのファイルでひとまとまりです。
今回はGEO_PATHSに格納した4つのフォルダに入っているshape形式のデータが対象になります。
例 p584103.shp, p584103.dbf, p584103.shx
import geopandas as gpd
import folium
import pandas as pd
# 入力ファイルのパス
GEO_PATHS = [
'./vg67_04/shp584103/p584103.shp',
'./vg67_04/shp584104/p584104.shp',
'./vg67_04/shp574173/p574173.shp',
'./vg67_04/shp574174/p574174.shp',
]
# 複数のshpファイルを読み込み、結合
gdfs = [gpd.read_file(path, encoding='cp932') for path in GEO_PATHS]
gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
print(f'number of records = {len(gdf)}') # レコード数
# 植生データ:EPSG4612
gdf = gdf.set_crs("EPSG:4612")
print(gdf.head())
gdf.to_csv('geodata.csv', index=False)
# 中心座標を計算
center = gdf.geometry.centroid.unary_union.centroid
# folium地図作成
m = folium.Map(location=[center.y, center.x], zoom_start=12)
# GeoDataFrameを地図に追加
for _, row in gdf.iterrows():
# ポップアップに表示する属性情報を設定
popup_info = f"植生大区分: {row['SHOKU_N']}<br>植生中区分: {row['CHU_C']}<br>植生細区分: {row['SAI_N']}" # 必要な属性を指定
# ジオメトリにマーカーを追加
folium.GeoJson(
row['geometry'],
popup=folium.Popup(popup_info, parse_html=True),
tooltip=row['SHOKU_N'] # ツールチップに名前を表示
).add_to(m)
# 地図を表示
m
shapeファイルのデータの詳細をcsv形式で確認
データの詳細をわかりやすく表示するために先ほど出力したcsvファイルを確認し、クヌギとコナラのありそうなデータに絞ります。
…と思ったのですがまさかのクヌギがヒットせず。。
気になったのでクヌギの群生を調べてみると東北あたりにはかなり数が少なそうです。今回のデータが2013年採取ということも影響しているかもしれません。
データの絞り込みと再表示
ということで今回はコナラに絞ってデータを抽出するようにします。
先ほどのプログラムを以下のように書き換え、HANREI_Nがコナラ群落(V)のものに絞ってデータを表示しなおします。
import geopandas as gpd
import folium
import pandas as pd
# 入力ファイルのパス
GEO_PATHS = [
'./vg67_04/shp584103/p584103.shp',
'./vg67_04/shp584104/p584104.shp',
'./vg67_04/shp574173/p574173.shp',
'./vg67_04/shp574174/p574174.shp',
]
# 複数のshpファイルを読み込み、結合
gdfs = [gpd.read_file(path, encoding='cp932') for path in GEO_PATHS]
gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
print(f'number of records = {len(gdf)}') # レコード数
# 植生データ:EPSG4612
gdf = gdf.set_crs("EPSG:4612")
print(gdf.head())
gdf.to_csv('geodata.csv', index=False)
# HANREI_Nが「コナラ群落(V)」のデータだけを抽出
filtered_gdf = gdf[gdf['HANREI_N'] == 'コナラ群落(V)']
# 中心座標を計算
center = filtered_gdf.geometry.centroid.unary_union.centroid
# folium地図作成
m = folium.Map(location=[center.y, center.x], zoom_start=12)
# GeoDataFrameを地図に追加
for _, row in filtered_gdf.iterrows():
# ポップアップに表示する属性情報を設定
popup_info = f"植生大区分: {row['SHOKU_N']}<br>植生中区分: {row['CHU_C']}<br>植生細区分: {row['SAI_N']}" # 必要な属性を指定
# ジオメトリにマーカーを追加
folium.GeoJson(
row['geometry'],
popup=folium.Popup(popup_info, parse_html=True),
tooltip=row['SHOKU_N'] # ツールチップに名前を表示
).add_to(m)
# 地図を表示
m
結果はこのようになりました
まとめ
今回はコナラの木が生えている地域を可視化してみました。カブトムシがいるかどうかは他の条件もあるので、考慮して可視化できるとより精度が上がると思います。
たとえば樹液が出やすい木が多い=木を傷つけるカミキリムシや蛾の幼虫が生息しているかどうかなどですね。
まだまだ絞り込みなど工夫の余地があると思いますし、これの応用でアカマツの木が生えているところだけ可視化してキノコ狩りにも使えないかなあなんて思っています。