標高を知りたい
先日行った権現岳への山行の際、ログ取りを行っていたものの、センサーが外れてしまっており気圧と温度のログが取れていなかった。いつもはこれから高度を算出し山行時の高度の変化をグラフ化していたができなくなってしまった。幸い位置情報については取れていたため、ここからなんとかできんだろかと思った。
高度情報を提供しているAPI
まぁそういう情報提供しているAPIあるじゃろなーと軽い気持ちでググって出てきたものを見てみる。目的と外れるので詳細な比較とかはしてかない。
Google Maps JavaScript API

登録必要、有料。高度データは何を基にしてるか分かんない。
Open-Elevation API
登録不要、無料。簡単に使える。GETで1024バイトまで、POSTは制限なし(!)。高度データはSRTMが基らしい。
天女山駐車場 1546.0m
Open-Meteo Elevation API
スイスの気象関連の会社らしい。提供しているAPIの一つに高度がある。登録不要、無料。リミットはよく分かんない。これも簡単そう。Copernicus Digital Elevation ModelのGLO-90という全世界の90m四方解像度のデータを基にしているらしい。
天女山駐車場 1557.0m
Microsoft Bing Maps Elevations API

登録必要、価格はよく分からん。基データもよく分からん。
HUAWEI Elevation API
なんかあった。登録は必要そう。POSTのみ。
Opentopodata
色んなデータセットをまとめましたーって感じなんだろうか。無料のパブリックAPIは
- Max 100 locations per request.
- Max 1 call per second.
- Max 1000 calls per day.
という制限がある。↓で試してみたが他との差がすごい。
天女山駐車場 671.7135620117188m
国土地理院 サーバサイドで経緯度から標高を求めるプログラム
国土地理院の……APIといっていいと思うんですが。登録不要、無料で使える。制限は常識的な範囲での利用、とな。Yahooの標高APIとかでも使われてるデータから作られてるそう。データとしては実測値の最近点4点を平滑化したものだそう。
天女山駐車場 1533.4m
とまぁ色々見てきたけど結局国土地理院が無難かなー。あとは制限がかからないかがあれだけど。どれもこれも戻り値はJSONなのでやっぱJavascriptで書くのがいいんかな。ぶっちゃけあんまり好きじゃないんよね~。あとなんかCORSのエラーでそうー。
プログラムからWebAPIとやりとり
何の言語でやろうかな?というところで、悩ましい。もうVBAでいいんじゃないか。
VBA
ためしに
Sub req() Dim httpobj As XMLHTTP60 Set httpobj = New XMLHTTP60 httpobj.Open "GET", "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=138.3979072&lat=35.9216733&outtype=JSON" httpobj.send Do While httpobj.readyState < 4 DoEvents Loop Debug.Print httpobj.responseText End Sub
結果
{"elevation":1533.4,"hsrc":"5m\uff08\u30ec\u30fc\u30b6\uff09"}
いいですね~。JSONのパーサを使いましょう。
そしたらこう
Sub req() Dim httpobj As XMLHTTP60 Set httpobj = New XMLHTTP60 httpobj.Open "GET", "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=138.3979072&lat=35.9216733&outtype=JSON" httpobj.send Do While httpobj.readyState < 4 DoEvents Loop Dim Json As Object Set Json = JsonConverter.ParseJson(httpobj.responseText) Debug.Print Json("elevation") End Sub
結果
1533.4
ふむー。あとはもうログの1行ごとに取得するようにすりゃいいね。私は常識村の常識的な常識人なので1秒のスリープを入れておこう。
Sub req() Dim httpobj As XMLHTTP60 Set httpobj = New XMLHTTP60 For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row httpobj.Open "GET", "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=" _ & Range("D" & i).Value & "&lat=" & Range("C" & i).Value & "&outtype=JSON" httpobj.send Do While httpobj.readyState < 4 DoEvents Loop Dim Json As Object Set Json = JsonConverter.ParseJson(httpobj.responseText) Range("F" & i).Value = Json("elevation") Application.Wait Now() + TimeValue("00:00:01") Next i End Sub
こうの
こうなりました。意外ときれい。15000件とかだと15000/60/60で約4時間強……。センサーの接続はちゃんとチェックしようね。
Python
久しぶりにPython。単純に考えて、CSV読み込み→行ごとにAPIにアクセス→取得したデータを書き込み→CSVを出力って流れでできると思われる。
import csv
import time
import requests
l = []
with open("test.csv", "r") as f:
reader = csv.reader(f)
for row in reader:
url = (
"https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon="
+ row[3]
+ "&lat="
+ row[2]
+ "&outtype=JSON"
)
headers = {"User-Agent": "Mozilla/5.0"}
res = requests.get(url=url, headers=headers)
data = res.json()
row.append(data["elevation"])
l.append(row)
time.sleep(1)
with open("output.csv", "w", newline="") as f:
writer = csv.writer(f)
for row in l:
writer.writerow(row)
こう。で、追記済みのoutput.csvが出力される。いつもながらキレイに書けんなぁ。
ChatGPTとBardにレビューしてもらった
そういえば最近話題の対話型AIがレビューもできるって話なのでやってもらった。以下結果
ChatGPT
改善点と注意点:
-
- コードの機能は理解できましたが、エラー処理が不足しています。HTTPリクエストが失敗した場合やJSONデータの取得に問題がある場合に備えてエラーハンドリングを追加することが重要です。
- time.sleep(1)による1秒の待機は、サーバーへの負荷を軽減するためのものと思われますが、必要に応じて調整することができます。
- コード内の変数名やコメントは十分にわかりやすいですが、もし他の人がコードを読むことを考える場合、より詳細なコメントやドキュメンテーションを追加すると良いでしょう。
- Pythonのrequestsライブラリを使用してHTTPリクエストを送信していますが、エラー処理とリトライの実装も検討することをお勧めします。
これは基本的な概要ですが、コードは機能的に見えます。詳細な改善やカスタマイズはプロジェクトの要件に応じて行うことができます。
Bard
レビュー
このスクリプトは、わかりやすく、読みやすいコードで書かれています。また、APIの呼び出し頻度を制限するためにtime.sleep()を使用している点も適切です。
ただし、次の点に注意する必要があります。
- CSVファイルの各行に標高を追加するときに、インデックスのエラーが発生する可能性があります。これを回避するには、次のようなコードを使用できます。
Python try: row.append(data["elevation"]) except KeyError: pass
- 出力CSVファイルを開くときに、newline=””を指定しています。これは、Windows環境でCSVファイルを書き込むときに、不要な改行文字が挿入されないようにするためです。ただし、MacやLinux環境でCSVファイルを書き込むときは、newline=””を指定しない方がよい場合があります。
上記の点に注意すれば、このスクリプトを安心して使用することができます。
すごい!
コメント