BlueViewer是基於.NET Link進行ArcIMS二次開發的一個執行個體,裡麵包含了WebGIS最基本的一些功能。關於ArcIMS結構及其簡介可以參考我的另外一篇隨筆《ArcIMS體繫結構》。關於.NET Link連接器的介紹可以參考《ArcIMS連接器--.NET Link使用方法》。Mars寫了一篇《淺析ArcIMS》,對BlueViewer做了簡單的分析。
使用.NET Link進行ArcIMS二次開發並不複雜,但不少剛剛接觸GIS朋友面對大量JavaScript和ArcXML,加上對WebGIS運行機制不瞭解,還是感覺無從下手。這篇隨筆將對BlueViewer地圖載入顯示機制進行剖析,看看整個代碼的運行過程,代碼語言使用C#。
使用HTML、ArcExplorer、JavaViewer用戶端進行開發,需要在用戶端使用JavaScript對ArcXML進行編寫與封裝,雖然ArcXML的傳輸過程變得相對簡單,但對人的耐力絕對是個莫大的考驗,因此一般建議使用ArcIMS的各種連接器進行二次開發,BlueViewer就是基於.NET Link進行二次開發的一個執行個體。
連接器的主要作用,就是根據用戶端的請求,將請求封裝為ArcXML傳輸到ArcIMS應用伺服器,以及將ArcIMS應用伺服器發送回來的結果提取出來(一般為圖片),發送給用戶端,響應使用者請求。在用戶端,使用者對地圖的操作及地圖的顯示還是由JavaScript來控制,但相對於在用戶端編寫ArcXML來說,其工作量還是要減輕不少,開發方法更符合OOP,其中.NET Link相對來說在物件導向方面做的不怎麼好,但使用ASP.NET進行開發,.NET Link是不二的選擇。
下面是對程式啟動地圖顯示過程的分析
----------------------------------------
在default.aspx中有五個隱藏欄位,hvMinX、hvMinY、hvMaxX、hvMaxY、hvMapPage,前四個對象描述當前地圖顯示範圍,最後一個返回地圖顯示的url。程式啟動第一步就是初始化這些值,在default.aspx.cs中有詳細描述。
protected void Page_Load(object sender, System.EventArgs e)
{
if (!(IsPostBack))
{
Session.Add("VALID_USER", true);
hvMapPage.Value = "MakeMap.aspx";
}
if ((Request.QueryString["XMIN"] == null | Request.QueryString["YMIN"] == null | Request.QueryString["XMAX"] == null | Request.QueryString["YMAX"] == null))
{
hvMinX.Value = System.Configuration.ConfigurationSettings.AppSettings["DEFAULT_EXTENT_XMIN"];
hvMinY.Value = System.Configuration.ConfigurationSettings.AppSettings["DEFAULT_EXTENT_YMIN"];
hvMaxX.Value = System.Configuration.ConfigurationSettings.AppSettings["DEFAULT_EXTENT_XMAX"];
hvMaxY.Value = System.Configuration.ConfigurationSettings.AppSettings["DEFAULT_EXTENT_YMAX"];
}
else
{
hvMinX.Value = Request.QueryString["XMIN"];
hvMinY.Value = Request.QueryString["YMIN"];
hvMaxX.Value = Request.QueryString["XMAX"];
hvMaxY.Value = Request.QueryString["YMAX"];
}
}
在default.aspx的<body/>中,onload調用main.js的startUp()方法。在startUp()中,先後調用posLoadingImage()、posBorder()、posBorderNavigation()、posTools()四個方法,它們分別代表映像載入時的"Loading"表徵圖、放大縮小圖框、方位移動表徵圖的定位(A)、下方整個工具狀態列的位置(B,依賴方位移動表徵圖的位置)。然後通過handleToolClick()確定當前滑鼠操作是放大縮小(iToolMode==1),還是移動圖層(iToolMode==2),通過m_txtXCoord和m_txtYCoord初始化當前X/Y座標的顯示(C)。
m_imgMapCanvas.onload = hideWaitImage;
這段代碼說明了在伺服器響應使用者操作之前的時刻,用戶端所作的狀態清理工作,hideWaitImage主要的作用是清楚使用者的放大縮小框,隱藏"Loading"表徵圖。
到目前為止,程式完成了在向ArcIMS應用伺服器發送ArcXML之前的所有工作,包括程式介面顯示、用戶端對使用者介面操作的響應,下面緊接著,就是使用者請求的發送與系統伺服器端(Web應用伺服器、ArcIMS應用伺服器和ArcIMS空間伺服器統稱)對使用者請求的響應。因為這裡描述的是程式啟動的過程,不涉及到使用者對地圖的實際操作,但使用者對地圖的操作無非是一堆JavaScript代碼,對後面的程式響應過程沒有太多影響。不論是程式啟動,還是使用者對地圖進行操作請求服務,都要通過submit()方法來發送請求並返回系統伺服器端響應。
function submit() {
var sURL = m_hvMapPage.value+"?XMIN="+
m_mapViewer.getExtent().getLeft()+
"&YMIN="+m_mapViewer.getExtent().getBottom()+
"&XMAX="+m_mapViewer.getExtent().getRight()+
"&YMAX="+m_mapViewer.getExtent().getTop()+
"&WIDTH="+m_mapViewer.getTagWidth()+
"&HEIGHT="+m_mapViewer.getTagHeight();
updateZoomLevel(m_mapViewer.getLevel());
showWaitImage();
if (navigator.userAgent.indexOf('Netscape6/6') > -1) {
m_lTimerID = setInterval("hideWaitImageForNetscape6();",100);
}
m_imgMapCanvas.src = sURL;
persistExtent();
}
在default.aspx的Page_Load()中,hvMapPage.Value已被賦值為"MakeMap.aspx",此時將調用MakeMap.aspx頁面並啟動其Page_Load()過程,在這個過程中實現了根據使用者請求封裝ArcXML的發送,和系統伺服器端的響應,具體的過程可以參考《ArcIMS連接器--.NET Link使用方法》。頁面會返回使用者所需要的圖片的url,並定義當前地圖的顯示範圍,賦給submit()的各個參數,通過persistExtent()方法將地圖範圍儲存在hvMinX、hvMinY、hvMaxX、hvMaxY四個隱藏欄位中。
到此,程式完成了整個啟動過程,其介面如所示,當使用者對其進行操作請求服務時,除了JavaScript操作不同外,其他過程基本相同。熟悉JavaScript和XML,理解了ArcIMS的體繫結構和服務要求過程,進行.NET Link二次開發還是不複雜的。在Ajax橫行天下的年代,將用戶端請求服務和響應用戶端請求的過程用Ajax來實現,可以擺脫frame架構的束縛,改善代碼的邏輯結構,增強WebGIS的使用者體驗。