淺析ArcIMS

引言

最早使用的ArcIMS是3.5還是4.0忘記了,很久前的事情了。當時是做一個簡單的系統,包括地圖的 顯示,點擊顯示一個點對象的屬性信息,對這些屬性的查詢,以及添加點對象到一個圖層。顯示和界面的東西都不需要編程實現,使用ArcIMS的Author 和Design就可以了,然後簡單調整一下佈局和顏色,由於是內部使用,這部分無所謂。而添加點對象到某個圖層,就需要使用其他方法了,當時的做法是使用 MO封裝了一個ActiveX EXE(MO無法封裝爲ActiveX DLL),然後通過ASP調用。

這次重拾ArcIMS,安裝、試用,第一感覺是很熟悉,畢竟這麼多版本以來,ArcIMS變化不大,或者說,沒有什麼變化。第二是ArcIMS速度挺快,這2年也用過MapXtreme、MapServer,一直以爲ArcIMS慢,這次安裝後發現其實挺快。因爲沒有測試數據,一臺計算機也不好做測試,不過感覺上,ArcIMS佔上風,這也許和其實現有關,後面再說。

幾個要點:
  • ArcIMS的定位是空間數據發佈系統,雖然也可以做進一步定製和開發,但因爲ArcIMS的定位,有些事情很難或無法實現,例如無法(很難)使用ArcIMS進行復雜的空間分析(嗯,可以調用AO或者MO,這個另當別論)。
  • ArcIMS和目前的ArcGIS Server不是一個基礎,後者基於由COM實現的AO,不過由於ArcIMS任務單一,所以效率較高,而且可以跨平臺(核心代碼應該是ArcInfo時代的純C++?)。
  • Web服務器的Application Server Connector和ArcIMS的應用服務器(Application Server)的通信是基於Servlet發送ArcXML,因此需要安裝Java環境和Servlet運行環境。ArcIMS的Author和Design、Administrator也是基於Java實現。
  • ArcIMS的幾個主要部件:
    • Application Server Connectors,即ArcIMS定製開發的API,有Java、ActiveX、.net等API,但最終和Application Server通信,都需要將請求轉換爲ArcXML,由Servlet Connector發送給Application Server,這也是爲什麼ArcIMS需要一個Servlet運行環境的原因;
    • Application Server,應該是基於Java實現,主要用於維護Spatial Server的狀態及其與Web服務器的交互。
    • Spatial Server,核心的地圖渲染器,基於C++實現?主要用於根據請求渲染地圖,即地圖render。
  • ArcIMS的開發模式:
    • 使用Author、Designer通過可視化方式來設計地圖,發佈,無須編程;
    • 使用Connectors來開發,目前可以使用ASP、.net、Java等等方式來開發。
  • 閒話,記得有過ArcView IMS,MO IMS的產品,沒有使用過,應該是類似MapXtreme for Windows的產品,這個東東是基於MapX實現的,而MapXtreme.net和MapXtreme for Java則是比較純粹的產品。
  • ArcIMS的核心是ArcXML,ArcXML是Web服務器的Application Server Connector,Application Server,Spatial Server之間的通訊協議(語言),其調用模式類似Web Service。

ArcIMS的架構

ArcIMS的體系結構如下圖所示:

 

這個結構應該是在ArcIMS 3.0的時候就確定下來的,之後基本沒有什麼變化。ArcIMS 3.0的發佈時間是2000年,而2000年正是3-tier架構開始成爲主流的年代。

每 層具體的說明可以查看ArcIMS的文檔,早先的文檔和資料一般把客戶端歸於表現層,Web Server、Application Server、Spatial Server歸於邏輯層,空間數據歸於數據層。其實與這些層次做一一對應也無大的必要。其中的Web Server及Application Server Connectors可以部署在一臺計算機;Application Server可以部署在一臺計算機;而Spatial Server可以部署於多臺計算機,由Application Server管理;數據則可以是文件,SDE等格式。實際中,一般把Spatial Server安裝於多臺計算機,因爲Spatial Server是整個系統中負荷最重的部分,執行了大部分的運算任務。

Application Server管理Spatial Server,處理ArcXML請求,並返回ArcXML的結果,對於不同的開發接口(Connector),或者也處理這樣的XML,或者由 Connector封裝了此類請求,然後在後臺與Application Server交互。

運行於Application Server的地圖服務(Service)是無狀態的,也就是說他只是根據ArcXML請求,調度Spatial Server來不斷的生成圖片或者其他數據,然後以ArcXML的格式返回給Web Server的Application Server Connectors。因此,用戶(地圖)的狀態,例如當前的縮放比例,位置等,或者在Web服務器端通過Seesion保留,或者在客戶端通過某種方式 保留(如表單的隱藏域,Url參數等等)。

