地理院地図のタイル仕様と、地図ファイルURL

## 地理院地図の地理院タイル仕様ページを眺めてた

以前（2012年頃)、地理院地図の仕様を見ていた時に、地図画像ファイルURLの仕様がわからず、
使用を断念したことがありました。

2014年の夏が始まる頃に、地図を使うタイミングが来たので仕様を確認した所、**業界標準**
というキーワードを見つけたので、その**業界標準**とやらを調べてみました。

> 地理院タイルは正方形のタイル状に分割された地図画像です。その仕様は業界標準と同一であるため、容易にサイト構築やアプリ開発にご利用いただけます。  
[地理院地図｜技術情報](http://portal.cyberjapan.jp/help/development/siyou.html)
http://portal.cyberjapan.jp/help/development/siyou.html

## 業界標準とは?

それは、"Bing maps"や"Google maps"で使われているシステムだった。確かに業界標準といってもいい。
仕様に関して、様々なサイトで解説されていたが、
以下のMicrosoft Developer Network内のBing mapsの仕様解説ページが一番親切。

[Bing Maps Tile System](http://msdn.microsoft.com/en-us/library/bb259689.aspx)
http://msdn.microsoft.com/en-us/library/bb259689.aspx

簡単に言えば、メルカトル図法で引き伸ばした世界地図を、
四分の一ごとに分割して、一つ一つのにIDを振っていったものですね。

もっと簡単にイメージ感を掴みたいのであれば、
以下のサイトを参照すると、視覚的に理解できるでしょう。

Google mapsの地図のタイル一枚ごとに、タイルIDが表示されたレイヤーが載せてあります。

[Tiles à la Google Maps  Coordinates, Tile Bounds and Projection - conversion to EPSG 900913 (EPSG 3785) and EPSG 4326 (WGS84)](http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/)
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

## 緯度経度から、タイルIDを返すコードを書いてみた

```ruby:get_tile_id.rb
require 'json'
require 'pp'

# longitude = x
# latitude  = y

# 渋谷駅の緯度経度情報	
lat = 35.658517
long = 139.701334

lat_rad = lat * Math::PI / 180;
long_rad = long * Math::PI / 180;

R = 128 / Math::PI;

world_coord_x = R * (long_rad + Math::PI)
world_coord_y = - R / 2 * Math::log( (1 + Math::sin(lat_rad)) / (1 - Math::sin(lat_rad)) ) + 128

zoom_level = 15

qredkey_data_set = Array.new

for zoom_level in 0..24 do
	pixel_coord_x = world_coord_x * 2 ** zoom_level
	pixel_coord_y = world_coord_y * 2 ** zoom_level

	tile_coord_x = (pixel_coord_x / 256).to_i
	tile_coord_y = (pixel_coord_y / 256).to_i

	qredkey_separeta = {:zoomlevel => zoom_level, :x => tile_coord_x, :y => tile_coord_y}
	
	qredkey_data_set.push(qredkey_separeta)

end
qredkey_jsondata = qredkey_data_set.to_json
# pp qredkey_jsondata

print_data = JSON.parse(qredkey_jsondata)
pp print_data

```
指定した緯度経度情報から、
タイルIDを求めるだけのコードです。
このコードを実行すると、以下の結果が標準出力で吐き出されます。

>[{"zoomlevel"=>0, "x"=>0, "y"=>0},
 {"zoomlevel"=>1, "x"=>1, "y"=>0},
 {"zoomlevel"=>2, "x"=>3, "y"=>1},
 {"zoomlevel"=>3, "x"=>7, "y"=>3},
 {"zoomlevel"=>4, "x"=>14, "y"=>6},
 {"zoomlevel"=>5, "x"=>28, "y"=>12},
 {"zoomlevel"=>6, "x"=>56, "y"=>25},
 {"zoomlevel"=>7, "x"=>113, "y"=>50},
 {"zoomlevel"=>8, "x"=>227, "y"=>100},
 {"zoomlevel"=>9, "x"=>454, "y"=>201},
 {"zoomlevel"=>10, "x"=>909, "y"=>403},
 {"zoomlevel"=>11, "x"=>1818, "y"=>806},
 {"zoomlevel"=>12, "x"=>3637, "y"=>1613},
 {"zoomlevel"=>13, "x"=>7274, "y"=>3226},
 {"zoomlevel"=>14, "x"=>14549, "y"=>6452},
 {"zoomlevel"=>15, "x"=>29099, "y"=>12905},
 {"zoomlevel"=>16, "x"=>58199, "y"=>25811},
 {"zoomlevel"=>17, "x"=>116399, "y"=>51623},
 {"zoomlevel"=>18, "x"=>232799, "y"=>103246},
 {"zoomlevel"=>19, "x"=>465598, "y"=>206493},
 {"zoomlevel"=>20, "x"=>931197, "y"=>412987},
 {"zoomlevel"=>21, "x"=>1862395, "y"=>825975},
 {"zoomlevel"=>22, "x"=>3724790, "y"=>1651950},
 {"zoomlevel"=>23, "x"=>7449581, "y"=>3303900},
 {"zoomlevel"=>24, "x"=>14899162, "y"=>6607801}]

## まとめ
Google mapsやBing mapsで出来なかったことが、
地理院地図だと利用可能なこともあるので、
選択肢の一つとして、地理院地図があがると、
面白くなるのかなと思った、今日このごろ。