使用OpenLayers访问天地图WFS数据

天地图官方网站提供的二次开发文档和例子过于简单,很多关键信息没有给予说明,例如给出了WFS服务接口,却没有提供详细的开发文档。
不过这并不影响我们的使用,因为OGC WFS规范包含元数据查询命令,通过发送getCapabilities请求,我们可以得知服务器提供哪些WFS服务。

获取WFS服务器元数据
http://search.tianditu.com/wfs?request=getCapabilities
返回信息如下:
<WFS_Capabilities version=”1.0.0″ xsi:schemaLocation=”http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-capabilities.xsd”>
<Service>
<Name>GeoGlobe WFS</Name>
<Title>GeoGlobe网络要素服务器</Title>
<Abstract>武大吉奥信息技术有限公司GeoGlobe网络要素服务器</Abstract>
<KeywordList/>
<OnlineResource>http://search.tianditu.com:80/wfs</OnlineResource>
</Service>
<Capability>
<Request>
<GetCapabilities>
<DCPType>
<HTTP>
<Get onlineResource=”http://search.tianditu.com:80/wfs”/>
</HTTP>
</DCPType>
</GetCapabilities>
<GetFeature>
<ResultFormat>
<GML2/>
</ResultFormat>
<DCPType>
<HTTP>
<Get onlineResource=”http://search.tianditu.com:80/wfs”/>
<Post onlineResource=”http://search.tianditu.com:80/wfs”/>
</HTTP>
</DCPType>
</GetFeature>
<DescribeFeatureType>
<SchemaDescriptionLanguage>
<XMLSCHEMA/>
</SchemaDescriptionLanguage>
<DCPType>
<HTTP>
<Get onlineResource=”http://search.tianditu.com:80/wfs”/>
</HTTP>
</DCPType>
</DescribeFeatureType>
</Request>
<VendorSpecificCapabilities/>
</Capability>
<FeatureTypeList>
<Operations>
<Query/>
</Operations>
<FeatureType>
<Name>DOMAIN_POI_NEW</Name>
<Title>DOMAIN_POI_NEW</Title>
<Abstract>DOMAIN_POI_NEW</Abstract>
<Keywords>DOMAIN_POI_NEW</Keywords>
<SRS>EPSG:4326</SRS>
<LatLongBoundingBox minx=”-180.0″ miny=”-90.0″ maxx=”180.0″ maxy=”90.0″/>
</FeatureType>
<FeatureType>
<Name>iso19112:SI_Gazetteer</Name>
<Title>iso19112:SI_Gazetteer</Title>
<SRS>EPSG:4326</SRS>
<LatLongBoundingBox minx=”-180.0″ miny=”-90.0″ maxx=”180.0″ maxy=”90.0″/>
</FeatureType>
</FeatureTypeList>
<ogc:Filter_Capabilities>
<ogc:Spatial_Capabilities>
<ogc:Spatial_Operators>
<ogc:BBOX/>
<ogc:Equals/>
<ogc:Disjoint/>
<ogc:Intersect/>
<ogc:Touches/>
<ogc:Crosses/>
<ogc:Within/>
<ogc:Contains/>
<ogc:Overlaps/>
<ogc:Beyond/>
</ogc:Spatial_Operators>
</ogc:Spatial_Capabilities>
<ogc:Scalar_Capabilities>
<ogc:Logical_Operators/>
<ogc:Comparison_Operators>
<ogc:Simple_Comparisons/>
<ogc:Like/>
<ogc:Between/>
</ogc:Comparison_Operators>
</ogc:Scalar_Capabilities>
</ogc:Filter_Capabilities>
</WFS_Capabilities>

返回信息包含了WFS服务器的开发单位(武大吉奥),WFS图层的名称(DOMAIN_POI_NEW和iso19112:SI_Gazetteer),支持的逻辑操作符和空间操作符。

继续测试
http://search.tianditu.com/wfs?request=GetFeature&version=1.0.0&typeName=DOMAIN_POI_NEW&BBOX=105.99,29.99,106,30
返回
<wfs:FeatureCollection xsi:schemaLocation=”http://www.opengis.net/wfs WFS_Basic.xsd http://www.geostart.com.cn/geoglobe describe.xsd”>
<gml:boundedBy>
<gml:Box>
<gml:coordinates>-180.0,-90.0 180.0,90.0</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<DOMAIN_POI_NEW>
<OID>6764930</OID>
<Geometry>
<gml:Point srsName=”-1″>
<gml:coordinates>105.999183,29.995258</gml:coordinates>
</gml:Point>
</Geometry>
<DOMAINNAME>梅子村</DOMAINNAME>
<DOMAINCODE>1CHN50022400000130172</DOMAINCODE>
<NLEVEL>16</NLEVEL>
<X>105.999183</X>
<Y>29.995258</Y>
<COLDATE/>
<NAMETIME/>
<ENDTIME/>
<CLASSID/>
<STANDARDNAME>亚洲中国重庆市铜梁县梅子村</STANDARDNAME>
<TELEPHONE/>
<ADDRESS/>
<KIND>BB80</KIND>
<ZIPCODE/>
<ADMINCODE>500224</ADMINCODE>
<POI_ID>5000000130172</POI_ID>
<PID/>
<DATATYPE>chinapoi</DATATYPE>
<FENAME/>
<locationType>
<SI_LocationType>
<name>DOMAIN_POI_NEW</name>
</SI_LocationType>
</locationType>
</DOMAIN_POI_NEW>
</gml:featureMember>
</wfs:FeatureCollection>

