文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/。
1.前言
在第七章里我們知道了WebGIS中要素的本質是UIComponent,而矢量圖層的本質是包含了n(n>=0)個UIComponent的Canvas。我們在UIComponent的graphics中,根據矢量數據畫出矢量的形狀(shape),並且將矢量數據的屬性(attributes)賦予該UIComponent。
在接下來進行要素和矢量圖層的設計前,我們有必要了解這四個問題
(1)矢量數據是什么?
(2)矢量數據從何而來?
(3)矢量數據如何組織的?
(4)矢量數據得到后如何使用?
在這一章里,我將着重回答第1、2、3個問題,第四個問題涉及到一些算法知識,我們將專門在下一章進行講解。
2.矢量數據的本質
矢量數據跟一般性數據最大的差別在於矢量數據是包含了空間(geometry)信息的。我們知道要素是由有序的空間坐標連接組成,而這個空間信息中便包含了該序列坐標。如果geometry為空,說明此要素不存在。同時矢量數據還包含一般性數據所有的信息,即屬性數據。不過屬性數據並不是必須的,只要geometry信息存在,attributes信息沒有,要素也是同樣存在的。
3.矢量數據的來源
我將矢量數據的來源分為兩種:
(1)非向后台請求獲得。
這些數據是已經存在於前台代碼中,或者由第三方調用者通過參數在前台調用我們系統時本身通過參數傳遞進來。
(2)向后台請求獲得。
向后台請求獲得又要分為兩種:
a.向業務服務器請求獲得。
b.向地圖服務器請求獲得。
向業務服務器請求獲得矢量數據跟一般的請求並沒有區別,業務服務器只要按照一定的規范,組織好矢量數據,返回即可。本章的重點是向大家介紹后者,如何向地圖服務器請求矢量數據。
3.1通過ArcGIS Server獲得矢量數據
3.1.1 AGS中幾種服務的介紹
在我們發布地圖服務時,如果勾選了Mapping(必須勾選),我們將能發布一個MapServer服務。當然,我們的AGS還能發布多個其他種類服務,比如NAServer、GeometryServer、FeatureServer、GPServer。其中NAServer可以用來進行路徑分析,GeometryServer服務中包含了一系列拓撲操作的服務,FeatureServer可以用來進行要素編輯,GPServer則可以利用發布的模型來進行復雜的空間操作。下面兩張圖分別是10.0中發布的幾種服務,以及Geometry服務中提供的一些功能(在10.1和10.2中Geometry服務的默認地址有變化)。
這一章里,我主要講的是MapServer中的Query服務。其他服務在我們以后的功能設計模塊中,如果涉及,會跟大家再一起探討。
3.1.2MapServer的詳解
首先MapServer支持兩種請求方式,並且支持一些查詢操作。具體如下:
在MapServer的頁面中,我們還可以看到該服務中所包含的圖層的具體信息:
點擊具體圖層,進入該圖層頁面后,能看到該圖層的詳細信息,同樣此頁面中也詳細的描述了可以支持的操作。如下圖所示:
點擊Query后便可以進入該圖層空間查詢的具體頁面:
在此頁面中,我們可以通過對各個查詢參數的設置來獲取想要的查詢結果。
3.1.3 Query查詢的具體URL
MapServer中圖層提供的查詢服務是只支持rest樣式的。通過上面的Query截圖我們可以知道,Query查詢的參數為:objectIds、where、geometry、geometryType、spatialRel、outFields、returnGeometry、returnIdsOnly、f、time。
這些參數所代表的實際含義如下:
objectIds:要素的ObjectID號。比如:objectIds=37, 462。
where:查詢條件,支持標准sql中的where寫法。比如:where=POP2000 > 350000。
geometry:geometry中為要查詢的范圍。其與Geometrytype應保持一致。geometry中,有點、線、面三種寫法。這里給出接口API中的描述:
geometryType:它的內容與geometry中的內容是對應的,它可以選擇的值有:esriGeometryPoint 、 esriGeometryMultipoint 、 esriGeometryPolyline 、esriGeometryPolygon 、 esriGeometryEnvelope。
spatialRel:為空間參考參數。
outFields:為需要返回的屬性字段。
returnGeometry:是否范圍幾何信息。默認是ture。
returnIdsOnly:是否只范圍ObjectID。默認是false。
f:返回數據的格式。有html、json 、kmz 、 amf。對我們開發者來說,返回json是最適合的。
time:賦為一個隨機值即可,設置了此參數,可以避免查詢讀緩存。
這里給出一個URL示例的截圖:
注意:我在這里將where設置為1=1,此表示能夠返回我們在發布服務時已經設置好的返回的最大數據個數。默認為返回1000個數據。outFields設置為*是返回數據中所有關鍵字段的信息。另外,對於URL還想做進一步了解的讀者,可以參考ArcGIS Server中的API Reference。
我們在程序中,向AGS服務器發送請求,查詢某個關鍵字段時,便可以仿照這個URL的樣式來進行請求。AGS的Query服務支持GET和POST兩種請求方式。
3.2通過GeoServer獲得矢量數據
3.2.1Geoserver的簡介
GeoServer作為開源的地圖服務工具,由於其易擴展性、開源性、功能完整性等等優點,被越來越多的實際項目所使用。Geoserver支持OGC中的WMS、WFS等標准,且Geoserver的請求方式同樣支持Rest和Soap兩種協議。GeoServer本身是由Maven進行組織的,內部使用了struts和Spring框架,這里我跟大家展示一下GeoServer的源碼內部構造,讓大家對GeoServer的本質有個稍微清晰的認識:
如何開發GeoServer並不是我們這個系列的重點,我們這個系列是跟大家一起探索WebGIS的一些原理知識,設計並實現一些基於原理知識的模型和功能。如果大家對Geoserver有興趣,我將在以后的其他系列里和大家一起研究。
Geoserver發布成功后,便可以登陸、進入如下頁面:
回到正題上,如何用GeoServer來實現如AGS中的Query查詢呢?
3.1.2 詳解Query查詢
查詢圖層信息為WFS服務中的getFeature服務,其請求方式與標准的WFS請求方式是一樣的。但是,與AGS相比,Geoserver的Query查詢條件編寫是相對復雜的,並且一般有兩種方式。
3.1.2.1第一種方式,URL方式
http://www.someserver.com/wfs?SERVICE=WFS& VERSION=1.1.0& REQUEST=GetFeature& PROPERTYNAME=InWaterA_1M/wkbGeom,InWaterA_1M/tileId& TYPENAME=InWaterA_1M& FILTER=<Filter><Within><PropertyName>InWaterA_1M/wkbGeom<PropertyName> <gml:Envelope><gml:lowerCorner>10,10</gml:lowerCorner> <gml:upperCorner>20 20</gml:upperCorner></gml:Envelope></Within></Filter>
3.1.2.2第二種:連接后發送XML方式
在連接到http://www.someserver.com/wfs 后,向其發送下面的XML:
3.1.2.3對兩種請求方式的小結
這兩種方式中,Filter均是編寫重點。Filter本身是一種基於XML的並且符合OGC規范的語言。WFS在所有需要定位操作對象的地方都會使用Filter。Filter的作用是構建一個表達式,返回值就是Feature的集合,換句話說Filter就如它的名字一般為我們從一個集合中過濾出一個滿足我們要求的子集。而過濾的方法就是Filter定義的操作符。Filter定義了三種操作符:地理操作符(Spatial operators),比較操作符(Comparison operators)和邏輯操作符(Logical operators)。
Spatial operators定義了地理屬性的操作方式,他們有:Equals、Disjoint、Touches、Within、Overlaps、Crosses、Intersects、Contains、Dwithin、Beyond、BBOX。
Comparison operators定義了標量屬性的操作方式,他們有:PropertyIsEqualTo、PropertyIsNotEqualTo、PropertyIsLessThan、PropertyIsGreaterThan、PropertyIsLessThanOrEq、PropertyIsLike、PropertyIsNull、PropertyIsBetween。
Logical operators邏輯操作符,定義了組合這些操作的方式,他們有:And、Or、Not。
在Query編寫中,Geometry參數的編寫也很重要,同時也有一定的難度,他需要我們對GML語言有一定的了解。這里給出GML的三個例子,分別對應point、box、Polygon:
如果我們希望前台直接向Geoserver發送請求,可以選擇第一種URL方式。如果我們是通過我們的業務服務器轉發對Geoserver的請求,建議使用第二種方式。第二種可以發送的數據量更大,並且易於形成標准請求。
4.矢量數據的組織
矢量數據本身的組織方式並沒有規定的格式,可以視具體的項目而定。不過對於AGS和Geoserver返回的數據,是有固定格式的。這里我們分別給出例子。
4.1AGS的矢量數據組織格式
下圖便為一個AGS標准的矢量數據格式:
它由attributes和geometry組成。Attributes中包含了查詢得到的屬性結果,geometry中則包含了查詢所得要素的空間信息。針對不同的要素,返回的geometry的組織是各不相同的。Geometry對線和面分別有paths和rings兩種數據組織格式。
4.2Geoserver的矢量數據組織格式
Geoserver中返回的矢量數據組織格式與AGS的差不多,需要注意的是兩點:
(1)表示點、線、面的字段名稱有不同之處。在Geoserver中線和面的字段名分別是:Line、Polygon| MultiPolygon。
(2)返回的坐標,相對於AGS中的坐標(X,Y),Geoserver中的是相反的,即為(Y,X)。
5.總結
在這一章里,我們對AGS和Geoserver中的WFS服務進行了詳細的講解。實際項目中,矢量圖層的數據大多是來源於此服務所返回的數據的。我們回到我在本章開頭時提出的第四個問題:矢量數據得到后如何使用?
矢量數據中的Geometry數據為地理坐標數據,我們在前端表現矢量圖層時,是在要素(UIComponent)中畫出Geometry的形狀,所以這里就涉及到,如何將得到的地理坐標轉換為對應的屏幕坐標,讓前端的UIComponent上可以畫出該要素形狀。
在下一章里我將跟大家一起探討這個問題,下一章:地理坐標與屏幕坐標的轉換,敬請關注。
--歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS
朋友喜歡讀歷史,但我私下覺得,他這個愛好有點把讀閑書當做干正事之嫌。原因主要有如下幾點:
1.所讀的歷史書籍均是私貨太多、經過別人幾層過濾之書,不是做歷史研究該多看之書。
2.每當問起最近做了什么有意義的事情時,朋友便會說我看了什么什么歷史書,卻避重就輕的逃避了應該去做的更多更實際的事情。
3.如果真心想研究歷史,朋友應該不只停留在看書上面。應該還要有多問、多聽、多寫這三個方面。
期待朋友能在歷史方面有更多收獲,小的收獲是豐富生活、增加談資,中等收獲是陶冶情操、學會做人,高等收獲是成一家之言、立百代之學。
有中等收獲,就已經是一個了不起的讀史人了。朋友,希望你能夠實現。