はじめに
Bing Maps AJAX Control 4回目の今回はタイルについてです。前回までに地図上に表示できるものとして、
Bing Mapsの地図は画像をタイル状に並べて構成されています。これを単にタイルと呼んでいます。Bing Maps AJAX Controlを利用するとオリジナルのタイルを重ねて表示でき、
図1は、
![図1 昔の航空写真の表示 図1 昔の航空写真の表示](/assets/images/dev/serial/01/bing-sdk/0016/thumb/TH800_001.png)
国土画像情報
タイルの表示
さっそくタイルを表示するコードを書いてみましょう。オリジナルのタイルを利用するには、
![図2 サンプルのタイル 図2 サンプルのタイル](/assets/images/dev/serial/01/bing-sdk/0016/thumb/TH800_002.png)
HTMLを含めたすべてのコードは次のようになります。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Sample</title>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&mkt=ja-jp"></script>
<script type="text/javascript">
var map = null;
function GetMap() {
var options = {
credentials: "BingMapsKey",
center: new Microsoft.Maps.Location(48.03, -122.4),
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
zoom: 12
};
map = new Microsoft.Maps.Map(document.getElementById("map"), options);
// TileSource
var sourceOptions = {
uriConstructor: 'http://www.microsoft.com/maps/isdk/ajax/layers/lidar/{quadkey}.png'
};
var tileSource = new Microsoft.Maps.TileSource(sourceOptions);
// TileLayer
var layerOptions = {
mercator: tileSource,
opacity: 0.9
};
var tilelayer = new Microsoft.Maps.TileLayer(layerOptions);
// タイルの追加
map.entities.push(tilelayer);
}
</script>
</head>
<body onload="GetMap();">
<div id='map' style="position: relative; width: 640px; height: 640px"></div>
</body>
</html>
コード中のBingMapsKey部分は、
タイルの表示は、
名前 | 説明 |
---|---|
opacity | 不透明度 0 |
zIndex | ほかの地図上のオブジェクトとの表示順序 値の大きい方を上に表示 |
mercator | TileSourceオブジェクト |
名前 | 説明 |
---|---|
height | タイル画像の縦幅 64, 128, 256 |
uriConstructor | タイル画像のURLの書式 URL内の{subdomain}, {quadkey}部分が置換されます |
width | タイル画像の横幅 64, 128, 256 |
タイルの構成
タイルは、
![図3 タイル構成とQuadKeys 図3 タイル構成とQuadKeys](/assets/images/dev/serial/01/bing-sdk/0010/thumb/TH800_009.png)
QuadKeysの求め方については第10回で紹介していますので、
URLの書式
Bing Maps AJAX Controlの場合、
http://www.microsoft.com/maps/isdk/ajax/layers/lidar/{quadkey}.png
{quadkey}の部分が、
Bing Maps AJAX Controlはタイルの指定に関して簡易な仕組みとなっており、
uriConstructorには、
経緯度からQuadKeysへの変換
参考までに経緯度とズームレベルからQuadKeysへ変換するコードを載せておきます。LocationオブジェクトとズームレベルをgetQuadkey関数に渡すとQuadKeyが返ります。
function getQuadKey(location, zoom) {
// Location オブジェクト, ズームレベルからピクセル座標に変換
var x = (location.longitude + 180) / 360;
var sinLatitude = Math.sin(location.latitude * Math.PI / 180);
var y = 0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);
var mapSize = 256 << zoom;
var pixelX = Math.round(clip(x * mapSize + 0.5, 0, mapSize - 1));
var pixelY = Math.round(clip(y * mapSize + 0.5, 0, mapSize - 1));
// ピクセル座標からタイル番号に変換
var tileX = pixelX / 256;
var tileY = pixelY / 256;
// QuadKey に変換
var quadKey = "";
for (var i = zoom; i > 0; i--) {
var digit = '0';
var mask = 1 << (i - 1);
if ((tileX & mask) != 0) {
digit++;
}
if ((tileY & mask) != 0) {
digit++;
digit++;
}
quadKey += digit;
}
return quadKey;
}
上記のコードを動かすには、
<input type="text" id="quadkey" />
そして、
Microsoft.Maps.Events.addHandler(map, "click", function (e) {
var location = map.tryPixelToLocation(new Microsoft.Maps.Point(e.getX(), e.getY()));
if (location != null) {
document.getElementById("quadkey").value = getQuadKey(location, map.getZoom());
}
});
タイル画像の作成
最初に示した航空写真を重ね合わせる例では、
![図4 タイル画像 図4 タイル画像](/assets/images/dev/serial/01/bing-sdk/0016/thumb/TH800_004.png)
これらのQuadKeysに対応した画像は、MapCruncher
![図5 MapCruncher 図5 MapCruncher](/assets/images/dev/serial/01/bing-sdk/0016/thumb/TH800_005.png)
MapCruncherを使用すると、
MapCruncherでは画像だけではなくMap Controlを使用したWebページも含めて出力しますが、
タイルの追加・削除
オリジナルのタイルを使用する場合、
次のコードはズームレベル12の場合のみTileLayerオブジェクトを追加するようサンプルコードを変更した場合です。
Microsoft.Maps.Events.addHandler(map, "viewchangeend", function () {
var zoom = map.getZoom();
// 指定した TileLayer オブジェクトが Map オブジェクトの entities コレクションに含まれているか
var contains = map.entities.indexOf(tilelayer) >= 0;
// TileLayer オブジェクトの追加・削除
if (zoom == 12) {
if (!contains) {
map.entities.push(tilelayer);
}
} else {
if (contains) {
map.entities.remove(tilelayer);
}
}
});
// 下記の記述をコメントアウトする
//// タイルの追加
//map.entities.push(tilelayer);
コードでは、
おわりに
Bing Maps AJAX Controlでは、
今回はここまでです。いかがでしたでしょうか。次回もBing Maps AJAX Controlについて紹介します。