基于Lealfet.js展示Turf.js生成的平滑曲线实践

目录

前言

一、问题的由来

1、创建网页框架

2、创建map对象

3、构建点位,生成路线

 二、Turf.js平滑曲线改造

1、官网方法介绍

2、0.4弯曲度曲线

3、0.85弯曲度曲线

4、0.1度弯曲曲线

5、综合对比 

总结


前言

        在很多的关于路线的gis应用中,我们经常会有展示路线的需求,比如采集关键点位的经纬度,最后连接成一条轨迹线。不知道各位朋友有没有遇到这种需求,如果只是在地图上采集一些关键点,得到的线经常是比较生硬的,尤其是在拐点的时候,展示效果更加的明显。形如下面的这种效果。

        那么有没有什么办法能让这些拐点练成的曲线实际效果看上去更加平滑呢?有的小伙会说,可以在数据采集阶段尽可能多的采集多的点位信息,通过更多点位的采集,形成一条更加平滑的曲线。从技术的角度来说,这种方式是可以的,只要将点采集的更多,那么练成的曲线一定是更加平滑的。但是这样会增加采集的工作量。有没有办法在现有的成果之上来进行数据的平滑处理呢?

         本博客给出一种解决方案,熟悉webgis开发的朋友一定知道多种解决方案。那么本文分享一款webgis的解决方案,基于Turf.js组件来动态生成平滑曲线,然后在webgis框架中进行展示。对于不熟悉或者没用过turf.js的小伙伴起到抛砖引玉的作用。对于想在Webgis中开发类似应用的小伙伴来说,可以看看这篇博客。

一、问题的由来

        众所周知,线对象是由多个点对象组合而来,把多个点两两相连即可连成一条线。因此,这里我们首先模拟构造一条虚拟的游览线路。然后使用turf.js组件生成不同程度的平滑曲线。

        为了展示最原始的线对象,我们采用Leaflet作为地图展示组件,再一起回顾一下Leaflet当中如何进行地图展示,以及集成Turf.js组件。

1、创建网页框架

        首先创建一个html页面。在页面中我们需要引入Leaflet.css和Leaflet.js两个基础组件,同时引入Turf.js这个组件。关键代码如下:

<!DOCTYPE html>
<html>
<head>
	<title>基于Leaflet和Turf生成平滑曲线实践</title>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
	<link rel="stylesheet" href="/2d/leaflet/leaflet.css" />
    <script src="/2d/leaflet/leaflet.js?v=1.0.0"></script>
	<!-- 使用unpkg -->
	<script src="https://unpkg.com/@turf/turf/turf.min.js"></script>
	<style>
        #map {
            margin: 0;
            padding: 0;
            position: absolute;
            width: 99%;
            height: 98%;
        }
    </style>
</head>
<body>
<div id="map"></div>
<script>
</script>
</body>
</html>

2、创建map对象

        在创建了基础的网页模板之后,再来定义map对象。以此在界面上绑定地图展示容器。代码如下:

var mymap = L.map('map').setView([29.052934, 104.0625], 6);

var tileLayer = L.tileLayer('http://localhost:8086/data/xxgc/q0403/{z}/{x}/{y}.png', {
	maxZoom: 7,
	minZoom:0
});
	
tileLayer.addTo(mymap); 

3、构建点位,生成路线

        这里仅为了演示效果,使用演示数据。虚拟场景为,构建一个自驾路线,从云南的保山市出发,依次经过攀枝花、昆明、成都、重庆、贵阳、长沙、赣州,最终到达福建的福州。以上城市的经纬度信息如下:

var cityPoint = new Array();
	cityPoint.push([99.116482, 25.078402]);//保山
	cityPoint.push([101.708392, 26.50289]);//攀枝花
	cityPoint.push([102.780718, 24.915559]);//昆明
	cityPoint.push([104.098757, 30.594412]);//成都
	cityPoint.push([106.559098, 29.452047]);//重庆
	cityPoint.push([106.515163, 26.461228]);//贵阳
	cityPoint.push([112.929622, 28.141659]);//长沙
	cityPoint.push([114.956049, 25.713705]);//赣州
	cityPoint.push([119.344081, 26.027307]);//福州
	

        然后,我们将这些点位数据连成一条线,在地图上展示出来。

var linestring = turf.lineString(cityPoint, {name: 'line 1'});