對於WebGIS的架構和實現,可以參照筆者以前寫過的幾篇文章,應該對理解ArcIMS的架構有用處:

WebGIS系統的設計與實現
http://maweifeng.cnblogs.com/articles/210080.html

使用.net Remoting和SuperMap Object設計WebGIS系統
http://maweifeng.cnblogs.com/articles/250284.html

開發模式與運行機制

使 用ArcIMS的設計工具Author、Designer來編輯Axl定義文件,增加地圖服務,定製Html客戶端或者Java客戶端,發佈地圖服務,這 種開發模式都屬於客戶端處理模式;而使用ActiveX Connector,.Net Link的方式開發,則屬於服務器端處理模式。這裏的處理是指處理ArcXML。

客戶端處理模式,使用Html客戶端或者定製Html客戶端開發。系統的運行機制如下:

 

這種模式下,客戶端的請求已經是ArcXML格式封裝的,然後由Web服務器委託Application Server Connectors處理,由於請求已經是ArcXML格式,Connector的任務只是簡單的把請求轉發給Application Server。

這種模式下,發送和返回請求都需要在客戶端來處理,因此,ArcIMS的Html客戶端的JS代碼行數達到萬行級別,也就不奇怪了。另外,返回和發送ArcXML,其中很多數據都是無關緊要或者不需要的,對於網絡通信,也是一個負擔。

得到服務器端返回的ArcXML後,客戶端JS負責解析,然後再在服務器下載需要的圖片,顯示在客戶端。

相 關的代碼在HtmlViewer的Javascript代碼的aimsMap.js這個文件內,一般的地圖操作設置參數後調用sendMapXML函數, 然後此函數再調用sendToServer函數,最後由htmlSendToServer通過表單方式發送請求(沒有使用XMLHttpRequest對 象,所有XML操作都是由JS完成)。ArcIMS文檔中的“Customizing_the_HTML_Viewer.pdf”中對 HtmlViewer的結構、運行原理、定製有詳細的說明,可以作爲參考。

對於ArcExplorer,JavaViewer等都是使用客戶端處理模式。

服務器端處理模式,包括使用Java、ASP、.net等開發的方式來定製開發的ArcIMS應用。其運行機制如下:

 

對 於服務器處理模式,ArcXML的轉換、解析在服務器端由Application Server Connector進行。客戶端的代碼由服務器端的ASP、JSP等程序動態生成。客戶端發送地圖服務請求後,由服務器端的API轉換爲ArcXML,然 後由Servlet發送給Application Server。

與客戶端處理模式比較,服務器端處理模式的優勢有:更少的數據傳輸,更易與其他程序集成等。

採用服務器處理模式開發,客戶端還是需要處理用戶操作,例如放大縮小,要獲得好的用戶交互體驗,這部分還是需要較強的JS纔可以完成,好在ArcIMS的例子中提供的JS代碼已基本夠用。

下面將分別以ActiveX Connector和.net Link爲例來分析ArcIMS的開發。

使用.net Link

.net Link是使用.net Framework來開發ArcIMS應用程序的API。使用.net Link的步驟爲:

1. 增加.NET Link的程序集引用到項目,程序集位於目錄:
<ArcIMS Installation Directory>/ArcIMS/Connectors/NET_Link

2. 連接到Application Server,可以使用HTTP或者TCP連接,例如下面的代碼建立一個TCP連接:

using ESRI.ArcIMS.Server;
..
ServerConnection connection= new ServerConnection();
connection.Host="localhost";
connection.AppServerPort=5300;
connection.Scheme=Scheme.TCP;

3. 發送一個ArcXML request。

4. 處理返回的ArcXML response。

和HTML下的JS相比,.net Link只是把XML操作使用.net程序集封裝了,並不是一個很面向對象的封裝,還需要開發者處理“機器友好,人類不友好”的XML。這也是筆者對.net Link比較失望的原因。

下面來看看隨ArcIMS一起安裝的.net Link的例子“BlueViewer”。工程的設置,數據安裝,ArcIMS的設置請參考例子目錄下的readme.htm。

設置好以後就可以在瀏覽器中打開這個站點,是一個包括了放大縮小等簡單功能的地圖服務,如下圖所示:



用VS 2003打開工程,其解決方案如下圖所示:



其中的核心是js代碼和MakeMap.aspx這個文件,我們來做一個分析。

程 序的default.aspx中除了界面元素,定義了hvMinX、hvMinY、hvMaxX、hvMaxY、hvMapPage,爲 HtmlControls.HtmlInputHidden類型(表單的隱藏域),前4個對象的值指示當前地圖的範圍,最後一個則用來獲取地圖的url。

在Page_Load過程中,有如下的語句:

hvMapPage.Value = "MakeMap.aspx"

