前言

缓冲区分析是地理信息系统(GIS)空间分析的核心功能之一。它通过围绕点、线或面等地理实体,自动生成指定距离(或宽度)的等距区域(缓冲区)。该功能为量化空间邻近度、评估影响范围、识别潜在冲突或关联区域提供了基础而强大的工具,是理解空间关系、支持空间决策不可或缺的重要手段。

本篇教程在之前一系列文章的基础上讲解如何将使用GeoTools工具结合OpenLayers实现空间数据的空间缓冲区分析功能。

  • GeoTools 开发环境搭建[1]
  • 将 Shp 导入 PostGIS 空间数据的五种方式(全)[2]
  • GeoTools 结合 OpenLayers 实现空间查询[3]

如果你还没有看过,建议从那里开始。

1. 开发环境

本文使用如下开发环境,以供参考。

时间:2025年

GeoTools:v34-SNAPSHOT

IDE:IDEA2025.1.2

JDK:v17

OpenLayers:v9.2.4

Layui:v2.9.14

2. 搭建后端服务

在项目接口层创建SpatialAnalyseController空间分析控制器。声明缓冲区分析需要的参数一个Geometry类型的GeoJSON标准对象和一个缓冲距离对象。

package com.example.geotoolsboot.controller;import com.example.geotoolsboot.service.ISpatialAnalyseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;/*** @name: SpatialAnalyseController* @description: 空间分析控制器* @author: gis_road* @date: 2025-08-05*/
@CrossOrigin(origins = "*") // 允许跨域
@RestController
public class SpatialAnalyseController {@Autowiredprivate ISpatialAnalyseService spatialAnalyseService;@GetMapping("/bufferAnalyse")public Map<String,Object> bufferAnalyse(@RequestParam() String geoJSON, Float bufferDistance){return spatialAnalyseService.bufferAnalyse(geoJSON,bufferDistance);}
}

在服务层创建ISpatialAnalyseService接口并定义缓冲分析方法。

package com.example.geotoolsboot.service;import java.util.Map;/*** @name: ISpatialAnalyseService* @description: 空间分析服务层* @author: gis_road* @date: 2025-08-05*/
public interface ISpatialAnalyseService {Map<String,Object> bufferAnalyse(String geoJSON,Float bufferDistance);
}

在服务层中实现ISpatialAnalyseService接口。首先将前端传递过来的Geomery GeoJSON字符串对象转换为GeoTools中的Geometry对象,之后便可以调用buffer方法创建缓冲区对象,最后将缓冲分析结果再转换为GeoJSON对象并返回给前端。

package com.example.geotoolsboot.service.impl;import com.example.geotoolsboot.service.ISpatialAnalyseService;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;
import org.springframework.stereotype.Service;import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;/*** @name: SpatialAnalyseServiceImpl* @description: 空间分析实现层* @author: gis_road* @date: 2025-08-05*/@Service
public class SpatialAnalyseServiceImpl implements ISpatialAnalyseService {@Overridepublic Map<String,Object>  bufferAnalyse(String geoJSON,Float bufferDistance) {Map<String,Object> resultMap = new HashMap<>();// 读取GeoJSON几何对象GeometryJSON geometryJSON = new GeometryJSON(15);StringReader reader = new StringReader(geoJSON);try{Geometry geometry = geometryJSON.read(reader);// 根据距离创建缓冲对象Geometry geoBuffer  = geometry.buffer(bufferDistance);// 将缓冲结果转换为Geometry GeoJSON对象StringWriter writer = new StringWriter();geometryJSON.write(geoBuffer,writer);String geoBufferJSON = writer.toString();resultMap.put("data",geoBufferJSON);}catch (Exception e){e.printStackTrace();}return resultMap;}
}

3. OpenLayers 加载缓冲对象

本文前端使用OpenLayers结合Layui框架实现。为了方便控制缓冲区生成距离,本文使用坐标系为投影坐标系,具体EPSG为4522。

缓冲区分析面板CSS结构。

.query-wrap {position: absolute;padding: 10px;top: 80px;left: 90px;background: #ffffff;width: 250px;border-radius: 2.5px;
}

HTML结构。

<div class="query-wrap"><form class="layui-form layui-form-pane" action=""><div class="layui-form-item"><label class="layui-form-label">绘制对象</label><div class="layui-input-block"><select name="condition" lay-filter="draw-select-filter"><option value="None">请选择绘制类型</option><option value="Point">点</option><option value="LineString">线</option><option value="Polygon">面</option></select></div></div><div class="layui-form-item"><label class="layui-form-label">缓冲距离</label><div class="layui-input-block"><input type="text" name="bufferDistance" lay-verify="required" placeholder="缓冲距离(m)"autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><button lay-submit lay-filter="clearAll" class="layui-btn layui-btn-primary">清除</button><button class="layui-btn" lay-submit lay-filter="spatialAnalyse">确认</button></div></form>
</div>

前端实现代码如下,逻辑也很简单。

let drawInteraction = null // 绘制控件
let geoJSON = null // 绘制的Geometry GeoJSON对象
let bufferDistance = 0 // 缓冲距离layui.use(['form'], function () {const form = layui.form;const layer = layui.layer;// 绘制事件form.on('select(draw-select-filter)', function (data) {removeInteraction()const value = data.value; // 获得被选中的值drawShape(value)});// 清除事件form.on("submit(clearAll)", function (data) {// 清除绘制事件removeInteraction()// 清除图形removeAllLayer(map)return false; // 阻止默认 form 跳转})// 提交事件form.on('submit(spatialAnalyse)', function (data) {if (!geoJSON) {layer.msg("请绘制缓冲区域")return false}const bufferDistance = +data.field.bufferDistanceif (!bufferDistance) {layer.msg("请输入缓冲距离")return false}const queryParam = encodeURIComponent(geoJSON)// 后端服务地址const JSON_URL = `http://127.0.0.1:8080/bufferAnalyse?geoJSON=${queryParam}&bufferDistance=${bufferDistance}`fetch(JSON_URL).then(response => response.json().then(result => {removeLayerByName("bufferLayer", map)const bufferJSON = JSON.parse(result.data)const feature = new ol.Feature({type: "Feature",geometry: new ol.format.GeoJSON().readGeometry(bufferJSON)})const vectorSource = new ol.source.Vector({features: [feature],format: new ol.format.GeoJSON()})// 缓冲区图层const bufferLayer = new ol.layer.Vector({source: vectorSource,style: new ol.style.Style({fill: new ol.style.Fill({color: "#e77b7e8f"}),stroke: new ol.style.Stroke({color: "#da4736c2",width: 2.5,}),})})bufferLayer.set("layerName", "bufferLayer")map.addLayer(bufferLayer)map.getView().fit(feature.getGeometry().getExtent())}))return false; // 阻止默认 form 跳转});
});

创建drawShape函数,用于绘制点、线和面等几何类型,removeInteraction方法用于移除绘制控件。需要监听绘制完成事件,当绘制结束后,读取绘制要素并获取Geometry对象。

/*** 根据几何类型绘制几何对象*/
function drawShape(type) {const drawSource = new ol.source.Vector({ wrapX: false })const drawLayer = new ol.layer.Vector({source: drawSource,style})drawLayer.setZIndex(999)map.addLayer(drawLayer)geoJSON = nullif (type === "None") {removeInteraction()// 清除图形drawSource.clear()return}let geometryFunction = nulldrawInteraction = new ol.interaction.Draw({source: drawSource,type,geometryFunction,style,// freehand: true // 是否开启自由绘制模式})map.addInteraction(drawInteraction)drawInteraction.on('drawend', evt => {const feature = evt.featureconst featObj = new ol.format.GeoJSON().writeFeature(feature)const geomtObj = new ol.format.GeoJSON().writeGeometry(feature.getGeometry())// 存储绘制对象geoJSON = geomtObj})}// 移除绘制控件
function removeInteraction() {if (drawInteraction) {map.removeInteraction(drawInteraction)}
}

参考资料

[1]GeoTools 开发环境搭建

[2]将 Shp 导入 PostGIS 空间数据的五种方式(全)

[3]GeoTools 结合 OpenLayers 实现空间查询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917851.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917851.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917851.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 接入SSE实现消息实时推送的优点,原理以及实现

SpringBoot 接入SSE实现消息实时推送的优点,原理以及实现 前言 上一篇文章 我写的关于SpringBoot整合t-io是websocket实时通信的文章中我们可以了解到 websocket是双向通信的,而且需要TCP连接的支持,今天在这里我要说的SSE(Server-Sent Events) 是一个单项通信的消息实时推…

创建型设计模式:对象诞生的艺术与智慧

&#x1f3ad; 创建型设计模式&#xff1a;对象诞生的艺术与智慧 &#x1f4a1; 温馨提示&#xff1a;本文将以轻松有趣的方式带你探索设计模式的世界&#xff0c;就像在听一个关于"如何优雅地生孩子"的故事一样&#xff01; &#x1f6aa; 传送门&#xff1a;在开始…

如何解决pip安装报错ModuleNotFoundError: No module named ‘gensim’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘gensim’问题 摘要 在使用 PyCharm 2025 进行 Python 开发时&#xff0c;常常需要通过 pip install 安装第三方包以丰富项目功能。但在安装 gensim 等包时&…

【嵌入式电机控制#26】BLDC:三相模拟采集

之前有些网友试着用有刷的平均电流法采集三相&#xff0c;还搞了个闭环控制。求&#xff01;结果直接把驱动板给干没了......做过仿真的朋友们都知道&#xff0c;无刷电机的相电流波形是介于方波和正弦波的。如果拿平均电流去测量&#xff0c;很不靠谱。这节内容为大家分享采集…

ref存储对象和reactive深度响应式递归地对对象的嵌套属性进行响应式处理

ref 不会递归地对 对象 或 数组 中的每个属性或元素进行深度响应式处理。如果你需要递归处理嵌套属性&#xff0c;reactive 是更适合的选择。让我通过具体的例子来展示这一点。 例子&#xff1a;ref 存储对象和嵌套对象 1. 使用 ref 存储嵌套对象&#xff1a; import { createA…

小鹏汽车前端面经

前端基础与浏览器机制 (Front-End Fundamentals & Browser Mechanics) 这些问题涵盖了Web工作的基本原理&#xff0c;包括网络、渲染和浏览器特性。 1. 浏览器渲染与性能 (Browser Rendering & Performance) URL输入发生什么&#xff1f;(What happens when you type a…

利用DeepSeek编写go语言按行排序程序

听说google出品的go语言也是系统开发中常用的&#xff0c;性能到底怎么样&#xff0c;还是老办法&#xff0c;让DeepSeek写个程序跑一下&#xff0c;基于以往的经验&#xff0c;直接让它同时编写有缓冲和无缓冲版本。 package mainimport ("bufio""fmt"&qu…

《解构Angular组件变化检测:从自动到手 动的效能突破》

为何有时数据更新后视图却无动于衷?为何看似简单的操作会引发连锁式的性能损耗?要解开这些疑问,需要穿透表层的API调用,深入到框架设计的底层逻辑中去。变化检测的核心使命,是确保视图层能够准确反映数据层的当前状态。这种"数据-视图"的同步关系,是所有前端框…

书单 | AI编程+Python+Go三大核心领域书单

这份书单聚焦AI编程、Python开发、Go语言三大核心领域&#xff0c;精选6本本月 最具前瞻性的技术图书&#xff0c;为你构建"工具链业务层系统层"的全栈能力。 1、人人皆可Vibe编程&#xff1a;玩转氛围编程 作者&#xff1a;池志炜,薛志荣 本书围绕Vibe编程这一AI驱…

Kali Linux 2025.2基于MITRE ATTCK框架

从彻底革新的菜单结构到新增的13款尖端工具&#xff0c;再到首次支持智能手表Wi-Fi注入&#xff0c;Kali Linux 2025.2为红队、蓝队以及安全研究人员提供了更高效、更直观的工具生态。菜单结构大变革&#xff1a;基于MITRE ATT&CK框架Kali Linux 2025.2最引人注目的变化之一…

javacc实现简单SQL解析器

文章目录前言本章节源码需求1&#xff1a;实现一个最简单的select sql要求实现jj文件编译测试需求2&#xff1a;理解Token及其他属性说明javajj文件需求3&#xff1a;实现解析得到SQL语法树 & 精确点位资料获取前言 博主介绍&#xff1a;✌目前全网粉丝4W&#xff0c;csdn…

Odoo OWL前端框架全面学习指南 (后端开发者视角)

核心理念&#xff1a; 将您熟悉的Odoo后端MVCORM架构思想&#xff0c;完整映射到前端OWL组件化开发中&#xff0c;让您在熟悉的概念体系下&#xff0c;快速掌握新的技术栈。第一部分&#xff1a;核心概念映射与环境搭建内容摘要&#xff1a; 本部分旨在建立后端与前端最核心的概…

Java开发工具包,jdk,idea,VMware,rocketmq,redis,CentOS7

Java开发工具包&#xff0c;jdk&#xff0c;idea&#xff0c;VMware&#xff0c;rocketmq&#xff0c;redis&#xff0c;CentOS7 下载地址 通过网盘分享的文件&#xff1a;Java开发环境工具包 链接: https://pan.baidu.com/s/1eJqvPx5DYqtmXgmEtOl8-A?pwdcj1f 提取码: cj1f –…

macOS Python 安装

目录 一、确认系统环境 二、安装 &#xff08;一&#xff09;下载安装包 &#xff08;二&#xff09;安装过程 三、配置环境变量 四、验证安装 一、确认系统环境 在安装 Python 之前&#xff0c;我们先简单了解一下自己的 MACOS 系统。可以点击屏幕左上角的苹果菜单&…

MySQL 全方位解析:从基础到高可用架构

1. 介绍 (Introduction) 1.1. 什么是 MySQL&#xff1f; MySQL 是全球最受欢迎的开源关系型数据库管理系统 (Relational Database Management System, RDBMS)。它由瑞典的 MySQL AB 公司开发&#xff0c;现隶属于 Oracle 公司。MySQL 将数据存储在不同的、预先定义好结构的表中…

力扣热题100——滑动窗口

无重复字符的最长子串步骤 1&#xff1a;初始状态 字符串 s “abcabcbb”&#xff0c;哈希表 charSet 初始为空&#xff0c;双指针 left 0&#xff0c;right 0。 哈希表&#xff08;charSet&#xff09;&#xff1a; {} 字符串&#xff1a; a b c a b c b b 指…

SOD-YOLO:增强基于YOLO的无人机影像小目标检测

摘要 https://www.arxiv.org/pdf/2507.12727 小目标检测仍是目标检测领域中的一个挑战性问题。为应对这一挑战&#xff0c;我们提出了一种基于YOLOv8的增强模型SOD-YOLO。该模型在颈部&#xff08;neck&#xff09;中集成了ASF&#xff08;注意力尺度序列融合&#xff09;机制以…

监督微调-指令微调-偏好微调

有监督微调 有监督微调是使用输入及其标签对的典型情况。例如&#xff0c;判断邮件是垃圾邮件还是非垃圾邮件&#xff0c;判断情感是积极还是消极。根据文档的主要主题对其进行分类也是一种常见应用。模型会将输入文本的相应表示&#xff08;隐藏状态或嵌入向量&#xff09;作为…

楼宇自控系统对建筑碳中和目标的实现具重要价值

随着全球气候变化问题日益严峻&#xff0c;建筑行业作为碳排放的重要来源之一&#xff0c;其节能减排工作备受关注。楼宇自控系统&#xff08;Building Automation System&#xff0c;BAS&#xff09;作为智能建筑的核心组成部分&#xff0c;通过集成控制、监测和管理建筑内的各…

【YOLO学习笔记】YOLOv5详解

一、数据增强 mosaic仿射变换与透视变换Mixup mosaic代码位置仿射变换 与 透视变换​代码片段位置 二、网络结构 1. 网络不同尺寸 nsmlx与网络深宽度 yolov5 官方提供了5个目标检测的网络版本&#xff1a;yolov5n、yolov5s、yolov5m、yolov5l、yolov5x &#xff0c;早年是…