加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ArcGIS Server FLEX API调用百度地图实现技术

发布时间:2020-12-15 04:56:27 所属栏目:百科 来源:网络整理
导读:调用百度地图的ActionScripts脚本是用的网上一位“GIS大奔”的博客,在网上查到以后,拷下来,安装好FLESH BUILDER 4独立版,下载ArcGIS server FIEX API 2.0安装上,写一个调用脚本的MXML,就成功地调到了百度地图。用了差不多1天时间吧,之前没有做过FLEX

调用百度地图的ActionScripts脚本是用的网上一位“GIS大奔”的博客,在网上查到以后,拷下来,安装好FLESH BUILDER 4独立版,下载ArcGIS server FIEX API 2.0安装上,写一个调用脚本的MXML,就成功地调到了百度地图。用了差不多1天时间吧,之前没有做过FLEX,但是对AE挺熟。虽然成功调到图了,由于前面那位大牛只共享了代码,没有说明实现的原理,不明所以也就不能在业务应用中按自己的需要进行调整,所以又花了两天的时间,看了看,这个实现脚本的各个部分的作用,结合百度地图的API,ArcGIS server FIEX API帮助,基本理解了实现原理,在此将自己的理解写出来。

参考文章地址

http://www.gisall.com/html/72/124272-6284.html.

百度地图API http://dev.baidu.com/wiki/static/index.htm


编写一个扩展TiledMapServiceLayer的类,类名叫BaiduTiledMapServiceLayer。主要是重载TiledMapServiceLayer的getTileURL方法和设置Extent、TileInfo等属性。

// ActionScript file

?

package samples

