leaflet学习笔记-贝塞尔曲线绘制(八)

前言

两点之间的连线是很常见的,但是都是直直的一条线段,为了使连线更加平滑,我们可以使用曲线进行连线,本功能考虑使用贝塞尔曲线进行连线绘制,最后将线段的两端节点连接,返回一个polygon。

贝塞尔简介

给定不同的点 P0 和 P1,线性贝塞尔曲线只是这两点之间的一条线。

相当于线性插值。

Turf.bezierSpline()简介

接受一条线,通过应用贝塞尔样条算法返回一个弯曲的版本

官方例子

var line = turf.lineString([[-76.091308, 18.427501],[-76.695556, 18.729501],[-76.552734, 19.40443],[-74.61914, 19.134789],[-73.652343, 20.07657],[-73.157958, 20.210656]
]);var curved = turf.bezierSpline(line);

参数说明

line:input LineString

options:{

resolution:点之间的时间(毫秒)

sharpness:衡量样条路径应该有多弯曲的一个度量

}

具体可以查看官方的bezierSpline函数

UseBezierSpline.js完整代码

import { onBeforeUnmount, reactive, ref } from 'vue'
import * as turf from '@turf/turf'/*** @Description 接受一条线,通过应用贝塞尔样条算法返回一个弯曲的版本(贝塞尔曲线)* @param mainMap 地图对象* @param drawComplete 完成绘制的回调函数* @Param bezierOptions* @Param bezierOptions.resolution 点之间的时间(毫秒)* @Param bezierOptions.sharpness 衡量样条路径应该有多弯曲的一个度量* @param drawLayer 绘制图形的layer* @Author ZhangJun* @Date  2024-01-11 09:55:12* @return void**/
export default function useBezierSpline(mainMap, drawComplete = null, bezierOptions = {}, drawLayer = undefined) {//默认的贝塞尔配置参数合并let bezierOptions_config = reactive({resolution: 1000,sharpness: 0.85,...bezierOptions,})//绘制事件状态let status = ref('start')// 记录当前状态是否可以拖动绘制let isDragging = true//拖动绘制的坐标let drawPath = []//拖动绘制的线let drawLine = reactive(null)//鼠标正在移动的点let movePoint//最终绘制的polygon,最终返回的就是它的轮廓坐标let polygon_draw = reactive(null)//鼠标提示let mouseEventPopup = new L.popup({ className: 'customPopup', closeButton: false })if (mainMap) {//关闭的时候一定要销毁onBeforeUnmount(() => {closeDraw()mainMap?.removeLayer(drawLayer)})if (!drawLayer) {drawLayer = L.featureGroup([])drawLayer.addTo(mainMap)}//初始化事件let initEvents = () => {isDragging = false//按下鼠标确定需要添加的节点(暂停中)mainMap.on('mousedown', (e) => {isDragging = falselet { lat, lng } = e.latlngdrawPath = [...drawPath, [lng, lat]]//如果才开始点击第一次,就创建一个polyline,后面需要动态需改它的pathif (drawPath?.length === 1) {status.value = 'start'//添加绘制linedrawLine = L.polyline(drawPath, { color: 'red' }).addTo(mainMap)}})//松开鼠标开始拖动绘制(开始绘制)mainMap.on('mouseup', (e) => {isDragging = true})//鼠标移动绘制(绘制中)mainMap.on('mousemove', (e) => {if (isDragging) {let { lat, lng } = e.latlngmovePoint = [lng, lat]//动态生成贝塞尔曲线的featurelet splineFeature = generationBezierSpline(drawPath, movePoint)if (splineFeature) {let tempCoords = turf.getCoords(turf.flip(splineFeature))//将生成的贝塞尔曲线的坐标传给polyline,在地图上刷新渲染drawLine?.setLatLngs(tempCoords)}}mouseEventPopup?.setLatLng(e.latlng)?.setContent('右键结束绘制')//如果还没有添加就直接先添加一下if (!mainMap.hasLayer(mouseEventPopup)) {//打开方向的popupmouseEventPopup?.openOn(mainMap)}})//右键结束(结束绘制)mainMap.on('contextmenu', (e) => {let coords = turf.getCoords(turf.flip(drawLine.toGeoJSON()))//生成polygonpolygon_draw = L.polygon(coords, { color: 'green' })clearDrawLayer()addLayersToDrawLayer([polygon_draw])//移除曲线mainMap?.removeLayer(drawLine)status.value = 'end'//绘制完成的回调if (typeof drawComplete === 'function') {let result = getResult(polygon_draw)drawComplete(result)}})}//移除事件let removeEvents = () => {//按下鼠标mainMap?.off('mousedown')//抬起鼠标mainMap?.off('mouseup')//拖拽事件mainMap?.off('mousemove')//右键事件mainMap?.off('contextmenu')}//开始绘制let startDraw = () => {//禁止拖动地图mainMap?.dragging?.disable()//初始化事件initEvents()}//清除原来绘制的内容let clearDrawLayer = () => {drawPath = []drawLayer?.clearLayers()}//添加要素到drawLayerlet addLayersToDrawLayer = (features = []) => {features?.forEach(feature => {drawLayer.addLayer(feature)})}/*** @Description 生成曲线* @Param originalPath 已经确定的点坐标集合* @Param lastPoint 最后一个坐标点,一般为移动的点坐标* @Author ZhangJun* @Date  2024-01-11 10:36:11* @return void**/let generationBezierSpline = (originalPath = drawPath, lastPoint = movePoint) => {if (originalPath?.length > 0) {//加入最后一个点let line = turf.lineString([...originalPath, lastPoint], bezierOptions_config)return turf.bezierSpline(line)}return null}//关闭绘制功能let closeDraw = () => {//清空绘制的几何clearDrawLayer()//一定要移除事件,否则事件之间会有干扰removeEvents()//移除popupmainMap?.closePopup(mouseEventPopup)//激活拖拽功能mainMap?.dragging?.enable()}//获取最终的polygon的轮廓坐标let getResult = (feature = polygon_draw) => {if (feature) {//获取输入 feature 并将它们的所有坐标从 [x, y] 翻转为 [y, x]。let featureCollection = turf.flip(feature.toGeoJSON())return turf.getCoords(featureCollection)}return []}return { status, getResult, closeDraw, drawLayer, bezierOptions_config, startDraw }}return {}
}

