アプリの座標変換・補正データベース解説

,

はじめに

アプリでは、高精度な測位・座標変換を実現するために、国土地理院(GSI)が公開しているパラメータファイルをSQLite3データベースに変換して利用しています。本記事では、各データベースの役割・元ファイルとの対応・補正計算方法を詳しく解説します。


1. データベース一覧と国土地理院パラメータファイルの対応

# DB ファイル名 元パラメータファイル 用途 レコード数 DB サイズ
1 SemiDyna2026.db SemiDyna2026.par セミ・ダイナミック補正(2026年度) 約21,134 1.6MB
2 SemiDyna2025.db SemiDyna2025.par セミ・ダイナミック補正(2025年度) 約21,134 1.6MB
3 pos2jgd_202601_ITRF2020.db pos2jgd_202601_ITRF2020.par GNSS測位座標→JGD2024補正 約21,134 1.6MB
4 TKY2JGD.db TKY2JGD.par 東京測地系→JGD2000変換 392,323 26MB
5 henkaku.db henkaku.csv 磁気偏角データ 4,909 404KB
6 gsigeo2011_ver2_2.db gsigeo2011_ver2_2.asc ジオイドモデル2011 2,163,001 95MB
7 JPGEO2024.db JPGEO2024+Hrefconv2024.isg ジオイドモデル2024(離島基準面補正含む) 224,677 167MB
8 jgdMerge2024.db 2011年以降地震parファイル4本をマージ 地震補正(JGD2024向け) 175,657 12MB
9 jgdMerge2011.db 2003〜2011年地震parファイル8本をマージ 地震補正(JGD2011向け) 203,287 14MB

jgdMerge系に使用した地震補正パラメータファイル

ファイル名 地震名 発生年
tokachi2003.par 十勝沖地震 2003
tokachi2003b.par 十勝沖地震(補完) 2003
fukuoka2005.par 福岡県西方沖地震 2005
noto2007_BL.par 能登半島地震 2007
chuetsuoki2007.par 新潟県中越沖地震 2007
iwatemiyagi2008.par 岩手・宮城内陸地震 2008
miyakojima2008.par 宮古島近海地震 2008
touhokutaiheiyouoki2011.par 東北地方太平洋沖地震 2011
kumamoto2016_BL.par 熊本地震 2016
noto2024_BL.par 令和6年能登半島地震 2024
noto2024_02BL.par 令和6年能登半島地震(補完) 2024
hyuganada2024_BL.par 日向灘地震 2024

2. 各データベースの詳細

2-1. SemiDyna2026.db / SemiDyna2025.db — セミ・ダイナミック補正

役割: JGD2011座標からJGD2024座標へ変換するためのセミ・ダイナミック補正パラメータ。

元ファイルフォーマット(SemiDyna2026.par抜粋):

for SemiDynaEXE    Ver.1.0.0
...
適用期間:2026年4月1日から2027年3月31日まで
補正パラメータ基準年月日:2026年1月1日
...
MeshCode dB(sec)  dL(sec) dH(m)
36230600  -0.06131   0.04401   0.00073
36230605  -0.06066   0.04414   0.00028
  • ヘッダー: 16行(17行目からデータ)
  • データ: メッシュコード ΔB(秒) ΔL(秒) ΔH(m)
  • 文字コード: UTF-8

テーブル定義:

CREATE TABLE semidyna_corrections (
    mesh_code TEXT PRIMARY KEY,  -- 3次メッシュコード(8桁)
    db_sec    REAL NOT NULL,      -- 緯度補正量(秒)
    dl_sec    REAL NOT NULL,      -- 経度補正量(秒)
    dh_m      REAL NOT NULL       -- 楕円体高補正量(m)
);
CREATE INDEX idx_mesh_code ON semidyna_corrections(mesh_code);

適用期間について: SemiDynaファイルは年度ごとに発行される。2026年度版(SemiDyna2026.par)の適用期間は2026年4月1日〜2027年3月31日。測量に使用する場合は、測量実施年度に対応するファイルを使用する必要がある。


2-2. pos2jgd_202601_ITRF2020.db — GNSS測位座標→JGD2024補正

