项目场景:
在做一个数据同步项目,服务端使用GeoServer作为数据存储服务器,本地使用spatialite存储数据,使用WFS的Transaction请求和GetFeature请求作为数据通信。wfs使用的版本是2.0.0,gml使用的3.2。
问题描述
wfs2.0.0默认获取的坐标顺序为先y后x:
请求如下:
<?xml version="1.0"?>
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
service="WFS" version="2.0.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ogc="http://www.opengis.net/ogc"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd">
<wfs:Query typeNames="w3:layer1" srsDimension="3">
<fes:Filter>
<fes:ResourceId rid="1"/>
<fes:ResourceId rid="2"/>
<fes:ResourceId rid="3"/>
<fes:ResourceId rid="4"/>
<fes:ResourceId rid="5"/>
<fes:ResourceId rid="6"/>
</fes:Filter>
</wfs:Query>
</wfs:GetFeature>
返回数据:
<w3:geom>
<gml:LineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" srsDimension="3" gml:id="layer1.5.geom">
<gml:posList>
30.7177734375 105.29296875 0
28.8720703125 107.2045898438 0
28.7292480469 109.9621582031 0
28.9709472656 111.0498046875 0
31.46484375 111.4453125 0
</gml:posList>
</gml:LineString>
</w3:geom>
使用以上gml插入spatialite数据库后,使用spatialite获取数据到gaiaPolygonPtr结构体内后,x、y坐标解析出来的值与实际的x、y正好相反。
原因分析:
spatialite解析geomtry字段时,是按xyz顺序解析的,而WFS2.0.0返回的gml坐标顺序是yxz,从而导致spatialite解析数据错误。
解决方案:
WFS的GetFeature请求可以指定参数将geomtry数据重投影,例如84坐标系,使用srsName="EPSG:4326"重投影后坐标顺序将更改为xyz。但是需要注意的是Get请求直接在url后添加上该参数可以实现没有问题,post请求该参数需要添加到<wfs:Query>节点的属性里,而不是<wfs:GetFeature>的属性里。
示例如下:
<?xml version="1.0"?>
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
service="WFS" version="2.0.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ogc="http://www.opengis.net/ogc"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd">
<wfs:Query typeNames="w3:layer1" srsName="EPSG:4326" srsDimension="3">
<fes:Filter>
<fes:ResourceId rid="1"/>
<fes:ResourceId rid="2"/>
<fes:ResourceId rid="3"/>
<fes:ResourceId rid="4"/>
<fes:ResourceId rid="5"/>
<fes:ResourceId rid="6"/>
</fes:Filter>
</wfs:Query>
</wfs:GetFeature>
返回的数据结果:
<w3:geom>
<gml:LineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" srsDimension="3" gml:id="layer1.5.geom">
<gml:posList>
105.29296875 30.7177734375 0
107.2045898438 28.8720703125 0
109.9621582031 28.7292480469 0
111.0498046875 28.9709472656 0
111.4453125 31.46484375 0
</gml:posList>
</gml:LineString>
</w3:geom>
注意:在GeoServer管理页面修改gml的srs样式并不会重投影,仅仅是改变返回gml中srsName后面的链接。
如下所示:
<w3:geom>
<gml:LineString srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="3" gml:id="layer1.5.geom">
<gml:posList>
30.7177734375 105.29296875 0
28.8720703125 107.2045898438 0
28.7292480469 109.9621582031 0
28.9709472656 111.0498046875 0
31.46484375 111.4453125 0
</gml:posList>
</gml:LineString>
</w3:geom>