L.geoJSON(linestring,{style:{color:"blue",wight:2,fill:false}}).addTo(mymap);

        先来看一下原始的曲线效果,请注意各个拐点的实际效果。通过以下结果可以看到,原始的路线展示确实不够平滑。

 二、Turf.js平滑曲线改造

        首先对turf.js对于平滑曲线改造的方法进行一个简单的介绍。首先来看一下Turf.js官网对多线段平滑的方法说明。

1、官网方法介绍

        turf.js是使用bezierSpline()进行多线段平滑的构建支持的。其原理是接受一条线,通过应用贝塞尔样条算法返回一个弯曲的版本。关于白塞尔曲线的的创建原理,有兴趣的朋友可以去查询相关搜索引擎。里面还是有一点知识点的。

        我们先来看一下这个方法:

        bezierSpline方法参数

参数类型描述
lineFeature <LineString>input LineString
optionsObject可选参数:见下文

        options选项

属性类型默认值描述
resolutionnumber10000点之间的时间(毫秒)
sharpnessnumber0.85衡量样条路径应该有多弯曲的一个度量

方法的返回值是Feature <LineString> - 弯曲的线。

2、0.4弯曲度曲线

        了解了上面的方法后,在我们的应用当中调用生成方法。弯曲度的设置这里,首先我们设置成0.4,来看一下在0.4的弯曲度下,生成的平滑曲线是什么效果。

var curved = turf.bezierSpline(linestring,{sharpness:0.4,resolution:10000});//0.4的弯曲度
	
L.geoJSON(curved,{style:{color:"red",wight:2,fill:false}}).addTo(mymap);

        为了与原始的路线进行差异对比,我们将0.4弯曲度的路线设置为红色。在浏览器中查看实际效果。很明显可以看到,与原始路线相比,整条路线看起来平滑多了。

3、0.85弯曲度曲线

        在弯曲度0.4的情况下,曲线已经明显发生光滑。来看一下0.85的弯曲度下是什么效果。

L.geoJSON(turf.bezierSpline(linestring,{sharpness:0.85,resolution:10000}),{style:{color:"green",wight:2,fill:false}}).addTo(mymap);//0.85的弯曲度

        我们发现0.85的曲线,其弯曲度处理的更大了,与实际效果有一定的差异。 

4、0.1度弯曲曲线

        最后再来看一下0.1度弯曲的曲线是什么效果。

L.geoJSON(turf.bezierSpline(linestring,{sharpness:0.1,resolution:10000}),{style:{color:"yellow",wight:2,fill:false}}).addTo(mymap);//0.1的弯曲度
	

5、综合对比 

        为了比较不同弯曲度下,曲线的平滑程度。为了直观的展示效果,将三种平滑度同时叠加。

         通过效果可以看到,弯曲度系数越大,曲线的平滑程度也是比较大。黄色表示0.1的弯曲度,红色表示0.4的弯曲度,绿色表示0.85的弯曲度。

序号弯曲度实际效果
10.1与原始拟合
20.4有一定弯曲
30.85弯曲较大

        最后给出完整的示例代码,请注意在运行时替换本地图源地址。

<!DOCTYPE html>
<html>
<head>
	<title>基于Leaflet和Turf生成平滑曲线实践</title>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
	<link rel="stylesheet" href="/2d/leaflet/leaflet.css" />
    <script src="/2d/leaflet/leaflet.js?v=1.0.0"></script>
	<!-- 使用unpkg -->
	<script src="https://unpkg.com/@turf/turf/turf.min.js"></script>
	<style>
        #map {
            margin: 0;
            padding: 0;
            position: absolute;
            width: 99%;
            height: 98%;
        }
    </style>
</head>
<body>
<div id="map"></div>
<script>
    var mymap = L.map('map').setView([29.052934, 104.0625], 6);

	var tileLayer = L.tileLayer('http://localhost:8086/data/xxgc/q0403/{z}/{x}/{y}.png', {
		maxZoom: 7,
		minZoom:0
	});
	
    tileLayer.addTo(mymap); 
	
	var cityPoint = new Array();
		cityPoint.push([99.116482, 25.078402]);
		cityPoint.push([101.708392, 26.50289]);
		cityPoint.push([102.780718, 24.915559]);
		cityPoint.push([104.098757, 30.594412]);
		cityPoint.push([106.559098, 29.452047]);
		cityPoint.push([106.515163, 26.461228]);
		cityPoint.push([112.929622, 28.141659]);
		cityPoint.push([114.956049, 25.713705]);
		cityPoint.push([119.344081, 26.027307]);
	
	var linestring = turf.lineString(cityPoint, {name: 'line 1'});
	
	L.geoJSON(linestring,{style:{color:"blue",wight:2,fill:false}}).addTo(mymap);
	
	var curved = turf.bezierSpline(linestring,{sharpness:0.4,resolution:10000});//0.4的弯曲度
	
	L.geoJSON(curved,{style:{color:"red",wight:2,fill:false}}).addTo(mymap);
	
	L.geoJSON(turf.bezierSpline(linestring,{sharpness:0.85,resolution:10000}),{style:{color:"green",wight:2,fill:false}}).addTo(mymap);//0.85的弯曲度
	
	L.geoJSON(turf.bezierSpline(linestring,{sharpness:0.1,resolution:10000}),{style:{color:"yellow",wight:2,fill:false}}).addTo(mymap);//0.1的弯曲度
	

</script>

</body>
</html>

总结

        以上就是本文的主要内容,那么本文分享一款webgis的解决方案,基于Turf.js组件来动态生成平滑曲线,然后在webgis框架中进行展示。对于不熟悉或者没用过turf.js的小伙伴起到抛砖引玉的作用。如果您对在webgis中如何展示平滑曲线有一定的处理需求,不妨来看看这篇博客。行文仓促,难免有不当之处,欢迎各位小伙伴,各位专家批评指正。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是485数据采集模块?

在工业自动化、智能楼宇、环境监测等众多领域&#xff0c;数据的采集与传输是实现智能化管理的关键。而485数据采集模块&#xff0c;作为一种高效、稳定的数据采集设备&#xff0c;正日益受到广泛关注。HiWoo Box&#xff0c;作为一款卓越的485数据采集模块&#xff0c;以其强大…

Android性能自测

目录 一、应用启动耗时自测 二、帧率查看 三、Top命令查看系统资源占用 3.1 第一行&#xff1a;任务(进程) 3.2 第二行&#xff1a;mem状态 3.3 第三行&#xff1a;swap交换分区 3.4 第四行&#xff1a;cpu状态 3.5 第五行&#xff1a;标题 四、抓取trace.html文件分析…

CCF-CSP认证考试 202305-3 解压缩 100分题解

更多 CSP 认证考试题目题解可以前往&#xff1a;CSP-CCF 认证考试真题题解 原题链接&#xff1a; 202305-3 解压缩 时间限制&#xff1a; 5.0s 内存限制&#xff1a; 512.0MB 题目背景 西西艾弗岛运营公司是一家负责维护和运营岛上基础设施的大型企业。在公司内&#xff0c;…

如何注册 onlyFans? onlyFans 如何订阅教程

一、onlyFans 介绍 OnlyFans 是一个在线平台&#xff0c;允许创作者为他们的内容提供订阅服务&#xff0c;通常是成人内容或独家内容。该平台于2016年成立&#xff0c;起初被认为是一个用于演员、模特、艺术家和其他创意行业从业者分享内容的地方。随着时间的推移&#xff0c;O…

linux命令(四)

操作文件 创建文件 touch test.txt修改文件后缀 mv test.txt test.sh将test.txt 改为test.sh 查看当前路径下的文件 ls如果你想知道你现在是在哪个目录下&#xff0c;可以使用pwd命令(不要认为pwd是密码的意思&#xff0c;pwd 是Print Working Directory的缩写) pwd查看文…

初识二叉树

文章目录 一.什么是树二.什么是二叉树三.二叉树的访问次序四.特殊的二叉树五.求结点个数六.平衡二叉树总结 一.什么是树 树是由一个集合以及在该集合上定义的一种关系构成的。 集合中的元素称为树的节点&#xff0c;所定义的关系称为父子关系。 父子关系在树的节点之间建立了一…

【C++ leetcode】双指针问题

1. 611. 有效三角形的个数 题目 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 题目链接 . - 力扣&#xff08;LeetCode&#xff09; 画图 和 文字 分析 判断是否是三角形要得到三边&#xff0c;由于遍历三边要套三层循环&#x…

LeetCode每日一题【24. 两两交换链表中的节点】

思路&#xff1a;先创建虚拟头结点&#xff0c;再用双指针&#xff0c;两两交换 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr…

推荐几个自动化测试实战练习项目

