wfs服务查询详解
基于Geoserver发布的wfs服务,与Openlayers结合实现空间和属性信息的查询。wfs包含getFeature操作,用来检索要素信息,支持返回gml格式的地理要素表达。
WFS的getFeature操作需要提供的参数:
举例:
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。
u
Comparison operators定义了标量属性的操作方式,他们有:PropertyIsEqualTo,PropertyIsNotEqualTo,PropertyIsLessThan,PropertyIsGreaterThan,PropertyIsLessThanOrEq,PropertyIsGreaterThanO,PropertyIsLike,PropertyIsNull,PropertyIsBetween。
u
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>
验证实例:之前走了一些弯路,自己构建Filter的xml编码,后来发现OpenLayers已经写好了Filter过滤条件和转成xml的类,这样Filter标签里的内容不用逐个编写了。
1.
拓扑查询(点与面相交– Intersects)
查询条件设置如下:
var XML;
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>’;
var xmlPara = XML; //返回结果无法解析为gml??-已解决(增加返回结果样式标签)
var request = OpenLayers.Request.POST({
url: “http://localhost:8080/geoserver/wfs?”,
data: xmlPara,
callback: onComplete
});
查询结果展示:地图上深色的部分为根据坐标点与行政区域面相交分析出的结果
2. 拓扑查询(面与面相交– Intersects)
查询条件设置:
var XML;
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>’;
var xmlPara = XML; //返回结果无法解析为gml??-已解决(增加返回结果样式标签)
var request = OpenLayers.Request.POST({
url: “http://localhost:8080/geoserver/wfs?”,
data: xmlPara,
callback: onComplete
});
查询结果展现:地图上深色的部分为查询到的行政辖区面要素
3. 拓扑查询(面与面包含– Contains)
使用Openlayers提供的方法构造过滤条件
1. 拓扑查询(空间相交与属性过滤)
查找指定空间范围(传入Geometry类型参数)内NAME字段以“幼儿园”结尾的要素。
或者NAME字段的值为“西罗园第三幼儿园”的要素。
或者OBJECTID字段的值的范围是从0到1000。
//验证利用Filter构建过滤条件
function conformationFilter(geo) {
var filter_1_0 = new OpenLayers.Format.Filter.v1_0_0();
//也可以使用1.1版本构造过滤条件
//var filter_1_1 = new OpenLayers.Filter({ version: “1.1.0” });
var xml = new OpenLayers.Format.XML(); //构造xml格式的文件
var filter = new OpenLayers.Filter.Logical({//逻辑操作符
type: OpenLayers.Filter.Logical.AND, //并且更改为或者
filters: [
new OpenLayers.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”
//
}),
new OpenLayers.Filter.Comparison({//比较操作符
type: OpenLayers.Filter.Comparison.LIKE, //模糊查询(通配符:*/#/!),速度很慢
property: “bj:NAME”,
value: “*幼儿园”
}),
new OpenLayers.Filter.Comparison({//比较操作符
type: OpenLayers.Filter.Comparison.EQUAL_TO, //精确查询
property: “bj:NAME”,
value: “西罗园第三幼儿园”
}),
new OpenLayers.Filter.Comparison({//比较操作符
type: OpenLayers.Filter.Comparison.BETWEEN, //在。。。之间(数值型)
property: “bj:OBJECTID”,
lowerBoundary: 0,
upperBoundary: 1000
})
]
});
//构造指定格式的xml
return result = xml.write(filter_1_0.write(filter));
};
展示结果:
返回结果的高亮显示和属性信息展示:
//AJAX请求结果处理函数(添加标注+属性列表)
function onComplete(req) {
//openlayers的GML解析器
var gmlParse = new OpenLayers.Format.GML();//如果使用wfs1.1.0,则需要增加如下参数:{xy:false
}//更改x,y坐标的读取顺序
var features = gmlParse.read(req.responseText);
var icon = new OpenLayers.Icon(“img/marker-blue.png”);
var feature, lonlat, marker;
var attributes = [];
//高亮显示
for (var feat in features) {
feature = features[feat];
//高亮显示
switch (feature.geometry.CLASS_NAME) {
case “OpenLayers.Geometry.MultiPolygon”:
{
var polygon = feature.geometry.components[0].clone();
var vec = new OpenLayers.Feature.Vector(polygon);
temVectorLayer.addFeatures([vec]);
}
break;
case “OpenLayers.Geometry.Point”:
{
//经度纬度是相反的,所以需要重新构建
var pt = feature.geometry.clone();
var vec = new OpenLayers.Feature.Vector(pt);
temVectorLayer.addFeatures([vec]);
}
break;
}
attributes.push(feature.attributes);
}
var strAttributes = “”;
if (!document.all(“attr”)) return;
if (document.all(“attr”).firstChild) {
document.all(“attr”).firstChild.removeNode(true);
}
for (var key in attributes) {
var attr = attributes[key];
strAttributes += “[“;
var trHead = document.all(“attr”).insertRow();
var tdHead = trHead.insertCell();
tdHead.innerText = “编号:” + key;
for (var k in attr) {
var tr = document.all(“attr”).insertRow();
var td0 = tr.insertCell();
td0.innerText = k;
var td1 = tr.insertCell();
td1.innerText = attr[k];
strAttributes += k + “:” + attr[k];
}
strAttributes += “]”;
};
alert(strAttributes);
};
转自:http://www.gisvip.com/bbs/forum.php?mod=viewthread&tid=2723
转载自:https://blog.csdn.net/yrlzmm/article/details/48532035