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.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;早年是…