您的位置:首页 > 运维架构

GIS的学习(二十)基于Geoserver的WFS服务与Openlayers实现地理查询

2015-02-25 16:09 691 查看

GIS的学习(二十)基于Geoserver的WFS服务与Openlayers实现地理查询

基于Geoserver发布的wfs服务,与Openlayers结合实现空间和属性信息的查询。wfs包含getFeature操作,用来检索要素信息,支持返回gml格式的地理要素表达。

WFS的getFeature操作需要提供的参数:
http://www.gisvip.com/bbs/forum.php?mod=viewthread&tid=2723
参数名称

是否必须

默认值

举例

含义

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.xzqy

typeName=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

举例:

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>

<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.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>

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: