Flex+Google Mapsで独自地図の表示
本記事では、Flex+Google Mapsでデフォルトの世界地図ではなく、独自の地図を表示する方法について説明します。
地図画像を準備
Google Mapsの地図は一枚の画像ではなく複数のタイル画像から構成されます。
地図のズームレベルを0, 1, 2, 3・・・とすると、対応するタイル画像の枚数は、それぞれ、1, 4, 8, 16・・・です。
したがって、Google Mapsにて独自地図画像を表示させるためには、複数のタイル画像を用意する必要があります。
もし、独自地図画像のズームレベルを0, 1, 2の範囲で表示したいなら、必要な画像の枚数は1+4+8=13枚です。
こんな枚数の画像の用意を手作業で行うのは非常に酷なことです。
Google Maps用の地図画像を生成するツールは多数あるので大丈夫です。
ここでは、GMapImageCutter1.4を使用します。
Google Map Image Cutter
その使用手順は以下の通りです。
- GMapImageCutter1.4をダウンロードして解凍
- 解凍したフォルダ内の「GMapImageCutter.jar」を実行
- 表示したい地図画像を読み込む
- ズームレベルの最大値を指定
- 「Create」ボタンを押す
すると、地図画像と同一フォルダ内に「tiles」というフォルダが作成され、その中に各ズームレベルに応じた複数のタイル画像が生成されます。
生成されるタイル一枚の大きさは256×256です。
「tiles」フォルダを見ると、jpg形式の画像ファイルがt, tq, tr, ts, tt, tqt, tqr, tqs, tqt・・・という名前で作成されています。
ここで、ファイル名の長さはズームレベルを表します。
例えば、ファイル名をtならズームレベル0のタイル画像であり、ttqrstならズームレベル5のタイル画像の一枚であることが分かります。
また、ファイル名に使用される文字は、地図上での位置を表します。ファイル名に使用される文字は、q, r, s, tであり、左上、右上、右下、左下を意味しています。
qrstの解釈
ズームレベル0-2までのタイルの構成を下に示す。
レベル0 | レベル1 | レベル2 |
Flexで独自地図画像を表示
Flexから上で用意したタイル画像から独自地図画像を表示する方法を説明します。
Flex+Google Mapsで独自地図画像を表示するためには、TileLayerBaseクラスの継承クラスを作成し、loadTileメッソドをオーバライドする必要があります。
TileLayerBaseクラスを継承したクラスの名前をMyTileLayerとし、その実装コードを下に示します。
public class MyTileLayer extends TileLayerBase { //画像ファイルへのパス private var path : String; //画像形式 private var format : String; public function MyTileLayer(path : Strings, format : String) { this.path = path; this.format = format; super(new CopyrightCollection(), 0, 4); } //tilePosはtile座標 //zoom=1なら、tilePosは(0,0)(1,0)(0,1)(1,1) override public function loadTile(tilePos:Point, zoom:Number) : DisplayObject { var loader : Loader = new Loader(); var tileUrl : String = path + "/" + getTileName(tilePos, zoom) + format; trace(tilePos, zoom, tileUrl); loader.load(new URLRequest(tileUrl)); return loader; } //タイルの位置とzoomレベルから適切なファイル名を生成する関数 //例:tilePos=(0, 0) zoom=1のときの返り値はtq private function getTileName(tilePos : Point, zoom : Number) : String { var tileChar : Object = {0 : {0 : "q", 1 : "t"}, 1 : {0 : "r", 1 : "s"}} var imageName : String = "t"; for(var i : int = int(zoom); i >= 1; i--) { var den : Number = Math.pow(2, i - 1); imageName += tileChar[int(tilePos.x / den) % 2][int(tilePos.y / den) % 2]; } return imageName; } }
MyTileLayerクラスの使用例(mapはMapクラスのインスタンス)
//タイル画像の配置パスはtile、画像形式はjpgとする var myTileLayer : MyTileLayer = new MyTileLayer("tile", "jpg"); var tileLayers : Array = new Array(myTileLayer); var mapType : MapType = new MapType(tileLayers, map.MERCATOR_PROJECTION, "original map"); myTileLayer.setMapType(mapType); map.addMapType(mapType); map.setMapType(mapType);