役割: スマートフォンやGNSS受信機が出力するITRF2020(GRS80楕円体)座標を、日本の国家基準であるJGD2024に変換するパラメータ。

元ファイルフォーマット(pos2jgd_202601_ITRF2020.parヘッダー抜粋):

GRIDDED CORRECTION PARAMETER FOR POS2JGD
FORMAT_VERSION             = 1.01
NATIONAL_DATUM             = JGD2024
POSITIONING_DATUM          = ITRF2020+GRS80
EPOCH_OF_PARAMETER         = 20260101
START_OF_APPLICABLE_PERIOD = 20260401
END_OF_APPLICABLE_PERIOD   = 20260531
DATA_FIELDS                = '4 MeshCode dB dL dH'
  • ヘッダー: 18行(19行目からデータ)
  • 文字コード: UTF-8

テーブル定義:

CREATE TABLE pos2jgd_corrections (
    mesh_code TEXT PRIMARY KEY,
    db_sec    REAL NOT NULL,
    dl_sec    REAL NOT NULL,
    dh_m      REAL NOT NULL
);

SemiDynaとの違い:

項目 SemiDyna pos2jgd
変換元 JGD2011 ITRF2020(GNSS測位値)
変換先 JGD2024 JGD2024
主な用途 既存測量データの変換 リアルタイムGNSS測位値の補正
適用期間 1年度ごと 約2ヶ月ごとに更新

2-3. TKY2JGD.db — 東京測地系→JGD2000変換

役割: 旧来の東京測地系(Tokyo Datum)座標をJGD2000へ変換するパラメータ。2003年以前の地図・測量データとの互換性のために使用。

元ファイルフォーマット(TKY2JGD.par):

JGD2000-TokyoDatum Ver.2.1.2
MeshCode   dB(sec)   dL(sec)
46303582  12.79799  -8.13354
46303583  12.79879  -8.13749
  • ヘッダー: 2行(3行目からデータ)
  • データ: メッシュコード ΔB(秒) ΔL(秒) (高さ補正なし)
  • 文字コード: Shift_JIS (cp932)

テーブル定義:

CREATE TABLE tky2jgd_corrections (
    mesh_code TEXT PRIMARY KEY,
    db_sec    REAL NOT NULL,
    dl_sec    REAL NOT NULL
);

2-4. henkaku.db — 磁気偏角データ

役割: コンパスが示す磁北と、地図の真北のずれ角(磁気偏角)を補正するデータ。2次メッシュ単位で収録。

元ファイルフォーマット(henkaku.csv):

ido,kdo,henkaku,mesh2
34.0,130.0,-6.5,5130
34.0,131.0,-6.3,5131
  • フォーマット: CSV(ヘッダー行あり)
  • 文字コード: Shift_JIS (cp932)

テーブル定義:

CREATE TABLE henkaku_data (
    mesh2   TEXT PRIMARY KEY,   -- 2次メッシュコード
    ido     REAL NOT NULL,       -- 緯度(度)
    kdo     REAL NOT NULL,       -- 経度(度)
    henkaku REAL NOT NULL        -- 磁気偏角(度)
);

2-5. gsigeo2011_ver2_2.db — ジオイドモデル2011

役割: GNSS測位で得られる楕円体高を、実用的な標高(平均海面からの高さ)に変換するためのジオイド高データ。JGD2011準拠。

元ファイルフォーマット(gsigeo2011_ver2_2.asc):

  20.00000 120.00000 0.016667 0.025000 1801 1201 1 ver2.2
 999.0000 999.0000 ...  ← 陸域外は999.0000(無効値)
  • 1行目: 南端緯度 西端経度 緯度間隔 経度間隔 行数 列数 ... バージョン
  • 2行目以降: ジオイド高(m)、空白区切りで連続
  • 文字コード: Shift_JIS (cp932)

グリッド仕様:

項目
カバー範囲 北緯20〜50度、東経120〜150度
緯度間隔 0.016667度(約1分)
経度間隔 0.025度(約1.5分)
グリッド数 1801行 × 1201列 = 2,163,001点
無効値 999.0000(陸域外)

テーブル定義(JPGEO2024と共通構成):

