GeoServer增删改请求-解决空间存储经纬度顺序问题

645 阅读2分钟

一、前言

GeoServer通过WFS提供增删改的请求接口,用户可以通过增删改请求来管理地理空间数据。具体示例可以参考GeoServer的主页面Demo → Demo requests模块。

该文章主要根据官方示例WFS_transactionDelete.xmlWFS_transactionInsert.xmlWFS_transactionUpdate.xmlWFS_transactionUpdateGeom.xml的内容进行测试。

本章示例使用的图层是将数据库表进行发布的,使用接口请求时,需要注意: 图层关联的关系型数据库表需要设置主键,如果不设置主键,执行增删改请求时会有gis_tour is read-only的报错。

二、增删改请求(PG数据库)

wfs增删改相关的接口都是同一个请求地址。 请求地址

http://localhost:1302/geoserver/wfs

1、更新请求

1.1、业务属性更新

请求体

<wfs:Transaction service="WFS" version="1.0.0"
  xmlns:topp="http://www.openplans.org/topp"
  xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:wfs="http://www.opengis.net/wfs">
  <wfs:Update typeName="chatgis:gis_tour">
    <wfs:Property>
      <wfs:Name>name</wfs:Name>
      <wfs:Value>趵突泉2</wfs:Value>
    </wfs:Property>
    <ogc:Filter>
      <PropertyIsEqualTo>
        <PropertyName>id</PropertyName>
        <Literal>1</Literal>
      </PropertyIsEqualTo>
    </ogc:Filter>
  </wfs:Update>
</wfs:Transaction>

返回结果

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:1302/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
    <wfs:InsertResult>
        <ogc:FeatureId fid="none"/>
    </wfs:InsertResult>
    <wfs:TransactionResult>
        <wfs:Status>
            <wfs:SUCCESS/>
        </wfs:Status>
    </wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

1.2、空间数据更新

请求体

<wfs:Transaction service="WFS" version="1.0.0"
  xmlns:topp="http://www.openplans.org/topp"
  xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:wfs="http://www.opengis.net/wfs"
  xmlns:gml="http://www.opengis.net/gml"
  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-transaction.xsd">
  <wfs:Update typeName="chatgis:gis_tour">
    <wfs:Property>
      <wfs:Name>geom</wfs:Name>
      <wfs:Value>
        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:lineStringMember>
          	<gml:LineString>
            	<gml:coordinates>117.018054,36.661197 117.02129,36.661448 117.024922,36.661858 117.027353,36.662228 117.03443,36.662451 117.033678,36.663021 117.03262,36.663606</gml:coordinates>
          	</gml:LineString>
          </gml:lineStringMember>
        </gml:MultiLineString>
      </wfs:Value>
    </wfs:Property>
    <ogc:Filter>
      <ogc:FeatureId fid="gis_tour.2"/>
    </ogc:Filter>
  </wfs:Update>
</wfs:Transaction>

2、插入请求

请求体

<wfs:Transaction service="WFS" version="1.0.0"
  xmlns:wfs="http://www.opengis.net/wfs"
  xmlns:chatgis="http://www.openplans.org/chatgis"
  xmlns:gml="http://www.opengis.net/gml"
  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-transaction.xsd http://www.openplans.org/chatgis http://localhost:8080/geoserver/wfs/DescribeFeatureType?typename=chatgis:gis_tour">
  <wfs:Insert>
    <gis_tour>
      <geom>
        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:lineStringMember>
            <gml:LineString>
              <gml:coordinates decimal="." cs="," ts=" ">
117.028812,36.665438 117.023321,36.664734 117.023029,36.668971 117.023539,36.669651 117.023685,36.670137 117.022738,36.672262
              </gml:coordinates>
            </gml:LineString>
          </gml:lineStringMember>
        </gml:MultiLineString>
      </geom>
      <name>旅游线路2</name>
    </gis_tour>
  </wfs:Insert>
</wfs:Transaction>

返回参数

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:1302/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
    <wfs:InsertResult>
        <ogc:FeatureId fid="gis_tour.3"/>
    </wfs:InsertResult>
    <wfs:TransactionResult>
        <wfs:Status>
            <wfs:SUCCESS/>
        </wfs:Status>
    </wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

3、删除请求

请求体

