今天我们用FGMap来加载百度地图数据。

从目前国内的地图服务商提供的地图来看,地图瓦片切图规则只少分为三种。其中Google Map、Bing地图、MapABC、QQ地图是一类,而百度地图、搜狗地图是使用的另一类,还有一类应该是mapbar的地图(还没有仔细去分析它的瓦片编号规则)。

第一类FGMap中已经都是集成,这里就不再说了,今天说说第二类:百度地图。前几天看到狮兄写的百度地图Silverlight版和Flex版(via SuperMap iClient) ,里面有一个例子是用Flex写的,可能是我的知识有限,没有太明白他说的内容。但大体知道他说的瓦片组织的方式需要用一个偏移量,所以今天特意去BaiduMap 的API里看看了,发现有一个很有意义的信息,在开发指南->地图图层->自定义图层有这么一段话:

经纬度是一种利用三维空间的球面来定义地球上的空间的球面坐标系,它能够标示地球上任何一个位置。通过伦敦格林尼治天文台原址的经线为0度经线,从0度经线向东、向西各分180度。赤道为0度纬线,赤道以北的纬线称为北纬、以南的称为南纬。在百度地图中,东经和北纬用正数标示,西经和南纬用负数标示。

使用百度地图和谷歌地图进行了一个对比,可能大家更能明白些:

从上图中可以出来,百度是以经纬度0,0开始编号,向东X正增加,向西X负增加,向北Y增加,向南Y负增加,而谷歌地图是从左上角开始编号,向东X增加,向南Y增加,这种计算很方便。

知道了这种对应规则后,我们就可以得到计算的方式,代码如下:

package com.fgmap.maps.examples
{
	import com.fgmap.maps.Copyright;
	import com.fgmap.maps.CopyrightCollection;
	import com.fgmap.maps.LatLng;
	import com.fgmap.maps.LatLngBounds;
	import com.fgmap.maps.TileLayerBase;
	import com.fgmap.maps.interfaces.ICopyrightCollection;
	
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.IOErrorEvent;
	import flash.geom.Point;
	import flash.net.URLRequest;
	
	public class BaiduTileLayer extends TileLayerBase
	{
		private var mapMinZoom:int = 1;	//最小显示等级
		private var mapMaxZoom:int = 18;//最大显示等级

		public function BaiduTileLayer(tileSize:Number)
		{
			var copyrightCollection:CopyrightCollection = new CopyrightCollection();
			
			super(copyrightCollection, mapMinZoom, mapMaxZoom, 1);	//调用父类的方法
			
			//创建一个自己的版权说明
			copyrightCollection.addCopyright(
				new Copyright("BaiduData",
					new LatLngBounds(new LatLng(-180, -90),
						new LatLng(180, 90)),  0,
					"百度地图数据"));
		}
		
		//覆盖加载地图数据的方法,这个很重要,地图数据从这里读取
		override public function loadTile(tilePos:Point, zoom:Number):DisplayObject {
			var testLoader:Loader = new Loader();
			zoom = zoom - 1;
			
			var offsetX:Number = Math.pow(2,zoom);
			var offsetY:Number = offsetX - 1;
			
			var numX:Number = tilePos.x - offsetX;
			var numY:Number = (-tilePos.y) + offsetY;
			
			zoom = zoom + 1;
			var num:int = (tilePos.x + tilePos.y) % 8 + 1;
			
			var x:String = numX.toString().replace("-","M");
			var y:String = numY.toString().replace("-","M");
			
			var strURL:String = "";
			strURL = "http://q" + num + ".baidu.com/it/u=x=" + x + ";y=" + y + ";z=" + zoom + ";v=005;type=web&fm=44";
			
			var urlRequest:URLRequest;
			urlRequest =  new URLRequest(strURL);	//没有地图时显示的内容
			
			testLoader.load(urlRequest);
			testLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			
			return testLoader;
		}		
		
		//出错处理
		private function ioErrorHandler(event:IOErrorEvent):void {
			trace("ioErrorHandler: " + event);
		}
	}
}


因为地图瓦片都是以四叉树的形式存在的,所以计算相对就会简单些了。运行结果如下:

这只是地图瓦片加载了,可能还会存在坐标转换的问题。

下次有时间,可以把mapbar的地图数据也加载进来,这样,国内的地图数据都应该可以加载了。

如果不明白的地方,可以与我联系。

posted on 2011-05-09 23:06  liongis  阅读(6317)  评论(4编辑  收藏  举报