CREATE TABLE geoid_data (
    row_idx      INTEGER NOT NULL,  -- 南端=0、北に向かって増加
    col_idx      INTEGER NOT NULL,  -- 西端=0、東に向かって増加
    geoid_height REAL    NOT NULL,  -- ジオイド高(m)
    PRIMARY KEY (row_idx, col_idx)
);
CREATE TABLE metadata (
    key   TEXT PRIMARY KEY,
    value TEXT
);
CREATE INDEX idx_row_col ON geoid_data(row_idx, col_idx);

メタデータに格納される情報:

lat_south    = 20.0      ← グリッド南端緯度
lon_west     = 120.0     ← グリッド西端経度
lat_interval = 0.016667  ← 緯度方向グリッド間隔
lon_interval = 0.025     ← 経度方向グリッド間隔
nrows        = 1801
ncols        = 1201
nodata       = 999.0

注意: gsigeo2011では無効値(999.0)もデータとして保存している(全2,163,001レコード)。座標からの検索後に無効値チェックが必要。


2-6. JPGEO2024.db — ジオイドモデル2024(離島基準面補正含む)

役割: JGD2024準拠の最新ジオイドモデル。離島の局所基準面(Hrefconv2024)を含む版(JPGEO2024+Hrefconv2024.isg)。

元ファイルフォーマット(ISG 2.0形式):

begin_of_head ====...
model name     : JPGEO2024+Hrefconv2024
data ordering  : N-to-S, W-to-E    ← 北→南の順でデータが並ぶ
ref ellipsoid  : GRS80
lat min        =  15°00'00"
lat max        =  50°00'00"
lon min        = 120°00'00"
lon max        = 160°00'00"
delta lat      =   0°01'00"   ← 1分間隔
delta lon      =   0°01'30"   ← 1.5分間隔
nrows          =        2101
ncols          =        1601
nodata         =  -9999.0000
creation date  =  01/04/2025
end_of_head ===...
-9999.0000 -9999.0000 ...   ← 陸域外はnodata

グリッド仕様:

項目
カバー範囲 北緯15〜50度、東経120〜160度
緯度間隔 1分(0.016667度)
経度間隔 1.5分(0.025度)
グリッド数 2101行 × 1601列 = 3,363,701点
無効値 -9999.0000
有効レコード数 224,677(nodata除く)

テーブル定義: gsigeo2011と同一構成。

行インデックスの方向:
ISGファイルは「北から南」の順でデータが並んでいるが、DBへの格納時に row_idx = (nrows - 1) - row_from_north として反転させ、「南端=0」の統一フォーマットに変換している。


2-7. jgdMerge2024.db / jgdMerge2011.db — 地震補正パラメータ

役割: 日本で発生した大地震による地殻変動量を補正するパラメータ。各地震のPatchJGDファイルを時系列順に格納し、アプリ側が year_no 昇順に繰り返し座標補正を適用することで累積地殻変動を反映する。

補正の適用ロジック(アプリ側):

// year_no 昇順に各地震の補正を順番に適用する
var corrections = db.Query(
    "SELECT db_sec, dl_sec FROM mesh_corrections WHERE mesh_code IN (...) ORDER BY year_no ASC");

foreach (var (yearNo, dB, dL) in corrections)
{
    // 地震ごとに補正を繰り返し適用(バイリニア補間を都度実施)
    (lat, lon) = ApplyBilinearCorrection(lat, lon, dB, dL);
}

設計のポイント: 補正は「累積加算した1回分」ではなく「各地震を1回ずつ順番に適用」する。 これにより、補正後の座標を次の補正の入力とする連鎖的な変換が正確に行われる。 DBには各地震の単体補正量year_no 付きで格納し、累積合算は行わない。 (累積値は .par ファイル側にのみ書き出されている)

テーブル定義:

CREATE TABLE mesh_corrections (
    mesh_code TEXT    NOT NULL,
    db_sec    REAL    NOT NULL,   -- その地震単体の緯度補正量(秒)
    dl_sec    REAL    NOT NULL,   -- その地震単体の経度補正量(秒)
    year_no   INTEGER NOT NULL,   -- 地震発生順のシーケンシャルNo(0始まり)
    PRIMARY KEY (mesh_code, year_no)
);
CREATE INDEX idx_mesh_code ON mesh_corrections(mesh_code);
CREATE INDEX idx_year_no   ON mesh_corrections(year_no);

