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

WFS的getFeature操作需要提供的参数:

参数名称是否必须默认值举例含义
VERSION1.1.0version=1.1.0或version=1.0.0版本号
SERVICEWFSWFS服务名称
REQUEST=GetFeature  请求操作(固定值)
TYPENAMEtext/xml; subtype=gml/3.1.1typeName=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=过滤条件,gml格式定义空间范围,可包含属性条件。Filter是一种符合OGC规范的语言,一种XML实现的语言。SLD用它来实现复杂的Rule选择。WFS在所有需要定位操作对象的地方都会使用Filter。Filter的作用是构建一个表达式,返回值就是Feature的集合。
SORTBY   排序字段
MAXFEATURES   最多返回结果个数
PROPERTYNAME  propertyName=STATE_NAME,PERSONS属性字段名称,逗号隔开
SRSNAME   投影方式名称
FEATUREID  FEATUREID=states.3ID号(图层名称.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=InWaterA_1M/wkbGeom10,1020 20

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利用通配符等符号对字符进行模糊匹配

 

PropertyIsNull为空 
PropertyIsBetween在…之间 
  •  Logical operators逻辑操作符,定义了组合这些操作的方式,他们有:And,Or,Not。

    举例:构建一个表达式,人口在一千万以上,并且在指定的空间范围内的城市。

<Filter>
    <And>
        <PropertyIsGreaterThan>
            <PropertyName>populationPropertyName>
            <Literal>10000000Literal>
        PropertyIsGreaterThan>
        <BBOX>
            <PropertyName>geomPropertyName>
            <Envelope srsName="EPSG:4326">
                <lowerCorner>-180 -90lowerCorner>
                <upperCorner>180 90upperCorner>
            Envelope>
        BBOX>
    And>Filter>

 

验证:

拓扑查询(点与面相交- Intersects)点查询  查询条件设置如下:

<Filter xmlns="http://www.opengis.net/ogc"xmlns:gml="http://www.opengis.net/gml">
    <Intersects>
        <PropertyName>bj:the_geomPropertyName>
        <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
            <gml:coordinates>116.817265,40.5296504gml:coordinates>
        gml:Point>
    Intersects>Filter>

目前我用到的应用场景在于点击查询,当我点击底图上的一个点的时候,我获得了当前点击的坐标值,然后来构造查询filter

其中需要注意的是PropertyName所表示的含义,

我们在geoserver中选择用geojson来打开服务

WFS服务查询方法_WFS

 

在这个服务中,propertyname对应的是值为the_geom

在另一个服务中则为geom ,所以我认为在做拓扑查询的时候,propertyname所对应的是geometry_name这个属性

WFS服务查询方法_WFS_02

 

线查询的Filter构造

<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
    <Within>
        <PropertyName>GEOMPropertyName>
        <gml:LineString>
            <gml:coordinates>113.763,34.435 113.763,34.5 113.844,34.5 113.844,34.435gml:coordinates>
        gml:LineString>
     Within>Filter>

面查询(最常用)Filter构造

<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
    <Intersects>
        <PropertyName>GEOMPropertyName>
     <gml:Polygon>
       <gml:outerBoundaryIs>        
            <gml:LinearRing>
                 <gml:coordinates>113.763,34.435 113.763,34.5 113.763,34.435gml: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> geomPropertyName>
            <gml:Polygon>
              <gml:outerBoundaryIs>
                  <gml:LinearRing>
                    <gml:coordinates>filterPointgml: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);
            }
        })