也 就是說,hvMapPage對象的值最終由MakeMap.aspx來返回。我們先看看MakeMap.aspx這個文件。這個文件的邏輯很簡單,在 Page_Load過程中根據地圖範圍發送一個ArcXML請求,並獲得Response,解析這個XML,最終如果成功,則定向到生成的圖片文件 url,或者返回錯誤信息:

If bRequestFailed Then
     ...
Else
     Response.Redirect(imageURL)
End If

這樣,通過重定向,最終由ArcIMS生成的圖片的地址被賦值給default.aspx中hvMapPage的值,我們再回到default.aspx,看這個圖片最終是如何顯示出來的。

在default.aspx中,在頁面的load事件中調用了js函數startUp():

<BODY οnlοad="startUp()" MS_POSITIONING="GridLayout" style="MARGIN: 0px">

startUp()定義在main.js中。在startUp()中通過一系列的初始化,然後顯示Loading圖片(加載地圖的那段動畫),並指定事件:

m_imgMapCanvas.onload = hideWaitImage;

即當m_imgMapCanvas(最終顯示的地圖的圖片)顯示以後,調用hideWaitImage過程,隱藏Loading圖片(NC需要特殊處理)。

最 後調用submit函數。submit函數根據目前的地圖範圍,發送一個submit,這時候,服務器端MakeMap.aspx就會運行,最後把結果 (圖片的url)保存在hvMapPage的值中。我們在default.aspx中也看到,MakeMap.aspx也必須是提交表單後才運行,就是這 個道理。

請求(submit)返回後,替換顯示圖片的url:

m_imgMapCanvas.src = sURL;

而m_imgMapCanvas就是default.aspx中中間顯示地圖的區域,爲一個<img>。

對於NC需要特殊處理以隱藏Loading圖片,對於IE則自動調用hideWaitImage函數來隱藏之。最後調用persistExtent函數把地圖範圍保存在hvMinX等幾個隱藏的表單域中。

這樣,我們就對這個例子的運行機制和過程做了一個縱向的剖析,從中我們也看到,.net或者ASP.net的工作其實很少,僅僅是發送和解析ArcXML請求,地圖的顯示和操作都集中在JS代碼中。

使用ActiveX Connector來開發

ActiveX Connector應該是ArcIMS裏比較成熟的一個API,另外的應該是Java的API。

ArcIMS的例子在Samples的ActiveX目錄下,ActiveX_Samples是使用ASP來操作ArcIMS的一些例子,例如獲得一幅地圖:

Set mConnector = Server.CreateObject("aims.ArcIMSConnector")
mConnector.ServerName = "localhost"   
mConnector.ServerPort = 5300
Set mMap = Server.CreateObject("aims.Map")   
resultInit = mMap.InitMap( mConnector, "SanFrancisco" )
mMap.Width = 500   
mMap.Height = 300
mMap.BackColor = 15130848
urlImage = mMap.GetImageAsUrl()
Response.write "<IMG SRC=" + urlImage + ">"

創建aims.ArcIMSConnector對象,與Application Server的連接,創建Map對象,並與一個Service綁定,然後設置大小,調用GetImageAsUrl返回一個圖片的Url。

ActiveX_Template目錄下有圖層、地圖、選擇操作等一些模版,可以在自己的程序中使用。大多程序都通過Session來保存地圖對象,然後通過該對象來運行。

和.net Link比較,ActiveX Connector是一個比較成熟的API,但由於ASP本身的限制,使用ASP來開發ArcIMS應用的會越來越少。

Ajax及其他

目前流行的地圖應用是Ajax客戶端,比較“老土”的ArcIMS似乎已經很落後了。但如果瞭解現今網絡地圖的基本原理,也瞭解WebGIS的架構和原理,那麼,使用ArcIMS作爲後端,開發一個類似的應用也不是難事。國外已經有人在做了,推薦一個站點:

http://www.mapdex.org/blog/

本文的後續版本也許也會涉及這個話題。

總結

由本文的敘述,我們可以得出下面一些結論:

1. ArcXML,深入編程需要了解ArcXML,因爲很多操作必須自己寫ArcXML來請求Application服務器,特別是對於.net Link這樣的API;

2. JavaScipt,其實對於所有的WebGIS開發,這點都必不可少;客戶端操作,自定義的操作,和其他應用在UI的集成,都需要使用JS。

3. 服務器端開發技術,需要的不多,大概看看書就可以照貓畫虎了。

4. 由於目前ESRI的主要精力在ArcGIS系列上,因此ArcIMS下一版本的.net Link等是否會得到加強,目前還不得而知。

5. 對於.net運行時,1.1和2.0筆者使用好像都可以,畢竟只是一個程序集的事情,而且要做的事情不多,估計是兼容的。

6. 最後,ESRI的很多產品,由於其歷史“悠久”和用戶衆多,因此尋找有關問題的答案還是很容易的,只要可以上網,有Google可用,大多問題都有答案。 
發佈了27 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章