{

???

??? 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;

???

??? import flashx.textLayout.formats.Float;

???

??? import mx.controls.Alert;

???

??? public class BaiduTiledMapServiceLayer extends TiledMapServiceLayer

??? {

??????? //成员变量

??????? private var _tileInfo:TileInfo = new TileInfo();// see buildTileInfo()

??????? private var _wkid:int = 102100;//102113;//102100;

??????? private var leftcorner:Number=0.0;

??????? private var cornerCoordinate:Number = 20037508.3427892;

??????? private var _mapType:String = "Image";

???????

???????

??? ??? public function BaiduTiledMapServiceLayer()

??????? {

??????????? super();

???????????

??????????? buildTileInfo(); // to create our hardcoded tileInfo

???????????

??????????? setLoaded(true);// Map will only use loaded layers

??????? }

???????

??????? //----------------------------------

??????? //? 全屏范围

??????? //? - required to calculate the tiles to use

??????? //----------------------------------

??????? override public function get fullExtent():Extent

??????? {

??????????? return new Extent(-cornerCoordinate,-cornerCoordinate,cornerCoordinate,new SpatialReference(_wkid));

??????? }

???????

??????? //----------------------------------

??????? //? 初始化范围

??????? //? - needed if Map doesn't have an extent

??????? //----------------------------------

???????

??????? override public function get initialExtent():Extent

??????? {

??????????? return new Extent(-cornerCoordinate,new SpatialReference(_wkid));

??????? }

???????

??????? //----------------------------------

??????? //? 空间参考系

??????? //? - needed if Map doesn't have a spatialReference

??????? //----------------------------------

??????? override public function get spatialReference():SpatialReference

??????? {

??????????? return new SpatialReference(_wkid);

??????? }

???????

??????? //----------------------------------

??????? //? tileInfo

??????? //----------------------------------

??????? override public function get tileInfo():TileInfo

??????? {

??????????? return _tileInfo;

??????? }

???????

??????? public function set mapType(strMapType:String):void

??????? {

??????????? this._mapType = strMapType;

??????? }

???????

??????? public function get mapType():String

??????? {

??????????? return this._mapType;

??????? }

??????????????? //--------------------------------------------------------------------------

??????? //

??????? //? 关键方法,用于读取服务器上的缓存图片

??????? //????? getTileURL(level:Number,row:Number,col:Number):URLRequest

??????? //

??????? //--------------------------------------------------------------------------

??????? override protected function getTileURL(level:Number,col:Number):URLRequest

??????? {

???????????

??????????? var zoom:int = level - 1;

??????????? var offsetX:int = Math.pow(2,zoom)as int;

??????????? var offsetY:int = offsetX - 1;

???????????

??????????? var numX:int = col - offsetX;

??????????? var numY:int = (-row) + offsetY;

???????????

??????????? zoom = level + 1;

??????????? var num:int = (col + row) % 8 + 1;

???????????

???????????

??????????? var url:String =null;

??????????? if (mapType =="Map")

??????????? {

??????????????? url = "http://q" + num +".baidu.com/it/u=x=" + numX +";y=" + numY +";z=" + zoom +";v=009;type=web&fm=44";

??????????? }

??????????? else if (mapType == "Image")

??????????? {

??????????????? url = "http://q"+num+".baidu.com/it/u=x="+numX+";y="+numY+";z="+zoom+";v=009;type=sate&fm=46";

??????????? }

??????????? else if (mapType == "POI")

??????????? {

??????????????? url = "http://q"+num+".baidu.com/it/u=x="+numX+";y="+numY+";z="+zoom+";v=009;type=trans&fm=47";

??????????? }

??????????? return new URLRequest(url);

??????? }

???????

??????? //--------------------------------------------------------------------------

??????? //

??????? //? 自定义方法,定义地图缩放等级

??????? //

??????? //--------------------------------------------------------------------------

??????? private function buildTileInfo():void

??????? {

??????????? _tileInfo.height=256;

??????????? _tileInfo.width=256;

??????????? _tileInfo.origin=new MapPoint(-cornerCoordinate,cornerCoordinate);

??????????? _tileInfo.spatialReference=new SpatialReference(_wkid);

???????????

??????????? _tileInfo.lods = [

??????????????? new LOD(0,156543.033928,591657527.591555),

??????????????? new LOD(1,78271.5169639999,295828763.795777),

??????????????? new LOD(2,39135.7584820001,147914381.897889),

??????????????? new LOD(3,19567.8792409999,73957190.948944),

??????????????? new LOD(4,9783.93962049996,36978595.474472),

??????????????? new LOD(5,4891.96981024998,18489297.737236),

??????????????? new LOD(6,2445.98490512499,9244648.868618),

??????????????? new LOD(7,1222.99245256249,4622324.434309),

??????????????? new LOD(8,611.49622628138,2311162.217155),

??????????????? new LOD(9,305.748113140558,1155581.108577),

??????????????? new LOD(10,152.874056570411,577790.554289),

??????????????? new LOD(11,76.4370282850732,288895.277144),

??????????????? new LOD(12,38.2185141425366,144447.638572),

??????????????? new LOD(13,19.1092570712683,72223.819286),

??????????????? new LOD(14,9.55462853563415,36111.909643),

??????????????? new LOD(15,4.77731426794937,18055.954822),

??????????????? new LOD(16,2.38865713397468,9027.977411),

??????????????? new LOD(17,1.19432856685505,4513.988705),

??????????????? new LOD(18,0.597164283559817,2256.994353),

??????????????? new LOD(19,0.298582141647617,1128.497176)

??????????? ];

??????? }

???????

??? }

}


编写一个Mxml页面文件ArcGISserverSamples.mxml,调用自定义扩展类,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

??????????? ?? xmlns:s="library://ns.adobe.com/flex/spark"

??????????? ?? xmlns:mx="library://ns.adobe.com/flex/mx"

??????????? ?? xmlns:esri="http://www.esri.com/2008/ags"

??????????? ?? xmlns:samples="com.esri.ags.samples.*"

??????????? ?? pageTitle="Extending TiledMapServiceLayer in Flex API" xmlns:baidu="com.esri.viewer.components.common.baidu.*" xmlns:Test="Test.*">

?

<esri:Map id="myMap">

??????? <samples:BaiduTiledMapServiceLayer id="virtualTiles" fadeInFrameCount="12"/>

??? </esri:Map>

</s:Application>



调用 后如下图:

(不会传图啊!)


