Openlayers6 图形绘制和修改功能(结合React)

Openlayers常用的API了解的差不多了,就开始进入实战了,首先从绘制基本的图形开始,这里主要介绍一下绘制圆形、矩形和多边形。

通过使用openlayers的ol.interaction.Drawol.interaction.Modify模块实现地图上绘制圆形、矩形、多边形并修改编辑。在这里插入图片描述
首先我们需要创建一个地图容器,并添加地图和矢量图层。底图我这里使用了高德图层,矢量图层用于显示用户绘制结果。然后我们通过添加Draw交互控件来实现绘制功能。每个绘制按钮都有一个点击事件处理函数,调用addInteraction方法来添加相应类型的绘制控件。通过添加Modify交互控件实现修改功能。

一、创建地图

在Openlayers中创建一个简单的地图可以通过一下步骤完成:

  1. 引入Openlayers库。
  2. 创建地图视图ol/View实例,并设置初始中心点和缩放级别。
  3. 创建地图层ol/layer/Tile,通常使用瓦片图层ol/source/OSM
  4. 创建地图实例ol/Map,并将之前创建的视图和图层添加进去。
  5. 获取DOM元素并将地图实例挂载到该元素上。
// 引入OpenLayers库
import { Map, View } from 'ol';
import { Tile as TileLayer } from 'ol/layer';
import * as Proj from 'ol/proj';const [map, setMap] = useState(null); // 地图
const [view, setView] = useState(null); // 地图视图useEffect(() => {// 监听地图视图并创建地图实例if (view) {// 创建一个高德图层const tileLayer = new TileLayer({source: new XYZ({url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&scl=1&size=1&style=7&x={x}&y={y}&z={z}'})});// 创建实例const _map = new Map({target: 'map',layers: [tileLayer], // 使用高德图层view: view});setMap(_map);}
}, [view]);useEffect(() => {// 创建一个地图视图const viewObj = new View({center: Proj.transform([104.06403453968424, 30.597419070782898], 'EPSG:4326', 'EPSG:3857'), // 使用'EPSG:3857'投影zoom: 16});setView(viewObj);
}, []);return <div id='map' style={{ width: '100%', height: '100%' }}></div>

二、绘制图形

可以使用VectorLayerVectorSource添加一个矢量图层,该图层可以用来绘制图形。

