当前位置: 首页 > news >正文

GeoTools 结合 OpenLayers 实现缓冲区分析

前言

缓冲区分析是地理信息系统(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.dtcms.com/a/318493.html

相关文章:

  • LINQ 要点
  • 92、【OS】【Nuttx】【构建】cmake 支持构建的目标
  • SOD-YOLO:增强基于YOLO的无人机影像小目标检测
  • Product Hunt 每日热榜 | 2025-08-06
  • GoogLeNet训练
  • FastDeploy2.0:Error reading file: SafeTensorError::MetadataIncompleteBuffer
  • chdir系统调用及示例
  • 【C/C++】形参、实参相关内容整理
  • 零基础-动手学深度学习-8.7. 通过时间反向传播
  • Spring_事务
  • 国产3D大型装配设计新突破①:图纸打开设计双加速 | 中望3D 2026
  • C语言的数组与字符串练习题2
  • 如何快速翻译PPT中的文字(或简繁体转换)
  • 【51单片机2个独立按键2个独立数码管静态显示内容自定】2022-10-22
  • Perforce P4 Plan - DevOps实时规划工具
  • 指挥中心自动化的演变
  • 无人机遥控器波特率技术解析
  • 前端开发_怎么禁止用户复制内容
  • 计算机网络:如何判断B或者C类IP地址是否划分了子网
  • 设备 AI 知识库如何提升管理效率?实测分享
  • 【STM32U385RG 测评】基于VSCode的STM32开发环境搭建
  • 认识河豚毒素!剧毒神经毒素详解!
  • 向量数据库基础夯实:相关概念的详细介绍
  • 淘宝/天猫商品详情API详解(tb.item_get)
  • 一文读懂:什么是CLIP
  • 分布式存储 Ceph 的演进经验 · SOSP 2019
  • 【Web安全】csrf、ssrf和xxe的区别
  • GPT-OSS-20B vs Qwen3-14B 全面对比测试
  • 【大模型系列】gpt-oss系列模型初探
  • ACL 2025 Oral|Evaluation Agent:面向视觉生成模型的高效可提示的评估框架