
Pythonで3次メッシュコードを中心とした周囲のメッシュコードを生成する
この記事では、Pythonを使って3次メッシュコードを中心とした周囲のメッシュコードを生成する方法について解説します。メッシュコードは地理情報を扱う際に便利なコード体系で、日本では特に利用されています。以下のコードは、指定された3次メッシュコードを中心とした周囲のメッシュコードを生成する方法を示しています。
コードの概要
以下のコードは、8桁の3次メッシュコードを受け取り、そのメッシュコードを中心とした指定された範囲(n)の周囲のメッシュコードを生成します。
generate_surrounding_mesh3:8桁の3次メッシュコードを中心とした周囲のメッシュコードリストを生成する
decompose_mesh3_code:8桁の3次メッシュコードを受け取り、緯度と経度の部分に分解する
generate_surrounding_codes:指定された範囲(-nからnまで)のコードを生成する
calculate_mesh_code:3次メッシュの進法ルールに従って計算する
combine_lon_lat_codes:経度コードと緯度コードのリストを組み合わせてメッシュコードを生成する
# 8桁の3次メッシュコードを受け取り、緯度と経度の部分に分解する
def decompose_mesh3_code(mesh_code: str) -> str:
# メッシュコードが8桁でない場合はエラーを発生させる
if len(mesh_code) != 8:
raise ValueError("メッシュコードは8桁である必要があります。")
# 緯度部分を分解(上2桁 + 5桁目 + 7桁目)
decompose_lat = mesh_code[:2] + mesh_code[4] + mesh_code[6]
# 経度部分を分解(3-4桁目 + 6桁目 + 8桁目)
decompose_lon = mesh_code[2:4] + mesh_code[5] + mesh_code[7]
# 経度と緯度の分解結果を返す
return decompose_lon, decompose_lat
# 3次メッシュの進法ルールに従って計算する
def calculate_mesh_code(decompose_code:str, value:int) -> str:
if not len(decompose_code)==4:
raise ValueError("入力値は4桁である必要があります。")
# 上4桁は10進法
value4 = int(decompose_code[3]) + value
carry4 = value4 // 10
calculate_code4 = str(value4 % 10)
# 上3桁は8進法
value3 = int(decompose_code[2]) + carry4
carry3 = value3 // 8
calculate_code3 = str(value3 % 8)
# 上1~2桁は10進法
calculate_code1_2 = str(int(decompose_code[:2]) + carry3)
# 結果を結合する
calculate_code = calculate_code1_2 + calculate_code3 + calculate_code4
return calculate_code
# 指定された範囲(-nからnまで)のコードを生成する
def generate_surrounding_codes(decompose_code: str, n: int) -> list[str]:
# 結果を格納するリスト
calculate_codes = []
# -nからnまでの範囲でループ
for r in range(-1 * n, n + 1):
# rが0の場合は元のコードをそのまま追加
if r == 0:
calculate_codes.append(decompose_code)
continue
# calculate_mesh_code関数を使ってコードを計算
calculate_code = calculate_mesh_code(decompose_code, r)
# 計算結果をリストに追加
calculate_codes.append(calculate_code)
# 計算されたコードのリストを返す
return calculate_codes
# 経度コードと緯度コードのリストを組み合わせてメッシュコードを生成する
def combine_lon_lat_codes(surrounding_lon_codes: list[str], surrounding_lat_codes: list[str]) -> list[str]:
# 結果を格納するリスト
surrounding_mesh_codes = []
# 経度コードのリストをループ
for lon_code in surrounding_lon_codes:
# 緯度コードのリストをループ
for lat_code in surrounding_lat_codes:
# 緯度と経度のコードを組み合わせてメッシュコードを生成
surrounding_mesh_code = f"{lat_code[:2]}{lon_code[:2]}{lat_code[2]}{lon_code[2]}{lat_code[3]}{lon_code[3]}"
# 生成されたメッシュコードをリストに追加
surrounding_mesh_codes.append(surrounding_mesh_code)
# 生成されたメッシュコードのリストを返す
return surrounding_mesh_codes
# 8桁の3次メッシュコードを中心とした周囲のメッシュコードリストを生成する
def generate_surrounding_mesh3(mesh_code:str, n:int) -> list[str]:
# 8桁の3次メッシュコードを受け取り、緯度と経度の部分に分解する
decompose_lon, decompose_lat = decompose_mesh3_code(mesh_code)
# 指定された範囲(-nからnまで)の経度コードを生成する
surrounding_lon_codes = generate_surrounding_codes(decompose_lon, n)
# 指定された範囲(-nからnまで)の緯度コードを生成する
surrounding_lat_codes = generate_surrounding_codes(decompose_lat, n)
# 経度コードと緯度コードのリストを組み合わせてメッシュコードを生成する
surrounding_mesh3_codes = combine_lon_lat_codes(surrounding_lon_codes, surrounding_lat_codes)
return surrounding_mesh3_codes
mesh_code = "53393599"
n = 2
surrounding_mesh3_codes = generate_surrounding_mesh3(mesh_code, n)
import numpy as np
np.flipud(np.array(surrounding_mesh3_codes).reshape((5, 5)).T)
# 出力結果
# array([['53394517', '53394518', '53394519', '53394610', '53394611'],
# ['53394507', '53394508', '53394509', '53394600', '53394601'],
# ['53393597', '53393598', '53393599', '53393690', '53393691'],
# ['53393587', '53393588', '53393589', '53393680', '53393681'],
# ['53393577', '53393578', '53393579', '53393670', '53393671']],
# dtype='<U8')