year_no とファイルの対応(jgdMerge2011.db):

year_no ファイル 地震名 レコード数
0 tokachi2003.par 十勝沖地震 33,220
1 tokachi2003b.par 十勝沖地震(補完) 8,602
2 fukuoka2005.par 福岡県西方沖地震 1,165
3 noto2007_BL.par 能登半島地震 604
4 chuetsuoki2007.par 中越沖地震 694
5 iwatemiyagi2008.par 岩手・宮城内陸地震 7,851
6 miyakojima2008.par 宮古島近海地震 348
7 touhokutaiheiyouoki2011.par 東北地方太平洋沖地震 161,053

year_no とファイルの対応(jgdMerge2024.db):

year_no ファイル 地震名 レコード数
0 kumamoto2016_BL.par 熊本地震 10,651
1 noto2024_BL.par 令和6年能登半島地震 15,347
2 noto2024_02BL.par 令和6年能登半島地震(補完) 2,001
3 hyuganada2024_BL.par 日向灘地震 3,747

2種類の用途:

DB名 マージ対象 用途
jgdMerge2024.db 2011年以降(4ファイル) JGD2011→JGD2024変換(熊本地震以降)
jgdMerge2011.db 2003〜2011年(8ファイル) WGS84/JGD2000→JGD2011変換

3. 補正計算方法

3-1. メッシュコード計算

すべてのメッシュベースDBは**3次メッシュコード(8桁)**をキーにしている。緯度・経度からメッシュコードを算出する方法:

緯度 lat、経度 lon から 3次メッシュコード
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1次コード(4桁): p = floor(lat * 1.5)       → 2桁
                  u = floor(lon) - 100         → 2桁
                  1次 = p * 100 + u + 100 * 36  ... 実際はp,u連結で4桁

2次コード(6桁): q = floor((lat * 1.5 - p) * 8)
                  v = floor((lon - floor(lon)) * 8)
                  2次 = 1次コード + q * 8 + v  (2桁追加)

3次コード(8桁): r = floor((lat * 1.5 - p - q/8) * 10 * 8)
                  w = floor((lon - floor(lon) - v/8) * 10 * 8)
                  3次 = 2次コード + r * 10 + w  (2桁追加)

3-2. バイリニア補間

3次メッシュ(約1km四方)の中心値だけでは精度が不足するため、対象点の周囲4メッシュの補正値を使ってバイリニア補間を行う。

対象点 P(lat, lon) に対して4隅のメッシュを取得:
  P11 = (i,   j)    P12 = (i,   j+1)
  P21 = (i+1, j)    P22 = (i+1, j+1)

メッシュ内の相対位置:
  t = (lat - lat_P11) / mesh_lat_size    (0〜1)
  s = (lon - lon_P11) / mesh_lon_size    (0〜1)

補間値:
  val = (1-t)(1-s) * P11
      + (1-t)(  s) * P12
      + (  t)(1-s) * P21
      + (  t)(  s) * P22

3-3. 座標変換フロー

アプリで使用している座標変換の全体フローを示す。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  スマートフォンGNSS測位値 (ITRF2020/WGS84)
          │
          ├──→ pos2jgd補正 ──→ JGD2024 (緯度・経度)
          │     └─ pos2jgd_202601_ITRF2020.db
          │
          ├──→ 3次元座標変換 ──→ JGD2011
          │     └─ 7パラメータBursaWolf変換(定数)
          │          │
          │          ├──→ jgdMerge2024補正 ──→ JGD2024
          │          │    └─ jgdMerge2024.db
          │          │
          │          └──→ SemiDyna補正 ──→ JGD2024
          │               └─ SemiDyna2026.db(年度で選択)
          │
          └──→ TKY2JGD補正 ──→ JGD2000/JGD2011
               └─ TKY2JGD.db(東京測地系データとの互換用)

  ジオイド高変換(楕円体高→標高):
  楕円体高 h (GNSS)
      │
      ├──→ ジオイド高 N (gsigeo2011_ver2_2.db or JPGEO2024.db)
      │
      └──→ 標高 H = h - N  (JGD2011: gsigeo2011使用、JGD2024: JPGEO2024使用)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

