ArcGIS API for Flex 調用天地圖、e都市瓦片地圖
眾所周知,像天地圖和e都市的地圖都是以切片的形式存放在服務端的,系統根據用戶選擇的范圍加載該范圍的瓦片地圖,這比傳統的實時渲染地圖的響應速度更快。google地圖和baidu地圖的原理也不外乎如此。
所以說,如果本地硬盤上有瓦片地圖,或者我們知道瓦片地圖在遠程服務器端的組織形式,利用簡單的javascript腳本語言和瀏覽器就可以實現對地圖的瀏覽,通俗地說,這其實就是一個圖片瀏覽器。考慮到遠程服務器需要網絡連接,最近利用閑暇時間將長沙市范圍的e都市上的瓦片下載到本地,這樣在沒有網絡的情況下也能瀏覽地圖了。
采用網上廣泛流傳的完全利用js腳本寫的開源“webgis完整功能例子”,換上本地硬盤上下載好的長沙范圍內e都市地圖,效果圖如下。
當然,以上是網絡上js高手寫的API,功能不是很強大,但是至少為我等開發者提供了值得借鑒的思路。
esri也提供了可以瀏覽瓦片地圖的API,包括javascript API,silverlight API和flex API,作為客戶端語言,這三者提供的功能大致相似,甚至在類的命名上都保持了高度的一致性。利用arcgis api for javascript同樣可以將下載到本地的瓦片和遠程服務器端的瓦片進行地圖瀏覽,本人結合最近做的利用ArcGIS API for Flex(以下簡稱ags4fx)加載天地圖的瓦片地圖來說明該過程,javascript api和silverlight api可以參考該方法加載瓦片地圖。
根據最新的ags4fx 2.4可知,esri為我們提供了TiledMapServiceLayer類,這個類正是所有瓦片地圖服務都必須繼承的類,像ArcGISTiledMapServiceLayer, OpenStreetMapLayer, VETiledLayer等esri提供的瓦片類都是繼承了該類的,所以我們要擴展該TiledMapServiceLayer類,名字暫且叫TianDiTuTiledMapServiceLayer。
從TiledMapServiceLayer類的API可知,fullExtent屬性、tileInfo屬性、units屬性和getTileURL()方法是子類必須要重寫的,於是最簡單的TianDiTuTiledMapServiceLayer類定義如下:
{
import com.esri.ags.SpatialReference;
import com.esri.ags.geometry.Extent;
import com.esri.ags.geometry.MapPoint;
import com.esri.ags.layers.TiledMapServiceLayer;
import com.esri.ags.layers.supportClasses.LOD;
import com.esri.ags.layers.supportClasses.TileInfo;
import flash.net.URLRequest;
public class TianDiTuTiledMapServiceLayer extends TiledMapServiceLayer
{
private var _tileInfo:TileInfo;
/*
一幅完整的圖片url有如下格式: http://tile0.tianditu.com/DataServer?T=sbsm0210 &X=1&Y=1&L=1
*/
private var _baseURL:String; /* http://tile */
private var _baseURLs:Array; /* 由諸如.tianditu.com/DataServer?T=sbsm0210組成的數組 */
private var _initExtent:String;
private var _id:String;
private var _name:String;
private var _alpha:Number;
private var _visible:Boolean;
public function TiandituTiledMapServiceLayer()
{
this ._tileInfo = new TileInfo();
this ._baseURLs = [];
this ._initExtent = null ;
this .buildTileInfo(); // 設置tileinfo信息
setLoaded( true );
}
public function set baseURL(baseurl:String): void
{
_baseURL = baseurl;
}
public function set baseURLs(baseurls:Array): void
{
_baseURLs = baseurls;
}
override public function get fullExtent() : Extent
{
return new Extent( - 180 , - 90 , 180 , 90 , new SpatialReference( 4326 ));
}
public function set initExtent(initextent:String): void
{
this ._initExtent = initextent;
}
override public function get initialExtent() :Extent
{
if ( this ._initExtent == null ) // 如果沒有配置initExtent節點,則默認初始范圍為長沙市區
return new Extent( 111.9 , 27.85 , 114.25 , 28.67 , new SpatialReference( 4326 ));
var coors:Array = this ._initExtent.split( " , " );
return new Extent(Number(coors[ 0 ]), Number(coors[ 1 ]), Number(coors[ 2 ]) ,Number(coors[ 3 ]), new SpatialReference( 4326 ));
}
override public function get spatialReference() : SpatialReference
{
return new SpatialReference( 4326 );
}
override public function get tileInfo() : TileInfo
{
return this ._tileInfo;
}
override public function get units() : String
{
return " esriDecimalDegrees " ;
}
override protected function getTileURL(level:Number, row:Number, col:Number) : URLRequest
{
var url:String = null ;
var rank:Number = this ._baseURLs.length / 2 ;
var tempLevel:Number = 0 ;
for (var i:Number = 0 ; i < rank; i ++ )
{
if (tempLevel <= level && level < Number( this ._baseURLs[i * 2 ]))
{
url = this ._baseURLs[i * 2 + 1 ];
break ;
}
if (i != rank - 1 )
tempLevel = Number( this ._baseURLs[i * 2 ]);
}
return new URLRequest(urlRequest);
}
private function buildTileInfo() : void
{
this ._tileInfo.height = 256 ;
this ._tileInfo.width = 256 ;
this ._tileInfo.origin = new MapPoint( - 180 , 90 );
this ._tileInfo.spatialReference = new SpatialReference( 4326 );
this ._tileInfo.lods = new Array();
this ._tileInfo.lods = [
new LOD( 0 , 0.703125 , 2.95498e+008 ),
new LOD( 1 , 0.351563 , 1.47749e+008 ),
new LOD( 2 , 0.175781 , 7.38744e+007 ),
new LOD( 3 , 0.0878906 , 3.69372e+007 ),
new LOD( 4 , 0.0439453 , 1.84686e+007 ),
new LOD( 5 , 0.0219727 , 9.2343e+006 ),
new LOD( 6 , 0.0109863 , 4.61715e+006 ),
new LOD( 7 , 0.00549316 , 2.30857e+006 ),
new LOD( 8 , 0.00274658 , 1.15429e+006 ),
new LOD( 9 , 0.00137329 , 577144 ),
new LOD( 10 , 0.000686646 , 288572 ),
new LOD( 11 , 0.000343323 , 144286 ),
new LOD( 12 , 0.000171661 , 72143 ),
new LOD( 13 , 8.58307e-005 , 36071.5 ),
new LOD( 14 , 4.29153e-005 , 18035.7 ),
new LOD( 15 , 2.14577e-005 , 9017.87 ),
new LOD( 16 , 1.07289e-005 , 4508.9 ),
new LOD( 17 , 5.36445e-006 , 2254.47 )
];
}
}
}
在mxml頁面,配置地圖參數如下:
< s:Application xmlns:fx ="http://ns.adobe.com/mxml/2009"
xmlns:s ="library://ns.adobe.com/flex/spark"
xmlns:viewer ="com.esri.viewer.*"
xmlns:tdt ="tdt.*" >
< esri:Map >
< tdt:TianDiTuTiledMapServiceLayer >
< tdt:baseURL > http://tile </ tdt:baseURL >
< tdt:baseURLs >
< mx:String > 10 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=A0512_EMap </ mx:String >
< mx:String > 12 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=B0627_EMap1112 </ mx:String >
< mx:String > 18 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=siwei0608 </ mx:String >
</ tdt:baseURLs >
</ tdt:TianDiTuTiledMapServiceLayer >
< tdt:TianDiTuTiledMapServiceLayer >
< tdt:baseURL > http://tile </ tdt:baseURL >
< tdt:baseURLs >
< mx:String > 10 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=sbsm0210 </ mx:String >
< mx:String > 11 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=e11 </ mx:String >
< mx:String > 12 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=e12 </ mx:String >
< mx:String > 13 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=e13 </ mx:String >
< mx:String > 14 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=eastdawnall </ mx:String >
< mx:String > 18 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=sbsm1518 </ mx:String >
</ tdt:baseURLs >
< tdt:initExtent > 111.9, 27.85, 114.25, 28.67 </ tdt:initExtent >
</ tdt:TianDiTuTiledMapServiceLayer >
< tdt:TianDiTuTiledMapServiceLayer >
< tdt:baseURL > http://tile </ tdt:baseURL >
< tdt:baseURLs >
< mx:String > 10 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=A0610_ImgAnno </ mx:String >
< mx:String > 14 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=B0530_eImgAnno </ mx:String >
< mx:String > 18 </ mx:String >
< mx:String > .tianditu.com/DataServer?T=siweiAnno68 </ mx:String >
</ tdt:baseURLs >
</ tdt:TianDiTuTiledMapServiceLayer >
</ esri:Map >
</ s:Application >
加載地圖后的 flex頁面如