應用ArcIMS構建Google Map風格的地圖應用

Google Maps之前,各種 網絡 地圖 技術 上採用傳統 WebGIS 的方式,使用Java Applet、SVG、動態生成地圖圖片,而Google Maps採用 Ajax 和瓦片拼接方案構建出的新的網絡地圖模式得到了廣泛認同,一時間, 電子地圖 服務的網站,除了少數外,幾乎都採用或提供了這種模式的瀏覽方式。那麼,傳統的WebGIS是否也可以通過某種方式支持類似的地圖 應用 呢,答案是肯定的。

上一篇關於 ArcIMS 的文章中提到了Mapdex使用ArcIMS和 GMap 的API構建GMap風格的網絡地圖,但需要使用GMap的API,本文則介紹一種無須使用任何API的解決方案。

要構建GMap風格的網絡地圖,首先需要有一個類似GMap風格的JS庫,作爲客戶端;其次是如何使該客戶端和ArcIMS連接起來,如何緩存圖片等等。本文是在以下基礎上構建的:

  • MapEasy,一個國人寫的網絡地圖JS庫,可以在mapeasy.sf.net下載,不過該庫好像很久沒有更新了,比較可惜。類似的JS庫還有不少,但沒有相對完整、可用的。
  • 來自Maplex的一段連接GMap API和ArcIMS的ASP程序,本文的程序是在這段程序的基礎上修改而來的。

以下是運行截圖:



讀者可以 下載 試用,地址:

http://www.3snews.net/html/95/295_itemid_2823.html

使用前需要修改config.asp文件中的有關參數:

ArcIMSServer        = "localhost"               ' 服務器
ArcIMSServerHost    = 5300                      ' 端口
MapService          = "BlueViewer"              ' 地圖服務

MapImageWidth       = 256                       ' 輸出地圖的大小

' 地圖的範圍
MapXMin             = -130
MapXMax             = -50
MapYMin             = 0
MapYMax             = 70   

ImageType           = "png"                    ' 輸出類型
CacheName           = "test"                   ' 緩存名稱
CacheDir            = "E:/Documents/ArcIMS/GMap/img/"        ' 緩存路徑


然後在瀏覽器中打開瀏覽即可。

需要說明的是,由於客戶端的JS代碼默認的範圍是(-180,180,-90,90),因此,按照經緯度座標加上去的標註返回位置不對,需要進行校正。

下面簡單說一下運行機制:

在html文件中,創建一個地圖的JS代碼:

function IMSMapType() {

    MapType.apply(this);

    this.getSrc = function(level, row, column) {
        return "arcims.asp?z="+level+"&x="+column+"&y="+row
    }
}
MapModel.mapTypes = new Array(new IMSMapType());
MapModel.maxZoomLevel=10


這段代碼創建了一個地圖類型,也可以創建多種地圖類型(類似GMap),其中getSrc函數定義瞭如何返回圖片的方法,其中有3個參數:縮放比例、橫向位置和縱向位置。而在MapEasy這個庫中,不同縮放級別的圖片是按照類似二維數組的下標方式拼接的。

例如縮放比例爲2(4(22)幅拼接圖片):

0,0  1,0
0,1  1,1

縮放比例爲3(8(23)幅拼接圖片):

0,0  1,0  2,0  3,0
0,1  1,1  2,1  3,1
0,2  1,2  2,2  3,2
0,3  1,3  2,3  3,3

也就是說,從左上角依次增加數值,然後調用arcims.asp,根據位置參數和縮放比例,將地圖縮放到相應的位置(縮放比例),返回圖片就可以了。

在arcims.asp 中,主要的程序流程就是(下圖),首先根據圖片的位置參數,構建圖片名,然後判斷是否存在,如果存在,則返回之,否則調用ArcIMS渲染並保存圖片。其 中返回圖片沒有使用重定向到圖片,而是通過寫數據流的方式來做的(類似ASP中上傳文件保存到數據庫,然後返回給客戶端的做法)。



如果判斷圖片在緩存存在的執行流程爲:1,2,3,7;判斷圖片在緩存不存在的執行流程爲:1,2,4,5,6,7。所以,每個縮放比例的圖片在ArcIMS中只渲染一遍,因此可以大大提高運行效率。

其中如何獲取一幅地圖的代碼如下:

if isObject(Session("IMSGmapMapObj")) then
    Set mMap = Session("IMSGmapMapObj")
else
    call InitMapServer()
end if 

set mLayers    = mMap.Layers

'計算地圖範圍,獲得寬度
Dim MapWidth1, MapWidth2
MapWidth1 = MapXMax - MapXMin
MapWidth2 = MapYMax - MapYMin
If MapWidth1 < MapWidth2 Then
    MapWidth = MapWidth1
Else
    MapWidth = MapWidth2
End if

Dim mExtent      
Set mExtent  = Server.CreateObject("aims.Envelope")
mExtent.XMin = MapWidth / (2^(z-1)) * x + MapXMin
mExtent.YMin = MapWidth / (2^(z-1)) * (2^(z-1) - y - 1) + MapYMin
mExtent.XMax = mExtent.XMin + MapWidth / (2^(z-1))     
mExtent.YMax = mExtent.YMin + MapWidth / (2^(z-1))      
mMap.DoZoomToExtent mExtent     

mMap.Refresh                                           
OUT_IMAGEURL     = mMap.GetImageAsUrl()


首先獲得地圖對象(如果沒有緩存在Session,則初始化服務器),然後計算範圍,根據參數返回範圍內的地圖路徑。

地圖保存後,通過Response.BinaryWrite向瀏覽器端發送,這種方式可以保護圖片,例如可以將圖片保存在通過Web服務器無法直接訪問的地方,在返回圖片時進行身份驗證。

ps:

目前對於大多數開發者,最缺乏的是一個可用的、功能齊全的JS前端,MapEasy提供了基礎的功能,如果可以在這基礎上繼續完善,是一件不錯的事情。MapTools下的Kmap也是一個類似的東西,但由於和PHP綁定比較死,要在其他環境使用還需要一些工作。

通過透明圖層疊加,或者在渲染端做一些工作,可以使類似應用增加圖層功能,這樣就可以用於比較專業的領域。 
發佈了27 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章