分析返回的GML数据,可知DOMAIN_POI_NEW是地名图层,包含名称、代码、类别码等属性字段。

将图层改为iso19112:SI_Gazetteer,没有返回任何信息,google ISO19112,得到如下解释:
DIN EN ISO 19112-2005 地理信息.通过地理标识符的空间定位标准号: DIN EN ISO 19112-2005 标准名称:地理信息.通过地理标识符的空间定位

得到以上信息后,我们尝试使用Openlayers获取,即全国地名数据库。

通过URL(GET方式)访问“天地图”WFS服务,可以使用OpenLayers.Request.GET类,示例代码如下:
   //使用FEATUREID查询

   new OpenLayers.Request.GET( {
        url : “http://search.tianditu.com/wfs?request=GetFeature”,
        params: {
            typeName: “DOMAIN_POI_NEW”,
            FEATUREID: “DOMAIN_POI_NEW.6649356”
        },
        callback : handler
    });

 

   //使用BBOX查询

    new OpenLayers.Request.GET( {
        url : “http://search.tianditu.com/wfs?request=GetFeature”,
        params: {
            typeName: “DOMAIN_POI_NEW”,
            BBOX: “105.99,29.99,106,30”  //map.getExtent().toBBOX()
        },
        callback : handler
    });

说明:
url WFS服务器地址,必须加上?request=GetFeature
typeName 图层名称
FEATUREID WFS的图元ID,采用标准格式: [图层名].[OID编号]
BBOX 指定区域查询,注意不要设置过大,否则浏览器可能失去响应。

通过POST方式访问“天地图”WFS服务,可以使用OpenLayers.Request.POST类,示例代码如下:

    var xmlPara = “<?xml version=’1.0′ encoding=’UTF-8′?>”
            + “<wfs:GetFeature maxFeatures=’100′ service=’WFS’ version=’1.0.0′ “
            + “xmlns:wfs=’http://www.opengis.net/wfs’ “
            + “xmlns:gml=’http://www.opengis.net/gml’ “
            + “xmlns:ogc=’http://www.opengis.net/ogc’ “
            + “xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’ “
            + “xsi:schemaLocation=’http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd’>”
            + “<wfs:Query typeName=’iso19112:SI_Gazetteer’ srsName=’EPSG:4326′>”
            + “<ogc:Filter xmlns:ogc=’http://www.opengis.net/ogc’>”
            + “<ogc:And><ogc:PropertyIsLike wildCard=’*’ singleChar=’.’ escape=’!’>”
            + “<ogc:PropertyName>STANDARDNAME</ogc:PropertyName>”
            + “<ogc:Literal>*解放碑*</ogc:Literal>”
            + “</ogc:PropertyIsLike></ogc:And></ogc:Filter>”
            + “</wfs:Query></wfs:GetFeature>”;
    
    var request = OpenLayers.Request.POST( {
        url : “http://search.tianditu.com/wfs?”,
        data : xmlPara,
        callback : handler
    });
};

说明:

url WFS服务器地址

data WFS请求正文,返回的GML由回调函数handler处理

 

在XML查询请求中定义过滤条件ogc:Filter,查询符合条件的地名。

定义过滤条件时请使用STANDARDNAME字段,不要使用DOMAINNAME字段,前者应该有索引支持,而后者没有,查询速度差别很大。

经过测试,typeName=”DOMAIN_POI_NEW”和typeName=”iso19112:SI_Gazetteer”都能返回结果。由于缺少官方文档说明,不知道这两个图层有何区别。

 

尝试使用OpenLayers.Protocol.WFS无法访问“天地图”WFS服务,服务器返回: 请求参数[REQUEST]的值为空或不正确。

 

提醒: 使用POST查询时,页面文件或代码文件务必保存为utf-8编码,如果使用gbk、gb2312编码,汉字地名会变成乱码,导致javascript代码错误。

 

附:回调函数handler获取矢量和属性数据的通用代码如下:
var g = new OpenLayers.Format.GML();
var features = g.read(req.responseText);
for ( var i = 0; i < features.length; ++i) {
   var feature = features[i];
   var geometry = feature.geometry;
   var attributes = feature.attributes;
}

(to:fire323 CSDN回复不了,只好附在文章最后了)

转载自:https://blog.csdn.net/iwillsw/article/details/6069328

You may also like...