タイトル : 緯度経度から標高を求めよう 国土地理院API 2026/03
更新日 : 2026-03-23
カテゴリ : プログラミング
タグ :
python   
pillow   
opendata   

スマホのGPSでの標高

スマホのGPSからは緯度経度しかとれないと思い込んでいました。

写真にGPS情報を含めたら、確かに標高も入ってた。

GPSロガーアプリ:ルートヒストリーを使ってみよう 2026/03で書いたけど、

Geminiさんによると、緯度経度が正確なら、国土地理院APIを使うのが良いらしい。

サンプルプログラムの作成と実行

国土地理院APIを試してみましょう。

写真にGPS情報を含めて、写真の緯度経度から標高を 国土地理院API で求めてみます。

実行例

$ python test01.py 東林間の桜の写真.JPG 
スマホ GPSの標高 : 126.0 、国土地理院APIでの標高 : 86.7
$
  • 国土地理院ってすごい

    東林間駅の標高は 84-85mぐらいとのことなので、国土地理院APIの結果は合っているような気がする。

    国土地理院でAPI出しているの知らなかった。すごい。フリーです。(使いすぎる人がいて規制はあるみたい)

    国土地理院で 基盤地図情報のダウンロードも出している。 すごい。オープンデータだな

  • スマホ単体での標高の精度は高くなさそう

    あとスマホはm単位なのかも

ソース

import sys

import requests
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS

def get_gps_info(image_path):
    # 画像を開く
    img = Image.open(image_path)
    # EXIF情報の取得
    exif = img._getexif()
    
    if not exif:
        return None

    # GPS情報の取得
    #   EXIF 2.3の規格  https://www.cipa.jp/std/documents/j/DC-008-2012_J_C.pdf
    gps_info = {}
    for tag, value in exif.items():
        tag_name = TAGS.get(tag, tag)
        if tag_name == "GPSInfo":
            for gps_tag, gps_val in value.items():
                gps_info[GPSTAGS.get(gps_tag, gps_tag)] = gps_val
            break
            
    if not gps_info:
        return None
    
    # 緯度・経度の変換
    def to_deg(value, loc):
        d = float(value[0])
        m = float(value[1])
        s = float(value[2])
        return d + (m / 60.0) + (s / 3600.0)

    # 緯度
    lat = to_deg(gps_info['GPSLatitude'], gps_info['GPSLatitudeRef'])
    if gps_info['GPSLatitudeRef'] != 'N': lat = -lat

    # 経度
    lon = to_deg(gps_info['GPSLongitude'], gps_info['GPSLongitudeRef'])
    if gps_info['GPSLongitudeRef'] != 'E': lon = -lon
    
    # 標高
    alt = float(gps_info["GPSAltitude"])
    if gps_info["GPSAltitudeRef"] != b'\x00': alt = -alt

    return lat, lon, alt

# 緯度、経度、標高の取得
(lat, lon, gps_alt) = get_gps_info(sys.argv[1])

# 国土地理院APIのURIを用意
url = ("http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php"
       f"?lon={lon}&lat={lat}&outtype=JSON")

# 呼び出し、JSON取得
resp = requests.get(url, timeout=10)
data = resp.json()
# 国土地理院APIでの標高
#   例.{'elevation': 86.7, 'hsrc': '5m(レーザ)'}
alt = float(data["elevation"])

print(f'スマホ GPSの標高 : {gps_alt} 、国土地理院APIでの標高 : {alt}')

uv関係

$ uv add pillow
Using CPython 3.14.3
Creating virtual environment at: .venv
Resolved 2 packages in 226ms
Prepared 1 package in 334ms
Installed 1 package in 2ms
 + pillow==12.1.1
$ 

このあと requestsもaddした。

  • uv add pillow インストールする。依存関係を pyproject.toml(または他の設定ファイル)に記録する。

  • uv pip install pillow インストールするのみ