import { Vector as VectorLayer } from 'ol/layer';
import { Vector as VectorSource } from 'ol/source';
import { Style, Stroke, Fill } from 'ol/style';let drawSource = null;
let drawLayer = null;useEffect(() => {if (map) {drawSource = new VectorSource();// 添加画板layerdrawLayer = new VectorLayer({source: drawSource,style: new Style({fill: new Fill({color: 'rgba(237, 57, 47, 0.35)'}),stroke: new Stroke({color: '#ED392F',width: 4,lineDash: [10]})})});map.addLayer(drawLayer);}
}, [map]);

三、添加地图交互操作

添加DrawModify交互操作,允许用户在地图上绘图并编辑。

ol.interaction.Draw简述

使用 ol.interaction.Draw 绘制图形,Draw控件需要指定一个矢量源和绘制类型。当用户在地图上进行绘制时,绘制结果会被添加到矢量源中。可调用removeInteraction方法取消绘制。

常用属性
  • type:绘制的几何图形的几何类型,包括Point单点、LineString线、Circle圆、Polygon多边形四种类型。
  • features:表示绘制的图形将添加在指定的要素上。
  • source:绘制时指定的数据来源。表示绘制的图形将添加在指定的图层上。
  • geometryFunction:用于指定geometry,包括两参数,分别是coordinatesgeometry,返回geometry。通过该方法可以重新构建图形,比如将圆形构造成五角星。
  • style:指定绘制图形的样式。
  • freehand:手绘线、面等图形。设置属性为true开启手绘模式(随意绘制曲线或者直线)。
  • maxPoints:最多可以绘制多少个点,比如设置成5,在绘制多边形时,如果超过了5个点就不能绘制了。
  • minPoints:在完成多边形环或线时,必须指定绘制的点数。多边形的默认值为3,线段的默认值为2。
常用方法
  • createBox:当typeCircle时将geometryFunction设置成该方法,可以绘制矩形。
  • createRegularPolygon:当typeCircle时将geometryFunction设置成该方法,可以正多边形。
  • appendCoordinates:当在绘制完线或者多边形后,还可以通过该方法往图形中添加坐标。
  • extend:扩展图片,可以往图形上再添加一个图形,仅限于线条。
  • finishDrawing:结束绘制。
  • removeLastPoint:删除最后一个坐标点。
常用事件
  • drawend:绘制结束时触发。
  • drawstart:绘制开始时触发。
Draw实例
import { Draw } from 'ol/interaction';
import { Style, Stroke, Fill, Circle as CircleStyle } from 'ol/style';let draw = null;// 添加Draw交互操作
draw = new Draw({source: drawSource,type: 'Polygon',style: new Style({fill: new Fill({color: 'rgba(237, 57, 47, 0.35)'}),stroke: new Stroke({color: '#ED392F',width: 4,lineDash: [10]}),image: new CircleStyle({radius: 7,fill: new Fill({color: '#ED392F'})})})
});
// 添加Draw交互
map.addInteraction(draw);draw.on('drawend',function() {// 绘制结束时触发
});
draw.on('drawstart',function() {// 绘制开始时触发
});
ol.interaction.Modify简述

使用 ol.interaction.Modify 编辑图形。只要将它初始化作为交互控件加入Map对象,就可以对几何图形进行动态编辑。
将鼠标移动到已经绘制好的线条或点上面,再移动鼠标,可以对图形进行修改。
按住Alt键时,再点击鼠标,可以删除选中的点。

常用属性
  • condition:设置一个函数,在修改时监听点击事件,返回一个布尔值表示是否处理该点击事件。比如返回false时,选中点后,点击选中的点再移动鼠标时将不处理移动事件。
  • deleteCondition:设置一个函数,返回一个布尔值是否执行删除的操作。
  • insertVertexCondition:设置一个函数,返回一个布尔值表示是否添加新的点。比如我们在编辑多边形时,点击多边形上的线条时,默认是可以在点击的位置添加一个点。如果返回值为false,不会添加新的坐标点。
  • pixelTolerance:设置捕捉点的像素差,如果设置的很大,离坐标点很远也能捕捉到点,默认值 为10px。
  • style:用于修改点或顶点的样式。对于LineString和Polygon类,style将影响它们的顶点;对于Circle类,style将影响沿着圆的点;对于Point,style影响的就是实际的点。如果没有配置的话,就会使用默认的配置,默认配置是蓝色的。
  • source:要修改的数据源。如果未提供数据源,则必须提供要修改的Feature。
  • features:要修改的Feature。如果未提供Feature,则必须提供数据源。
常用方法
  • removePoint:删除当前正在编辑的点。
常用事件
  • modifystart:编辑开始时触发
  • modifyend:编辑接触时触发
Modify实例
import { Collection } from 'ol';
import { Modify } from 'ol/interaction';
import { Style, Stroke, Fill, Circle as CircleStyle } from 'ol/style';let modify = null;let features = new Collection();
features.push(event.feature);
modify = new Modify({features: features // 选中的要素
});
// 添加Modify交互
map.addInteraction(modify);modify.on('modifystart', () => {// 编辑开始时触发
});
modify.on('modifyend', () => {// 编辑接触时触发
});

四、完整代码示例

import React, { useState, useEffect } from 'react';
import { Map, View, Collection } from 'ol'; // 地图Collection
import * as Proj from 'ol/proj'; // 转化
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; // 图层
import { XYZ, Vector as VectorSource } from 'ol/source'; // 资源
import Draw, { createBox } from 'ol/interaction/Draw';
import { Modify } from 'ol/interaction';
import { Style, Stroke, Fill, Circle as CircleStyle } from 'ol/style'; // 样式let drawSource = null;
let drawLayer = null;
let draw = null;
let modify = null;const OpenlayerInteraction = () => {const [map, setMap] = useState(null); // 地图const [view, setView] = useState(null); // 地图视图const [drawType, setDrawType] = useState(null); // 画板类型 1圆形 2矩形 3多边形// 设置绘制类型function setDraw(type) {let kind = null;let geometryFunction = null;if (type === 1) {kind = 'Circle';} else if (type === 2) {kind = 'Circle';geometryFunction = createBox();} else if (type === 3) {kind = 'Polygon';}draw = new Draw({source: drawSource,type: kind,geometryFunction: geometryFunction,style: new Style({fill: new Fill({color: 'rgba(237, 57, 47, 0.35)'}),stroke: new Stroke({color: '#ED392F',width: 4,lineDash: [10]}),image: new CircleStyle({radius: 7,fill: new Fill({color: '#ED392F'})})})});map.addInteraction(draw);setDrawType(type);// 监听线绘制结束事件,获取坐标draw.on('drawend', (event) => {// 移除绘制功能map.removeInteraction(draw);// 重置数据setDrawType(null);draw = null;// 获取绘制信息let geometryDraw = event.feature.getGeometry();console.log(geometryDraw);// 添加修改功能let features = new Collection();features.push(event.feature);modify = new Modify({features: features,style: new Style({image: new CircleStyle({radius: 7,fill: new Fill({color: '#ED392F'})})})});map.addInteraction(modify);// 监听修改事件modify.on('modifyend', () => {});});}useEffect(() => {if (map) {// 添加画板layerdrawSource = new VectorSource();drawLayer = new VectorLayer({source: drawSource,style: new Style({fill: new Fill({color: 'rgba(237, 57, 47, 0.35)'}),stroke: new Stroke({color: '#ED392F',width: 4,lineDash: [10]})})});drawLayer.setZIndex(2);map.addLayer(drawLayer);}}, [map]);useEffect(() => {// 监听地图视图,创建地图if (view) {// 使用高德图层const tileLayer = new TileLayer({source: new XYZ({url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&scl=1&size=1&style=7&x={x}&y={y}&z={z}'})});// 创建实例const _map = new Map({target: 'map',layers: [tileLayer], // 使用高德图层view: view});setMap(_map);}}, [view]);useEffect(() => {// View用于创建2D视图const viewObj = new View({center: Proj.transform([104.06403453968424, 30.597419070782898], 'EPSG:4326', 'EPSG:3857'), // 使用'EPSG:3857'投影zoom: 16});setView(viewObj);}, []);return <div className='interaction_container'><div>openlayer地图绘制、修改圆形、矩形、多边形</div><div className='map_box'><div className='draw_type'><span className="title">选择绘制图形</span><div className={`list ${drawType === 1 ? "active" : ''}`} onClick={() => { setDraw(1); }}>圆形</div><div className={`list ${drawType === 2 ? "active" : ''}`} onClick={() => { setDraw(2); }}>矩形</div><div className={`list ${drawType === 3 ? "active" : ''}`} onClick={() => { setDraw(3); }}>多边形</div></div><div id='map' style={{ width: '100%', height: '100%' }}></div></div></div>;
}
export default OpenlayerInteraction;// 样式
.interaction_container {width: 100%;height: 100%;display: flex;flex-direction: column;.map_box {flex: 1;position: relative;.draw_type {position: absolute;z-index: 4;top: 16px;right: 16px;background-color: #ffffff;box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.1);border-radius: 4px;padding: 16px;color: #333333;.title {font-size: 14px;line-height: 20px;margin-bottom: 6px;display: inline-block;}.list {width: 130px;height: 32px;border-radius: 4px;display: flex;justify-content: center;align-items: center;margin-top: 8px;cursor: pointer;border: 1px solid #D5D5D5;color: #333333;background: #ffffff;transition: all .1s ease;}.list:hover {border: 1px solid #10BDFA;color: #ffffff;background: #10BDFA;}.active {border: 1px solid #10BDFA;color: #ffffff;background: #10BDFA;}}}
}

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

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

相关文章

mesh格式转换:glb转ply——使用Blender烘焙贴图到顶点色

1. 导入glb文件 选择shading后&#xff0c;选中物体&#xff0c;就能看到下面的节点树。 2. 创建顶点颜色 这个时候我们可以看到模型的顶点颜色是纯白色的。 2. 将贴图付给材质 原来&#xff1a; 现在&#xff1a; 3. 切换渲染器并烘焙顶点颜色 第三行选择CPU渲染或者GPU…

论文阅读:一种基于凸规划的高效有向最密子图发现方法 | SIGMOD 2022

论文概述 这篇论文的主题是研究如何在有向图中找到密度最高的子图&#xff0c;这个问题被称为有向最密子图&#xff08;Directed Densest Subgraph, DDS&#xff09;问题。该问题在许多应用中非常重要&#xff0c;如社交网络分析、社区发现、假粉丝检测等。论文提出了一种基于…

AI for reading ML paper

心流 心流 Kimi Kimi Humata Humata Bytez Bytez Chatgpt4 scholar 学术版chatgpt4&#xff0c;需要充值&#xff1b; 还有更多AI工具等待你发现&#xff1b;

sqlserver清理数据库日志并写作业定期执行

清理数据库日志最终sql&#xff1a; USE [master] GO ALTER DATABASE lsrz_zjwb_w SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE lsrz_zjwb_w SET RECOVERY SIMPLE --简单模式 GO USE lsrz_zjwb_w GO DBCC SHRINKFILE (Nlsrz_zjwb_log , 2, TRUNCATEONLY) --日志文件…

【网络】IO

IO 一、五种IO模型同步通信 vs 异步通信阻塞 vs 非阻塞 二、其他高级IO非阻塞IOSetNoBlockI/O多路转接之selectselect函数原型fd_set&#xff08;位图&#xff09;select代码select缺点poll&#xff08;用select修改&#xff09; I/O多路转接之epoll高级版改进select和poll的问…

企业如何组建安全稳定的跨国通信网络

当企业在海外设有分公司时&#xff0c;如何建立一个安全且稳定的跨国通信网络是一个关键问题。为了确保跨国通信的安全和稳定性&#xff0c;可以考虑以下几种方案。 首先&#xff0c;可以在分公司之间搭建虚拟专用网络。虚拟专用网络通过对传输数据进行加密&#xff0c;保护通信…

前端vue项目——打包部署(nginx中部署静态资源)

1、当前的开发方式 前端人员开发前端&#xff0c;后端人员开发后端的java工程&#xff0c;最终要将开发完毕的前端工程和后端工程分开部署在对应的服务器上&#xff08;前端流行的nginx&#xff09; 2、打包 &#xff08;1&#xff09;原理 &#xff08;2&#xff09; &#xf…

java实现七牛云内容审核功能,文本、图片和视频的内容审核(鉴黄、鉴暴恐、敏感人物)

目录 1、七牛云内容审核介绍 2、查看内容审核官方文档 2.1、文本内容审核 2.1.1、文本内容审核的请求示例 2.1.2、文本内容审核的返回示例 2.2、图片内容审核 2.2.1、请求参数 2.2.2、返回参数 2.3、视频内容审核 3、代码实现 3.1、前期代码准备 3.2、文本内容审核…

Scrapy框架进行数据采集详细实现

摘要 本项目是python课程的课程项目&#xff0c;在简要学习完python和爬虫相关的Scrapy框架后&#xff0c;基于这两者的运用最终完成了对于北京链家网站新房页面的信息进行爬取&#xff0c;并将爬取的数据存放于excel之中&#xff0c;可使用excel或者wps进行查看。 1 引言 1…

HYDRUS2D/3D模型技术教程

原文链接&#xff1a;HYDRUS2D/3D模型技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247612514&idx6&snadf080ddb3394d2f758fc269fa6ce9dc&chksmfa827985cdf5f093af1410f151e11fb6d4b39e7533f401624dc2a2375bdcc74b4b0f6160c58b&token1585…

论文分享 | Fuzz4All: 基于大语言模型的通用模糊测试

大语言模型是当前最受关注的研究热点&#xff0c;基于其生成和理解能力&#xff0c;对现有领域在提升性能和效果上做更多尝试。分享一篇发表于2024年ICSE会议的论文Fuzz4All&#xff0c;它组合多个大语言模型以非常轻量且黑盒的方式&#xff0c;实现了一种跨语言和软件的通用模…

适合所有人的生成式人工智能-学习先导课

欢迎来到为所有人提供的生成式人工智能课(generative AI )。自ChatGPT发布以来&#xff0c;人工智能特别是生成式人工智能引起了许多个人、企业和政府的关注。 这是一项非常颠覆性的技术&#xff0c;已经在改变许多人的学习和工作方式。许多开发者认为生成式AI将使许多人得以赋…

[240812] X-CMD 发布 v0.4.5:更新 gtb、cd、chat、hashdir 模块功能

目录 &#x1f4c3;Changelog✨ gtb✨ cd✨ chat✨ hashdir &#x1f4c3;Changelog ✨ gtb 调整了 fzf 预览窗口中书籍文本的显示效果&#xff0c;通过识别文本中的特殊字符、日期、章节标题等信息&#xff0c;为其赋予不同的颜色。 ✨ cd cd 模块新增功能&#xff1a;在找…

RS®ZN-Z8x 开关矩阵

R&SZN-Z8x 开关矩阵 专为多端口矢量网络分析仪测量而设计 R&SZN-Z8x 开关矩阵经过优化设计&#xff0c;专门用于罗德与施瓦茨的矢量网络分析仪。这款经济高效的多方位解决方案可用于多端口设备或多个设备的简单和复杂的测量任务。开关矩阵支持宽频率范围&#xff0…

【论文阅读】YOLOv10: Real-Time End-to-End Object Detection

题目&#xff1a;YOLOv10: Real-Time End-to-End Object Detection 作者&#xff1a;Ao Wang Hui Chen∗ Lihao Liu Kai Chen Zijia Lin Jungong Han Guiguang Ding∗ 清华大学的 motivation: 作者觉得YOLO系列的NMS和某些结构非常的耗时&#xff0c;提出NMS-free和一些列高效…

Qt编译配置OpenCV+opencv_contrib(使用cmake)

本文使用环境 OpenCV: 4.7.0 cmake: 3.30.2 Qt: 5.12.1一、配置环境变量 安装好OpenCV、Qt、cmake后&#xff0c;应配置好一下环境变量&#xff1a; 二、编译OpenCV 打开cmake&#xff0c;编译的源码路径选择opencv文件夹中的sources目录&#xff0c;在opencv文件夹下新建一…

视频汇聚平台智能边缘分析一体机分析平台摄像头异常位移算法识别检测

智能边缘分析一体机在摄像头异常位移检测方面扮演着关键角色&#xff0c;它利用先进的图像处理技术和机器学习算法来实时监测摄像头状态&#xff0c;判断是否发生了非预期的位移。下面是智能边缘分析一体机如何检测摄像头异常位移的详细步骤&#xff1a; 1. 图像帧对比&#x…

SpringBoot中生成条形码的方案实战

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 ZXing库介绍 ZXing库是一个用于解析和生成多种格式的一维和二维条形码的开源Java库。 ZXing&#xff08;“zebra crossing”的缩写&#xff09;库提供了多种条形码格式的支持&#xff0c;包括但不限于QR码、…

Vue3 el-tabs 切换记录选项卡,离开前提示

最近做了一个项目&#xff0c;tabs选项卡 需要在离开当前的选中的项时进行提示并且当取消时定位原位置。 看效果图 当我进行编辑时 触发编辑 但是没有进行保存即提示信息。取消后返回原tabs ,否则确认后进入下个tab。 上代码 tab 一般默认会有一个值&#xff0c;一把是第一…

经典算法题总结:二叉树篇

二叉树解题的思维模式分两类&#xff1a; 是否可以通过遍历一遍二叉树得到答案&#xff1f;如果可以&#xff0c;用一个 traverse 函数配合外部变量来实现&#xff0c;这叫「遍历」的思维模式。是否可以定义一个递归函数&#xff0c;通过子问题&#xff08;子树&#xff09;的…