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;jsessionid=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中。
圖 9 EsriMap中放置圖片的div
下面我們以動態地圖為例,看一下當拖動地圖時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等也是萬變不離其宗,雖各有特點,但大體思路和原理也大概如此,有興趣的話你還可以做更深入的研究。