UseBezierSpline.js使用

if (wizMap?.map) {let { startDraw, closeDraw, status: temp, getResult } = useBezierSpline(wizMap?.map)getCoords = getResult//当前绘制状态(是否完成绘制)status.value = temponMounted(() => {//需要这种处理,不然会有异常nextTick(() => {startDraw()})})
}

效果

贝塞尔曲线


本文为学习笔记,仅供参考

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

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

相关文章

iPad Pro如何使用SSH远程连接服务器云端编程开发【内网穿透】

文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. 配置固定TCP端口地址4.1 保留固定TCP地址4.2 配置固定的TCP端口地址4.3 使用固定TCP地址远程vscode 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 …

Python自动化测试框架:Unittest 断言详解

断言是编程中常用的一种验证方法,也是测试代码中最重要的部分,用于验证某个条件是否为真,验证测试结果与预期结果是否一致。 unittest 提供了方便的断言方法,用于验证测试结果是否符合预期,若验证失败,则会…

ABeam×StartUp丨ABeam旗下德硕管理咨询(深圳)新创部门拜访「光子晶体科技」

光子晶体科技 ABeamStartUp 光子透明芯片 显示技术 光学材料 近日,ABeam 旗下德硕管理咨询(深圳)有限公司(以下简称“ABeam-SZ”)新创部门一行拜访了深圳光子晶体科技有限公司(以下简称“光子晶体科技”…

分布式引擎Elasticsearch本地部署并结合内网穿透远程访问

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

PCL 使用克拉默法则进行四点定球(C++详细过程版)

目录 一、算法原理二、代码实现三、计算结果本文由CSDN点云侠原创,PCL 使用克拉默法则进行四点定球(C++详细过程版),爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT生成的文章。 一、算法原理 已知空间内不共面的四个点,设其坐标为 A (…

24/1/10 qt work

1. 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配&…

ArcMap实现多行标注

地图标注是地图的重要组成部分,也是地理信息的重要表达方式​。ArcMap的符号化系统为我们添加地图标注提供了方便,但是有时我们却需要添加多行标注,今天我们一起来探索一下ArcMap中两行标注的实现方式​。 首先,我们右击目标图层…

TS 36.322 V12.0.0-PDU,格式和参数

​本文的内容主要涉及TS 36.322,版本是C00,也就是V12.0.0。

【大数据】NiFi 中的处理器(二):PutDatabaseRecord

NiFi 中的处理器(二):PutDatabaseRecord 1.基本介绍2.属性配置3.连接关系4.应用场景 1.基本介绍 PutDatabaseRecord 处理器使用指定的 RecordReader 从传入的流文件中读取(可能是多个,说数组也成)记录。这…

Springboot使用自带Logback 与 整合log4j 和 log4j2过程详解

logback 1、添加依赖 <!--spring boot依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>2、logback-spring.xml配置 <?xml version"1.0&…

CMake入门教程【高级篇】CPack打包项目Linux的deb和windows的msi

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1. 什么是CPack?2. 如何使用CPack?2.1 在CMakeLists.txt中包含CPack模块2.2 设置CPack变量2.3 创建分发包3.CPack命

huggingface下载太慢的问题

解决问题&#xff1a;huggingface网站模型文件太大&#xff0c;下载太慢 方式&#xff1a; huggingface镜像站网址 使用方法3的python脚本文件内容 import os# 下载模型 os.system(huggingface-cli download --resume-download THUDM/chatglm2-6b --local-dir /home/bennie…