<wfs:Transaction service="WFS" version="1.0.0"
  xmlns:cdf="http://www.opengis.net/cite/data"
  xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:wfs="http://www.opengis.net/wfs"
  xmlns:chatgis="http://www.openplans.org/chatgis">
  <wfs:Delete typeName="gis_tour">
    <ogc:Filter>
      <ogc:PropertyIsEqualTo>
        <ogc:PropertyName>id</ogc:PropertyName>
        <ogc:Literal>4</ogc:Literal>
      </ogc:PropertyIsEqualTo>
    </ogc:Filter>
  </wfs:Delete>
</wfs:Transaction>

返回结果

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:1302/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
    <wfs:InsertResult>
        <ogc:FeatureId fid="none"/>
    </wfs:InsertResult>
    <wfs:TransactionResult>
        <wfs:Status>
            <wfs:SUCCESS/>
        </wfs:Status>
    </wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

三、增删改请求(MySQL8.X数据库)

1、纬度在前,经度在后

由于MySQL8.X版本数据库存储空间数据是按照纬度在前,经度在后的顺序进行存储的,所以采用上面的方式插入、更新空间数据是有问题的。 比如:插入请求 请求体

<wfs:Transaction service="WFS" version="1.0.0"
  xmlns:wfs="http://www.opengis.net/wfs"
  xmlns:chatgis="http://www.openplans.org/chatgis"
  xmlns:gml="http://www.opengis.net/gml"
  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-transaction.xsd http://www.openplans.org/chatgis http://localhost:8080/geoserver/wfs/DescribeFeatureType?typename=chatgis:gis_tour_1">
  <wfs:Insert>
    <gis_tour_1>
      <geom>
        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:lineStringMember>
            <gml:LineString>
              <gml:coordinates decimal="." cs="," ts=" ">
117.028812,36.665438 117.023321,36.664734 117.023029,36.668971 117.023539,36.669651 117.023685,36.670137 117.022738,36.672262
              </gml:coordinates>
            </gml:LineString>
          </gml:lineStringMember>
        </gml:MultiLineString>
      </geom>
      <name>旅游线路2</name>
    </gis_tour_1>
  </wfs:Insert>
</wfs:Transaction>

返回结果

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:1302/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
    <wfs:InsertResult>
        <ogc:FeatureId fid="none"/>
    </wfs:InsertResult>
    <wfs:TransactionResult>
        <wfs:Status>
            <wfs:FAILED/>
        </wfs:Status>
        <wfs:Message>Insert error: Error inserting features</wfs:Message>
    </wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

查看日志,可以查看更明确的报错信息

Caused by: java.io.IOException: Error inserting features
	at org.geotools.jdbc.JDBCDataStore.insert(JDBCDataStore.java:1878)
	at org.geotools.jdbc.JDBCInsertFeatureWriter.flush(JDBCInsertFeatureWriter.java:130)
	at org.geotools.jdbc.JDBCInsertFeatureWriter.write(JDBCInsertFeatureWriter.java:102)
	at org.geotools.data.InProcessLockingManager$1.write(InProcessLockingManager.java:308)
	at org.geotools.data.store.ContentFeatureStore.addFeature(ContentFeatureStore.java:295)
	at org.geotools.data.store.ContentFeatureStore.addFeatures(ContentFeatureStore.java:250)
	at org.geoserver.feature.retype.RetypingFeatureStore.addFeatures(RetypingFeatureStore.java:76)
	at org.vfny.geoserver.global.GeoServerFeatureStore.addFeatures(GeoServerFeatureStore.java:63)
	at org.geoserver.wfs.InsertElementHandler.execute(InsertElementHandler.java:205)
	... 120 more
Caused by: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Latitude 117.028812 is out of range in function st_geomfromtext. It must be within [-90.000000, 90.000000].
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104)
	at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1335)
	at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2089)
	at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1340)
	at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:323)
	at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:323)
	at org.geotools.jdbc.JDBCDataStore.insertNonPS(JDBCDataStore.java:2069)
	at org.geotools.jdbc.JDBCDataStore.insert(JDBCDataStore.java:1874)
	... 128 more

根据日志可知:Latitude 117.028812 is out of range in function st_geomfromtext. It must be within [-90.000000, 90.000000].

2、解决方式

将经纬度顺序调换即可;将示例中的117.028812,36.665438 117.023321,36.664734 117.023029,36.668971 117.023539,36.669651 117.023685,36.670137 117.022738,36.672262改为36.665438,117.028812 36.664734,117.023321 36.668971,117.023029 36.669651,117.023539 36.670137,117.023685 36.672262,117.022738