3-4. メッシュコードDB vs グリッドDB の補正値取得方法

メッシュコードDB(SemiDyna、TKY2JGD、pos2jgd、jgdMerge系):

// 1. 緯度経度から3次メッシュコードを計算
string meshCode = CalcMeshCode(lat, lon);

// 2. DBからその周辺4メッシュの補正値を取得
var corrections = db.Query("SELECT mesh_code, db_sec, dl_sec FROM ... WHERE ...");

// 3. バイリニア補間で補正値を計算
(double dB, double dL) = BilinearInterpolate(lat, lon, corrections);

// 4. 補正適用
double correctedLat = lat + dB / 3600.0;
double correctedLon = lon + dL / 3600.0;

グリッドDB(gsigeo2011、JPGEO2024):

// 1. 緯度経度からグリッドインデックスを計算
// メタデータから lat_south, lon_west, lat_interval, lon_interval を取得
double rowF = (lat - lat_south) / lat_interval;
double colF = (lon - lon_west)  / lon_interval;

int row0 = (int)Math.Floor(rowF);
int col0 = (int)Math.Floor(colF);

// 2. 周辺4点のジオイド高を取得
double N00 = GetGeoidHeight(row0,   col0);
double N01 = GetGeoidHeight(row0,   col0+1);
double N10 = GetGeoidHeight(row0+1, col0);
double N11 = GetGeoidHeight(row0+1, col0+1);

// 3. バイリニア補間
double t = rowF - row0;  // 0〜1
double s = colF - col0;  // 0〜1
double N = (1-t)*(1-s)*N00 + (1-t)*s*N01 + t*(1-s)*N10 + t*s*N11;

// 4. 標高計算
double H = ellipsoidHeight - N;

4. データベース生成方法(内部資料)

cd jgdPara/idokido

# 地震補正パラメータのマージとDB化(jgdMerge系3ファイル)
python3 mergePar.py

# その他のパラメータファイルのDB化(SemiDyna/pos2jgd/TKY2JGD/henkaku/ジオイド)
python3 convertParToDb.py

出力先: parOut/ フォルダ

注意: gsigeo2011_ver2_2.db(95MB)と JPGEO2024.db(167MB)は大容量のためGit LFSで管理されている。新規クローン後は git lfs pull で取得が必要。


5. 参照元データの入手先(国土地理院)

データ 入手先URL
SemiDyna(セミ・ダイナミック補正) https://www.gsi.go.jp/sokuchikijun/semidyna.html
pos2jgd(GNSS測位値→JGD2024) https://www.gsi.go.jp/sokuchikijun/pos2jgd.html
TKY2JGD(東京測地系→JGD2000) https://www.gsi.go.jp/sokuchikijun/tky2jgd.html
PatchJGD(地震補正) https://www.gsi.go.jp/sokuchikijun/patchjgd.html
gsigeo2011(ジオイド2011) https://www.gsi.go.jp/buturisokuchi/geoid.html
JPGEO2024(ジオイド2024) https://www.gsi.go.jp/buturisokuchi/geoid.html
磁気偏角 https://www.gsi.go.jp/buturisokuchi/menu03_magnetic_chart.html

まとめ

アプリでは計10種類のSQLite3データベースを使い分けることで、以下の変換を高速かつ高精度に実現している:

  • 測地系変換: 東京測地系→JGD2000、WGS84→JGD2011→JGD2024、GNSS測位値→JGD2024
  • 地殻変動補正: 2003〜2024年の12大地震による変動量をメッシュ単位で補正
  • 標高変換: 楕円体高からジオイド高を差し引いた正規直交高(標高)への変換
  • コンパス補正: 磁気偏角を用いた真北補正

すべてのDBにインデックスが張られており、O(1)〜O(log n)での検索が可能。アプリ起動時のDBロードと、バイリニア補間による内挿計算を組み合わせることで、1cm精度クラスの高速座標変換を実現している。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

PAGE TOP