【python】緯度経度から標準地域コードの取得
標準地域コードとは
wikipedia地域メッシュ
日本地図の上に碁盤の目を張り巡らせて、1つ1つの枠にユニークなコードを割り振ました。ということですね。
以降の記述は、世界測地系、10進数で緯度経度を扱うものとします。
1次メッシュ 定義&取得
- 1辺の長さが約80kmの四角形となります。
- 4桁の数字で構成され、枠の西南端の緯度を上2桁、経度を下2桁で表します。
- 緯度を1.5倍した値の上2桁 + 経度から100引いた値となります。
#encoding:utf-8 import math class MeshCodeUtility(object): #1次メッシュコードの取得 @staticmethod def get_1st_mesh(lat, lon): left_operator = int( math.floor(lat * 15 / 10 ) ) right_operator = int( math.floor(lon - 100 ) ) #南西端のlat,lonを取得 dest_lat = left_operator / 15.0 * 10 dest_lon = right_operator + 100.0 src = {"mesh_code":str(left_operator)+str(right_operator), "lat":dest_lat, "lon":dest_lon} return src
1次メッシュコードの取得は簡単ですね。
同時に変換したコードが指すメッシュの西南端の緯度、経度を取得しておきます。
2次メッシュ 定義&取得
- 1次メッシュを縦、横ともに8等分した四角形(1次メッシュを64分割)。
- 1辺の長さは約4kmで、緯度5分(5/60)、経度7分30秒(7/60+30/60/60)となります。
- 1次メッシュの西南端を基点(0,0)とし、上1桁が北方向へのメッシュ位置、下1桁が東方向へのメッシュ位置を表します。
- 1次メッシュと組み合わせてnnnn-nnと記述します。
まずは、上1桁の値を取得してみましょう。
#2次メッシュコードの取得 @staticmethod def get_2nd_mesh(lat, lon): #所属する1次メッシュの西南端のlat,lonを取得します。 base_data = MeshCodeUtility.get_1st_mesh(lat, lon) #2次メッシュは緯度方向5分(5/60=0.08333)区切りとなります。 left_operator = int(math.floor((lat - base_data["lat"]) * 100000 / 8333))
引数の緯度から1次メッシュの西南端の緯度を引くことによって、北方向に何度進んだ地点かがわかります。
あとは、緯度5分区切りの四角形なので、0.08333…で割りますと所属するメッシュ地点がわかります。
同様に下2桁も
#経度方向7分30秒(7/60+30/60/60=0.11666+0.008333=0.1249))区切りとなります。 right_operator = int(math.floor((lon - base_data["lon"]) * 1000 / 125))
これで、2次メッシュが取得出来ました。1次メッシュの計算時と同様に2次メッシュ西南端の緯度、経度を取得しておきます。
#南西端のlat,lon dest_lat = left_operator * 8333.0 / 100000 + base_data["lat"] dest_lon = right_operator * 125.0 / 1000 + base_data["lon"] src = {"mesh_code":base_data["mesh_code"]+"-"+str(left_operator)+str(right_operator), "lat":dest_lat, "lon":dest_lon} return src
3次メッシュ 定義&取得
- 2次メッシュを縦、横ともに10等分した四角形(2次メッシュを100分割、1次メッシュを6400分割)。
- 1辺の長さは約1kmで、緯度30秒(30/60/60)、経度45秒(45/60/60)となります。
- 2次メッシュの西南端を基点(0,0)とし、上1桁が北方向へのメッシュ位置、下1桁が東方向へのメッシュ位置を表します。
- 1次メッシュ、2次メッシュと組み合わせてnnnn-nn-nnのように記述します。
3次メッシュも分割距離が変わっただけすので、2次メッシュの計算を応用します。
#3次メッシュコードの取得 @staticmethod def get_3rd_mesh(lat, lon): base_data = MeshCodeUtility.get_2nd_mesh(lat, lon) #3次メッシュは緯度方向 30秒(30/60/60=0.008333)区切りとなります left_operator = int(math.floor((lat - base_data["lat"]) * 1000000 / 8333)) #経度方向 45秒(45/60/60=0.0125)区切りとなります。 right_operator = int(math.floor((lon - base_data["lon"]) * 10000 / 125)) #南西端のlat,lon dest_lat = left_operator * 8333 / 1000000.0 + base_data["lat"] dest_lon = right_operator * 125 / 10000.0 + base_data["lon"] src = {"mesh_code":base_data["mesh_code"]+"-"+str(left_operator)+str(right_operator), "lat":dest_lat, "lon":dest_lon} return src
では早速、試してみましょう。
#渋谷区役所の緯度、経度となります。 print MeshCodeUtility.get_3rd_mesh(35.6640352,139.6982122) #{'mesh_code': '5339-35-95', 'lat': 35.658320333333329, 'lon': 139.6875} #札幌市役所 print MeshCodeUtility.get_3rd_mesh(43.0620958,141.3543763) #{'mesh_code': '6441-42-78', 'lat': 43.058317666666667, 'lon': 141.34999999999999} #沖縄市役所 print MeshCodeUtility.get_3rd_mesh(26.3344266,127.8055832) #{'mesh_code': '3927-46-04', 'lat': 26.333320000000001, 'lon': 127.8}
正しく取得出来ました。
完成したコードは、githubに置きました。
pythonのコード
phpのコード