NOAA の Magnetic Declination Estimated Value 計算サービスを python から使う

これは今回のネタの脇道なのでした、の巻。

「本物の磁偏差」は観測でしか得られませぬ(だけでなく日々刻々と変わる)。そうではなくて、ここで取ろうとしてるのは、モデルに従った計算。緯度経度と現在日時があれば取れる。

WEB サービスがないかなと思ったら NOAA が提供してくれてたので、ってことで。

説明は全部ここにある。つまり

http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination?lat1=35.68306&startYear=2015&startDay=26&startMonth=7&lon1=139.80889&model=WMM&resultFormat=xml

のように使う。プログラム的に使う場合は xml が使いやすいが、html 形式は面白いので試してみるといい

xml フォーマットの結果例はこんな具合:

 1 <maggridresult>
 2 <version>
 3 0.5.0.7
 4 </version>
 5 <result>
 6 <date>
 7 2016.56011
 8 </date>
 9 <latitude units = "degree">
10 35.68306
11 </latitude>
12 <longitude units="degree">
13 139.80889
14 </longitude>
15 <elevation units="km">
16 0.00000
17 </elevation>
18 <declination units="degree">
19 -7.38336
20 </declination>
21 <declination_sv units="degree">
22 -0.05923
23 </declination_sv>
24 <declination_uncertainty units="degree">
25 0.29981
26 </declination_uncertainty>
27 </result>
28 </maggridresult>

単純な形式。declination が目的のもの。degrees 形式だが一般的な UI では度分秒に直しているため、対応がわかりにくかもね。(プログラムで取ったのと WEB UI で見るのとで対応がとりずらいのね。)

python からこの WEB サービスを使って xml を解析するまでの一連:

 1 # -*- coding: utf-8 -*-
 2 import urllib
 3 import urllib2
 4 import xml.etree.ElementTree as ET
 5 
 6 url = 'http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination'
 7 values = {
 8     'model': 'WMM', # 'WMM' or 'IGRF'
 9     'resultFormat': 'xml',  # 'html', 'csv', 'xml', or 'pdf'
10     'lon1': 139.80889,
11     'lat1': 35.68306,
12     'startYear': 2015,
13     'startMonth': 7,
14     'startDay': 26,
15     }
16 
17 data = urllib.urlencode(values)
18 #print(url + '?' + data)
19 req = urllib2.Request(url, data)
20 response = urllib2.urlopen(req)
21 the_page = response.read()
22 root = ET.fromstring(the_page)
23 result = dict(((r.tag, float(r.text.strip())) for r in root.find('result')))
24 #print(result)
25 #...

じっつに簡単だ。このコード中の result は辞書になってて、こんな:

1 {'elevation': 0.0, 'longitude': 139.80889, 'latitude': 35.68306, 'declination': -7.32437, 'date': 2015.56438, 'declination_sv': -0.05925, 'declination_uncertainty': 0.29982}

…これで何がしたいのかって?

実はイマサラながら android なスマホを買ったもんで、android + python で遊び中なのれす。それでちょっとしたコンパスを作っててね。磁偏差も欲しくなったんでした。

2016-07-30 追記:
配慮不足過ぎた。続編参照してください。