コードの詳細
ここから詳細な解説をします。
3次メッシュコードの分解
まず、3次メッシュコードを緯度と経度の部分に分解する関数を定義します。
def decompose_mesh3_code(mesh_code: str) -> str:
# メッシュコードが8桁でない場合はエラーを発生させる
if len(mesh_code) != 8:
raise ValueError("メッシュコードは8桁である必要があります。")
# 緯度部分を分解(上2桁 + 5桁目 + 7桁目)
decompose_lat = mesh_code[:2] + mesh_code[4] + mesh_code[6]
# 経度部分を分解(3-4桁目 + 6桁目 + 8桁目)
decompose_lon = mesh_code[2:4] + mesh_code[5] + mesh_code[7]
# 経度と緯度の分解結果を返す
return decompose_lon, decompose_lat
# 使用例
mesh_code = "53393599"
decompose_lon, decompose_lat = decompose_mesh3_code(mesh_code)
print(f"decompose_lon: {decompose_lon}, decompose_lat: {decompose_lat}")
# decompose_lon: 3959, decompose_lat: 5339
この関数は、8桁の3次メッシュコードを受け取り、緯度と経度の部分に分解して返します。
緯度部分の分解
次に、緯度部分を分解します。緯度部分は、メッシュコードの上2桁、5桁目、7桁目を組み合わせて作成します。
decompose_lat = mesh_code[:2] + mesh_code[4] + mesh_code[6]
mesh_code[:2]は、メッシュコードの上2桁を取得します。
mesh_code[4]は、メッシュコードの5桁目を取得します。
mesh_code[6]は、メッシュコードの7桁目を取得します。
経度部分の分解
次に、経度部分を分解します。経度部分は、メッシュコードの3-4桁目、6桁目、8桁目を組み合わせて作成します。
decompose_lon = mesh_code[2:4] + mesh_code[5] + mesh_code[7]
mesh_code[2:4]は、メッシュコードの3-4桁目を取得します。
mesh_code[5]は、メッシュコードの6桁目を取得します。
mesh_code[7]は、メッシュコードの8桁目を取得します。
特定の進法ルールに従った計算
以下のコードは、4桁の分解されたメッシュコード(decompose_code)に対して特定の値(value)を加算し、特定の進法ルールに従って計算します。
def calculate_mesh_code(decompose_code: str, value: int) -> str:
if not len(decompose_code) == 4:
raise ValueError("入力値は4桁である必要があります。")
# 上4桁は10進法
value4 = int(decompose_code[3]) + value
carry4 = value4 // 10
calculate_code4 = str(value4 % 10)
# 上3桁は8進法
value3 = int(decompose_code[2]) + carry4
carry3 = value3 // 8
calculate_code3 = str(value3 % 8)
# 上1~2桁は10進法
calculate_code1_2 = str(int(decompose_code[:2]) + carry3)
# 結果を結合する
calculate_code = calculate_code1_2 + calculate_code3 + calculate_code4
return calculate_code
# 使用例
value2 = 3
result = calculate_mesh_code(decompose_lon, value2)
print(result)
# 3962
上4桁の計算(10進法)
4桁目は3次メッシュコードに当たります。 4桁目にvalueを加算し、10進法で計算します。繰り上がりが発生する場合は次の桁に繰り上げます。
value4 = int(decompose_code[3]) + value
carry4 = value4 // 10
calculate_code4 = str(value4 % 10)
value4は、4桁目にvalueを加算した結果です。
carry4は、繰り上がりの値です。
calculate_code4は、4桁目の計算結果の1桁目を文字列として取得します。
上3桁の計算(8進法)
3桁目は2次メッシュコードに当たります。 3桁目に繰り上がりを加算し、8進法で計算します。繰り上がりが発生する場合は次の桁に繰り上げます。
value3 = int(decompose_code[2]) + carry4
carry3 = value3 // 8
calculate_code3 = str(value3 % 8)
value3は、3桁目に繰り上がりを加算した結果です。
carry3は、繰り上がりの値です。
calculate_code3は、3桁目の計算結果の1桁目を文字列として取得します。
上1~2桁の計算(10進法)
1~2桁目は1次メッシュコードに当たります。 次に、上1~2桁に繰り上がりを加算し、10進法で計算します。
calculate_code1_2 = str(int(decompose_code[:2]) + carry3)
calculate_code1_2は、上1~2桁に繰り上がりを加算した結果を文字列として取得します。
結果の結合
最後に、計算結果を結合して新しい4桁の数値を返します。
calculate_code = calculate_code1_2 + calculate_code3 + calculate_code4
return calculate_code
使用例
以下は、実際に4桁の分解されたメッシュコードに対して特定の値を加算して計算する例です。
value2 = 3
result = calculate_mesh_code(decompose_lon, value2)
print(result)
# 3962
この例では、decompose_lonに対してvalue2を加算して計算しています。
周囲のコードを生成
以下のコードは、4桁の分解されたメッシュコード(decompose_code)に対して、指定された範囲(n)の周囲のコードを生成します。
def generate_surrounding_codes(decompose_code: str, n: int) -> list[str]:
# 結果を格納するリスト
calculate_codes = []
# -nからnまでの範囲でループ
for r in range(-1 * n, n + 1):
# rが0の場合は元のコードをそのまま追加
if r == 0:
calculate_codes.append(decompose_code)
continue
# calculate_mesh_code関数を使ってコードを計算
calculate_code = calculate_mesh_code(decompose_code, r)
# 計算結果をリストに追加
calculate_codes.append(calculate_code)
# 計算されたコードのリストを返す
return calculate_codes
# 使用例
n = 2
surrounding_lon_codes = generate_surrounding_codes(decompose_lon, n)
surrounding_lat_codes = generate_surrounding_codes(decompose_lat, n)
print(surrounding_lon_codes)
# ['3957', '3958', '3959', '3960', '3961']
print(surrounding_lat_codes)
# ['5337', '5338', '5339', '5340', '5341']
結果を格納するリストの初期化
まず、結果を格納するためのリストを初期化します。
calculate_codes = []
指定された範囲でループ
次に、指定された範囲(-nからnまで)でループを実行します。
for r in range(-1 * n, n + 1):
range(-1 * n, n + 1)は、-nからnまでの範囲を生成します。
元のコードをそのまま追加
ループ内で、rが0の場合は元のコードをそのままリストに追加します。
if r == 0:
calculate_codes.append(decompose_code)
continue
コードの計算
rが0でない場合は、calculate_mesh_code関数を使ってコードを計算します。
calculate_code = calculate_mesh_code(decompose_code, r)
calculate_mesh_code関数は、分解されたメッシュコードに対してrを加算して新しいコードを計算します。
計算結果をリストに追加
計算結果をリストに追加します。
calculate_codes.append(calculate_code)
計算されたコードのリストを返す
最後に、計算されたコードのリストを返します。
return calculate_codes
使用例
以下は、実際に4桁の分解されたメッシュコードに対して指定された範囲の周囲のコードを生成する例です。
n = 2
surrounding_lon_codes = generate_surrounding_codes(decompose_lon, n)
surrounding_lat_codes = generate_surrounding_codes(decompose_lat, n)
print(surrounding_lon_codes)
# ['3957', '3958', '3959', '3960', '3961']
print(surrounding_lat_codes)
# ['5337', '5338', '5339', '5340', '5341']
この例では、decompose_lonとdecompose_latに対して、範囲nの周囲のコードを生成しています。
経度と緯度のコードを組み合わせ
以下のコードは、経度コードと緯度コードのリストを受け取り、それらを組み合わせてメッシュコードを生成します。
def combine_lon_lat_codes(surrounding_lon_codes: list[str], surrounding_lat_codes: list[str]) -> list[str]:
# 結果を格納するリスト
surrounding_mesh_codes = []
# 経度コードのリストをループ
for lon_code in surrounding_lon_codes:
# 緯度コードのリストをループ
for lat_code in surrounding_lat_codes:
# 緯度と経度のコードを組み合わせてメッシュコードを生成
surrounding_mesh_code = f"{lat_code[:2]}{lon_code[:2]}{lat_code[2]}{lon_code[2]}{lat_code[3]}{lon_code[3]}"
# 生成されたメッシュコードをリストに追加
surrounding_mesh_codes.append(surrounding_mesh_code)
# 生成されたメッシュコードのリストを返す
return surrounding_mesh_codes
# 使用例
n = 2
surrounding_mesh3_codes = combine_lon_lat_codes(surrounding_lon_codes, surrounding_lat_codes)
print(surrounding_mesh3_codes)
# 出力結果
# ['53393577', '53393587', '53393597', '53394507', '53394517',
# '53393578', '53393588', '53393598', '53394508', '53394518',
# '53393579', '53393589', '53393599', '53394509', '53394519',
# '53393670', '53393680', '53393690', '53394600', '53394610',
# '53393671', '53393681', '53393691', '53394601', '53394611']
結果を格納するリストの初期化
まず、結果を格納するためのリストを初期化します。
surrounding_mesh_codes = []
経度コードのリストをループ
次に、経度コードのリストをループします。
for lon_code in surrounding_lon_codes:
surrounding_lon_codesは、周囲の経度コードのリストです。
緯度コードのリストをループ
経度コードのループ内で、緯度コードのリストをループします。
for lat_code in surrounding_lat_codes:
surrounding_lat_codesは、周囲の緯度コードのリストです。
緯度と経度のコードを組み合わせてメッシュコードを生成
緯度と経度のコードを組み合わせてメッシュコードを生成します。
surrounding_mesh_code = f"{lat_code[:2]}{lon_code[:2]}{lat_code[2]}{lon_code[2]}{lat_code[3]}{lon_code[3]}"
lat_code[:2]は、緯度コードの上2桁を取得します。(1次メッシュの緯度)
lon_code[:2]は、経度コードの上2桁を取得します。(1次メッシュの経度)
lat_code[2]は、緯度コードの3桁目を取得します。(2次メッシュの緯度)
lon_code[2]は、経度コードの3桁目を取得します。(2次メッシュの経度)
lat_code[3]は、緯度コードの4桁目を取得します。(3次メッシュの緯度)
lon_code[3]は、経度コードの4桁目を取得します。(3次メッシュの経度)
生成されたメッシュコードをリストに追加
生成されたメッシュコードをリストに追加します。
surrounding_mesh_codes.append(surrounding_mesh_code)
生成されたメッシュコードのリストを返す
最後に、生成されたメッシュコードのリストを返します。
return surrounding_mesh_codes
使用例
以下は、実際に経度コードと緯度コードのリストを組み合わせてメッシュコードを生成する例です。
n = 2
surrounding_mesh3_codes = combine_lon_lat_codes(surrounding_lon_codes, surrounding_lat_codes)
print(surrounding_mesh3_codes)
# 出力結果
# ['53393577', '53393587', '53393597', '53394507', '53394517',
# '53393578', '53393588', '53393598', '53394508', '53394518',
# '53393579', '53393589', '53393599', '53394509', '53394519',
# '53393670', '53393680', '53393690', '53394600', '53394610',
# '53393671', '53393681', '53393691', '53394601', '53394611']
この例では、surrounding_lon_codesとsurrounding_lat_codesを組み合わせてメッシュコードを生成しています。
周囲のメッシュコードリストを生成
最後に、8桁の3次メッシュコードを中心とした周囲のメッシュコードリストを生成する関数を定義します。
def generate_surrounding_mesh3(mesh_code: str, n: int) -> list[str]:
# 8桁の3次メッシュコードを受け取り、緯度と経度の部分に分解する
decompose_lon, decompose_lat = decompose_mesh3_code(mesh_code)
# 指定された範囲(-nからnまで)の経度コードを生成する
surrounding_lon_codes = generate_surrounding_codes(decompose_lon, n)
# 指定された範囲(-nからnまで)の緯度コードを生成する
surrounding_lat_codes = generate_surrounding_codes(decompose_lat, n)
# 経度コードと緯度コードのリストを組み合わせてメッシュコードを生成する
surrounding_mesh3_codes = combine_lon_lat_codes(surrounding_lon_codes, surrounding_lat_codes)
return surrounding_mesh3_codes
# 使用例
mesh_code = "53393597"
n = 1
surrounding_mesh3_codes = generate_surrounding_mesh3(mesh_code, n)
import numpy as np
np.flipud(np.array(surrounding_mesh3_codes).reshape((5, 5)).T)
# 出力結果
# array([['53394517', '53394518', '53394519', '53394610', '53394611'],
# ['53394507', '53394508', '53394509', '53394600', '53394601'],
# ['53393597', '53393598', '53393599', '53393690', '53393691'],
# ['53393587', '53393588', '53393589', '53393680', '53393681'],
# ['53393577', '53393578', '53393579', '53393670', '53393671']],
# dtype='<U8')
この関数は、指定された3次メッシュコードを中心とした周囲のメッシュコードを生成します。
まとめ
このコードは、8桁の3次メッシュコードを中心とした指定された範囲の周囲のメッシュコードを生成する方法を示しています。個人的に作りたかっただけです。