学习自动化测试最难的是没有合适的项目练习。 测试本身既要讲究科学&#xff0c;又有艺术成分&#xff0c;单单学几个 API 的调用很难应付工作中具体的问题。 你得知道什么场景下需要添加显性等待&#xff0c;什么时候元素定位需要写得更加优雅&#xff0c;为什么需要断言这个…

js处理数组分类

const obj [{"groupingType": "1","remark": "梨花带雨","totalRmbMoney": 7,"kyeGroupingType": "广州一组"},{"groupingType": "2","remark": "99","…

权限管理系统-0.6.0

七、员工端审批 员工端审批的大致流程如下图&#xff1a; 这个模块目的是实现员工在微信端的审批提交和处理功能&#xff0c;为了与之前的管理系统区分开&#xff0c;新建一个controller完成这些功能。 7.1 查询审批分类和审批模板 7.1.1 后端接口 //controller Api(tags …

【论文速读】| 视觉对抗样本:突破对齐的大语言模型

本次分享论文为&#xff1a;Visual Adversarial Examples: Jailbreak Aligned Large Language Models 基本信息 原文作者&#xff1a;Xiangyu Qi, Peter Henderson, Kaixuan Huang, Ashwinee Panda, Mengdi Wang, Prateek Mittal 作者单位&#xff1a;普林斯顿大学、斯坦福大…

使用npm创建一个全局的cli命令,就像vue-cli一样

我们用过vue-cli等工具包&#xff0c;全局安装之后&#xff0c;我们可以直接使用vue create等命令&#xff0c;实际上能够这样使用的原因&#xff0c;就是使用了package.json里面的bin字段注册命令。接下来就以一个脚本文件为例子为大家演示一下bin是如何发挥作用的。 创建项目…

数据库引论:2.SQL简介

SQL(Structured Query Language,结构化查询语言) 2.1 SQL查询语言概览 SQL语言包含 数据定义语言(Data-Definition Language,DDL)。SQL DDL提供定义关系模式、删除关系以及修改关系模式的命令。数据操纵语言(Data-Manipulation Language,DML)。SQL DML提供从数据库中查询信息…

PLC通过智能网关采用HTTP协议JSON文件对接MES等服务系统平台

智能网关IGT-DSER集成了多种PLC的原厂协议&#xff0c;方便实现各种PLC、智能仪表通过HTTP协议与MES等各种系统平台通讯对接。PLC内不用编写程序&#xff0c;通过网关的参数配置软件(下载地址)绑定JSON文件的字段与PLC寄存器地址&#xff0c;配置URL即可。支持POST/GET/PUT等多…

基于YOLOv5s的电动车入梯识别系统(数据集+权重+登录界面+GUI界面+mysql)

本人训练的yolov5s模型&#xff0c;准确率在98.6%左右&#xff0c;可准确完成电梯内检测电动车任务&#xff0c;并搭配了GUI检测界面&#xff0c;支持权重选择、图片检测、视频检测、摄像头检测、识别结果拍照和在线标注数据集等功能。 并且为用户提供了登录注册功能&#xff0…

python版:使用TotalSegmentator工具可在1分钟内自动分割全身117个器官,附批量技巧

TotalSegmentator用于对 CT 图像中超过 117 个类别进行分割的工具。它接受了各种不同 CT 图像&#xff08;不同扫描仪、机构、协议等&#xff09;的训练&#xff0c;因此应该适用于大多数图像。大部分训练数据集可以从Zenodo下载&#xff08;1228 个主题&#xff09;。您还可以…

由浅到深认识Java语言(7):方法(函数)

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

ZYNQ EMIO MIO

1 概述 先来了解GPIO的BANK分布&#xff0c;在UG585文档GPIO一章中可以看到GPIO是有4个BANK&#xff0c; 注意与MIO的BANK区分。 BANK0 控制32个信号&#xff0c;BANK1控制22个信号&#xff0c;总共是MIO的54个引脚&#xff0c;也就是诸如 SPI,I2C,USB,SD 等 PS 端外设接口&am…

【二进制求公约数】【数学】【数论】2543. 判断一个点是否可以到达

本文涉及知识点 二进制求公约数 LeetCode2543. 判断一个点是否可以到达 给你一个无穷大的网格图。一开始你在 (1, 1) &#xff0c;你需要通过有限步移动到达点 (targetX, targetY) 。 每一步 &#xff0c;你可以从点 (x, y) 移动到以下点之一&#xff1a; (x, y - x) (x - y…