基於Geoserver發布的wfs服務,實現空間和屬性信息的查詢。wfs包含getFeature操作,用來檢索要素信息,支持返回gml格式的地理要素表達。
WFS的getFeature操作需要提供的參數:
參數名稱 | 是否必須 | 默認值 | 舉例 | 含義 |
VERSION | 是 | 1.1.0 | version=1.1.0或version=1.0.0 | 版本號 |
SERVICE | 是 | WFS | WFS | 服務名稱 |
REQUEST=GetFeature | 是 | 請求操作(固定值) | ||
TYPENAME | 是 | text/xml; subtype=gml/3.1.1 | typeName=bj.xzqytypeName=bj.xzqy, bj:sqdw_font_point | 圖層名稱(命名空間.圖層名稱),多個圖層名稱用逗號隔開 |
OUTPUTFORMAT | outputFormat=GML2 | 輸出類型 | ||
BBOX | BBOX=-75.102613,40.212597,-72.361859,41.512517,EPSG:4326 | 矩形范圍(左下角X坐標,左下角Y坐標,右上角X坐標,右上角Y坐標,EPSG:4326) | ||
FILTER | 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> | 過濾條件,gml格式定義空間范圍,可包含屬性條件。Filter是一種符合OGC規范的語言,一種XML實現的語言。SLD用它來實現復雜的Rule選擇。WFS在所有需要定位操作對象的地方都會使用Filter。Filter的作用是構建一個表達式,返回值就是Feature的集合。 | ||
SORTBY | 排序字段 | |||
MAXFEATURES | 最多返回結果個數 | |||
PROPERTYNAME | propertyName=STATE_NAME,PERSONS | 屬性字段名稱,逗號隔開 | ||
SRSNAME | 投影方式名稱 | |||
FEATUREID | FEATUREID=states.3 | ID號(圖層名稱.ID號),多個用逗號隔開 | ||
EXPIRY | 排除 | |||
RESULTTYPE | ||||
FEATUREVERSION |
舉例:
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>
FILTER詳解:Filter是一種基於XML的並且符合OGC規范的語言。SLD用它來實現復雜的Rule選擇。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。
名稱 | 含義 | 舉例 |
Equals | 等於 | |
Disjoint | 不相交 | |
Intersects | 相交(存在交集) | |
Touches | ||
Within | 在..內部 | |
DWithin | 在…外部 | |
Overlaps | 疊加 | |
Crosses | 通過 | |
Contains | 包含 | |
Beyond | ||
BBOX | 矩形范圍 |
- Comparison operators定義了標量屬性的操作方式,他們有:PropertyIsEqualTo,PropertyIsNotEqualTo,PropertyIsLessThan,PropertyIsGreaterThan,PropertyIsLessThanOrEq,PropertyIsGreaterThanO,PropertyIsLike,PropertyIsNull,PropertyIsBetween。
名稱 | 含義 | 舉例 |
PropertyIsEqualTo | == | |
PropertyIsNotEqualTo | != | |
PropertyIsLessThan | < | |
PropertyIsGreaterThan | > | |
PropertyIsLessThanOrEq | <= | |
PropertyIsGreaterThanO | >= | |
PropertyIsLike | 利用通配符等符號對字符進行模糊匹配 | <Filter> <PropertyIsLike wildCard="*" singleChar="#" escapeChar="!"> <PropertyName>LAST_NAME</PropertyName> <Literal>JOHN*</Literal> </PropertyIsLike> </Filter> |
PropertyIsNull | 為空 | |
PropertyIsBetween | 在…之間 |
- Logical operators邏輯操作符,定義了組合這些操作的方式,他們有:And,Or,Not。
舉例:構建一個表達式,人口在一千萬以上,並且在指定的空間范圍內的城市。
<Filter> <And> <PropertyIsGreaterThan> <PropertyName>population</PropertyName> <Literal>10000000</Literal> </PropertyIsGreaterThan> <BBOX> <PropertyName>geom</PropertyName> <Envelope srsName="EPSG:4326"> <lowerCorner>-180 -90</lowerCorner> <upperCorner>180 90</upperCorner> </Envelope> </BBOX> </And> </Filter>
驗證:
拓撲查詢(點與面相交- Intersects)點查詢 查詢條件設置如下:
<Filter xmlns="http://www.opengis.net/ogc"xmlns:gml="http://www.opengis.net/gml"> <Intersects> <PropertyName>bj:the_geom</PropertyName> <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:coordinates>116.817265,40.5296504</gml:coordinates> </gml:Point> </Intersects> </Filter>
目前我用到的應用場景在於點擊查詢,當我點擊底圖上的一個點的時候,我獲得了當前點擊的坐標值,然后來構造查詢filter
其中需要注意的是PropertyName所表示的含義,
我們在geoserver中選擇用geojson來打開服務
在這個服務中,propertyname對應的是值為the_geom
在另一個服務中則為geom ,所以我認為在做拓撲查詢的時候,propertyname所對應的是geometry_name這個屬性
線查詢的Filter構造
<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"> <Within> <PropertyName>GEOM</PropertyName> <gml:LineString> <gml:coordinates>113.763,34.435 113.763,34.5 113.844,34.5 113.844,34.435</gml:coordinates> </gml:LineString> </Within> </Filter>
面查詢(最常用)Filter構造
<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"> <Intersects> <PropertyName>GEOM</PropertyName>
<gml:Polygon> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>113.763,34.435 113.763,34.5 113.763,34.435</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Intersects> </Filter>
面查詢用的最多是因為,在實際點擊中,你很難准確的點擊到比如線上面 所以一般使用的是面與線相交,我們構造一個容差值(構造出一個面)
let filterPointLT = Number(_param.x) - Number(_param.tolerance) + "," + Number(_param.y) + Number(_param.tolerance); //左上角坐標 let filterPointLB = Number(_param.x) - Number(_param.tolerance) + "," + (Number(_param.y) - Number(_param.tolerance)); //左下角坐標 let filterPointRT = Number(_param.x) + Number(_param.tolerance) + "," + Number(_param.y) + Number(_param.tolerance); //右上角坐標 let filterPointRB = Number(_param.x) + Number(_param.tolerance) + "," + (Number(_param.y) - Number(_param.tolerance)); //右下角坐標 let filterPoint = filterPointLT + " " + filterPointLB + " " + filterPointRB + " " + filterPointRT + " " + filterPointLT;
構造Filter
<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"> <Intersects> <PropertyName> geom</PropertyName> <gml:Polygon> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>filterPoint</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </Intersects> </Filter>
最后構造一個HTML請求
let _wfsUrl = "http://localhost:8080/geoserver/gas/ows? service=WFS&version=1.0.0&request=GetFeature &typeName=gas:t_area&outputFormat=application%2Fjson&filter="+ filter;
發送請求
$.ajax({ url: _wfsUrl, async: true, type:'GET', dataType: 'json', success(result) { callback(result); }, error(err) { console.log(err); } })