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()})})
}
效果
贝塞尔曲线
本文为学习笔记,仅供参考
相关文章:
leaflet学习笔记-贝塞尔曲线绘制(八)
前言 两点之间的连线是很常见的,但是都是直直的一条线段,为了使连线更加平滑,我们可以使用曲线进行连线,本功能考虑使用贝塞尔曲线进行连线绘制,最后将线段的两端节点连接,返回一个polygon。 贝塞尔简介 …...
42-单双多路分支,嵌套分支,switch分支,for循环,for in,while,do while,break,continue
js流程控制,代码的执行机制:顺序控制,分支控制,循环控制 1.顺序控制:就是按照代码的书写顺序,自上而下执行 2.分支控制 2.1单路分支 // 单路分支// if(条件表达式){// 执行代码// }// 如果条件表达式满…...
CNCF之CoreDNS
目前我们学习云原生技术,就不得不去了解CNCF,即Cloud Native Computing Foundation,云原生计算基金会,它的宣言或理念是: The Cloud Native Computing Foundation (CNCF) hosts critical components of the global tec…...
MySQL一主一从读写分离
MySQL主从复制 一、主从复制概念 主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从服务器中,然后在从服务器上对这些日志重新执行也叫重做,从而使得从数据库和主库的数据保持同步。 MySQL支持一台主库同时向多台从库进行赋值,从…...
【学术会议】第三届神经计算青年研讨会 学习笔记
第三届神经计算青年研讨会 学习笔记 会议时间:2024-1-6至2024-1-7 会议地点:电子科技大学 会议介绍: 为提升我国神经计算⻘年研究队伍的学术⽔平和国际影响⼒,研讨会主题涵盖:神经系统建模与模拟、脑机接⼝与类脑智能、…...
[C#]使用winform部署PP-MattingV2人像分割onnx模型
【官方框架地址】 https://github.com/PaddlePaddle/PaddleSeg 【算法介绍】 PP-MattingV2是一种先进的图像和视频抠图算法,由百度公司基于PaddlePaddle深度学习框架开发。它旨在提供更精准和高效的图像分割功能,特别是在处理图像中的细微部分…...
回顾2023,立2024flag
文章目录 回顾2023与CSDN相识专栏整理数据回顾 立2024flag 回顾2023 在过去的一年里,前端技术不断演进和创新。新技术、新框架层出不穷,给前端工程师提供了更多选择和挑战。2023年已经成为过去,回首这一年,我们也经历了许多挑战和…...
【PostgreSQL创建索引的锁分析和使用注意】
1.1 创建普通B-tree索引的整体流程 如下是梳理的创建普通B-tree索引的大概流程,可供参考。 1.校验新索引的Catalog元数据|语法解析 ---将创建索引的sql解析成IndexStmt结构|校验B-Tree的handler -----校验内核是否支持该类型的索引,在pg_am中查找&q…...
什么是云安全?如何保护云资源
云计算允许组织通过互联网按需向其客户、合作伙伴或员工提供关键业务应用程序、服务和资源。换句话说,不再需要物理维护资源。每当您通过 Internet 从计算机访问文件或服务时,您都是在访问云。 迁移到云可以帮助企业增强安全性、简化运营并降低成本。企…...
Android可换行的RadioGroup
Android可换行的RadioGroup,有时候需要换行显示的单选列表,当然可以有多种实现方式,比如recycleview或者listview实现,本文采用的是RadioGrouprediobutton方式实现。 一、首先自定义view public class WrapRadioGroup extends RadioGroup {pr…...
【ASP.NET Core 基础知识】--环境设置
一、简介 1.1 .NET Core SDK 概述 .NET Core SDK(Software Development Kit)是Microsoft推出的一个开源跨平台框架,用于开发和部署.NET应用程序。它是.NET Core平台的核心组件之一,为开发者提供了在多个操作系统上构建高性能、可…...
docker/华为云cce 部署nacos 2.3.0 集群模式
镜像地址 https://hub.docker.com/r/nacos/nacos-server 版本 nacos/nacos-server:v2.3.0-slim 关键环境变量 使用mysql数据源 变量值备注MODEcluster启用集群模式MYSQL_SERVICE_DB_NAME数据库名MYSQL_SERVICE_USER数据库用户名MYSQL_SERVICE_PASSWORD数据库密码SPRING_D…...
Doris 数据模型—Aggregate 模型
Doris 数据模型—Aggregate 模型 文章目录 Doris 数据模型—Aggregate 模型基本概念Aggregate 模型示例1:导入数据聚合示例2:保留明细数据示例3:导入数据与已有数据聚合Aggregate 模型限制Aggregate 模型使用场景本文主要从逻辑层面,描述 Doris 的数据模型,以帮助用户更好…...
数据库管理-第130期 JSON二元性(20240109)
数据库管理130期 2024-01-09 第130期 JSON二元性(20240109)1 简介2 关系型表和JSON存储的优劣3 Oracle JSON关系型二元性视图总结 第130期 JSON二元性(20240109) 上周,又双叒飞了一趟上海,也是2024年第一飞…...
k8s--动态pvc和pv
前情回顾 存储卷: emptyDir 容器内部,随着pod销毁,emptyDir也会消失 不能做数据持久化 hostPath:持久化存储数据 可以和节点上目录做挂载。pod被销毁了数据还在 NFS:一台机器,提供pod内容器所有的挂载点…...
C++:常量
const的最初动机 const的使用方法 使用const的好处是允许指定一种语义上的约束,即某种对象不能被修改,且由编译器具体实施这种约束。 const声明格式:const 类型名 对象名;修饰普通变量,时期不能被随意修改 【注意】1.C中的const…...
java JDBC 连接数据库
必须先插入工具包 DataSource ds JdbcHelper.getDs();System.out.println(ds);JdbcTemplate jdbcTemplatenew JdbcTemplate(ds);System.out.println(jdbcTemplate);//新增String sql1"insert into biao values(null,?,?,?)";int ijdbcTemplate.update(sql1,"…...
图神经网络|5.消息传递的计算方法 6.多层GNN的作用
5.消息传递的计算方法 边的存放方式 注意,在实际的边的实现方式中,并不是以邻接矩阵来进行实现的,这是因为在图的更新中,用邻接矩阵进行更新所占用的时间开销相对大,二是因为领接矩阵占用的空间大(N方&am…...
构建中国人自己的私人GPT
创作不易,请大家多鼓励支持。 在现实生活中,很多人的资料是不愿意公布在互联网上的,但是我们又要使用人工智能的能力帮我们处理文件、做决策、执行命令那怎么办呢?于是我们构建自己或公司的私人GPT变得非常重要。 先看效果 一、…...
添加气泡与菜单
目录 1、添加气泡 1.1、文本提示气泡 1.2、带按钮的提示气泡 1.3、自定义气泡 2、菜单 2.1、创建默认样式的菜单 2.2、创建自定义样式的菜单 1、添加气泡 Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。主要用于…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
