ArcGIS學習(五)OpenLayers呼叫WMS服務
OpenLayers:
OpenLayers是一個開源的js框架,用於在您的瀏覽器中實現地圖瀏覽的效果和基本的zoom,pan等功能。OpenLayers支援的地圖來源包括了WMS,GoogleMap,KaMap,MSVirtualEarth等等,您也可以用簡單的圖片作為源,在這一方面OPenLayers提供了非常多的選擇。
WMS服務:
1 OGC組織及其開放性規範
為了實現異構的地理空間資訊及GIS處理功能的互操作的整合,OGC(Open GIS Consortium)一直致力於尋求一種方式,將地理資訊系統技術、分佈處理技術、面向物件技術、資料庫設計以及實時資訊處理方法有效地結合起來,實現分散式異構平臺上GIS互操作[2]。OGC制定了開放地理資訊互操作規範(OGIS),試圖通過共同的開放地理資料模型(OGM)和OGIS參考模型(ORM)來實現互操作。其目的是希望提出一個可擴充套件的、基於各種標準的、能無縫整合各種線上空間處理和位置服務的框架,使得分散式空間處理系統能通過XML和HTTP技術進行互動,併為各種線上空間資料資源,來自感測器的資訊、空間處理服務和位置服務和基於Web的發現、訪問、整合、分析、利用和視覺化提供互操作框架[3]。
OGC的中心主題是共享資訊和提供服務,在OGC的抽象規範中共有17個主題,其中主題12是開放式Web Services空間資訊服務框架[4,5],它包含一系列的抽象規範和實現規範。概括地來講,OGC OpenGIS Web Services(OWS)包括三個主要的地理資訊服務即Web Map Service(WMS)、Web Feature Service(WFS)和Web Coverage Service(WCS)。除此之外,還包括Simple Feature Specillcation(SFS),Geography Markup Language(GML)等。
2 WMS規範及其實現過程
2.1 WMS規範
OGC WMS屬於OGC圖示表達服務,它利用具有地理空間位置資訊的資料製作地圖。在WMS規範中將地圖定義為地理資料可視的表現,WMS返回的不是地圖資料,而是地圖影象。WMS規範定義了三個操作[6]:
●GetCapabilities操作返回服務級元資料,它是對服務資訊內容和請求引數的一種描述,元資料使用XML形式檔案表示。
●GetMap操作根據客戶端發出的請求引數在服務端進行檢索,伺服器端返回一個地圖影象,其地理空間引數和大小引數是已經明確定義的,返回的地圖影象可以是GIF、JPEG、PNG或SVG格式。
●GetFeaturelnfo操作根據使用者所請求的X、Y座標或感興趣的圖層,返回地圖上某些特殊要素的資訊,資訊以HTML,GML或ASCII的格式表示。
2.2 WMS的具體實現過程
在WMS的三個操作中,GetCapabilities和GetMap是必須要實現的,而GetFeaturelnfo是可選的,下面介紹這三種操作的具體實現過程。
WMS的請求與響應是在客戶端和伺服器端實現的,客戶端既可以是普通的瀏覽器,也可以是應用系統或元件。圖1是一個用UML時序圖描述的客戶端與伺服器端的互動過程。
客戶端通過HTTP協議向伺服器端傳送請求並完成空間資料的視覺化。伺服器端要響應三種基於URL的請求,即GetCapablilties、GetMap和GetFeaturelnfo。客戶端接收GIF,JPEG,PNG格式的影象檔案或XML格式的元資料檔案、GML檔案。
圖1 客戶端與伺服器端的互動過程
Fig. 1 Process of interaction between client and server
客戶端在請求一個Web地圖服務之前,必須瞭解WMS伺服器所能提供地圖的相關資訊,這些資訊包含在地圖元資料檔案中。在OGCWMS規範中,通過傳送GetCapabilities請求獲得描述伺服器端所能提供服務的元資料,例如,使用者可以通過瀏覽器傳送下列請求獲得XML文件:
http://localhost:8080/query Capabilities?REQU EST=GetCapabilities & VERSION=version&SERVICE=WMS。
元資料是以XML文件的形式返回的。XML文件中提供的資訊包括:WMS伺服器支援的所有功能介面列表;所能提供的影象格式;從伺服器端傳送地圖資料的可用的空間參照系列表;從伺服器端返回的所有異常的列表;特定與某一軟體商的WMS伺服器修改和控制功能的專用元資料的列表;某一WMS伺服器的可用圖層及可選屬性的列表;該WMS是否支援可選的GetFeaturelnfo操作等。
客戶端解析元資料描述文件,從中檢索到需要的資訊,然後發出下面格式的GetMap請求,http//localhost:8080/deegeewms? SERVIC
E=WMS&REQUEST = GetMap&LAYERS = layers&STYLES=styleS&FORMAT = format &sRS=coordinate-system&BBOX=bounding_box&WIDTH = width & HEIGHT=height
WMS伺服器處理來自使用者的請求,通過訪問資料庫或檔案獲得需要的資料,以影象的方式返回給使用者請求的地圖,格式可以為JPEG、PNG、GIF或SVG。
由於每一個GetMap請求將返回對應一個地圖的一個或多個圖層。多個圖層在構成一個新的地圖時就有可能相互覆蓋,解決方法就是將它們設定成透明的。使用者不僅可以請求單個WMS伺服器上的多個圖層,也可以向多個WMS伺服器發出請求,由於每一個伺服器有不同的元資料描述檔案,客戶端就需要向每一個WMS伺服器傳送Get Captilities請求獲取各自不同的元資料描述文件,當用戶選擇的圖層分別位於不同的WMS伺服器上時,每一個伺服器將返回一個或多個圖層,這些圖層有可能使用不同的座標參照系、顯示範圍等引數,只有引數相同的圖層才可以進行疊加。
選定地圖上的某一點,通過傳送GetFeaturelnfo請求可以獲得該區域的更詳細的資訊,WMS伺服器的響應將是以下三種格式的一種,GML格式、文字格式和HTML檔案。由於GML是基於XML的,所以客戶端可以通過程式設計的方式解析GML檔案,轉化為可以在瀏覽器上顯示的SVG向量格式。
3 基於WMS的體系結構及實現過程
圖2 WMS應用例項體系結構框架
Fig. 2 The architecture of WMS instance
由於WMS規範從語義和語法兩個角度詳細定義了WMS伺服器向客戶程式提供的操作介面,所以它提供了規範化網路空間資訊系統的能力。所有遵循該規範的伺服器都可以被客戶端訪問。同所有基於Web的應用程式一樣,OGCWMS規範可以有多種實現方式。三層或多層體系結構由於可以對顯示層、業務邏輯層和資料層進行邏輯上和物理上的分離,便於系統的維護和升級,最大程度地減少了系統間的耦合,成為構建基於Web的應用系統的首選。本文設計了一個基於開源WMS伺服器的三層結構的WMS應用框架,即WMS客戶端、WMS伺服器端和資料來源端。其體系結構見圖2OpenLayers呼叫WMS服務:
影象的載入是採用的螺旋式載入。首先從右上角開始按照順時針方向給整個img矩陣建立一個堆疊,其實質是按照堆疊先進後出思想設計的一個數組,然後按堆疊中的位置順序從視窗中間開始逆時針方向依次載入柵格影象。
整個img矩陣構成一個grid格網,當移動地圖使得grid的範圍[即bound值]不能包含視窗的bound,或者地圖的顯示比例發生變化時會重新向伺服器請求資料,否則只會移動各個img的位置,從而使得視窗在grid之內。
客戶端用於柵格圖顯示的img數量是由計算得到的。使用者指定的用於顯示的div作為視窗,視窗大小除以每張img的長寬得到一個m*n的矩陣,表示要填滿整個視窗在長寬方向所需的最少的img數量,然後將Img長寬方向都快取兩個img得到一個(m+2)*(n+2)的矩陣,即為客戶端img數,預設快取為兩格,當然我們也可以將快取數作為引數傳入以改變快取預設值buffer,那麼改動之後的矩陣為(m+buffer)*(n+buffer)。
在移動的時候取grid網格中左上角那個tile的左上角座標值,即grid[0][0]為參考點,當這個點的座標超出閾值的時候會搬動grid中各個節點的位置。
這裡的img在openlayers中其實已經被封裝成了Tile類,該圖層有一個div作為容器。每個image都有一個div將其包裝起來,tileSize是按照OpenLayers.TILE_WHITH,OpenLayers.TILE_HEIGHT常量事先就定義好了,表示每個tile例項的大小。
柵格圖形顯示之提供了基於標準的WMS呼叫的,即只要伺服器端提供了標準的WMS服務,客戶端就可以呼叫到。由於OpenLayers的螺旋載入功能是和最底下的一層分開的,因此我們可以在最底層擴充套件自己的柵格地圖呼叫類,即讓自己的類繼承自OpenLayers.Layer.Grid,在我們自己的類中重構getURL方法。但是,這也有個弊端,那就是我們依然很大程度上繼承了OpenLayers的柵格呼叫方法,這種方法具有很高的重用性,非常利於擴充套件,但是不一定會帶來高的效率。
舉個例子:我們需要自己的呼叫方式,伺服器端提供的柵格圖金字塔一共有17級,整個顯示範圍是-180,-90,180,90,第零級每張柵格圖經緯度方向上的跨度都是18度,隨著級數升高經緯度方向上的跨度相比前一級都減半,柵格圖採用的是格網座標,座標原點在左上角。我們自己的呼叫方式有一部分和WMS柵格圖呼叫相同。當移動或者縮放的範圍超出閾值的時候會向伺服器傳送請求,我們根據每個Tile的經緯度範圍計算得到該柵格圖中心點的經緯度座標,而根據當前經緯度可以知道該解析度下伺服器端柵格圖矩陣,然後再根據該解析度下柵格圖的經緯度跨度得到Tile在伺服器端提供的柵格圖上所處的位置,從而取到該圖。從伺服器端過來的柵格影象每張大小為256*256畫素。這個過程是很我重新寫過的,基本繼承了OpenLayers的WMS呼叫的核心思想,當然效率也不會有改進。
其實我們完全可以讓自己的柵格顯示類直接繼承自OpenLayers.Layer,這樣一方面利用了OpenLayers圖層操作的框架,令一方面又最大程度上放棄了OpenLayers帶來低效率的機制。經過本人試驗,雖然做了這個改進,但是最終的效果也沒有很明顯的改進,原因容後續分析。
該部分主要包含4個類:
OpenLayers.Layer,OpenLayers.Layer.HTTPRequest,OpenLayers.Layer.Grid,OpenLayers.Layer.WMS,它們的繼承關係如圖所示: