突然の降雪・雨・降雪・強風・急激な気温変化・また降雪、、と雪崩を否応なく意識させられる時期です
雪崩の危険回避にはそもそもコンディションの悪いときに入山しないことが最重要ですが、「情報収集のなかで気象条件側へ注意を割くあまり山の斜面構造へ注意を向けきれないことがあるな」と個人的に感じたのでヤマレコユーザーとして比較的とりやすい対策を考えてみました
特に、斜度30度超の雪崩危険箇所が登山ルートのうちどのあたり・どの程度の範囲に分布しているかを簡単に把握できると見通しがよくなりそうです
(斜度30度〜 で雪崩事故へつながりやすい面発生雪崩の発生危険が大きくなるためです。詳しくはJANの雪崩基礎知識 - 雪崩地形 を参照ください https://snow.nadare.jp/basic/unit_3.html )
地理院地図で等高線をもとに地形推測するのはもちろん重要ですが、縮尺と等高線を意識して斜面の構造を正確に想像するのは結構難しいです
ヤマレコの山行計画機能に表示される標高グラフも参考になる情報ですが、アクセス用の林道が長大なルートでは横軸のダイナミックレンジが低下するため情報として精度が悪化します
地理院地図Vectorの断面機能を併用する方法も検討しましたが、gpxから変換したKMLファイルを流し込んでも私の手元環境ではうまく断面出力できませんでした
「ここは急登です」というタイプのコメントを記載頂いているレコなどをありがたく参考にさせてもらったりもするのですが、どうしても主観から切り離しにくい部分があります
このため、ヤマレコのらくルートで作成した計画から取り出せるgpxファイルをデータ処理することで実際に自分が通ろうとしている登山道の斜面がどの程度の急勾配なのかを手軽でいながらそれなりに正確に把握することを検討してみました
いくつか試行錯誤した結果
視覚的把握方法:
- 緑:±15度
- 黄:±30度
- 赤:それよりもキツい
という色分け
把握方法:
・gpxトラックのwaypointsをもとに「縦軸:斜度(%よりdegree)」「横軸:累積距離」のグラフを生成し、ざっくり把握
・同、地図上へトラックをマッピングして拡大縮小しつつ詳細検討
という構成が個人的にはしっくり来ました
もちろんすべての山行をしっかり準備して実施するのが理想ではありますが、慎重に練った計画ばかりではなく天候にあわせて状況よさそうな山域を直前チョイスすることもあるでしょう
そういった際にざっとデータ処理してみることで雪崩を含む危険箇所に気付けると嬉しいかなと思いました
実際のコードはPythonなのでPython実行環境が前提となります
分かりやすい例として、上高地出発で槍ヶ岳の頂上を目指す山行計画を作成しました
https://www.yamareco.com/modules/yr_plan/detail-3969841.html
横尾まわりでひたすら距離の長い、一部の登山者には不人気な人気ルートです
これだけルートが長いとヤマレコの標高グラフから勾配を正確に読み取るのはまずムリです
早速、この山行計画からgpxファイルをエクスポートして今回の手法の生成結果を見てみます
累積距離対斜度のグラフが1枚目、ルート全図と該当部分の地図拡大画像が2-3枚目です
添付の斜度グラフによると槍沢大曲りから先が黄色、時折赤くなっています
結果のなかで面白くそして落とし穴でもあり注意が必要なのは、つづら折りで登っていく部分(急斜面を長いトラバースで稼ぐパターンも同様です)が斜度ゆるめと判定されるところです
添付3枚目がその拡大です
これはレコを読んでいるだけでは案外気付かないところで、ヤマレコ運営による丁寧なルート設定のおかげでもあります
こういう箇所を登山道で黙々と登っている際の体感は「あまり急ではない道」という側なのですが、雪崩という文脈で捉えた場合には「斜度がキツくないはずなのに雪崩リスクが高い斜面」ということになるため、地図をインタラクティブに拡大縮小しながら状況理解を深めるという使い方がとてもよさそうです
そして「登山道としては緩やかだけど実際には急な斜面っぽいな」という場所を絞り込めたら地理院地図Vectorで断面チェックをして斜度を正確に把握する、という応用もアリな感じです
仮に急ごしらえの計画であっても(ここで例に挙げた槍ヶ岳の計画は20秒で作りました。もちろん今は行きません)、ほんの1-2分時間を確保すれば地形に対する理解度を上げて山行の安全度を高められる、と考えるとなかなか良い方法であるように思いました
◆ 補足事項
ヤマレコのらくルートで作った計画からエクスポートしたgpxファイルに含まれる標高データをどの程度信用してよいか、というのが今回のデータ処理において割とクリティカルな点なのですが
手元のチェック範囲において、guchi999さんのGPXeditで国土地理院の標高タイルを適用したgpxファイルとの差分も確認してみた範囲ではあまり大きな違いはないようでした
このあたりはどちらかというとスマホからアップロードされたログに含まれる標高データを直接ダウンロードして利用する際にどうなるか、という話であるように思います
ご承知のとおりGPSで拾う標高データはほとんどのパターンでメチャクチャな値になり、L1Sの補強信号対応端末以外ではまず使い物になりません
また、以前個人的にSpresenseを試した限りだとL1Sでfixした状態でも周辺状況(電波反射するビル陰)によっては厳しい結果だったので山行中でも尾根ならともかく谷や崖付近の歩行では結構厳しいでしょう
(gpxログをヤマレコ経由でダウンロードするとヤマレコ内部で標高タイル適用処理をしてくれている? と期待はしますが未確認です)
◆ コード
それぞれpastebinに貼り付けておきました
1. 画像作成のほう
https://pastebin.com/vYD9MVCw
2. 地図生成のほう(地理院地図版。おすすめ)
https://pastebin.com/CPwJ40WU
3. 地図生成のほう(OpenStreetMap版。最初に貼った画像はこれ。基本的に(2)の地理院地図版のほうがおすすめ)
https://pastebin.com/yw4YeE8s
pastebinがいつの日かサービス終了する可能性もありますし、最初に掲載していた画像出力のほうのChatGPTで生成したコード全文は残しておきます(インデントがぶっ壊れますがHTMLソースには残っているので必要な方はソース表示からいい感じにコピペしてください)
pip install folium==0.16.0 geopy==2.4.1 matplotlib==3.8.3 numpy==1.26.4
でお願いします
import sys
import numpy as np # numpyをインポート
from geopy.distance import geodesic
import matplotlib.pyplot as plt
from xml.etree import ElementTree as ET
from math import atan, degrees
def parse_gpx(file_path):
ns = {'default': 'http://www.topografix.com/GPX/1/1'}
tree = ET.parse(file_path)
root = tree.getroot()
trkpts = root.findall('.//default:trkpt', ns)
data = []
for pt in trkpts:
lat = float(pt.attrib['lat'])
lon = float(pt.attrib['lon'])
ele = float(pt.find('default:ele', ns).text)
data.append((lat, lon, ele))
return data
def calculate_gradients_and_distances(data):
gradients_degrees = []
distances = [0] # 初期値として0を挿入
for i in range(1, len(data)):
point1 = data[i-1][:2]
point2 = data[i][:2]
ele1 = data[i-1][2]
ele2 = data[i][2]
segment_distance = geodesic(point1, point2).meters
gradient_percent = (ele2 - ele1) / segment_distance
gradient_degrees = degrees(atan(gradient_percent))
gradients_degrees.append(gradient_degrees)
distances.append(segment_distance)
cumulative_distances = np.cumsum(distances) # 累積距離を計算
return gradients_degrees, cumulative_distances
def plot_gradients(gradients_degrees, cumulative_distances, output_path):
colors = []
for gradient in gradients_degrees:
if -15 <= gradient <= 15:
colors.append('green')
elif -30 <= gradient <= 30:
colors.append('yellow')
else:
colors.append('red')
plt.figure(figsize=(10, 6))
plt.bar(cumulative_distances[:-1], gradients_degrees, width=np.diff(cumulative_distances), color=colors, align='edge')
plt.xlabel('Cumulative Distance (m)')
plt.ylabel('Gradient (degrees)')
plt.title('Gradient of Each Segment in Degrees Along the Track')
plt.savefig(output_path)
plt.close()
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python main.py <path_to_gpx_file>")
sys.exit(1)
gpx_file_path = sys.argv[1]
output_path = 'gradient_plot_degrees.png'
data = parse_gpx(gpx_file_path)
gradients_degrees, cumulative_distances = calculate_gradients_and_distances(data)
plot_gradients(gradients_degrees, cumulative_distances, output_path)
print(f"Gradient plot in degrees saved to {output_path}")
とても興味深い内容だったのでソースコードを使わせていただきました。
今後の登山計画の参考情報として使いたいと思います。
ありがとうございます。
初めまして! 興味を持って頂きありがとうございます
やはりちょっとペーストしにくいのに加えて、せっかくなので地図のほうも貼ってみました
画像作成のほう
https://pastebin.com/vYD9MVCw
地図生成のほう
https://pastebin.com/yw4YeE8s
ありがとうございます。
地図生成もうまく出来ました!
マップに表示させると見やすくていいですね。
地図のほうも試して頂きありがとうございます
ヤマレコユーザーとしてはやはり地理院地図のほうが等高線も見れて安心なので、地図を地理院タイルへ差し替えた版のコードも掲載しておきます
https://pastebin.com/CPwJ40WU
あわせてこの日記の本文も更新いたしました
関心を示してくださる方が居ないと億劫で手を付けずじまいだったと思いますので感謝しております!
コメントを編集
いいねした人
コメントを書く
ヤマレコにユーザー登録いただき、ログインしていただくことによって、コメントが書けるようになります。ヤマレコにユーザ登録する