0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日本の標準地域メッシュコードを緯度経度に変換する(中心補正つき)

Posted at

n番煎じの感じがありますが、作ってしまったので書いておきます。

地域メッシュコードとはなんぞや、というのはまず以下のページを参照してください。
地域メッシュ統計について - 総務省統計局
メッシュデータについて - 国土数値情報ダウンロードサイト

さてメッシュコードを緯度経度に変換する際、注意する点の一つは、「メッシュコードが示す座標は、該当のメッシュの南西端(左下)である」ということです。
メッシュコードの中心座標を求めたい場合、メッシュの大きさに応じて補正する必要があります。

というわけで、補正機能付きの関数を書きましょう。

def mesh_code_to_latlon(mesh_code: str, apply_correction: bool = True):
    """
    日本の地域メッシュコードを緯度・経度に変換する。

    標準地域メッシュ(4桁)から5次メッシュ(10桁)までをサポート。
    無効なメッシュコードの場合は `ValueError` を発生させる。

    Parameters
    ----------
    mesh_code : str
        変換する地域メッシュコード。ハイフン("-")が含まれていても自動で除去される。
    apply_correction : bool, optional
        メッシュの中心点を取得するかどうか(デフォルトは `True`)。
        `False` にすると、メッシュの南西端(左下)の座標を返す。

    Returns
    -------
    tuple[float, float]
        (緯度, 経度) のタプルを返す。

    Raises
    ------
    ValueError
        メッシュコードが無効(4桁未満、5桁・7桁、または10桁超過)である場合。
    """

    # ハイフンを削除
    mesh_code = mesh_code.replace("-", "")

    # 無効なメッシュコードのチェック
    if not mesh_code.isdigit() or len(mesh_code) not in {4, 6, 8, 9, 10}:
        raise ValueError("Invalid mesh code.")

    # メッシュコードの種類を特定
    mesh_level = {4: 0, 6: 1, 8: 2, 9: 3, 10: 4}.get(len(mesh_code))

    # 各メッシュレベルの増分(緯度・経度の単位距離)
    increments = [
        (40 / 60, 1),              # 第1次メッシュ
        (5 / 60, 7.5 / 60),        # 第2次メッシュ
        (30 / 3600, 45 / 3600),    # 第3次メッシュ
        (15 / 3600, 22.5 / 3600),  # 第4次メッシュ(2分の1地域メッシュ, 1/2メッシュ)
        (7.5 / 3600, 11.25 / 3600) # 第5次メッシュ(4分の1地域メッシュ, 1/4メッシュ)
    ]

    # メッシュレベルごとに座標を加算
    for i, (lat_inc, lon_inc) in enumerate(increments):
        # メッシュコード内の該当位置を取得
        if i == 0:  # 第1次メッシュ(2桁)
            # 基本の緯度・経度
            latitude = int(mesh_code[:2]) / 1.5
            longitude = int(mesh_code[2:4]) + 100
        else:
            if i < 3:  # 第2・3次メッシュ(2桁)
                index = 4 + (i - 1) * 2
            else:  # 第4・5次メッシュ(1桁)
                index = 8 + (i - 3)

            # メッシュレベルごとの加算処理
            if i < 3:
                # 2桁番号に応じた緯度経度の加算
                latitude += int(mesh_code[index]) * lat_inc # 緯度方向の番号
                longitude += int(mesh_code[index + 1]) * lon_inc # 経度方向の番号
            else:
                # 1桁番号で縦横2分割した緯度経度の加算
                code_value = int(mesh_code[index])  # 1桁の番号
                latitude += ((code_value - 1) // 2) * lat_inc  # 緯度方向の移動
                longitude += ((code_value - 1) % 2) * lon_inc  # 経度方向の移動

        # 最終レベルの場合、補正値を適用して返す
        if i == mesh_level:
            if apply_correction:
                return latitude + lat_inc / 2, longitude + lon_inc / 2
            else:
                return latitude, longitude

特にこれ以上説明することはないです。
コードは好きに使ってください。
最近はAIがこういうのも簡単に作ってくれるので良いですね。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?