ゆべねこの足跡

アプリケーションの個人開発をはじめとした話を書いていきます

平面直角座標と緯度経度の変換を行う(C#)

ARアプリを作る際に緯度経度と平面直角座標の相互変換の技術が必要になりそうなので、C#で変換をするためのスクリプトを書いてみました。

変換式は?

国土地理院のサイトに変換式についてのページがあります。

平面直角座標への換算 計算式

緯度、経度への換算 計算式

数式がいっぱいで頭が痛くなりそうですね...。幸いにもこれらの数式の中間結果の依存関係を図式化している方がいらっしゃったので、そちらを参考にしながらコーディングをしました。

sw1227.hatenablog.com

コード

平面直交座標と緯度経度の相互変換をする。

使い方

using System;
using GeoCoordinateUtility;

namespace ConvertGeoCoordinate
{
    class Program
    {
        static void Main (string[] args)
        {
            var latLon = GeoCoordinateConverter.Coordinate2LatLon (
                x0: 53999.2571,
                y0: -83939.5673,
                latOrigin_deg : 36.00000000,
                lonOrigin_deg : 139 + 50d / 60d);
            Console.WriteLine ($"緯度, 経度 = {latLon.X}, {latLon.Y}");

            var coordinate = GeoCoordinateConverter.LatLon2Coordinate (
                lat0_deg: 36.483011,
                lon0_deg: 138.896538,
                latOrigin_deg: 36.00000000,
                lonOrigin_deg: 139 + 50d / 60d);
            Console.WriteLine ($"X, Y = {coordinate.X}, {coordinate.Y}");
        }
    }
}

結果

緯度, 経度 = 36.48301100025305, 138.89653799991123
X, Y = 53999.25707184523, -83939.56729232075

ちなみに、サンプルで指定した場所は某車漫画の聖地です。

ざっくりとした変換の仕組みの解説

そもそもどうやって緯度経度を座標に変換するのでしょうか。考え方としては、ある地点の周りが平面になっていると仮定してその地点を平面直角座標の原点として座標系を定めるといった感じです。日本にはその「ある地点」が19個あります。19個もある理由ですが、これは一つの原点だけでは地球の丸みによるずれが生じてしまうためです。地点によって原点の緯度経度が決まります。例えば、群馬県なら系番号9に該当するため、平面直角座標の原点の緯度経度は北緯36度0分0秒、東経139度50分0秒となります。

わかりやすい平面直角座標系 | 国土地理院

本コードの変換メソッドはどちらも座標系原点の緯度経度を引数にとります。なお、引数の緯度経度の単位は10進数の度単位になっているので、度分秒表記の場合は度単位に変換する必要があります。

コード内の定数(a, F, m0)についての詳細はこちらをご覧ください。

日本の測地系 | 国土地理院

注意

緯度経度から座標に変換する際に国土地理院のサイトを使って変換してみると分かるのですが、どうやら測量分野ではXが南北方向を表し、Yが東西方向を表すようです。普段イメージする座標軸とは逆になっているので注意が必要です。

参考サイト

[C#]平面直角座標系と緯度経度を変換する

緯度経度と平面直角座標の相互変換をPythonで実装する - Qiita