Web地圖服務、WMS 請求方式、網路地圖服務(WMS)的三大操作
1、GeoServer(地理資訊系統伺服器)是 OpenGIS Web 伺服器規範的 J2EE 實現(geoserver只能用j2ee開發),利用GeoServer 可以方便的釋出地圖資料。GeoServer的主要特徵包括:相容 WMS 和 WFS 特性;能夠將網路地圖輸出為jpeg、gif、png、SVG、KML等格式;能夠執行在任何基於 J2EE/Servlet 容器之上。其安裝方式有兩種,一種是常見的.EXE安裝,這種安裝方式最簡單,只要確保你電腦上安裝了JDK並且8080埠是開的,按照安裝步驟一步一步來就可以完成安裝,安裝完成以後,可以從開始選單中選擇GeoServer-> Start GeoServer進行啟動,啟動服務後,開啟瀏覽器,輸入http://localhost:8080/geoserver/就可以檢視到GeoServer的歡迎介面了。另一種安裝是以.WAR的形式安裝,開發者電腦上得先安裝有Tomcat,然後將此WAR匯入即可。
Geoserver是一個功能齊全,遵循OGC開放標準的開源WFS-T和WMS伺服器。利用Geoserver可以把資料作為maps/images來發布(利用WMS來實現)也可以直接釋出實際的資料(利用WFS來實現),同時也提供了修改,刪除和新增的功能(利用WFS-T)。 GeoServer, 顧名思義,是一個Server. 它是開源的 ,允許使用者檢視和編輯地理資料。GeoServer能夠釋出的資料型別:
(1)地圖或影象——應用WMS
(2)實時資料——應用WFS
(3)使用者更新、刪除和編輯的資料——應用WFS-T。
GeoServer 是您需要顯示地圖在網頁的那些工具的當中一個,使用者可以縮放並且移動。可以與一些客戶端聯合使用,比如: MapBuilder(for web pages), UDig, GVSig,等等。 對標準的使用允許資訊從GeoServer 到其它地理資訊可以很容易地被結合。
2、Web地圖服務(WMS):利用具有地理空間位置資訊的資料製作地圖,其中將地圖定義為地理資料可視的表現,地圖本身並不是資料。地圖通常以影象格式表達,例如PNG,GIF或是JPEG,有時候也表達為基於向量圖形,如可縮放向量圖形(SVG)或是網路電腦圖形元檔案等格式(WebCGM)。根據OGC規範,地圖服務是專門提供共享地圖資料的服務,負責根據客戶程式的請求,提供地圖影象、指定座標點的要素資訊、以及地圖服務的功能說明資訊。
WMS規範定義了三個介面(操作):GetCapabilities(獲取服務能力), GetMap(獲取地圖)和GetFeatureInfo(獲取物件資訊)。其中GetMap為核心操作。GetCapabitities返回服務級元資料,它是對服務資訊內容和要求引數的一種描述;GetMap返回一個地圖影像,其地理空間參考和大小引數是明確定義了的;GetFeatureInfo(可選)返回顯示在地圖上的某些特殊要素的資訊。這個規範還定義了一個用於呼叫上述操作的全球資訊網統一資源定位器(URL)語法和服務級元資料的XML(可擴充套件標記語言)表達法。
3、WMS 請求方式: WMS 支援標準 HTTP 中標準的 GET 請求和 POST 請求方式,不過對於 WMS 來說,基本都是基於 GET 方式的服務請求,而且 OGC 官方提供的相容性測試中也都是基於 GET 方式的請求。
OGC網路服務明確支援的唯一的分散式計算平臺(DCP)就是是全球資訊網本身,更明確地說是實現了超文字傳遞協議(HTTP)的網路主機。因此,每個由服務例項支援的各操作的線上資源都是一個HTTP的統一資源定位器(URL)。HTTP支援兩個請求方法:GET和POST,一個基本的WMS規範僅僅定義用來呼叫操作的HTTP GET。URL規範保留了一些特定的字元並賦予它們必要的意義,如下表1,
表1 HTTP GET查詢中的保留字元
字元 |
用 途 |
? |
查詢語句開始的分隔符 |
& |
查詢語句引數之間的分隔符 |
= |
引數名字和引數值之間的分隔符 |
/ |
格式引數值中MIME型別子型別之間的分隔符 |
: |
SRS引數值中名稱空間和標識之間的分隔符 |
, |
清單型引數中單個值的分隔符(例如GETMAP請求中的BBOX,LAYERS和STYLES) |
用於HTTPGET請求的線上資源URL事實上僅僅是一個URL字首,為了建立一個有效的操作請求,在其後還添加了另外的引數。URL字首被定義為一個不透明的字串,它包括協議、主機名、埠號(可選)、路徑、和一個問號“?”,還可以包括一個或幾個用於具體伺服器的引數並以“&”結束。
表2總結了操作請求URL的各個構件:
表2 普通OGC網路服務請求
URL 構件 |
描 述 |
http://host[:port]/path?{name[=value]&} |
服務操作的URL字首。[ ]表示可選擇0個或1個事件;{}表示0個或更多的事件。字首完全取決於服務提供者。 |
name=value& |
由OGC網路服務定義的一個或更多的標準請求引數的名稱和數值對。對於每個操作,相應的的OWS規範都規定了請求中使用的必選和可選引數的實際列表。 |
4、網路地圖服務(WMS)的三大操作
(1)GetCapabilities(必選)
(瀏覽器會返回提示開啟或儲存一個檔案,我的機器返回的是一個叫“wms”的檔案,沒有副檔名。沒關係我們把它儲存為“wms.xml”就可以了)
GetCapabilities請求返回的是一個對於WMS服務的一個元資料的描述,其中包括有當前服務提供商的一些基本資訊以及當前服務的一些能力,而對於使用WMS服務的客戶端來說,能獲取到的所有資訊全部包含在此文件中,當客戶端傳送一個服務中沒有提供的的圖片格式時,此時服務端將沒有能力處理此請求。在使用WMS服務時需要確認當前服務提供的能力,以便在使用過程中發生一些不必要的麻煩。
GetCapabilities 介面用於向客戶端提供當前地圖伺服器可以提供的空間資訊型別和範圍、具體的圖層資訊和顯示樣式、支援的查詢方式、沒有查詢結果時(異常)的預設返回資訊格式等服務描述資訊。
GetCapabilities 請求URL的引數
請求引數 |
必選(M)/可選(O) |
說明 |
VERSION=version(Version ( 版本 )=(1.1.1 或者 1.3.0) ) |
O |
請求版本,URL 中可選的請求引數,當沒有使用時就使用當前服務提供商提供的最高的 wms 版本服務 |
SERVICE=WMS |
M |
服務型別 |
REQUEST=GetCapabilities |
M |
請求名,請求中必須設定當前請求的操作,可以設定 request 的值為 Getcapabilities 、 GetMap 、 GetFeatureInfo |
FORMAT=MIME_type |
O |
服務元資料的輸出格式 |
UPDATESEQUENCE=string |
O |
用於控制緩衝儲存的數字序列或字串 |
(2)GetMap(必選)
GetMap 介面的目的在於請求伺服器生成一幅具有確定地理位置座標範圍的地圖影象。但按照WMS規範,這個操作需要明確地指定出操作本身遵循的WMS規範的版本號以及需要顯示的具體圖層、對應的座標範圍、返回影象的大小和格式等。
GetMap請求的引數
請求引數 |
必選的(M)/ |
說 明 |
VERSION=version |
M |
請求版本. |
REQUEST=GetMap |
M |
請求名稱. |
LAYERS=layer_list |
M |
以逗號隔開的一個或多個圖層列表,若存在SLD引數則是可選的。 |
STYLES=style_list |
M |
以逗號隔開的請求圖層的一個再現風格列表,若存在SLD引數則是可選的。 |
CRS=namespace:identifier |
M |
座標參考系。 |
BBOX=minx,miny,maxx,maxy |
M |
以SRS單位表示的邊界框邊角 (左下角,右上角)。 |
WIDTH=output_width |
M |
以畫素表示的地圖影象寬度。. |
HEIGHT=output_height |
M |
以畫素表示的地圖影象高度 |
FORMAT=output_format |
M |
地圖輸出格式。. |
TRANSPARENT=TRUE|FALSE |
O |
地圖背景的透明性 (default=FALSE). |
BGCOLOR=color_value |
O |
以十六進位制RGB顏色值表示的背景顏色(default=0xFFFFFF). |
EXCEPTIONS=exception_format |
O |
WMS通告異常的格式 (default=SE_XML). |
TIME=time |
O |
請求層的時間值。 |
ELEVATION=elevation |
O |
請求層的高程。 |
Other sample dimension(s) |
O |
其它適當維度的值。. |
Vendor-specific parameters |
O |
可選的實驗性引數。. |
下列引數只用於支援格式化層描述符規範的網路地圖服務 [3]. |
||
SLD=styled_layer_descriptor_URL |
O |
格式化層描述符的URL(如同SLD規範中確定的). |
WFS=web_feature_service_URL |
O |
網路要素服務URL,該服務提供將要用SLD進行符號化的要素。. |
注:在LAYERS引數值和STYLES引數值之間存在一個一一對應關係
對GetMap的響應:
對有效的GetMap請求的響應必須是一張地圖,它包含了所請求的具有地理參考座標的資訊層,使用的是期望的樣式,並且採用了指定的空間參照系、範圍框、大小和透明性。一個無效的GetMap請求必須產生一個按請求的Exceptions格式輸出的錯誤資訊(或在極端情況下回答一個網路協議錯誤)。
(3)GetFeatureInfo(可選)
GetFeatureInfo是一個可選操作。該操作向WMS的客戶端程式提供了進一步查詢特定空間實體資訊的能力。這種操作往往是由客戶程式在WMS伺服器先前返回的地圖上指定了一個空間實體,進而提交查詢而形成。支援GetFeatureInfo操作的僅僅是那些定義或繼承了屬性queryable=“1”的層。對於其它層,客戶端不能傳送GetFeatureInfo請求。如果一個WMS不支援該請求而遇到了它,則應該應答一個適當格式的服務異常。
GetFeatureInfo請求引數
請求引數 |
必選(M)/ |
描述 |
VERSION=version |
M |
請求版本。 |
REQUEST=GetFeatureInfo |
M |
請求名稱。 |
map request part |
M |
地圖請求引數的部分拷貝,這些引數產生了需要查詢其資訊的地圖。 |
QUERY_LAYERS=layer_list |
M |
用逗號分隔的需要查詢的一個或多個層的列單。 |
INFO_FORMAT=output_format |
M |
要素資訊的返回格式(MIME 型別)。 |
FEATURE_COUNT=number |
O |
需要返回其資訊的要素個數(default=1)。 |
X=pixel_column |
M |
用畫素表達的要素的X座標 (以左上角座標為0)。 |
Y=pixel_row |
M |
用畫素表達的要素的Y座標 (以左上角座標為0)。 |
EXCEPTIONS=exception_format |
O |
WMS報告異常資訊採用的格式(default=application/vnd.ogc.se_xml)。 |
5、三大操作的樣例
(1)GetMap請求類似於在Web上請求一幅影象,但它的請求引數更加複雜。下面是一個樣例請求:
返回的影象如下圖所示:
>
其中:
http:// —— 使用的網路協議
webmapping.mgis.psu.edu/ —— 主機域名
geoserver/wms —— 頁面或web程式位置
version=1.1.1 —— WMS版本號
request=getmap —— 操作動詞,可以為GetCapabilities, GetMap和GetFeatureInfo等
layers=topp:states —— 請求地圖所包含的圖層名,可以為多層
styles=population —— 指定圖層繪製的樣式名
SRS=EPSG:4326 —— 指定地圖的座標投影系統程式碼
bbox=-125,24,-67,50 —— 請求地圖的範圍(The Bounding Box)
width=400 —— 地圖的畫素寬度
height=200 —— 地圖的畫素高度,寬度和高度的不同設定可能會引起返回影象的變形
format=image/png —— 返回地圖影象的格式,可以為Image/gif, image/jpg, image/svg+xml等等
如果引數設定錯誤,將返回一個XML檔案來描述錯誤資訊。如下所示:
<ServiceExceptionReportversion="1.1.1">
<ServiceException code="">
WIDTH and HEIGHT incorrectly specified
</ServiceException>
</ServiceExceptionReport>
(2)GetCapabilities請求的樣例如下所示:
返回的是一個XML檔案(檔案很大,內容略),包括Service、Capability等部分,詳細資訊可以檢視返回XML檔案。
把這個文件去頭去尾以後留下兩個節點Service和Capability。 Service包含了有關伺服器的一般特性資料,對於只是想直接使用WMS伺服器的人來說,這個節點還不太用得上,唯一值得注意的就是KeywordList節點,它裡面是關鍵字,也就是伺服器的保留字。 Capability才是我們學習的重點。如果你想正確的使用WMS伺服器,這個節點裡面的內容就必須搞清楚了。你可以從這個節點獲得如下資訊:
1)伺服器支援哪些方法,WMS伺服器必須支援GetCapabilities和GetMap,此外還有許多擴充套件的方法。
2)伺服器支援哪些返回格式,WMS返回的地圖都是渲染好的圖片,因此這裡的格式基本上都是圖片格式,如image/png。
3)伺服器釋出了哪些圖層,這個是WMS的重點,不然你連最簡單的GetMap呼叫都構造不出來。
(3)GetFeatureInfo用於查詢螢幕某點的物件資訊,它的樣例請求如下所示:
此請求返回一個HTML文件來描述物件,如下所示:
Results forFeatureType 'states':
--------------------------------------------
the_geom = [GEOMETRY(MultiPolygon) with 153 points]
STATE_NAME = Arizona
STATE_FIPS = 04
SUB_REGION = Mtn
STATE_ABBR = AZ
LAND_KM = 294333.462
WATER_KM = 942.772
PERSONS = 3665228.0
FAMILIES = 940106.0
HOUSHOLD = 1368843.0
MALE = 1810691.0
FEMALE = 1854537.0
WORKERS = 1358263.0
DRVALONE = 1178320.0
CARPOOL = 239083.0
PUBTRANS = 32856.0
EMPLOYED = 1603896.0
UNEMPLOY = 123902.0
SERVICE = 455896.0
MANUAL = 185109.0
P_MALE = 0.494
P_FEMALE = 0.506
SAMP_POP = 468178.0
要注意的是不同規範版本對上述請求的引數規定不同,如WMS1.3對於GetFeatureInfo的X、Y引數要求使用經緯度。所以我們必須根據伺服器的WMS版本來設定我們的引數。
6、實現一個C#版本的WMS瀏覽器
(1)WmsBrowser需求
1)、使用者輸入WMS伺服器的URI,點選一個按鈕呼叫GetCapabilities方法。然後用返回的資料初始化控制介面。 使用者在控制介面上可以檢視伺服器的各種Capability資料,並且可以選擇要顯示的圖層,調整圖層順序 ,為圖層設定引數,然後返回一個地圖圖片顯示在預覽區。
2)、使用者可以把返回的圖片儲存成檔案。
已經有許多支援WMS的客戶端了,有許多程式碼可供學習和使用。但是,為了不干擾視線,為了避免介紹多餘的內容,為了體現“自主創新精神”,最重要的是為了體驗程式設計的樂趣(這也是我當初進入這個行業的原因),我決定只使用NotNet標準庫提供的類完全從頭開始編寫程式碼。
(2)WmsBrowser設計
根據需求,這是一個WinForm的執行程式。需求其實很不明確,完全沒有說明最重要的部分,控制介面是什麼樣子的,使用者如何使用它。所以有必要補充一下了。
控制介面有兩個功能:
1)檢視GetCapabilities返回的資料;
2)設定GetMap需要的呼叫引數。
我們可以據此來設計這個介面。GetCapabilities返回的資料我們前面已經介紹過了,想象一下我們這款軟體的潛在使用者可能想要看到哪些資料,他們會如何使用這些資料。首先肯定是伺服器釋出的圖層,這是訪問WMS的唯一原因。至於伺服器支援哪些呼叫應該不是他們關心的,而是我們開發者關心的。所以我們需要在介面上顯示出Layer的內容,由於Layer是巢狀的,自然而然我們需要一個樹控制元件。
除了Layer的Name,Title,Abstract這些屬性外,使用者應該還需要知道Layer支援的SRS,Style,Format和BoundingBox。這樣他們才能構造出合理的呼叫引數。我們顯然不應該讓使用者檢視完資料後手動構造呼叫引數,我們需要讓使用者很方便的用滑鼠完成工作。我們已經知道需要一個樹控制元件來顯示Layer資訊。然後我們需要提供構造呼叫引數的介面。首先我們設想使用者可能會如何完成這個工作。
上面的介紹中我們一直是手動敲入字串來完成呼叫URI的構建的,繁瑣而且容易出錯,但是這種方法很靈活,所以應該保留。於是我們需要一個TexBox來輸入URI。然後我們需要一個按鈕來發出GetMap請求。我們必須考慮到,有相當一部分人並不善於鍵盤操作(其中包括我),所以我們應該給他們提供滑鼠操作模式。於是第二個介面出現了,使用者在這裡使用滑鼠選擇想要顯示的Layer,調整Layer顯示的順序,選擇每個Layer的Style,選擇Format,選擇SRS,輸入BoundingBox,輸入返回圖片的尺寸。然後同樣點選上面提到的按鈕,發出GetMap請求。更進一步,我們可以用上面的介面來獲得一個基本的呼叫引數,然後到TextBox裡面去微調,這樣使用者會獲得更好的靈活性。
好了,到這裡我們基本上搞清楚控制介面的樣子了。現在需要討論一點設計風格方面的問題。我們可以把所有程式碼寫進一個叫MainForm的類裡面,它是一個WinForm類。這樣沒有錯,完全可以工作,實際上我見過的大部分程式碼都是這麼幹得。這樣做的結果是,我很快就會放棄這個專案,轉而去瀏覽cnblog或ifeng上面的帖子。我們需要一個更好的設計。我們在這裡並不是要討論架構,模式和開發方法,所以我們只需要達成一個共識就可以了: 我們需要把介面元素,操作響應以及資料模型分開編碼,為他們單獨建立類體系。
據此我們的設計也就差不多了,開始編碼咯。
WmsBrowser編碼ing。。。
程式完成。
啟動程式後會看見主介面如下: 下圖是返回的地圖
這個程式還很稚嫩,有許多問題沒有考慮,例如:輸入驗證,資料驗證,異常處理等。以後我們會逐步完善它,目前作為一個參考和學習WMS的起點已經足夠了。
(3)後續
在使用這個程式時,作為使用者,我覺得還有很多不方便的地方。首先,我如果敲錯了地址,我很容易敲錯,程式會彈出一個醜陋的異常對話方塊,顯示一大堆堆疊資訊,完全看不出是什麼錯誤。其次,設定引數BBox很不方便,如果能從已有的地圖上用滑鼠選擇就好了。還有,返回時只是顯示一個圖片想看細節又要重複設定,Apply,GetMap的操作,太繁瑣了。