基于Openlayers对GeoServer发布的数据进行增删改
使用GeoServer进行图斑数据管理
本文将介绍如何使用GeoServer进行图斑数据的新增、删除和修改。我们将通过一个Vue.js应用来演示这些功能。
设置Vue.js应用
首先,我们设置Vue.js应用,并添加必要的组件和交互逻辑。
Check.vue
Check.vue
文件包含初始化地图和处理图斑交互的主要逻辑。
// filepath: /D:/workspace/check/client/src/views/Check.vue
<template><div class="page"><Header /><Map @map="init" /><div class="tool"><button @click="enableDraw">新增</button><button @click="enableModify">编辑</button><button @click="enableDelete">删除</button></div></div>
</template><script setup>
import Header from '../components/Header.vue'
import Map from '../components/Map.vue'
import { getBlockData, addBlockData, updateBlockData, deleteBlockData } from '../api'
// ...existing code...function init(mapInstance) {map = mapInstance// ...existing code...select.on('select', (e) => {e.selected.forEach((feature) => {const featureId = feature.getId()deleteBlockData(featureId).then(response => {vectorLayer.getSource().removeFeature(feature)}).catch(error => {console.error('Error deleting block data:', error)})})})getBlock()// ...existing code...
}function getBlock() {const view = map.getView()const extent = view.calculateExtent()getBlockData(extent).then(response => {const features = new GeoJSON().readFeatures(response.data, {featureProjection: map.getView().getProjection()})vectorLayer.getSource().clear()vectorLayer.getSource().addFeatures(features)}).catch(error => {console.error('Error fetching block data:', error)})
}function initAction() {draw.on('drawend', (event) => {const feature = event.featureaddBlockData([feature]).then(response => {console.log('Add Response:', response.data)}).catch(error => {console.error('Error adding block data:', error)})})modify.on('modifyend', (event) => {const features = event.features.getArray()updateBlockData(features).then(response => {console.log('Update Response:', response.data)}).catch(error => {console.error('Error updating block data:', error)})})
}
</script><style scoped>
.page {position: relative;display: flex;flex-direction: column;align-items: center;justify-content: center;height: 100vh;background-color: #f0f0f0;
}
.tool {position: absolute;bottom: 10px;left: 10px;display: flex;gap: 10px;
}
</style>
API交互
接下来,我们来看一下api.js
中与GeoServer通信的函数。
api.js
api.js
文件包含获取、添加、更新和删除图斑数据的函数。
// filepath: /D:/workspace/check/client/src/api.js
import axios from 'axios';
import WFS from 'ol/format/WFS';
import GML from 'ol/format/GML';// 创建 axios 实例
const api = axios.create({baseURL: 'http://localhost:8080/geoserver/dahong',timeout: 10000,
});// 获取指定范围内的图斑数据
export function getBlockData(extent) {const url = `/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=dahong:block&maxFeatures=50&bbox=${extent.join(',')}&outputFormat=application/json`;return api.get(url);
}// 新增图斑数据
export function addBlockData(features) {const formatWFS = new WFS();const formatGML = new GML({featureNS: 'http://dahong.me',featurePrefix: 'dahong',featureType: 'block',srsName: 'EPSG:4490',});const node = formatWFS.writeTransaction(features, null, null, formatGML);const serializer = new XMLSerializer();const data = serializer.serializeToString(node);const d = data.replaceAll('geometry', 'geom');const url = `/wfs?service=WFS&version=1.0.0&request=Transaction`;return api.post(url, d, {headers: {'Content-Type': 'text/xml'}});
}// 更新图斑数据
export function updateBlockData(features) {const formatWFS = new WFS();const formatGML = new GML({featureNS: 'http://www.opengis.net/gml',featureType: 'block',srsName: 'EPSG:4490'});const node = formatWFS.writeTransaction(null, features, null, formatGML);const serializer = new XMLSerializer();const data = serializer.serializeToString(node);const d = data.replaceAll('geometry', 'geom');const url = `/wfs?service=WFS&version=1.0.0&request=Transaction`;return api.post(url, d, {headers: {'Content-Type': 'text/xml'}});
}// 删除图斑数据
export function deleteBlockData(featureId) {const url = `/wfs?service=WFS&version=1.0.0&request=Transaction`;const data = `<wfs:Transaction service="WFS" version="1.0.0"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/wfshttp://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"><wfs:Delete typeName="dahong:block"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="${featureId}"/></ogc:Filter></wfs:Delete></wfs:Transaction>`;return api.post(url, data, {headers: {'Content-Type': 'text/xml'}});
}export default api;
补充
上述内容是由AI工具生成的,太好用了,也是我太懒了,整理的工作省去了。但是有些易错点上述内容没有表达出来,我这里补充一些:
-
GeoServer发布的数据是基于Postgresql。如果GeoServer发布的是Shapefile时,编辑和删除操作是没问题的,但新增不行!
新增可以将记录添加进去,但没有空间几何信息,我尝试着修改geometry为the_geom也没用,GeoServer控制台的错误信息:The problem is almost certainly caused by the fact that there are still locks being held on the shapefiles.
-
图层服务需给定权限,否则接口报错如下
设置方法如下
-
接口提交的参数类型应与数据库表中geom类型一致
比如数据库表geom字段类型是MULTI,而提交的没有MULTI,就会报错。我使用Openlayers生成的参数并没有MULTI,导致接口总是报错——Error performing insert: java.lang.String cannot be cast to org.locationtech.jts.geom.Geometry
。
我最终是重新用PostGIS执行导入,在导入时勾上简单Geometry,如下:
-
GML设置正确的坐标系,否则生成的经纬度是相反的(即纬度在前,经度在后)
这里我没仔细探究——地图和图层我设置为4490,GML设置为4326时会出现这种错误顺序。GML改为4490时就恢复正常了。
我猜测是两者经纬度不一致,导致GML使用了默认的3857.
const formatGML = new GML({featureNS: 'http://www.opengis.net/gml',featureType: 'block',srsName: 'EPSG:4490'});
-
最后,将新增、编辑、删除相关的参数列一下,供各位参考
新增代码如下:
<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"><Insert><block xmlns="http://dahong.me"><geom><Polygon xmlns="http://www.opengis.net/gml" srsName="EPSG:4490"><exterior><LinearRing srsName="EPSG:4490"><posList srsDimension="2">120.17887305370036 30.133373356323716 120.18868580467692 30.13552737483077 120.18425809996798 30.127389971581913 120.17887305370036 30.133373356323716</posList></LinearRing></exterior></Polygon></geom></block></Insert>
</Transaction>
编辑代码如下:
<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"><Update typeName="feature:block"xmlns:feature="http://www.opengis.net/gml"><Property><Name>geom</Name><Value><feature:Polygon srsName="EPSG:4490"><feature:exterior><feature:LinearRing srsName="EPSG:4490"><feature:posList srsDimension="2">120.17887305 30.13337336 120.18333609178232 30.13696672765643 120.1886858 30.13552737 120.1842581 30.12738997 120.17887305 30.13337336</feature:posList></feature:LinearRing></feature:exterior></feature:Polygon></Value></Property><Property><Name>id</Name></Property><Filter xmlns="http://www.opengis.net/ogc"><FeatureId fid="block.55409"/></Filter></Update>
</Transaction>
删除代码如下:
<wfs:Transaction service="WFS" version="1.0.0"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/wfshttp://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"><wfs:Delete typeName="dahong:block"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="block.55409"/></ogc:Filter></wfs:Delete>
</wfs:Transaction>