国土地理院にて,日本地図をタイルに分割した画像が公開されています.
マップは何種類かありますが,今回は「標準地図」を利用してみます.
標準地図の取得URLは以下です.
https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png
この{z}{x}{y}が判れば好きな場所のマップタイルを取得できることになります.
これらの値の意味について,以下に記述がありました.
地理院タイル1枚1枚のURLは、ズームレベルとタイル座標に基づいて、原則として以下のように命名されています。
https://cyberjapandata.gsi.go.jp/xyz/{t}/{z}/{x}/{y}.{ext}
ここで、{t},{x},{y},{z},{ext}の意味は次の通りです。
{t}:データID
{x}:タイル座標のX値
{y}:タイル座標のY値
{z}:ズームレベル
{ext}:拡張子
https://maps.gsi.go.jp/development/siyou.html
また,タイル座標の原点について記述がありました.
また、各タイルにはX,Yからなるタイル座標を定義します。
西経180度、北緯約85.0511度の北西端を左上の端点にもつタイルを(0,0)として東方向をX正方向、南方向をY正方向にとります。
https://maps.gsi.go.jp/development/siyou.html
原点は判りましたが,具体的にこれらの値がどのように決定されるのかを判断する必要があります.
以下のサイトで,ズーム倍率と緯度経度を指定して,タイルがどのように分割されているかを確認できますので試してみます.
ズームを「2」にすると全世界のタイルは4×4に分割されます.
同様にズームを「3」にすると8×8,「4」にすると16×16に分割されることが判ります.
ということは,分割数Dは「2をズームレベルで乗じた値」のようです.
また、x値は「東経180°を原点0とし,経度に応じてDで分割したうちの数字」
y値は「北緯85.0511°を原点0とし、緯度0°が2/D、南緯85.0511°がD-1となるよう分割したうちの数字」
となると考えて良さそうです.
これを元に,緯度経度,およびズームレベルからz,x,yを算出する方法を検討します.
まず,ズームレベルは問題ありません.指定可能なレベルは2~18のようですから,好きな値をまず決めてやります.
次に,x値も比較的簡単です.求めたいxと、経度lng・分割数Dの関係は以下のようになります.
(lng+180) : x = 360 : D
Dは2をズームレベルzで乗じたものなので,変形すると以下のようになります.
x = ((lng + 180) * (2z)) / 360
このxの整数部分がタイル座標のx値になります.
(余談ですが,lngに180を足しているのはグリニッジ子午線からの差分があるためです.引くのではなく足しているのは,xの値はDをオーバーしたときには自動的にDからの余りが利用されるっぽいためです(つまり国土地理院APIの実装依存).本来であれば計算時lngに180をマイナスし、x値がマイナスの場合にはDを加算するのが正当です)
次に,y値を求めます.これは面倒です.
なぜなら,この地図は見ればわかる通りメルカトル図法です.
ということは,単純に緯度を360で割って分割数を乗じただけでは期待通りの値が取得できません.(単位緯度間の距離が極に近づくほど長くなります)
これを算出するための計算式は以下のようになりますが,ちゃんと解説できるほど理解できていないので流します.
xの場合と同様に,変形すると以下のようになります.
y = (PI - log(tan((45+lat/2) * PI/180))) *(2z/(2*PI))
このyの整数部分がタイル座標のy値になります.
という訳でズーム倍率・経度緯度からz,x,yの算出式が導出できました.
これでちゃんと計算できるか試してみましょう.
座標のランドマークとして判りやすい,明石市立天文科学館で試してみます.
天文科学館の座標は以下です.
- lat:34.649395
- long:135.001478
倍率を何パターンか替えて計算してみます.
ズームレベル | x値 | y値 |
---|---|---|
10 | 896.004204088889 | 406.819035768485 |
15 | 28672.134530844447 | 13018.20914459152 |
17 | 114688.53812337779 | 52072.83657836608 |
18 | 229377.07624675558 | 104145.67315673215 |
x値とy値にはこれらの整数部分を利用します.決定したURLは以下のようになります.
うまく行きました.いずれも天文科学館が視野に入っています.
という訳で今回,ズームレベルと緯度経度から,対応する一枚のマップ画像を取得できるようになりました.
これを応用すれば,指定した範囲の緯度経度のマップを自在に表示することが出来ます.
(以下の記事に続きます)
コメント