概要
GeoDiveExaアプリに、日本の新しい測地系「JGD2024(日本測地系2024)」への対応機能を実装しました。本記事では、JGD2024とは何か、JGD2011との違い、そして実装の詳細について解説します。
重要な前提:RTK補正済みWGS84 = JGD2011
まず、最も重要な前提を明確にします:
RTK(リアルタイムキネマティック)GNSS受信機で取得される補正済みWGS84座標は、実質的にJGD2011と同じです。
これは、RTK補正によって以下が実現されるためです:
- GRS80楕円体の使用(JGD2011と同じ)
- 2011年の地殻変動を反映した座標系
- センチメートル級の高精度測位
したがって、GeoDiveアプリでRTK受信機から取得したWGS84座標は、JGD2011座標として扱う事にします。
日本の測地系の変遷
1. Tokyo(日本測地系)
- 使用期間: 1918年~2002年
- 楕円体: Bessel楕円体
- 特徴: 日本独自の測地系、世界測地系との差が約400m
2. JGD2000(日本測地系2000)
- 導入年: 2002年
- 楕円体: GRS80楕円体
- 特徴: 世界測地系に準拠、Tokyo測地系から約400mの位置ずれ
3. JGD2011(日本測地系2011)
- 導入年: 2011年
- 楕円体: GRS80楕円体(JGD2000と同じ)
- 特徴: 2011年東日本大震災による地殻変動を反映
- JGD2000との差: 東北地方で最大5m程度の位置ずれ
4. JGD2024(日本測地系2024)
- 導入年: 2024年
- 楕円体: GRS80楕円体(JGD2011と同じ)
- 基準日: 2024年2月1日
- 特徴: プレート運動による定常的な地殻変動を補正(セミ・ダイナミック補正)
- JGD2011との差: 地域により数cm~1.4m程度
JGD2024の特徴:セミ・ダイナミック補正
なぜ新しい測地系が必要か?
日本列島は、複数のプレート(太平洋プレート、フィリピン海プレート、ユーラシアプレート、北米プレート)の境界に位置しており、プレート運動により年間数センチメートルの地殻変動が継続的に発生しています。
問題点:
- JGD2011の基準日: 2011年5月24日
- 時間経過とともに実際の座標と基準座標のずれが蓄積
- 2024年には地域により最大1.4m程度のずれが発生
JGD2024の解決策:
- 基準日を2024年2月1日に更新
- プレート運動による定常的な変動を補正
- より現実の地球の形状に即した座標系
測地系間の変換経路
正しい変換の流れ
RTK補正済みWGS84 = JGD2011
│
├─→ JGD2024(セミ・ダイナミック補正)
│ ↓
│ 年間数cm~1.4mの補正
│
└─→ JGD2000(PatchJGD逆補正)
│ ↓
│ 2011年地震の地殻変動を戻す
│ (東北地方で最大5m)
│
└─→ Tokyo(TKY2JGD逆補正)
↓
約400mの位置ずれ補正
使用する補正パラメータファイル
- TKY2JGD.par(392,323点)
- Tokyo測地系 ⇔ JGD2000 の変換補正
- 日本測地系の歪みを補正
- jgdMerge2011.par(217,891点)
- JGD2000 ⇔ JGD2011 の変換補正
- 2011年東日本大震災の地殻変動を補正
- SemiDyna2024.par(21,134点)
- JGD2011 ⇔ JGD2024 の変換補正
- プレート運動による定常的な地殻変動を補正
実装の詳細
1. WGS84とJGD2011の関係
/// <summary>
/// WGS84からJGD2011に変換
/// RTK補正済みWGS84はJGD2011と同じなので、そのまま返す
/// </summary>
public static (double Latitude, double Longitude) WGS84ToJGD2011(
double latitude, double longitude)
{
return (latitude, longitude);
}
/// <summary>
/// JGD2011からWGS84に変換
/// JGD2011とWGS84は同じなので、そのまま返す
/// </summary>
public static (double Latitude, double Longitude) JGD2011ToWGS84(
double latitude, double longitude)
{
return (latitude, longitude);
}
2. WGS84からJGD2000への変換
/// <summary>
/// WGS84からJGD2000に変換
/// RTK補正済みWGS84はJGD2011と同じなので、JGD2011→JGD2000の変換を行う
/// </summary>
public static (double Latitude, double Longitude) WGS84ToJGD2000(
double latitude, double longitude)
{
try
{
// RTK補正済みWGS84 = JGD2011 → JGD2000の変換(PatchJGD逆補正)
return JGD2011Correction.JGD2011ToJGD2000WithCorrection(latitude, longitude);
}
catch (Exception ex)
{
Log.Warn($"WGS84ToJGD2000 エラー: {ex.Message}");
return (latitude, longitude);
}
}
重要: ここでPatchJGD逆補正が行われます。2011年の地震による地殻変動を「戻す」処理です。
3. JGD2000からWGS84への変換
/// <summary>
/// JGD2000からWGS84に変換
/// JGD2000→JGD2011の変換を行い、結果はWGS84と同じ
/// </summary>
public static (double Latitude, double Longitude) JGD2000ToWGS84(
double latitude, double longitude)
{
try
{
// JGD2000 → JGD2011(=WGS84)の変換(PatchJGD補正)
return JGD2011Correction.JGD2000ToJGD2011WithCorrection(latitude, longitude);
}
catch (Exception ex)
{
Log.Warn($"JGD2000ToWGS84 エラー: {ex.Message}");
return (latitude, longitude);
}
}
4. WGS84からTokyoへの変換(2段階変換)
/// <summary>
/// WGS84からTokyo座標系に変換
/// RTK補正済みWGS84はJGD2011と同じなので、JGD2011→JGD2000→Tokyoの2段階変換
/// </summary>
public static (double Latitude, double Longitude) WGS84ToTokyo(
double latitude, double longitude)
{
try
{
// ステップ1: WGS84(=JGD2011) → JGD2000(PatchJGD逆補正)
var (jgd2000Lat, jgd2000Lon) = WGS84ToJGD2000(latitude, longitude);
// ステップ2: JGD2000 → Tokyo(TKY2JGD逆補正)
return TokyoJGDCorrection.JGD2000ToTokyoWithCorrection(jgd2000Lat, jgd2000Lon);
}
catch (Exception ex)
{
Log.Warn($"WGS84ToTokyo エラー: {ex.Message}");
return (latitude - 12.0 / 3600.0, longitude - 17.0 / 3600.0);
}
}
5. TokyoからWGS84への変換(2段階変換)
/// <summary>
/// Tokyo座標系からWGS84に変換
/// Tokyo→JGD2000→JGD2011(=WGS84)の2段階変換
/// </summary>
public static (double Latitude, double Longitude) TokyoToWGS84(
double latitude, double longitude)
{
try
{
// ステップ1: Tokyo → JGD2000(TKY2JGD補正)
var (jgd2000Lat, jgd2000Lon) = TokyoJGDCorrection.TokyoToJGD2000WithCorrection(
latitude, longitude);
// ステップ2: JGD2000 → JGD2011(=WGS84)(PatchJGD補正)
return JGD2011Correction.JGD2000ToJGD2011WithCorrection(jgd2000Lat, jgd2000Lon);
}
catch (Exception ex)
{
Log.Warn($"TokyoToWGS84 エラー: {ex.Message}");
return (latitude + 12.0 / 3600.0, longitude + 17.0 / 3600.0);
}
}
6. WGS84からJGD2024への変換
/// <summary>
/// WGS84からJGD2024に変換(2段階変換: WGS84→JGD2011→JGD2024)
/// </summary>
public static (double Latitude, double Longitude, double Height) WGS84ToJGD2024(
double latitude,
double longitude,
double height = 0.0)
{
try
{
// ステップ1: WGS84→JGD2011(RTK補正済みなのでそのまま)
var (jgd2011Lat, jgd2011Lon) = WGS84ToJGD2011(latitude, longitude);
// ステップ2: JGD2011→JGD2024(セミ・ダイナミック補正)
var (jgd2024Lat, jgd2024Lon, jgd2024Height) =
SemiDynaCorrection.JGD2011ToJGD2024WithCorrection(
jgd2011Lat,
jgd2011Lon,
height);
return (jgd2024Lat, jgd2024Lon, jgd2024Height);
}
catch (Exception ex)
{
Log.Warn($"WGS84ToJGD2024 エラー: {ex.Message}");
return (latitude, longitude, height);
}
}
7. JGD2024からWGS84への変換
/// <summary>
/// JGD2024からWGS84に変換(2段階変換: JGD2024→JGD2011→WGS84)
/// </summary>
public static (double Latitude, double Longitude, double Height) JGD2024ToWGS84(
double latitude,
double longitude,
double height = 0.0)
{
try
{
// ステップ1: JGD2024→JGD2011(セミ・ダイナミック補正の逆変換)
var (jgd2011Lat, jgd2011Lon, jgd2011Height) =
SemiDynaCorrection.JGD2024ToJGD2011WithCorrection(
latitude,
longitude,
height);
// ステップ2: JGD2011→WGS84(そのまま)
var (wgs84Lat, wgs84Lon) = JGD2011ToWGS84(jgd2011Lat, jgd2011Lon);
return (wgs84Lat, wgs84Lon, jgd2011Height);
}
catch (Exception ex)
{
Log.Warn($"JGD2024ToWGS84 エラー: {ex.Message}");
return (latitude, longitude, height);
}
}
セミ・ダイナミック補正の実装
SemiDynaCorrection.csクラス
public class SemiDynaCorrection
{
private static readonly Dictionary<string, MeshCorrection> meshCorrectionData = new();
/// <summary>
/// JGD2011からJGD2024に変換(セミ・ダイナミック補正)
/// </summary>
public static (double lat, double lon, double height) JGD2011ToJGD2024WithCorrection(
double jgd2011Lat, double jgd2011Lon, double height)
{
// メッシュコードから補正値を取得
var meshCode = MeshCodeUtility.GetMeshCode(jgd2011Lat, jgd2011Lon, 3);
if (!meshCorrectionData.TryGetValue(meshCode, out var correction))
{
// 補正パラメータが見つからない場合はそのまま返す
return (jgd2011Lat, jgd2011Lon, height);
}
// 双線形補間による高精度補正
var (dB, dL, dH) = GetInterpolatedCorrection(jgd2011Lat, jgd2011Lon);
// 補正を適用
// dB, dLは秒単位、dHはメートル単位
double jgd2024Lat = jgd2011Lat + dB / 3600.0;
double jgd2024Lon = jgd2011Lon + dL / 3600.0;
double jgd2024Height = height + dH;
return (jgd2024Lat, jgd2024Lon, jgd2024Height);
}
/// <summary>
/// JGD2024からJGD2011に変換(セミ・ダイナミック補正の逆変換)
/// </summary>
public static (double lat, double lon, double height) JGD2024ToJGD2011WithCorrection(
double jgd2024Lat, double jgd2024Lon, double height)
{
// 逆変換では補正値の符号を反転
var meshCode = MeshCodeUtility.GetMeshCode(jgd2024Lat, jgd2024Lon, 3);
if (!meshCorrectionData.TryGetValue(meshCode, out var correction))
{
return (jgd2024Lat, jgd2024Lon, height);
}
var (dB, dL, dH) = GetInterpolatedCorrection(jgd2024Lat, jgd2024Lon);
// 補正を逆方向に適用
double jgd2011Lat = jgd2024Lat - dB / 3600.0;
double jgd2011Lon = jgd2024Lon - dL / 3600.0;
double jgd2011Height = height - dH;
return (jgd2011Lat, jgd2011Lon, jgd2011Height);
}
}
動作確認結果
11地点でのテスト結果
起動時に以下の11地点で座標変換テストを実施し、すべて正常に動作することを確認しました:
| 地点 | JGD2011→JGD2024補正量 | 緯度差 | 経度差 | 特徴 |
|---|---|---|---|---|
| 東京都庁 | 0.32m | -0.09m | +0.31m | 関東地方の基準点 |
| 仙台駅周辺 | 1.43m | -0.45m | +1.36m | 最大補正量、東北地方 |
| 北海道庁 | 0.65m | -0.49m | +0.42m | 北海道地方 |
| 能登半島 | 0.69m | -0.13m | +0.67m | 北陸地方、地震多発地域 |
| 名古屋駅 | 0.43m | -0.23m | +0.37m | 中部地方 |
| 新潟駅 | 1.01m | -0.20m | +0.99m | 日本海側、補正量大 |
| 大阪駅 | 0.50m | -0.23m | +0.44m | 近畿地方 |
| 広島駅 | 0.62m | -0.17m | +0.60m | 中国地方 |
| 福岡駅 | 0.71m | -0.25m | +0.67m | 九州地方 |
| 鹿児島中央駅 | 0.94m | -0.59m | +0.73m | 九州南部 |
| 沖縄県庁 | 1.38m | -1.02m | +0.92m | 沖縄地方、補正量大 |
補正量の傾向
- 最大補正量: 仙台市(1.43m)- 太平洋プレートの沈み込みが活発
- 最小補正量: 東京都(0.32m)- プレート運動の影響が比較的小さい
- 地域差: 北東日本と南西日本で補正量に差
- 沖縄の特徴: フィリピン海プレートの影響で1.38mの大きな補正
変換の具体例
例1: 東京都庁(WGS84 → 各測地系)
入力: RTK補正済みWGS84 = JGD2011
緯度: 35.689444°
経度: 139.691667°
高さ: 50.00m
変換結果:
JGD2011: (35.68944400, 139.69166700, 50.00) ※そのまま(WGS84=JGD2011)
JGD2024: (35.68944323, 139.69167047, 50.10) ※セミ・ダイナミック補正: 0.32m
JGD2000: (35.68944396, 139.69166355, 50.00) ※PatchJGD逆補正: 0.01m
Tokyo: (35.68620969, 139.69489090, 50.00) ※TKY2JGD逆補正: 約470m
変換の流れ:
- WGS84(=JGD2011) → JGD2024: セミ・ダイナミック補正で0.32m移動(緯度-0.09m、経度+0.31m)
- WGS84(=JGD2011) → JGD2000: PatchJGD逆補正で0.01m移動(東京は地震の影響極小)
- JGD2000 → Tokyo: TKY2JGD逆補正で約470m移動(測地系の違い)
例2: 仙台駅周辺(WGS84 → 各測地系)
入力: RTK補正済みWGS84 = JGD2011
緯度: 38.268215°
経度: 140.869356°
高さ: 50.00m
変換結果:
JGD2011: (38.26821500, 140.86935600, 50.00) ※そのまま(WGS84=JGD2011)
JGD2024: (38.26821092, 140.86937161, 50.19) ※セミ・ダイナミック補正: 1.43m
JGD2000: (38.26822303, 140.86931978, 50.00) ※PatchJGD逆補正: 3.37m(地震影響大)
Tokyo: (38.26525304, 140.87275076, 50.00) ※TKY2JGD逆補正: 約479m
変換の流れ:
- WGS84(=JGD2011) → JGD2024: セミ・ダイナミック補正で1.43m移動(緯度-0.45m、経度+1.36m)
- WGS84(=JGD2011) → JGD2000: PatchJGD逆補正で3.37m移動(2011年地震の影響が大きい)
- JGD2000 → Tokyo: TKY2JGD逆補正で約479m移動(測地系の違い)
例3: 沖縄県庁(WGS84 → 各測地系)
入力: RTK補正済みWGS84 = JGD2011
緯度: 26.212222°
経度: 127.680833°
高さ: 50.00m
変換結果:
JGD2011: (26.21222200, 127.68083300, 50.00) ※そのまま(WGS84=JGD2011)
JGD2024: (26.21221279, 127.68084226, 50.04) ※セミ・ダイナミック補正: 1.38m
JGD2000: (26.21222200, 127.68083300, 50.00) ※PatchJGD逆補正: 0.00m(影響なし)
Tokyo: (26.20830080, 127.68269097, 50.00) ※TKY2JGD逆補正: 約485m
変換の流れ:
- WGS84(=JGD2011) → JGD2024: セミ・ダイナミック補正で1.38m移動(緯度-1.02m、経度+0.92m)
- WGS84(=JGD2011) → JGD2000: PatchJGD逆補正なし(沖縄は2011年地震の影響なし)
- JGD2000 → Tokyo: TKY2JGD逆補正で約485m移動(測地系の違い)
変換における注意点
- JGD2011→JGD2000: 2011年地震の地殻変動を「戻す」処理(東北で最大5m)
- JGD2011→JGD2024: プレート運動による定常変動を「補正」(最大1.4m)
- 補正の方向: 地域によって異なる(プレート運動の方向に依存)
TransformFromTo()による統合変換
任意の測地系間の変換
public static (double lat, double lon, double height) TransformFromTo(
double lat,
double lon,
double height,
CoordinateSystemType from,
CoordinateSystemType to)
{
// WGS84 → JGD2024
if (from == CoordinateSystemType.WGS84 && to == CoordinateSystemType.JGD2024)
{
return WGS84ToJGD2024(lat, lon, height);
}
// JGD2024 → WGS84
if (from == CoordinateSystemType.JGD2024 && to == CoordinateSystemType.WGS84)
{
return JGD2024ToWGS84(lat, lon, height);
}
// その他の組み合わせも実装...
return (lat, lon, height);
}
まとめ
実装のポイント
- RTK補正済みWGS84 = JGD2011: これが最も重要な前提
- JGD2000への変換: PatchJGD逆補正が必要(2011年地震の影響を戻す)
- Tokyoへの変換: 2段階変換(JGD2011→JGD2000→Tokyo)
- JGD2024への変換: セミ・ダイナミック補正(プレート運動)
- parファイルの活用: 高精度な補正パラメータ(国土地理院提供)
測地系の使い分け
| 測地系 | 用途 | 精度 |
|---|---|---|
| JGD2024 | 現在の高精度測量 | 最高(2024年基準) |
| JGD2011 | RTK-GNSS測位 | 高(2011年基準) |
| JGD2000 | 過去データとの整合性 | 中(2000年基準) |
| Tokyo | 古い地図・データとの照合 | 低(1918年基準) |
今後の展開
- 時系列補正: 任意の日付での座標値計算
- 逆変換の精度向上: 反復計算による高精度化
注意1:確認できていません
2025/10/6日現在、JGD2024変換を行える地理院のWebサイトがないため、変換結果の比較・確認ができていないので、あくまでも参考として見てください。
注意2:保証はありません
ここに載せたプログラムはあくまでも参考です。マージした結果を使用して座標補正を行った結果について何ら保証はありませんし、国土地理院の結果と同じとは限りません。
参考情報
データソース
- SemiDyna2024.par: 国土地理院提供(21,134点)
- jgdMerge2011.par: 国土地理院提供の2003年から2011年までの地震による地殻変動パラメータファイルを全てマージした物(217,891点):参考 国土地理院PatchJGD相当の地殻変動補正を実装する(1)
- TKY2JGD.par: 国土地理院提供(392,323点)
技術資料
- 国土地理院「測地成果2024」: https://www.gsi.go.jp/sokuchikijun/jgd2024.html
- セミ・ダイナミック補正: https://www.gsi.go.jp/sokuchikijun/semidyna.html
- PatchJGD: https://www.gsi.go.jp/sokuchikijun/patchjgd.html
作成日: 2025年11月6日
バージョン: 2.0(修正版)
著者: GeoDive開発チーム
修正内容: RTK補正済みWGS84 = JGD2011に基づく正しい変換経路に修正1/Mrg1 25.11.5以降
作成者: GeoDive開発チーム
関連投稿
- 国土地理院PatchJGD相当の地殻変動補正を実装する(1) 変換プログラム
- 国土地理院PatchJGD相当の地殻変動補正を実装する(2) 可視化
- 国土地理院PatchJGD相当の地殻変動補正を実装する(3) クラスター分割可視化
- 国土地理院Tky2Jgd補正相当の地殻変動補正を実装する(1) 変換プログラム
- 国土地理院Tky2Jgd補正相当の地殻変動補正を実装する(2) 可視化
- JGD2011とJGD2024の違い – GeoDiveExaのJGD2024対応(1) 説明
- JGD2011とJGD2024の違い – GeoDiveExaのJGD2024対応(2) 変換プログラム
- JGD2011とJGD2024の違い – GeoDiveExaのJGD2024対応(3) 可視化

コメントを残す