Geoserver的WFS服務
轉載自
http://www.gisvip.com/bbs/forum.php?mod=viewthread&tid=2723
基於Geoserver釋出的wfs服務,與Openlayers結合實現空間和屬性資訊的查詢。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)。
u
Spatial operators定義了地理屬性的操作方式,他們有:Equals,Disjoint,Touches,Within,Overlaps,Crosses,Intersects,Contains,DWithin,Beyond,BBOX。
名稱 | 含義 | 舉例 |
Equals | 等於 | |
Disjoint | 不相交 | |
Intersects | 相交(存在交集) | |
Touches | ||
Within | 在..內部 | |
DWithin | 在…外部 | |
Overlaps | 疊加 | |
Crosses | 通過 | |
Contains | 包含 | |
Beyond | ||
BBOX | 矩形範圍 |
u
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 | 在…之間 |
u
Logical operators邏輯操作符,定義了組合這些操作的方式,他們有:And,Or,Not。
舉例:構建一個表示式,人口在一千萬以上,並且在指定的空間範圍內的城市。
<Filter>
<And>
<PropertyIsGreaterThan>
<PropertyName>population</PropertyName>
<Literal>10000000</Literal>
</PropertyIsGreaterThan>
<BBOX>
<PropertyName>geom</PropertyName>
<EnvelopesrsName="EPSG:4326">
<lowerCorner>-180 -90</lowerCorner>
<upperCorner>180 90</upperCorner>
</Envelope>
</BBOX>
</And>
</Filter>
驗證例項:之前走了一些彎路,自己構建Filter的xml編碼,後來發現OpenLayers已經寫好了Filter過濾條件和轉成xml的類,這樣Filter標籤裡的內容不用逐個編寫了。
1.
拓撲查詢(點與面相交-Intersects)
查詢條件設定如下:
varXML;
XML ='<?xml version="1.1.0" encoding="UTF-8"?>'+"/n";
XML ='<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2"'+"/n";
XML +='
xmlns:topp="http://www.openplans.org/topp"'+"/n";
XML +='
xmlns:wfs="http://www.opengis.net/wfs"'+"/n";
XML +='
xmlns:ogc="http://www.opengis.net/ogc"'+"/n";
XML +='
xmlns:gml="http://www.opengis.net/gml"'+"/n";
XML +='
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+"/n";
XML +='
xsi:schemaLocation="http://www.opengis.net/wfs'+"/n";
XML +='
http://schemas.opengis.net/wfs/1.1.0/WFS-basic.xsd">'+"/n";
//上面是查詢用的gml的字首
XML +='<wfs:Query typeName="bj:xzqy">'+"/n";
XML +='<wfs:PropertyName>bj:ENTITY_ID</wfs:PropertyName>'+'/n';
XML +='<wfs:PropertyName>bj:the_geom</wfs:PropertyName>'+'/n';
XML +='<ogc:Filter>'+"/n";
XML +='<ogc:Intersects>'+"/n";
XML +='<ogc:PropertyName>bj:the_geom</ogc:PropertyName>'+"/n";
XML +=' <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">'+"/n";
XML +='<gml:coordinates>116.817265,40.5296504</gml:coordinates>'+"/n";
XML +='</gml:Point>'+"/n";
XML +='</ogc:Intersects>'+"/n";
XML +='</ogc:Filter>'+"/n";
XML +='</wfs:Query>'+"/n";
XML +='</wfs:GetFeature>';
varxmlPara = XML;//返回結果無法解析為gml??-已解決(增加返回結果樣式標籤)
varrequest = OpenLayers.Request.POST({
url:"http://localhost:8080/geoserver/wfs?",
data: xmlPara,
callback: onComplete
});
查詢結果展示:地圖上深色的部分為根據座標點與行政區域面相交分析出的結果
2. 拓撲查詢(面與面相交-Intersects)
查詢條件設定:
varXML;
XML ='<?xml version="1.1.0" encoding="UTF-8"?>'+"/n";
XML ='<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2"'+"/n";
XML +='
xmlns:topp="http://www.openplans.org/topp"'+"/n";
XML +='
xmlns:wfs="http://www.opengis.net/wfs"'+"/n";
XML +='
xmlns:ogc="http://www.opengis.net/ogc"'+"/n";
XML +='
xmlns:gml="http://www.opengis.net/gml"'+"/n";
XML +='
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+"/n";
XML +='
xsi:schemaLocation="http://www.opengis.net/wfs'+"/n";
XML +='
http://schemas.opengis.net/wfs/1.1.0/WFS-basic.xsd">'+"/n";
//上面是查詢用的gml的字首
XML +='<wfs:Query typeName="bj:xzqy">'+"/n";
XML +='<wfs:PropertyName>bj:ENTITY_ID</wfs:PropertyName>'+'/n';
XML +='<wfs:PropertyName>bj:the_geom</wfs:PropertyName>'+'/n';
XML +='<ogc:Filter>'+"/n";
XML +='<ogc:Intersects>'+"/n";
XML +='<ogc:PropertyName>bj:the_geom</ogc:PropertyName>'+"/n";
XML +='<gml:Polygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">'+"/n";
XML +='<gml:outerBoundaryIs>'+"/n";
XML +='<gml:LinearRing>'+"/n";
XML +='<gml:coordinates>115.40316,39.425701 116.40316,39.425701 116.40316,40.245 115.40316,40.245 115.40316,39.425701</gml:coordinates>'+"/n";//0,0 100,0 100,100 0,100 0,0
XML +='</gml:LinearRing>'+"/n";
XML +='</gml:outerBoundaryIs>'+"/n";
XML +='</gml:Polygon>'+"/n";
XML +='</ogc:Intersects>'+"/n";
XML +='</ogc:Filter>'+"/n";
XML +='</wfs:Query>'+"/n";
XML +='</wfs:GetFeature>';
varxmlPara = XML;//返回結果無法解析為gml??-已解決(增加返回結果樣式標籤)
varrequest = OpenLayers.Request.POST({
url:"http://localhost:8080/geoserver/wfs?",
data: xmlPara,
callback: onComplete
});
查詢結果展現:地圖上深色的部分為查詢到的行政轄區面要素
3. 拓撲查詢(面與麵包含-Contains)
使用Openlayers提供的方法構造過濾條件
1. 拓撲查詢(空間相交與屬性過濾)
查詢指定空間範圍(傳入Geometry型別引數)內NAME欄位以“幼兒園”結尾的要素。
或者NAME欄位的值為“西羅園第三幼兒園”的要素。
或者OBJECTID欄位的值的範圍是從0到1000。
//驗證利用Filter構建過濾條件
functionconformationFilter(geo) {
varfilter_1_0 =newOpenLayers.Format.Filter.v1_0_0();
//也可以使用1.1版本構造過濾條件
//var filter_1_1 = new OpenLayers.Filter({ version: "1.1.0" });
varxml =newOpenLayers.Format.XML();//構造xml格式的檔案
varfilter =newOpenLayers.Filter.Logical({//邏輯操作符
type: OpenLayers.Filter.Logical.AND,//並且更改為或者
filters: [
newOpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.INTERSECTS,//INTERSECTS, //相交OK
value: geo,
projection:"EPSG:4326"
}),
//BBOX方式OK
//
new OpenLayers.Filter.Spatial({
//
type: OpenLayers.Filter.Spatial.BBOX,
//
value: new OpenLayers.Bounds(115.40316, 39.425701, 116.40316, 40.245),
//
projection: "EPSG:4326"
//
}),
newOpenLayers.Filter.Comparison({//比較操作符
type: OpenLayers.Filter.Comparison.LIKE,//模糊查詢(萬用字元:*/#/!),速度很慢
property:"bj:NAME",
value:"*幼兒園"
}),
newOpenLayers.Filter.Comparison({//比較操作符
type: OpenLayers.Filter.Comparison.EQUAL_TO,//精確查詢
property:"bj:NAME",
value:"西羅園第三幼兒園"
}),
newOpenLayers.Filter.Comparison({//比較操作符
type: OpenLayers.Filter.Comparison.BETWEEN,//在。。。之間(數值型)
property:"bj:OBJECTID",
lowerBoundary: 0,
upperBoundary: 1000
})
]
});
//構造指定格式的xml
returnresult = xml.write(filter_1_0.write(filter));
};
展示結果:
返回結果的高亮顯示和屬性資訊展示:
//AJAX請求結果處理函式(新增標註+屬性列表)
functiononComplete(req) {
//openlayers的GML解析器
vargmlParse =newOpenLayers.Format.GML();//如果使用wfs1.1.0,則需要增加如下引數:{xy:false }//更改x,y座標的讀取順序
varfeatures = gmlParse.read(req.responseText);
varicon =newOpenLayers.Icon("img/marker-blue.png");
varfeature, lonlat, marker;
varattributes = [];
//高亮顯示
for(varfeatinfeatures) {
feature = features[feat];
//高亮顯示
switch(feature.geometry.CLASS_NAME) {
case"OpenLayers.Geometry.MultiPolygon":
{
varpolygon = feature.geometry.components[0].clone();
varvec =newOpenLayers.Feature.Vector(polygon);
temVectorLayer.addFeatures([vec]);
}
break;
case"OpenLayers.Geometry.Point":
{
//經度緯度是相反的,所以需要重新構建
varpt = feature.geometry.clone();
varvec =newOpenLayers.Feature.Vector(pt);
temVectorLayer.addFeatures([vec]);
}
break;
}
attributes.push(feature.attributes);
}
varstrAttributes ="";
if(!document.all("attr"))return;
if(document.all("attr").firstChild) {
document.all("attr").firstChild.removeNode(true);
}
for(varkeyinattributes) {
varattr = attributes[key];
strAttributes +="[";
vartrHead = document.all("attr").insertRow();
vartdHead = trHead.insertCell();
tdHead.innerText ="編號:"+ key;
for(varkinattr) {
vartr = document.all("attr").insertRow();
vartd0 = tr.insertCell();
td0.innerText = k;
vartd1 = tr.insertCell();
td1.innerText = attr[k];
strAttributes += k +":"+ attr[k];
}
strAttributes +="]";
};
alert(strAttributes);
};