基于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.feature
    addBlockData([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/wfs
                          http://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工具生成的,太好用了,也是我太懒了,整理的工作省去了。但是有些易错点上述内容没有表达出来,我这里补充一些:

  1. 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.

  2. 图层服务需给定权限,否则接口报错如下
    在这里插入图片描述
    设置方法如下
    在这里插入图片描述

  3. 接口提交的参数类型应与数据库表中geom类型一致
    比如数据库表geom字段类型是MULTI,而提交的没有MULTI,就会报错。我使用Openlayers生成的参数并没有MULTI,导致接口总是报错——Error performing insert: java.lang.String cannot be cast to org.locationtech.jts.geom.Geometry
    我最终是重新用PostGIS执行导入,在导入时勾上简单Geometry,如下:

  4. GML设置正确的坐标系,否则生成的经纬度是相反的(即纬度在前,经度在后)
    这里我没仔细探究——地图和图层我设置为4490,GML设置为4326时会出现这种错误顺序。GML改为4490时就恢复正常了。
    我猜测是两者经纬度不一致,导致GML使用了默认的3857.

  const formatGML = new GML({
    featureNS: 'http://www.opengis.net/gml',
    featureType: 'block',
    srsName: 'EPSG:4490'
  });
  1. 最后,将新增、编辑、删除相关的参数列一下,供各位参考

    新增代码如下:

<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/wfs
                          http://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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/973058.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动化之ansible(二)

一、ansible中playbook&#xff08;剧本&#xff09; 官方文档&#xff1a; Ansible playbooks — Ansible Community Documentation 1、playbook的基本结构 一个基本的playbook由以下几个主要部分组成 hosts: 定义要执行任务的主机组或主机。 become: 是否需要使用超级用户…

函数执行中的栈和寄存器调用

函数执行中的栈和寄存器调用 函数执行过程中主要用到的寄存器有程序计数器和栈指针。 程序计数器&#xff08;IP&#xff09;&#xff1a;指向下一条执行指令的地址&#xff0c;其值用%rip来表示 栈指针&#xff1a;指向栈顶地址&#xff0c;其值用%rsp来表示 当过程P调用过…

纯新手教程:用llama.cpp本地部署DeepSeek蒸馏模型

0. 前言 llama.cpp是一个基于纯C/C实现的高性能大语言模型推理引擎&#xff0c;专为优化本地及云端部署而设计。其核心目标在于通过底层硬件加速和量化技术&#xff0c;实现在多样化硬件平台上的高效推理&#xff0c;同时保持低资源占用与易用性。 最近DeepSeek太火了&#x…

建筑兔零基础自学python记录22|实战人脸识别项目——视频人脸识别(下)11

这次我们继续解读代码&#xff0c;我们主要来看下面两个部分&#xff1b; 至于人脸识别成功的要点我们在最后总结~ 具体代码学习&#xff1a; #定义人脸名称 def name():#预学习照片存放位置path M:/python/workspace/PythonProject/face/imagePaths[os.path.join(path,f) f…

【Java消息队列】应对消息丢失、重复、顺序与积压的全面策略

应对消息丢失、重复、顺序与积压的全面策略 引言kafka消息丢失生产者消费者重复消费顺序消费消息积压生产者消费者其他RabbitMQ消息丢失生产者事务机制,保证生产者发送消息到 RabbitMQ Server发送方确认机制,保证消息能从交换机路由到指定队列保证消息在 RabbitMQ Server 中的…

PHP会务会议系统小程序源码

&#x1f4c5; 会务会议系统 一款基于ThinkPHPUniapp框架&#xff0c;精心雕琢的会议管理微信小程序&#xff0c;专为各类高端会议场景量身打造。它犹如一把开启智慧殿堂的金钥匙&#xff0c;为会议流程优化、开支精细化管理、数量精准控制、标准严格设定以及供应商严格筛选等…

Unity通过Vosk实现离线语音识别方法

标注&#xff1a;deepseek直接生成&#xff0c;待验证 在Unity中实现离线语音识别可以通过集成第三方语音识别库来实现。以下是一个使用 Unity 和 Vosk&#xff08;一个开源的离线语音识别库&#xff09;的简单示例。 准备工作 Vosk&#xff1a;一个开源的离线语音识别库&am…

架构学习第七周--Prometheus

目录 一、监控系统基础 二、Prometheus介绍 三、Prometheus单机部署 四、服务发现与告警功能 4.1&#xff0c;服务发现 4.2&#xff0c;告警功能实现 五、Prometheus与Kubernetes 5.1&#xff0c;Kubernetes指标 5.2&#xff0c;Prometheus集群部署 一、监控系统基础…

技术总结 | MySQL面试知识点

MySQL面试知识点 1.存储引擎1.1 Archive1.2 BlackHole1.3 MyISAM1.4 InnoDB (重点记一下哦)1.5 Memory1.6 CSV 2. 事务2.1. 什么是事务2.2. 事务的特性2.3. 事务的操作sql2.4. 事务的隔离级别 3.三大日志3.1. undo log 回滚日志3.2. redo log 重做日志3.3. bin log 二进制日志4…

DeepSeek模型快速部署教程-搭建自己的DeepSeek

前言&#xff1a;在人工智能技术飞速发展的今天&#xff0c;深度学习模型已成为推动各行各业智能化转型的核心驱动力。DeepSeek 作为一款领先的 AI 模型&#xff0c;凭借其高效的性能和灵活的部署方式&#xff0c;受到了广泛关注。无论是自然语言处理、图像识别&#xff0c;还是…

图论 之 BFS

文章目录 3243.新增道路查询后的最短距离1311.获取你好友已观看的视频 BFS:广度优先搜索&#xff08;BFS&#xff09; 是一种常用的算法&#xff0c;通常用于解决图或树的遍历问题&#xff0c;尤其是寻找最短路径或层级遍历的场景。BFS 的核心思想是使用队列&#xff08;FIFO 数…

VSCode集成deepseek使用介绍(Visual Studio Code)

VSCode集成deepseek使用介绍&#xff08;Visual Studio Code&#xff09; 1. 简介 随着AI辅助编程工具的快速发展&#xff0c;VSCode作为一款轻量级、高度可扩展的代码编辑器&#xff0c;已成为开发者首选的工具之一。DeepSeek作为AI模型&#xff0c;结合Roo Code插件&#x…

Qt中利用httplib调用https接口

httplib中如果要调用https接口&#xff0c;需要开启OPENSSL支持&#xff0c;经过半天坑爹得摸索&#xff0c;总结下经验。 1&#xff0c;下载 并安装Win64OpenSSL 地址如下&#xff0c;我Qt版本是5.15.2 &#xff0c;openssl选择的是 64位&#xff08;Win64OpenSSL-3_3_3.msi…

使用Geotools读取DEM地形数据实战-以湖南省30米数据为例

目录 前言 一、DEM地形数据介绍 1、DEM数据简介 2、DEM应用领域 3、QGIS中读取DEM数据 二、GeoTools解析地形 1、Maven中依赖引用 2、获取数据基本信息 三、总结 前言 随着全球数字化进程的加速&#xff0c;各类地理空间数据呈爆炸式增长&#xff0c;DEM 数据作为其中的…

登录-01.基础登录功能

一.需求分析 当前的页面不需要登录就可以进入&#xff0c;十分不安全&#xff0c;因此要设置登录功能来维护系统的安全性。登录时要根据输入的用户名和密码进行登录校验&#xff0c;如果在数据库中没有找到匹配的用户名和密码的话&#xff0c;那么就无法登录。 因此要先根据用…

调用click.getchar()时Windows PyCharm无法模拟键盘输入

文章目录 问题描述解决方案参考文献 问题描述 调用 click.getchar() 时&#xff0c;Windows PyCharm 无法模拟键盘输入 解决方案 Run → Edit Configurations… → Modify options → Emulate terminal in output console 参考文献 Terminal emulator | PyCharm Documentati…

京东杀入外卖界,这波操作到底香不香?

京东杀入外卖界&#xff0c;这波操作到底香不香&#xff1f; 最近外卖圈炸了&#xff01;京东这个电商巨头&#xff0c;居然一声不吭地搞起了外卖&#xff01;一出手就是0佣金&#xff0c;品质堂食 两大杀招&#xff0c;直接把美团、饿了么整懵了。今天咱们就来唠唠&#xff0…

PTH 哈希传递攻击

参考文章&#xff1a;内网渗透 | 哈希传递攻击(Pass-the-Hash,PtH)-腾讯云开发者社区-腾讯云 哈希传递攻击(Pass-the-Hash,PtH)_c 实现 pass the hash功能-CSDN博客 域控机器账户&#xff1a;WIN-0V0GAORDC17 域控 ip&#xff1a;192.168.72.163 域内攻击者机器 ip&#xf…

Vue3项目,蛋糕商城系统

简单的vue3商城 蛋糕商城系统 下单平台 带用户 登录 注册 首页轮播图 购物车后台管理 商品订单 登录注册 商品详情 纯前端无后台、无数据库 纯Vue3项目作业 vue3 setup语法糖写法 技术实现 本项目主要使用如下技术实现&#xff0c; - 基于vue3vite搭建的项目框架 -…

快速上手gdb/cgdb

Linux调试器-gdb使用 1.背景2.调试原理、技巧命令2.1指令2.2 本质2.3 技巧 1.背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g…