| Top Page | プログラミング | メッシュコード |
Updated on 2016-11-23
以下の内容のファイルへのリンク (mesh_lib.py)。 「リンク先を保存」等でダウンロードして使用。
# mesh_lib.py
#
# メッシュコード計算パッケージ (for Python)
#
# 2010-07-12 TAKENAKA, Akio. (Original ver in Perl)
# 2016-11-06 TAKENAKA, Akio. (Port to Python)
#
# import mesh_lib で、このファイルて定義した4つの関数を
# 読み込んでから使用する。
#
# meshcode_to_latlong, メッシュコードから緯度・経度へ
# latlong_to_meshcode, 緯度・経度からメッシュコードへ。
# dms_to_deg, 度・分・秒から度(小数点表示)へ。
# deg_to_dms, 度(小数点表示)から度・分・秒へ。
import re # 正規表現によるパターンマッチ
########################################
# メッシュコードを渡し、対応する緯度・経度を返す。
# メッシュコードは数値(整数)でも文字列型でも可。
#
# 返値は数値データが2つ並んだタプル。
#
# 特に指定しなければメッシュの中央の座標を返す。
# メッシュコードは一次、ニ次、三次いずれも可。
#
# NW, NE, SW, SE を2つ目の引数として渡すと、それぞれ北西、北東、南西、南東の
# コーナーの座標を返す。
#
# 緯度・経度は度単位の小数。
#
# usage
# code_a = "55354251" # 三次メッシュコード
# lat_lon = mesh_lib.meshcode_to_latlong(code_a); # 中央の緯度・経度
# print('latitude\t', lat_lon[0], '\tlongitude\t', lat_lon[1],
#
# code_a = "55354251" # 三次メッシュコード
# lat_lon = mesh_lib.meshcode_to_latlong(code_a, 'NE') # 北東端
# print('latitude\t', lat_lon[0], '\tlongitude\t', lat_lon[1],
def meshcode_to_latlong(code, loc = 'C'):
if type(code) != int: # 整数型に(文字列が渡された場合に対応)
try:
code = int(code)
except: # 形式チェック
print("Error in mesh_lib.meshocode_to_latlong() Not a valid code handed.")
raise
code = str(code) # あらためて文字型に。
code12 = ''
code34 = ''
code5 = ''
code6 = ''
code7 = ''
code8 = ''
loc = loc.upper()
if re.match("^C|(NE)|(NW)|(SE)|(SW)$", loc) == None:
raise Exception ("Invalid option to meshcode_to_latlong()")
match_1_result = re.match("\d{4}", code)
if re.match("\d{4}", code): # 最初の4文字が数字
code12 = code[0:2]
code34 = code[2:4]
lat_width = 2.0 / 3.0 # grid cell の緯度方向の間隔
long_width = 1.0 # grid cell の経度方向の間隔
else:
return (None) # メッシュコードとして無効
if re.match("\d{6}", code): # 少なくとも最初の6文字は数字
code5 = code[4:5]
code6 = code[5:6]
lat_width /= 8.0;
long_width /= 8.0;
if re.match("\d{8}", code): # 最初の8文字は数字
code7 = code[6:7]
code8 = code[7:8]
lat_width /= 10.0;
long_width /= 10.0;
# 以下、南西コーナーの座標を求める。
lat = float(code12) * 2 / 3 # 一次メッシュ
long = float(code34) + 100
if (code5 != '') & (code6 != ''): # 二次メッシュ or 三次メッシュ
lat += (float(code5) * 2 / 3) / 8
long += float(code6) / 8
if (code7 != '') & (code8 != ''): # 三次メッシュ
lat += float(code7) * 2 / 3 / 8 / 10
long += float(code8) / 8 / 10
# ここまでで南東端の緯度・経度が得られた
# 中央の座標なら、一区画の幅(経度幅)・高さ(緯度幅)の半分を足す。
if loc == 'C':
lat += lat_width / 2
long += long_width / 2
# 北端の座標なら、一区画の高さ(緯度幅)を足す
if re.search('N', loc):
lat += lat_width
# 東端の座標なら、一区画の幅(経度幅)を足す
if re.search('E', loc):
long += long_width
return (lat, long) # タプルを返す。
##################
# 緯度・経度(度単位)を受けとり、これを含むメッシュのコードを返す
# 緯度。経度の型は float でも文字列でも可。
#
# 返値のメッシュコードは数値(整数)データ。
#
# 3番めの引数として 1,2,3 を渡せば、一次メッシュ、二次メッシュ、
# 三次メッシュコードを計算する。指定がなければ三次メッシュ、
#
# Usage:
# code3 = meshlib.latlong_to_meshcode(35.3, 138.5) # 三次メッシュコード
# code2 = meshlib.latlong_to_meshcode(35.3, 138.5, 2) # 二次メッシュコード
# code1 = meshlib.latlong_to_meshcode(35.3, 138.5, 1) # 一次メッシュコード
#
def latlong_to_meshcode(lat, long, order = 3):
if type(lat) != float: # 実数型でないなら変換
lat = float(lat)
if type(long) != float: # 実数型でないなら変換
long = float(long)
if (order < 1) | (order > 3):
raise Exception ("Invalid parameter to latlong_to_meshcode()")
# Latitude
lat_in_min = lat * 60.0
code12 = int(lat_in_min / 40) # codeの1, 2文字目部分(数値)
lat_rest_in_min = lat_in_min - code12 * 40 # 残差
code5 = int(lat_rest_in_min / 5 ) # code 5文字目 二次メッシュの1区画は緯度5分
lat_rest_in_min -= code5 * 5 # 残差
code7 = int(lat_rest_in_min / (5/10)) # code 7文字目 三次メッシュの1区画は緯度5分の 1/10
# Longitude
code34 = int(long) - 100 # codeの3, 4文字目部分(数値)
long_rest_in_deg = long - int(long)
code6 = int(long_rest_in_deg * 8)
long_rest_in_deg -= code6 / 8;
code8 = int(long_rest_in_deg / (1/80) )
code = code12 * 100 + code34
if order >= 2:
code = code * 100 + code5 * 10 + code6
if order == 3:
code = code * 100 + code7 * 10 + code8
return int(code)
##################
# 度、分、秒を受けとり、度の単位で小数点表示に変換して返す。
#
# Usage:
# deg = meshlib.dms_to_deg(35, 20, 15)
def dms_to_deg (deg, min, sec):
in_deg = deg + min / 60.0 + sec / 3600.0
return in_deg
##################
# 度の単位の小数点表示を受けとり、 度、分、秒に変換して返す。
# 戻り値は数値データが3つ並んだタプル。
#
# Usage:
# dms = meshlib.deg_to_dms(35.3375)
def deg_to_dms(in_deg):
deg = int(in_deg)
rest_in_deg = in_deg - deg
min = int( rest_in_deg * 60 )
rest_in_min = rest_in_deg * 60 - min;
sec = rest_in_min * 60;
# もし繰り上がってしまっていたら、その分の調整、
if sec >= 60: # 秒が60を越えたら
sec -= 60
min += 1
if min == 60: # 分が60 を越えたら
min -= 60
deg += 1
return (deg, min, sec) # タプルを返す。