用Flex构建地图应用 — 利用Google Map API制作自己的地图(2)

Silver 撰写  

接着上期的,这里用两个实例,给大家介绍一下Flex自定义地图制作的流程,看看是怎么从TileLayBase扩展成自定义的地图

首先是live的地图

package com.ityao.map
{
	import com.google.maps.CopyrightCollection;
	import com.google.maps.TileLayerBase;

	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.geom.Point;
	import flash.net.URLRequest;

	public class LiveDituTileLayerBase extends TileLayerBase
	{
		private var serviceUrls:Array=["http://r0.tiles.ditu.live.com/tiles/r",
									   "http://r1.tiles.ditu.live.com/tiles/r",
									   "http://r2.tiles.ditu.live.com/tiles/r",
									   "http://r3.tiles.ditu.live.com/tiles/r"];
		private var serviceUrlSuffix:String = ".png?g=29";

		public function LiveDituTileLayerBase()
		{
			super(new CopyrightCollection("http://cn.bing.com/ditu/"),0,19)
		}

		private function getTileUrl(p:Point,zoom:int):String{			

			var c:Number=Math.pow(2,zoom);
			var d:Number=p.x;
			var e:Number=p.y;
			var f:String="";
			for(var g:int=0;g<zoom;g++){
				c=c/2;
				if(e<c){
					if(d<c){
						f+="0"
					}else{
						f+="1";
						d-=c
					}
				}else{
					if(d<c){
						f+="2";
						e-=c
					}else{
						f+="3";
						d-=c;
						e-=c
					}
				}
			}
			var h:int=(p.x+p.y)%serviceUrls.length;
			return serviceUrls[h]+f+serviceUrlSuffix;

		}	

		public override function loadTile(tilePos:Point, zoom:Number):DisplayObject{

			var loader:Loader = new Loader();
			configureListeners(loader.contentLoaderInfo);
			var url:String = getTileUrl(tilePos,zoom);
			var tileUrl:URLRequest = new URLRequest(url);
			trace(tilePos.toString()+" z:"+zoom + " url:"+url);
			loader.load(tileUrl);
			return loader;

		}

		private function configureListeners(dispatcher:IEventDispatcher):void{
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR,_secondaryLoad);
		} 

		private function _secondaryLoad(event:IOErrorEvent):void{
			//image fail to load handler
		}
	}
}

然后是mapABC的地图

package com.ityao.map
{
	import com.google.maps.CopyrightCollection;
	import com.google.maps.TileLayerBase;

	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.geom.Point;
	import flash.net.URLRequest;

	public class MapABCDituTileLayerBase extends TileLayerBase{

		public function MapABCDituTileLayerBase(){
			super(new CopyrightCollection("http://www.mapabc.com"),0,17)
		}

		private function getTileUrl(p:Point,zoom:int):String{
			var url:String = "http://emap" + ((p.x + p.y) % 4) + ".mapabc.com/mapabc/maptile?v=";
			url += "w2.99" ;
			url += "&x=" + p.x + "&y=" + p.y + "&zoom=" + (17-zoom);
			return url;
		}	

		public override function loadTile(tilePos:Point, zoom:Number):DisplayObject{

			var loader:Loader = new Loader();
			configureListeners(loader.contentLoaderInfo);
			var url:String = getTileUrl(tilePos,zoom);
			var tileUrl:URLRequest = new URLRequest(url);
			trace(tilePos.toString()+" z:"+zoom + " url:"+url);
			loader.load(tileUrl);
			return loader;

		}

		private function configureListeners(dispatcher:IEventDispatcher):void{
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR,_secondaryLoad);
		} 

		private function _secondaryLoad(event:IOErrorEvent):void{
			//image fail to load handler
		}
	}
}

在上面的例子可以看见,其实只要重载loadTile方法就可以了,是不是非常简单?

loadTile的第一个参数是图块坐标,第二个参数是zoom的图层深度
这里有篇很好的文章和实例演示告诉你这些参数是怎么来的,
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

使用这两个参数,我们要针对不用的图瓦(live或mapABC)去构造图瓦的链接,从而用一块块图瓦拼接出完整的地图。

图瓦的链接是怎么获得的呢?
呵呵,可以是根据不同地图的文档说明(不过通常都很少),通常我在看一个地图的时候,用firefox进行浏览,然后打开”工具”->”页面信息”,如下图所示:
bingditu

然后就发挥你的小宇宙,去猜猜那串图瓦链接怎么来的,呵呵!
我把live的猜出来了,欢迎大家补充别的链接。


条评论

  1. 昕扬
    发表了 2009年09月15日 在 9:02 上午 | 永久链接 |

    学习中

发表评论

你必须在 登录 后才能发表评论.