现在的位置: 首页 > 综合 > 正文

利用flex加载离线地图

2014年04月05日 ⁄ 综合 ⁄ 共 3630字 ⁄ 字号 评论关闭

Flex web端为了安全性,没有提供File文件接口,无法读取本地文件,所以要在flex加载地图需要借助一个后台服务,说实话真的不喜欢这个后台服务,要能直接读最好了。具体思路是:flexhttp请求自己写的服务,相应的读取数据操作是在服务端完成,结果返回一个byte数组。再在flex端对数据流进行处理加载即可。

           服务端利用tcp协议线程监听flex请求,分析请求连接做出相应的操作,服务端功能有三个,加载conf.cdi(包含地图的范围信息)、加载conf.xml(包含切片信息)、加载某个切片:

代码在下面:

           Flex端是对ArcGISTiledMapServiceLayer进行继承重写。注意要点:

1.      对于一个地图的显示,需要知道地图的初始化范围和最大范围,只有地图范围确定了,map控件才会知道怎么计算行列号,才能请求到数据。

2.             地图的图层级别信息,map控件需要知道每个切片的大小,宽和高,原点坐标,空间坐标等信息。

3.      当map控件知道所需要的信息,计算出层级、行列号,这时候就会调用getTileURL()方法,参数为级别和行列号,请求该位置上的切片图。至于后台服务也就是主要替带server完成了这个功能。所以需要重写此方法将请求连接劫持即可。

                  前面提到flex无法读取本地文件,arcgisserver中加载地图时并未提到过xml cdi这两个文件,因为内部自行处理了,看不到。所以现在必须手动在flex端加载这两个文件并进行解析。在对文件解析后得到的信息,需要重写fullExtent
initialExtenttileInfo 这3个属性,将自己得到的配置信息设置到map控件上,不然读它干嘛喃。。。至此差不多过程就算完了,将自己的图层加到map控件上试试。

flex   端代码

package
{
import com.esri.ags.SpatialReference;
import com.esri.ags.geometry.Extent;
import com.esri.ags.geometry.MapPoint;
import com.esri.ags.layers.ArcGISTiledMapServiceLayer;
import com.esri.ags.layers.supportClasses.LOD;
import com.esri.ags.layers.supportClasses.TileInfo;

import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;

import mx.collections.ArrayList;


public class ArcGISLocalMapServiceLayer extends ArcGISTiledMapServiceLayer
{
private var pLocalUrl:String="";
private var pInfo:TileInfo=new TileInfo();
private var pextend:Extent=null;
private var pspatial=null;

public function ArcGISLocalMapServiceLayer(url:String=null, proxyURL:String=null, token:String=null)
{
super();
}

public function set conurl(value:String):void
{
if(this.pLocalUrl!=value)
{
if(value)
{
this.pLocalUrl=value;
var confurl:URLRequest=new URLRequest(pLocalUrl+"/?type=configxml");
var load:URLLoader=new URLLoader(confurl);
load.addEventListener(Event.COMPLETE,compelte);
}
}
}

public function get conurl():String
{
return this.pLocalUrl;
}


private function compelte(event:Event):void
{
var CacheInfo:XML=new XML(event.target.data);
//var TileCacheInfo:XMLList=xml.TileCacheInfo;
this.pInfo.height=CacheInfo.TileCacheInfo.TileRows;
this.pInfo.width=CacheInfo.TileCacheInfo.TileCols;
this.pInfo.dpi=CacheInfo.TileCacheInfo.DPI;
this.pInfo.origin=new MapPoint(CacheInfo.TileCacheInfo.TileOrigin.X,CacheInfo.TileCacheInfo.TileOrigin.Y);
pspatial=new SpatialReference(CacheInfo.TileCacheInfo.SpatialReference.WKID);
this.pInfo.spatialReference=this.pspatial;
this.pInfo.lods=new Array();
var lodsinfo:XMLList=CacheInfo.TileCacheInfo.LODInfos.LODInfo;
var i:int=0;
for(i;i<lodsinfo.length();i++)
{
this.pInfo.lods.push(new LOD(lodsinfo[i].LevelID,lodsinfo[i].Resolution,lodsinfo[i].Scale));
}

var cdiurl:URLRequest=new URLRequest(pLocalUrl+"/?type=configcdi");
var loadcdi:URLLoader=new URLLoader(cdiurl);
loadcdi.addEventListener(Event.COMPLETE,cdicomplete);

}

private function cdicomplete(event:Event):void
{
var EnvelopeN:XML=new XML(event.target.data);
pextend=new Extent(EnvelopeN.XMin,EnvelopeN.YMin,EnvelopeN.XMax,EnvelopeN.YMax,pspatial);
this.setLoaded(true);

}

override  protected function getTileURL(level:Number, row:Number, col:Number):URLRequest
{
//var pBaseUrl=pLocalUrl+"//_alllayers";
//var L:String="//L"+level.toString();
//var R:String="//R"+NunConVert(row);
//var C:String="//C"+NunConVert(col);
//pBaseUrl=pBaseUrl+L+R+C+".png";

var pBaseUrl=pLocalUrl+"/?type=t&l="+level.toString()+"&r="+row.toString()+"&c="+col.toString();
return new URLRequest(pBaseUrl);
}

override public function get fullExtent():Extent
{
return pextend;
}

override public function get initialExtent():Extent
{
return pextend;
}

override public function get tileInfo():TileInfo
{
return this.pInfo;
}

//protected function NunConVert(num:Number):String
//{
// var pNum:String=num.toString(16);
// var pCount:int=8-pNum.length;
// for(var i:int=0;i<pCount;i++)
// {
// pNum="0"+pNum;
// }
// return pNum;
//}

}

}

         

抱歉!评论已关闭.