ArcGIS Server FLEX API调用百度地图的实现原理主要是对不同切片Schema下制作的切片地图的调用。

要理解切片地图,首先要理解切片Schema。

切片Schema就是描述地图切片方案的详细信息,包括:

?? 切图层级

?? 各级比例尺

?? 各级分辨率

?? 图片大小

?? 图片格式

?? 切图原点

?? 空间参照系

?? DPI

?? 坐标原点

图片大小一般常用的为256和512的标准,其中ArcGIS OnLine为512,Google Maps &Virtual Earth为256。

DPI是每英寸点数,也就是鼠标每移动一英寸指针在屏幕上移动的点数。

缓存分辨率默认是96,ESRI官方建议如果客户端有需求打印地图可以将缓存分辨率(DPI)设置大于96。

图片格式方面, JPEG不支持透明底色,PNG32与PNG8支持透明底色。支持的颜色级别 JPEG与PNG32支持16万色,而PNG8支持256色。存储方式? JPEG为有损带高压缩比的文件格式,能支持55-90的压缩比例。而PNG32和PNG8都是无损的。JPEG比较适合用于影像切片,PNG32则适中与影像与矢量的切片。由于支持的颜色数较少及透明的特点PNG8更适合用于矢量数据的切片。


百度切片Schema的详细信息如下:

?? 切图层级:19

?? 图片大小:256*256

?? 空间参照系:Web 墨卡托

默认19级。第1级的分辨率为131072,第n级的分辨率为:131072 * Math.pow(2,n - 19)。

百度地图在每一个级别将整个地图划分成若干个图块,通过编号系统将整个图块整合在一起以便显示完整的地图。当地图被拖动或者级别发生变化时,地图API将会根据平面坐标计算出当前视野内所需显示的图块的编号。

切片坐标图:


从平面坐标原点(在非洲刚果盆地南部海域)开始的右上方向的图块编号为0,0,以此类推。在最低的缩放级别(级别 1)中,整个地球由 4 张图块组成。随着级别的增长,切片地图的图块个数也随之增多。


实现getTilesUrl方法告诉API取图规则。getTilesUrl方法的参数包括tileCoord和zoom,其中tileCoord为图块的编号信息,zoom为图块的级别,每当地图需要显示特定级别的特定位置的图块时就会自动调用此方法,并提供这两个参数。使用者需要告知API特定编号和级别所对应的图块的地址,这样API就能正常显示自定义的图层了。

本次扩展定义如下:

切片图块x= Col(屏幕展示图块列数)-(Zoom-1)^2

切片图块y= -row(屏幕展示图块行数)+(Zoom-1)^2-1

百度地图图片请求格式为:

http://q1.baidu.com/it/u=x=-2;y=1;z=3;v=009;type=sate&fm=46

其中q1代表的意义及后面的数字意义据说是为了向不同的服务器请求图片而生成的。

以下是测试时的一组URL请求:


第一次,请求第三级

http://q1.baidu.com/it/u=x=-2;y=1;z=3;v=009;type=sate&fm=46

http://q2.baidu.com/it/u=x=-2;y=0;z=3;v=009;type=sate&fm=46

http://q3.baidu.com/it/u=x=-2;y=-1;z=3;v=009;type=sate&fm=46

http://q4.baidu.com/it/u=x=-2;y=-2;z=3;v=009;type=sate&fm=46

?

http://q2.baidu.com/it/u=x=-1;y=1;z=3;v=009;type=sate&fm=46

http://q3.baidu.com/it/u=x=-1;y=0;z=3;v=009;type=sate&fm=46

http://q4.baidu.com/it/u=x=-1;y=-1;z=3;v=009;type=sate&fm=46

http://q5.baidu.com/it/u=x=-1;y=-2;z=3;v=009;type=sate&fm=46

?

http://q3.baidu.com/it/u=x=0;y=1;z=3;v=009;type=sate&fm=46

http://q4.baidu.com/it/u=x=0;y=0;z=3;v=009;type=sate&fm=46

http://q5.baidu.com/it/u=x=0;y=-1;z=3;v=009;type=sate&fm=46

http://q6.baidu.com/it/u=x=0;y=-2;z=3;v=009;type=sate&fm=46

?

http://q4.baidu.com/it/u=x=1;y=1;z=3;v=009;type=sate&fm=46

http://q5.baidu.com/it/u=x=1;y=0;z=3;v=009;type=sate&fm=46

http://q6.baidu.com/it/u=x=1;y=-1;z=3;v=009;type=sate&fm=46

http://q7.baidu.com/it/u=x=1;y=-2;z=3;v=009;type=sate&fm=46

?

http://q5.baidu.com/it/u=x=2;y=1;z=3;v=009;type=sate&fm=46

http://q6.baidu.com/it/u=x=2;y=0;z=3;v=009;type=sate&fm=46

http://q7.baidu.com/it/u=x=2;y=-1;z=3;v=009;type=sate&fm=46

http://q8.baidu.com/it/u=x=2;y=-2;z=3;v=009;type=sate&fm=46

第二次,放大,请求第四级

http://q5.baidu.com/it/u=x=0;y=3;z=4;v=009;type=sate&fm=46

http://q6.baidu.com/it/u=x=0;y=2;z=4;v=009;type=sate&fm=46

http://q7.baidu.com/it/u=x=0;y=1;z=4;v=009;type=sate&fm=46

http://q8.baidu.com/it/u=x=0;y=0;z=4;v=009;type=sate&fm=46

?

http://q6.baidu.com/it/u=x=1;y=3;z=4;v=009;type=sate&fm=46

http://q7.baidu.com/it/u=x=1;y=2;z=4;v=009;type=sate&fm=46

http://q8.baidu.com/it/u=x=1;y=1;z=4;v=009;type=sate&fm=46

http://q1.baidu.com/it/u=x=1;y=0;z=4;v=009;type=sate&fm=46

?

http://q7.baidu.com/it/u=x=2;y=3;z=4;v=009;type=sate&fm=46

http://q8.baidu.com/it/u=x=2;y=2;z=4;v=009;type=sate&fm=46

http://q1.baidu.com/it/u=x=2;y=1;z=4;v=009;type=sate&fm=46

http://q2.baidu.com/it/u=x=2;y=0;z=4;v=009;type=sate&fm=46

?

http://q8.baidu.com/it/u=x=3;y=3;z=4;v=009;type=sate&fm=46

http://q1.baidu.com/it/u=x=3;y=2;z=4;v=009;type=sate&fm=46

http://q2.baidu.com/it/u=x=3;y=1;z=4;v=009;type=sate&fm=46

http://q3.baidu.com/it/u=x=3;y=0;z=4;v=009;type=sate&fm=46

?

http://q1.baidu.com/it/u=x=4;y=3;z=4;v=009;type=sate&fm=46

http://q2.baidu.com/it/u=x=4;y=2;z=4;v=009;type=sate&fm=46

http://q3.baidu.com/it/u=x=4;y=1;z=4;v=009;type=sate&fm=46

http://q4.baidu.com/it/u=x=4;y=0;z=4;v=009;type=sate&fm=46


由于百度地图的实际有效范围小于全球范围,所以默认第一次加载时有大量空白图片,影响浏览效果。因此在实际应用中也常是需要以中国区域为主视图显示,并且限制显示无图区域。


地图范围设置实现可以通过在扩展类中设置FullExtent,InititExtent的具体值来实现。

另经初步测试,百度地图数据的有效范围为:

左下角:(0,0)

右上角:( 20037508.3427892,20037508.3427892)


地图显示层级设置通过设置扩展类的TileInfo属性的LODS级别来实现,如果要控制最小显示级别为3级,则将LODS的前两级删掉,则地图缩放时最小只能放到3级。

_tileInfo.lods = [

??????????????? //new LOD(0,

??????????????? //new LOD(1,

??????????????? new LOD(2,

??? ??????????? new LOD(6,1128.497176)

??????????? ];

百度地图包括三种类型:Map,Imag,POI,分别对应代码44,46,47。

在使用中,可以根据需要单独使用任何一种,也可以混合两种使用。





(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读