ベクトルタイルの座標は緯度経度じゃない? — タイル内の0〜4096を経緯度に戻す手順と、地理院タイルとズームが1ずれる話

,

ベクトルタイルの座標は緯度経度じゃない? — タイル内の0〜4096を経緯度に戻す手順と、地理院タイルとズームが1ずれる話

ベクトルタイルの座標は緯度経度じゃない? — タイル内の0〜4096を経緯度に戻す手順と、地理院タイルとズームが1ずれる話

ベクトルタイル(.pbf)を開いて出てくる座標は、緯度経度でもメートルでもありません。そのタイルの左上を原点とする 0〜4096 の整数で、しかもY軸は下向きです。緯度経度に戻すには、タイル番号 z/x/y と組み合わせて Webメルカトル経由で2段階に戻します。さらに地理院のベクトルタイルは、同じ見え方のラスタタイルよりズームレベルが1小さい、という別の落とし穴があります。

中に入っている「3つめの座標系」

ベクトルタイルを扱うときは、座標系が3層あると考えると整理できます。

層 値の形 範囲 原点・向き
① タイル内座標 整数 0〜4096(既定の extent) タイル左上。X右向き・Y下向き
② Webメルカトル(EPSG:3857) メートル ±約20,037,508 赤道と本初子午線の交点。X右・Y上
③ 経緯度(WGS84 / EPSG:4326) 度 緯度±85.05・経度±180 —

.pbf の中身をそのまま読むと①が出てきます。GISソフトが緯度経度を表示してくれるのは、裏で②③まで戻しているからです。

なお extent の 4096 は Vector Tile Specification の既定値であって、必ず4096とは限りません。タイルのレイヤごとに extent が書き込まれているので、4096を決め打ちせずレイヤの値を読むのが正しい実装です。

経緯度へ戻す2段階

タイル番号を z / X / Y、タイル内座標を px / py、extent を E とすると、まず「世界全体を1辺 2^z のマス目に切ったときの実数座標」に直します。

worldX = X + px / E
worldY = Y + py / E

そこから経緯度へ。

import math

def tile_to_lonlat(z, X, Y, px, py, extent=4096):
    n = 2.0 ** z
    world_x = (X + px / extent) / n
    world_y = (Y + py / extent) / n
    lon = world_x * 360.0 - 180.0
    lat = math.degrees(math.atan(math.sinh(math.pi * (1.0 - 2.0 * world_y))))
    return lat, lon

逆向き(経緯度 → タイル内座標)はこうです。

def lonlat_to_tile(z, lat, lon, extent=4096):
    n = 2.0 ** z
    xf = (lon + 180.0) / 360.0 * n
    lr = math.radians(lat)
    yf = (1.0 - math.log(math.tan(lr) + 1.0 / math.cos(lr)) / math.pi) / 2.0 * n
    X, Y = int(xf), int(yf)
    return X, Y, (xf - X) * extent, (yf - Y) * extent

Y が下向きなのは画像タイル(XYZ方式)と同じ並びだからです。平面直角座標系のように「X が北・Y が東」とは別の約束なので、ここを取り違えると南北が反転します。軸の順序と向きの落とし穴は 緯度経度の順序はどっちが先? にまとめてあります。

実例:東京駅を往復させる

東経139.767125度・北緯35.681236度でやってみます。

ズーム タイル番号 タイル内座標(丸め後) 戻した経緯度 元との差
z=16 (58211, 25806) px 3394 / py 2603 35.6812360 / 139.7671250 緯度 0.00000002度(約2mm)
z=11 (1819, 806) px 490 / py 1873 35.6812480 / 139.7671223 緯度 0.0000120度(約1.3m)

同じ点でも、ズームが小さいほど戻したときの位置が粗くなります。当たり前のようでいて、実務で効きます。タイル内座標は整数なので、1単位より細かい位置は保存されていないからです。

ズーム 1単位の大きさ(Webメルカトル上) 北緯35.7度の地上距離に直すと
z=11 4.78 m 約3.88 m
z=14 0.60 m 約0.49 m
z=16 0.149 m 約0.121 m

(地球半径6378137m・extent 4096 で計算。Webメルカトルの1mは緯度が上がるほど地上では短くなるので、右列は cos35.7度 を掛けた値です)

