您的位置:首页 > 其它

Arcgis api for flex项目实例—开发篇(1):地图浏览

2014-09-22 20:05 405 查看
前文已经明确数据用天地图,这样的选择一来是免费,二来各种来源的数据都大同小异,天地图用的2000坐标系是常见的经纬度,方便专题数据叠加。

闲话少说,看一下arcgis api for flex是如何吃定天地图的吧。首先要明确的是我们需要用到四个天地图瓦片服务,分别是经纬度地图底图、经纬度地图中文注记、经纬度影像底图、经纬度影像中文注记,详情可以参阅http://www.tianditu.com/guide/index.html。各种服务形式上都差不多,我们来写一个天地图图层类。

首先新建一个类,这个类必须是com.esri.ags.layers.TiledMapServiceLayer的扩展。

public class TDTTiledMapLayer extends TiledMapServiceLayer
{

}


然后,定义两个变量,_tileInfo、_baseUrl和layerId,_tileInfo是arcgis api瓦片图层的基本参数,_baseUrl是url的基本构成,_baseUrl只是定义了一些必要参数,完整的url还应包括基本地址和瓦片动态参数,再定义一个set属性,用于传入基本地址,瓦片动态参数后面再说,layerId是图层名,这个是天地图服务一个讨厌的参数,同样也要给它一个set属性把这个参数加到地址上。

private var _tileInfo:TileInfo = new TileInfo();
private var _baseURL:String = "?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles";
private var _layerId:String = "vec";
public function set baseUrl(value:String):void
{
_baseURL = value + _baseURL;
}
public function set layerId(value:String):void
{
_baseURL = _baseURL + "&LAYER=" + value;
}


然后就是定义_tileInfo了,这是我们这个类最为重要的一步,写一个函数buildTileInfo(),具体内容就不解释了,大致是定义瓦片规格,坐标参考系,以及地图级别。

private function buildTileInfo():void
{
_tileInfo.height = 256;
_tileInfo.width = 256;
_tileInfo.origin = new MapPoint(-180, 90);
_tileInfo.spatialReference = new SpatialReference(4490);
_tileInfo.lods = [
new LOD(1 , 0.703125,    2.958293554545656E8),
new LOD(2 , 0.351563,    1.479146777272828E8),
new LOD(3 , 0.175781,    7.39573388636414E7),
new LOD(4 , 0.0878906,   3.69786694318207E7),
new LOD(5 , 0.0439453,   1.848933471591035E7),
new LOD(6 , 0.0219727,   9244667.357955175),
new LOD(7 , 0.0109863,   4622333.678977588),
new LOD(8 , 0.00549316,  2311166.839488794),
new LOD(9 , 0.00274658,  1155583.419744397),
new LOD(10, 0.00137329,  577791.7098721985),
new LOD(11, 0.000686646,  288895.85493609926),
new LOD(12, 0.000343323,  144447.92746804963),
new LOD(13, 0.000171661,  72223.96373402482),
new LOD(14, 8.58307e-005, 36111.98186701241),
new LOD(15, 4.29153e-005, 18055.990933506204),
new LOD(16, 2.14577e-005, 9027.995466753102),
new LOD(17, 1.07289e-005, 4513.997733376551),
new LOD(18, 5.36445e-006, 2256.998866688275)
];
}


最后,需要实现一下getTileURL方法,这个方法是把每一张瓦片的动态参数和_baseUrl合并形成每一张瓦片的参数。

override protected function getTileURL(level:Number, row:Number, col:Number):URLRequest
{
var url:String = _baseURL + "&TILEMATRIX=" + level + "&TILEROW=" + row + "&TILECOL=" + col;
return new URLRequest(url);
}


然后,这个类要求我们override几个get方法,照单全收。唯一要注意的是initialExtent,这个可以依据当前地图需要的范围来设定,比如我现在就设成了安徽的。当然也可以随便设,调用时map的extent会覆盖它。

override public function get fullExtent():Extent
{
return new Extent(-180, -90, 180, 90, new SpatialReference(4326));
}
override public function get initialExtent():Extent
{
return new Extent(114.76,27.59,120.26, 35.64,new SpatialReference(4326));
}
override public function get spatialReference():SpatialReference
{
return new SpatialReference(4490);
}
override public function get tileInfo():com.esri.ags.layers.supportClasses.TileInfo
{
return _tileInfo;
}


最后在构造函数里写几笔,主要是要把buildTileInfo()加上。

public function TDTTiledMapLayer()
{
super();
buildTileInfo();
setLoaded(true);
}


好了。类构造完毕,下面我们去调用它。回到我们的index.html,给map加上图层。

<esri:Map id="map" left="0" right="0" top="0" bottom="0" logoVisible="false" scaleBarVisible="false">
<tool:TDTTiledMapLayer id="vec_c" baseUrl="http://t0.tianditu.com/vec_c/wmts" visible="true"/>
<tool:TDTTiledMapLayer id="cva_c" baseUrl="http://t0.tianditu.com/cva_c/wmts" visible="true"/>
<tool:TDTTiledMapLayer id="img_c" baseUrl="http://t0.tianditu.com/img_c/wmts" visible="false"/>
<tool:TDTTiledMapLayer id="cia_c" baseUrl="http://t0.tianditu.com/cia_c/wmts" visible="false"/>
</esri:Map>


影像底图和注记visible置为false是为了地图切换的需要,初始默认的是线划地图。下面来看效果。





再利用一点篇幅,把地图类型切换加上吧。两个按钮是toggleButton,其实有很多办法去做这个按钮,但是我们先简单实现一下。加上一个Bool型的Bindable属性IsVector,用它来标识当前地图类型以及控制按钮的状态。

[Bindable]
private var IsVector:Boolean = true;


然后,我们在mxml里做一些改动,主要是把ToggleButton的选中状态以及图层可见性绑定过来。

<esri:Map id="map" left="0" right="0" top="0" bottom="0" logoVisible="false" scaleBarVisible="false">
<tool:TDTTiledMapLayer id="vec_c" baseUrl="http://t0.tianditu.com/vec_c/wmts" layerId="vec" visible="{IsVector}"/>
<tool:TDTTiledMapLayer id="cva_c" baseUrl="http://t0.tianditu.com/cva_c/wmts" layerId="cva" visible="{IsVector}"/>
<tool:TDTTiledMapLayer id="img_c" baseUrl="http://t0.tianditu.com/img_c/wmts" layerId="img" visible="{!IsVector}"/>
<tool:TDTTiledMapLayer id="cia_c" baseUrl="http://t0.tianditu.com/cia_c/wmts" layerId="cia" visible="{!IsVector}"/>
</esri:Map>
<s:HGroup right="10" top="10" height="22" gap="0" verticalAlign="middle">
<s:ToggleButton width="60" label="地图" cornerRadius="0" selected="{IsVector}" click="mapType_clickHandler(event)"/>
<s:ToggleButton width="60" label="影像" cornerRadius="0" selected="{!IsVector}" click="mapType_clickHandler(event)"/>
</s:HGroup>


下面就把ToggleButton的Click事件绑定上,mxml里我已经写好了,下面看as代码,就一句。

private function mapType_clickHandler(event:MouseEvent):void
{
IsVector = !IsVector;
}


这样就好了,两个按钮就和地图的类型绑定在了一起。这里使用flex开发中非常重要的绑定机制,这一机制可以让代码变得非常优雅,但这不是重点,更重要的是,它让逻辑变得简单,也更安全。安全这一点后面遇到类似情况我会提出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: