用Flex和Google Map API制作自己的地图
用Flex构建地图应用 — 利用Google Map API制作自己的地图
现在地图应用已经成为网络应用的一个大类了,各个大的网站几乎都有自己的地图产品。最出名的莫过于国外的Google Map和国内的都市圈地图,前面Daniel Yang介绍了都市圈的Flex源代码,小弟也来一个介绍Flex构建地图的系列,希望能够让大家分享到地图开发的乐趣。
不过自己毕竟不是GIS科班出身,也没从事过GIS或者地图的真正商业开发,研究地图应用开发,纯属兴趣,所以不足之处,敬请斧正:)
构建Flex地图应用,首选Google的地图API来实现,有以下原因:
支持自定义扩展地图类型
有丰富的图形标注工具
有多种数据接口
详细的文档支持
Google map API的这些特点,可以使我们快速地开发出各式各样的地图web应用,由于本帖不是替google map打广告,就不一一介绍这些特点的详细情况了,本帖更关注于第一个特点,利用Google map api来构建属于自己的地图。
或者大家会问:构建自己的地图?可以是什么样子的呢?
小弟天马行空地替大家想象了一下,我初步想大家可以构建这样的一些应用:
在专业的地图服务器里写script导出图瓦(动态或静态),然后制作自己的地图应用,最好的例子就是google地图本身
利用网络的地图图瓦资源,构造地图应用,如利用API来显示e都市的三维地图,或者如后面演示的显示别的厂商如google的对手bingo的地图,mapABC的地图等
通过修改现成的地图图瓦,来创造自己的地图。呵呵,站在巨人的肩膀上啊,例如你可以抓取google的图瓦,把上面的藏南地区全改回中文,然后发布出去
发布大型的图画作品,例如你是卖画或者什么别的艺术品,或者你要做游戏地图,可以把照片割成图瓦,挂到网上去,让大家可以在不同分辨层次下欣赏作品
协同进行艺术创作,把地图想象成大图画,大家可以在一个图画上创作,通过Map API可以进行宏观创作或者细节创作
… 更多更多好点子,欢迎在评论里面留言
首先贴一个swf,给大家看看用Google Map API来显示Live地图和MapABC地图的效果。
实现这个效果的步骤如下:
使用Flex的google map api,首先要去这里 下载 (http://maps.googleapis.com/maps/flash/release/sdk.zip)
注册一个api使用的key,在这个页面进行注册 (http://code.google.com/intl/zh-CN/apis/maps/signup.html)
创建flex项目,项目目录结构如下图所示:
前面下载的SDK里面的map_flex_1_16.swc(下载时间不同,可能版本号不一致)需要放在项目的lib目录里面去。
创建mapsample.mxml主程序,代码如下: 查看源代码打印帮助01 <?xml version="1.0" encoding="utf-8"?>
02 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
03 <maps:Map xmlns:maps="com.google.maps.*" language="zh-CN" id="map"
04 mapevent_mapready="onMapReady(event)"
05 width="100%" height="100%" key="{mapKey}"/>
06 <mx:Script>
07 <![CDATA[
08 import com.ityao.map.MapABCDituTileLayerBase;
09 import com.ityao.map.GoogleDituTileLayerBase;
10 import com.ityao.map.LiveDituTileLayerBase;
11
12 import com.google.maps.overlays.TileLayerOverlay;
13 import com.google.maps.controls.MapTypeControl;
14 import com.google.maps.controls.PositionControl;
15 import com.google.maps.controls.ZoomControl;
16 import com.google.maps.LatLng;
17 import com.google.maps.Map;
18 import com.google.maps.MapEvent;
19 import com.google.maps.MapType;
20
21 //key for http://blog.ityao.com/
22 private static const mapKey:String = "ABQIAAAAjg2LNPeLd2SY_LMC4kTfyhREhvxbmPPYdzuafsMTRfCiNgtm-xT_QN9uPU6M7JTAKA4l_ycXr_8HOg";
23 private function onMapReady(event:Event):void {
24
25 map.addControl(new ZoomControl());
26 map.addControl(new PositionControl());
27 map.addControl(new MapTypeControl());
28 map.removeMapType(MapType.PHYSICAL_MAP_TYPE);
29 map.removeMapType(MapType.SATELLITE_MAP_TYPE);
30 map.removeMapType(MapType.HYBRID_MAP_TYPE);
31
32 //Live地图
33 var liveTileBase:LiveDituTileLayerBase = new LiveDituTileLayerBase();
34 var liveTileLayers:Array = new Array();
35 liveTileLayers.push(liveTileBase);
36 var liveMapType:MapType = new MapType(liveTileLayers,map.MERCATOR_PROJECTION,"Live地图");
37 liveTileBase.setMapType(liveMapType);
38 map.addMapType(liveMapType);
39
40 //mapABC地图
41 var mapABCDituTileLayerBase:MapABCDituTileLayerBase = new MapABCDituTileLayerBase();
42 var mapABCDituTileLayers:Array = new Array();
43 mapABCDituTileLayers.push(mapABCDituTileLayerBase);
44 var mapABCDituMapType:MapType = new MapType(mapABCDituTileLayers,map.MERCATOR_PROJECTION,"mapABC地图");
45 mapABCDituTileLayerBase.setMapType(mapABCDituMapType);
46 map.addMapType(mapABCDituMapType);
47 //设置缺省的地图中心和地图类型
48 map.setCenter(new LatLng(23.09656,113.19219), 10);
49 }
50 ]]>
51 </mx:Script>
52 </mx:Application>
注意需要在程序中修改mapKey变量成为你前面注册的google map api key。
在主程序里面,我们创建了两种自定义的地图类型,并且添加了这两种类型进google地图中进行显示
定制自定义地图,如果地图的投影方法和google map一致的话,那只要继承TileLayerBase并重载里面的loadTile(加载图瓦)方法就可以了,下一篇将用live地图和mapABC地图为大家做介绍。
接着上期的,这里用两个实例,给大家介绍一下Flex自定义地图制作的流程,看看是怎么从TileLayBase扩展成自定义的地图
首先是live的地图
02{
03 import com.google.maps.CopyrightCollection;
04 import com.google.maps.TileLayerBase;
05
06 import flash.display.DisplayObject;
07 import flash.display.Loader;
08 import flash.events.IEventDispatcher;
09 import flash.events.IOErrorEvent;
10 import flash.geom.Point;
11 import flash.net.URLRequest;
12
13 public class LiveDituTileLayerBase extends TileLayerBase
14 {
15 private var serviceUrls:Array=["http://r0.tiles.ditu.live.com/tiles/r",
16 "http://r1.tiles.ditu.live.com/tiles/r",
17 "http://r2.tiles.ditu.live.com/tiles/r",
18 "http://r3.tiles.ditu.live.com/tiles/r"];
19 private var serviceUrlSuffix:String = ".png?g=29";
20
21 public function LiveDituTileLayerBase()
22 {
23 super(new CopyrightCollection("http://cn.bing.com/ditu/"),0,19)
24 }
25
26 private function getTileUrl(p:Point,zoom:int):String{
27
28 var c:Number=Math.pow(2,zoom);
29 var d:Number=p.x;
30 var e:Number=p.y;
31 var f:String="";
32 for(var g:int=0;g<zoom;g++){
33 c=c/2;
34 if(e<c){
35 if(d<c){
36 f+="0"
37