ベクトルタイルは表示のための形式であって、測量成果の座標を持ち運ぶ形式ではありません。z=16 でも12cm刻み、z=11 なら約4m刻みです。図面や成果に使う座標は、必ず元データ側から取ります。

地理院のベクトルタイルは、ズームが1小さい

これが実務でいちばん引っかかるところです。国土地理院のベクトルタイル提供実験の仕様には、こう書かれています——画面上で同じ大きさに見えるとき、ベクトルタイルのズームレベルはラスタの地理院タイルより1小さい。

ベクトルタイル(提供実験) 同じ見え方のラスタ地理院タイル
4〜7 5〜8
8〜10 9〜11
11〜13 12〜14
14〜16 15〜17
17 18

つまりベクトルタイルの1枚は、ラスタタイル4枚ぶんの範囲を持っています。ラスタ用に書いた z/x/y の計算をそのまま流用すると、タイル番号が4倍ずれた場所を取りに行くことになります。上の復元式に入れる z は、URLに入れた z(ベクトルタイル側の番号)です。

ラスタの地理院タイルの仕組みそのものは 地理院タイルとは(GeoPrism JP) に図でまとめてあります。

提供URL・ズーム範囲は次のとおりです(2026年9月時点)。

  • URL: https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf
  • ズームレベル 4〜16(17はズーム16に含めてオーバーズーム表示)
  • データ更新: 2026年7月1日時点(四半期に一度の頻度で更新)

位置づけにも注意が要ります。これは「提供実験」であり、国土地理院は基本測量成果と位置付けているものではないと明記しています。URLやデータ構成が変わる可能性がある旨も書かれています。業務で使うなら、この前提を承知したうえで、出典として「国土地理院ベクトルタイル提供実験」を明示します。

残りの落とし穴3つ

① タイルの外にはみ出す座標がある。 レンダリング時に境界で線が切れないよう、タイルの外側の図形も少し含めて配信されます(バッファ)。そのため px / py は 0〜4096 の外——負の値や4096超——になることがあります。範囲外を捨てる実装にすると、境界の図形が消えます。

② 測地系は WGS84 系であって、日本の測量座標ではない。 Webメルカトルは WGS84 の経緯度から作られます。JGD2011 / JGD2024 の平面直角座標が必要なら、いったん経緯度へ戻してから測地系変換と投影を掛けます。タイル座標から直接ミリ単位の座標を作ろうとしないこと。

③ 距離や面積をタイル座標のまま計算しない。 Webメルカトルは緯度が上がるほど引き伸ばされるので、タイル座標の差をそのまま長さとして扱うと、日本付近で約23%大きく出ます。この性質は Webメルカトルと平面直角座標 に整理してあります。

平面直角座標系19系の区分地図

手順のまとめ

  1. タイルのレイヤから extent を読む(4096と決め打ちしない)
  2. URLの z / x / y と、図形の px / py を組み合わせて worldX / worldY を作る
  3. Webメルカトル経由で 経緯度(WGS84) に戻す。Y は下向きであることに注意
  4. 地理院のベクトルタイルなら、その z はラスタより1小さい系列だと意識しておく
  5. 測量に使う座標が要るなら、経緯度から測地系変換 → 平面直角座標へ。タイル座標の精度(z=16で約12cm)を成果の精度と混同しない

GeoConverter Pro は、こうして戻した経緯度を JGD2011 / JGD2024 の平面直角座標系19系へ変換するところを担当します。タイルから拾えるのは「だいたいの位置」までで、そこから先は測地系の話になります。

出典

  • 国土地理院「ベクトルタイルとその提供実験について」 https://maps.gsi.go.jp/development/vt.html
  • 国土地理院「地理院地図Vector提供実験」(ズームレベル対応表・提供URL・位置づけ) https://github.com/gsi-cyberjapan/gsimaps-vector-experiment
  • Mapbox「Vector Tile Specification」(extent・タイル内座標・原点) https://github.com/mapbox/vector-tile-spec
  • 国土地理院「地理院タイル一覧」 https://maps.gsi.go.jp/development/ichiran.html

次に確認する


開発者より: アプリ・Kindle本・公開プロジェクトの一覧は GitHub: amru195704 にまとめています。


お願い
本記事の情報は参考目的で掲載しており、正確性・完全性を保証するものではありません。誤記・不正確な情報がございましたら、コメント欄よりご指摘いただければ、確認のうえ修正いたします。


コメントを残す

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

トップへ戻る