EsriMap详解
提示:本小节所涉及内容主要由ADF自己完成,分析只是为了更好地了解原理,为将来有可能做的扩展进行准备。
EsriMap在“/WebContent/js/esri_map.js”中定义,让我们从Map组件输出的JavaScript代码开始去了解ADF在浏览器中所做的工作。
下面的代码是一个简单地图输出的JavaScript代码(为了便于阅读,我对某些代码作了等价的修改),其中“AgsTest”是我的项目名称:
现在让我们开始看浏览器一步一步执行的JavaScript代码。除了引入一些ADF的JavaScript脚本,首先将会执行的是位于最上面的一些变量声明和位于最下面的esriInitItems.push("esriMapInitmap()")代码,这里会将esriMapInitmap()这个函数添加到esriInitItems这个初始化数组里面去;然后,在页面加载完成后会触发window.onload事件,以致调用esriInitApp(e)函数;这时,由于esriMapInitmap()已经被添加到esriInitItems中,因此这个函数将被调用。下面让我们仔细看看在esriMapInitmap()中发生了些什么。
首先第一件事情就是实例化一个EsriMap对象,这一步其实有很多内涵,马上就会详细解释;其次,ADF会针对地图中最重要的数据源进行配置,我们在上面的代码可以看到,由于我们使用的是动态Map Service,因此ADF会新建一个EsriMapSourceDynamic(继承自EsriMapSource)对象,并通过EsriMap的addMapSource()方法添加到地图中;然后,addImage()方法会添加这个EsriMapSource对象的图片地址,可以看到,这个图片地址是一个相对路径,以下这个地址表明EsriMapSource中使用的图片格式是MIME 数据,jsessionid参数指示了当前会话的id:
/AgsTest/mimedata;jsessinotallow=5E13F6727CAA0433934A85EFA1AB8D49?wname=esriWebSession&id=map28171097&uniqueId=24691856-0
下面回过头去详细看一下在实例化EsriMap的时候所发生的事情,这一切相关的操作都封装在了“esri_map.js”这个文件中了,我们可以打开这个文件来看一下EsriMap实例化的详细内容。
首先,EsriMap是继承自EsriControl,关于EsriControl及其相关的内容,有兴趣可以在ADF JavaScript库中继续深入研究。事实上我们对EsriMap感兴趣的应该主要是两点:其一,地图图片在EsriMap中的放置关系;其二,对地图做操作时候EsriMap与ArcGIS Server的通讯。
我们先来看下EsriMap中地图图片的放置关系。EsriMap最外层的div是container,默认id是“EsriMapCell_map”(在“map.xsl”中定义),它是放置地图的容器,一般不作操作;在container中还有几个层次的div:divObject、controlDiv、imageGrid,它们和container的关系如图 9所示。地图图片会放在imageGrid中。
下面我们以动态地图为例,看一下当拖动地图时EsriMap是如何与ArcGIS Server通讯并更新图片的。我们首先找到EsriMap中有以下这段代码:
EsriControls.addPostBackTagHandler("map", EsriControls.maps[self.id].updateAsync);
EsriControls在“/WebContent/js/esri_core.js”中定义,它负责管理当前页面上所有的ADF的DHTML组件。以上的代码给EsriMap对象添加了一个回调函数updateAsync,它将会在页面收到AJAX响应并且响应中有“map”标签的时候被调用。
当我们拖动地图的时候,客户端的JavaScript会将需要的地图范围发给服务器(有兴趣可以参考EsriMapPan和EsriMapContinuousPan函数),服务器处理完成后会返回如下的响应:
这时,updateAsync函数就会被调用,它会更新页面上EsriMap相关的一系列div和其它对象的属性值,从而更新地图视图。具体更新的细节,有兴趣可以详细研究下updateAsync函数,这里就不赘述了。
从这个Map组件的服务器端对象和客户端对象,我们已经基本了解了Map的工作原理。ADF的其余几个常用组件:TOC、Toolbar、Overview等也是万变不离其宗,虽各有特点,但大体思路和原理也大概如此,有兴趣的话你还可以做更深入的研究。