在Leaflet中使用Turf.js生成范围多边形的两种实现方式

这篇具有很好参考价值的文章主要介绍了在Leaflet中使用Turf.js生成范围多边形的两种实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

一、场景需求

1、Leaflet.js的不足

2、Turf.js

二、原始数据展示

1、点位数据展示 

2、定义样式

3、定位数据初始化

三、Turfjs中bbox生成 

1、官网讲解

2、轨迹bbox生成

四、Turfjs生成外包多边形

1、官网例子

2、凸多边形生成

总结


前言

        在一些共享出行的应用地图中,以美团共享骑行为例,在城市的重要地方会设置电子围栏。防止由于共享单车无序停放而导致影响交通出行的障碍。比如在星城,湘江一桥及橘子洲景区就是设置了禁停区。可以看一下下面的地图:

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

        这里的禁停区就是一个非常明显的电子围栏的应用。 于此同时在面向GIS的安防领域,这方面的应用同样层出不穷。通过在地图上设置电子围栏,在安装了定位的自行车,就可以实现基于位置的管理。

        还有一些需求是这样的,我们可以获取车辆或者行人或者工程机械的工作GPS轨迹,根据这些GPS轨迹,我们不仅要得到轨迹线信息,同时还要根据轨迹线,可以大致还原目标的大致范围。这里的范围可能是一个矩形框(gis的bbox概念),也有可能是一个包含了轨迹信息的最大包围框,是一个面数据,而不是一个矩形数据。那么这种需求应该怎么处理呢?能否在前端实现这样的需求呢?

        本文就将重点介绍这种实现的方式,主要讲解Turf.js在求解范围多边形的两种实现方式,通过代码的方式让读者对实现过程更加的了解和掌握,可以快速的在学习和生产中进行应用。如果您当前也碰到了在webgis中进行展示,那么可以看看这篇博客,希望对您有所帮助。

一、场景需求

        这里介绍一下原来在项目当中遇到的一个场景,权当抛砖引玉,场景不尽相同,如有雷同,不慎荣幸。场景需求是这样的,需要在Webgis中展示某安装了定位的工程机械的工作点位移动情况,已天为一个展示窗口,把每天的点位信息在地图上展示出来。在此基础之上,需要求解出该工程机械的最大活动范围,同时用不同的颜色标识出来。

当时拿到这个需求之后呢,只是将这些点的信息整合起来,然后使用Leaflet的获取Bouds方法来求解包围框,通过getBounds()获取的包围框其实是一个最大矩形,是覆盖了当前空间数据四至的矩形。由于当时没有仔细考虑,使用getBounds()获取的范围会扩了许多,因为矩形的四条边都是直线,因此有很多区域是被错误的划分到了这个范围中。

        因此,这里需要一种更加灵活的方式,能更加准确的把这个区域的范围标记得更加的精准,保证这个面不仅包含目标范围,又没有浪费多余的空间。

1、Leaflet.js的不足

        在之前的博客中,介绍了很多Leaflet这个二维地图的开发组件,可以直接用于WegGIS系统的开发,可以作为底图展示和底图可视化的基座。但是对于这些需要动态绘制的空间对象,能力稍显不足。在查找了一些资料以后,并没有发现比较便捷的实现方式。因此需要考虑使用其它的技术组件来满足上述的需求。

2、Turf.js

        turf.js是一款面向webgis的前端地理空间分析库,其中包含了许多的实用的小工具,在实际项目开发当中,可以实现无缝衔接和继承接入,由于是面向客户端的产品,对于数据的安全性就大大的提高,因为无需将数据发送到本地,前端可以将后端返回的数据进行按需组合和可视化分析。关于turf的好处,这里不再赘述,感兴趣的博主可以到其turf.js中文网和turf.js官网,上面有更加详细的介绍。

        这里采用Turf.js的原因主要是其分析功能非常强大,同时其可以自动计算空间数据的bbox和最小外包多边形(支持凸、凹两种多边形)。下面将采用实例的方式分别从bbox和外包多边形的生成进行说明。

二、原始数据展示

        首先我们来看原始的数据在webgis中的展示效果是什么样的。工程机械的轨迹数据如下,通过接口可以取到其gps位置信息。示例数据如下所示:

"lat": 28.0394672,
"lng": 112.9439207,
"cog": 0.0,
"p_distance": 49.0,
"img_url": "https://agri-static.holdingbyte.com/d-1000-awwwhqgwyxqe/3ecced35-e23f-4e91-ae34-4bef6294f4c0.jpg",
"t": 1693124829,
"agri_id": "d-1000-awwwhqgwyxqe-50-00",
"the_type": 301,
"__db_name__": "0",
"t_display": "2023-08-27 08:27"
序号 参数 说明
1 lng 经度,112.9439
2 lat 纬度,28.039
3 t 时间
4 其它参数忽略 其它参数不是很重要,暂时忽略

         在实际情况下,这些数据是连续的点位数据,而不是孤立的点。上面为了将数据格式向朋友们描述清楚,所以进行了示例数据的截取,完整的大致数据体如下所示:

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

1、点位数据展示 

        为了将这些点位数据在空间上进行展示,webgis可视化组件,我们依然选择熟悉的leaflet。下面将简单回顾一下,如何在leaflet中展示点位信息。

        创建点位框架

        新建index2.html页面,在html网页中输入以下内容:

<!DOCTYPE html>
<html>
<head>
  <title>turf生成边界凸多边形实战</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./leaflet1.9.3/leaflet.css"/>
  <script src="./leaflet1.9.3/leaflet.js"></script>
  <style type="text/css">
    body {
       margin: 0;
       padding: 0;
    }
    html, body, #map{
       width: 100%;
       height: 100%;
    }
  </style>
</head>
<body>
  <div id="map"></div>
  <script type="text/javascript" src="jquery.min.js"></script>
  <!-- 使用unpkg -->
  <script src="https://unpkg.com/@turf/turf/turf.min.js"></script>
  <script>
  </script>
</body>
</html>

        定义地图

        在上面的html网页中增加javascript脚本,进行地图的定义和初始化,关键代码如下:

//声明图层组
    var workPoints = L.layerGroup();
	var wjLineGroup = L.layerGroup();
	
	var baseLayer = L.tileLayer('./yxtile/{z}/{x}/{y}.png', {
		minZoom: 14,
		maxZoom: 21,
		tms: false,
		attribution: 'turf生成边界凸多边形实战'
	  });
	  
	//声明地图并添加图层
	var map = L.map('map', {
		center: [28.038387, 112.951566],
		zoom: 16,
		layers: [baseLayer,wjLineGroup]
	});
 
	//新建图层控件的数据源-地图
	var baseLayers = {
		'离线底图': baseLayer
	};

	//新建图层控件的数据源-城市
	var overlays = {
		'行驶轨迹': wjLineGroup
	};

2、定义样式

        为了在程序中可以实现样式的复用,这里将样式的生成函数进行了封装,支持传递颜色进行自定义设置。在需要使用的时候,传入想要的颜色即可(温馨提示:这里仅实现了颜色这个参数的自定义,其它参数的自定义可以模仿这种方法进行)。

function getStyle(color){
		return { 
		  color: color, 
		  weight: 3, 
		  opacity: 1, 
		  fillColor: color, 
		  fillOpacity: 0.3, 
		  fill: true, 
		  stroke: true 
		}
	}
	

3、定位数据初始化

        定位数据采用后台接口的方式提供,这里为了演示方便,将后台接口的数据进行了静态临时存储。示例效果不变,不影响最终效果。关键代码如下:

var lineArray = new Array();
	var turfArray = new Array();
	$(document).ready(function(){
		$.ajax({
			url: "data.json", //模拟从服务器获取JSON数据的URL地址(请注意,URL必须与服务器上实际的文件名相同)
			type: "GET", // 请求方法(POST或GET)
			dataType: "json", // 响应数据类型为JSON
			success: function(data) {
			// 成功获取JSON数据后执行的函数
				var resData = data;
				for(var i=0;i<resData.results.length;i++){
					var item = resData.results[i];
					lineArray.push([item.lat, item.lng]);
				}
				
				var polyline = L.polyline(lineArray, {color: 'blue'}).addTo(wjLineGroup);
				map.fitBounds(polyline.getBounds());
			},
			error: function(xhr, status, error) {
				// AJAX请求失败时执行的函数
				console.log(xhr.responseText); // 输出错误消息到控制台
			}
		});
		
		//新建图层控件并添加到地图
		var layerControl = L.control.layers(baseLayers, overlays).addTo(map);

        在浏览器中运行以上的代码,可以看到以下的效果,即完成了对轨迹数据的web展示。

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

三、Turfjs中bbox生成 

        通过上面的例子可以看到,这里成功的把轨迹数据展示了出来。但我们怎么得到其边界范围呢?下面来深入讲解。

1、官网讲解

        首先,我们来看一下,turfjs中文网对bbox生成的介绍。Takes a set of features, calculates the bbox of all input features, and returns a bounding box.获取一组feature,计算所有featurebbox,并返回一个边界框。

        参数说明:

参数 类型 描述
geojson GeoJSON 任何 GeoJSON 对象

返回值如下:

        BBox - bbox在minX, minY, maxX, maxY顺序中的扩展

        来看一下官方的示例:

var line = turf.lineString([
        [104.99467, 30.071677],
        [107.13797, 36.550462],
        [112.607082, 34.991467]
      ]);
var bbox = turf.bbox(line);
var bboxPolygon = turf.bboxPolygon(bbox);

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

2、轨迹bbox生成

        首先,我们定义一个数组来接收数据,var turfArray = new Array();在for循环中添加新的点。

for(var i=0;i<resData.results.length;i++){
	var item = resData.results[i];
	turfArray.push(turf.point([item.lng,item.lat]));
	lineArray.push([item.lat, item.lng]);
}
				
var points = turf.featureCollection(turfArray);
var range = turf.bboxPolygon(turf.bbox(points));//turf生成最小外包框、bbox
L.geoJSON(range,{style:getStyle("red")}).addTo(map);

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

         可以看到,bbox生成的矩形范围框,包含了许多的未到达的区域。下面我们再生成最小外包多边形,来看看是否满足效果。

四、Turfjs生成外包多边形

1、官网例子

         Takes a Feature or a FeatureCollection and returns a convex hull Polygon.接受一个FeatureFeatureCollection,并返回凸多边形。

        参数说明:

参数 类型 描述
geojson GeoJSON Feature 或 FeatureCollection
options Object 可选参数:见下文

        options选项

属性 类型 默认值 描述
concavity number Infinity 1 - thin shape. Infinity - 凸多边形
var points = turf.featureCollection([
  turf.point([10.195312, 43.755225]),
  turf.point([10.404052, 43.8424511]),
  turf.point([10.579833, 43.659924]),
  turf.point([10.360107, 43.516688]),
  turf.point([10.14038, 43.588348]),
  turf.point([10.195312, 43.755225])
]);

var hull = turf.convex(points);

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

2、凸多边形生成

var hull = turf.convex(points);//turf 生成凸多边形最小外包框
L.geoJSON(hull,{style:getStyle("yellow")}).addTo(map);

在Leaflet中使用Turf.js生成范围多边形的两种实现方式,leaflet,turf实战,leaflet最小外包多边形,turf凸多边形实践

         请注意这里的最小外包多边形(黄色多边形表示的区域),基本是满足我们要求的,实现了范围最小,更精准的范围覆盖。

总结

        以上就是本文的主要内容。本文就将重点介绍这种实现的方式,主要讲解Turf.js在求解范围多边形的两种实现方式,通过代码的方式让读者对实现过程更加的了解和掌握,可以快速的在学习和生产中进行应用,详细对比了bbox和凸多边形的生成过程,最后展示了两个的实现效果。相信通过对比,能很明显的看出区别。如果有兴趣的,可以亲自动手实践一下。文章行文仓促,定有不当之处,如有不当之处,欢迎在评论区批评,非常感谢。文章来源地址https://www.toymoban.com/news/detail-839748.html

到了这里,关于在Leaflet中使用Turf.js生成范围多边形的两种实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • opencv 之 外接多边形(矩形、圆、三角形、椭圆、多边形)使用详解

    本文主要讲述opencv中的外接多边形的使用: 多边形近似 外接矩形、最小外接矩形 最小外接圆 外接三角形 椭圆拟合 凸包 将重点讲述最小外接矩形的使用 给一个opencv官方的例程: 过程图像如下: 椭圆拟合一般用于轮廓提取之后: 凸包绘制 计算两个旋转矩形交集: C++版的最

    2024年02月09日
    浏览(86)
  • 使用OpenCV的函数polylines()绘制多条相连的线段和多边形;使用函数fillPoly()绘制带填充效果的多边形

    函数polylines()可用来根据点集绘制多条相连的线段,也可用来绘制多边形。 函数polylines()有两种原型,这里只向大家介绍比较常用的那种原型。 函数polylines()的C++原型如下: 函数polylines()的Python原型如下: 函数polylines()的参数意义如下: img—绘制的多条相连线段或多边形所在

    2024年02月04日
    浏览(63)
  • three.js 点击交互事件 含解决点击的物体与看到的不一致问题(非全屏/多边形偏移)

    在 three.js 中,可以通过添加事件监听器来实现点击交互事件。具体步骤如下: 通过以上方法,可以实现 three.js 中的点击交互事件,并解决点击的物体与看到的不一致问题。

    2024年02月06日
    浏览(58)
  • 微信小程序原生使用map组件实现轨迹、多边形

    使用地图本身的map组件实现地图 初始化地图: map组件的属性 longitude 必须 Number 中心点经度 latitude 必须 Number 中心点纬度 scale 选填 Number 地图的缩放级别(缩放切换时使用) include-points 选填 Array. 缩放视野以展示所有坐标点 markers 选填 Array. 地图展示的坐标点集合 polyline 选填

    2024年02月03日
    浏览(54)
  • 【3Ds Max】可编辑多边形“点”层级的简单使用

    目录 简介 示例 (1)移除 (2)断开 (3)焊接 (4)挤出 (5)切角 (6)目标焊接  (7)连接         在3ds Max中,多边形点层级(Vertex Level)是指可以在编辑多边形网格时直接编辑的顶点(点)级别。您可以通过选择、移动、旋转、缩放等方式来编辑多边形的顶点,以

    2024年02月12日
    浏览(49)
  • 【3Ds Max】可编辑多边形“边”层级的简单使用

    目录 简介 示例  1. 编辑边  (1)插入顶点 (2)移除 (3)分割 (4)挤出  (5)切角 (6)焊接 (7)桥 (8)连接 2. 编辑几何体 (1)创建 (2)塌陷 (3)附加 (4)分离         在3ds Max中,可编辑多边形边层级(Edge Level)是指您可以在编辑多边形网格时直接编辑的

    2024年02月12日
    浏览(52)
  • 【3Ds Max】可编辑多边形“边界”层级的简单使用

    目录 示例 (1)挤出 (2)插入顶点 (3)切角 (4)利用所选内容创建图形 (5)封口 (6)桥 这里我们首先创建一个长方体,然后将其中键部分删除,形成上下底面缺失的长方体,这样就会有两个可选择的边界 (1)挤出 可以设置挤出的宽度和高度 (2)插入顶点 我们可以

    2024年02月11日
    浏览(46)
  • [C++] opencv - approxPolyDP(多边形拟合)函数介绍和使用场景

    OpenCV中的 approxPolyDP() 函数用于对形状进行逼近,以减少多边形的顶点数,可以用于对图像轮廓点进行多边形拟合。 函数原型如下: 其中, curve 是输入的点集,类型为 InputArray, 可以是 Mat 、 vectorPoint 等; approxCurve是输出的点集,类型为 OutputArray, 也是 Mat 类型; epsilon 是精

    2024年03月14日
    浏览(65)
  • [C++] opencv - fillPoly(填充多边形)函数介绍和使用场景

    fillPoly() 函数是OpenCV中用于绘制填充多边形的函数。函数原型如下: fillPoly() 函数适用于需要绘制填充多边形的场景,例如在图像上绘制一个封闭的图形、制作一个简单的遮罩等。   fillPoly() 函数是OpenCV中用于绘制填充多边形的函数。可以用来绘制实心三角形,实心矩形,实

    2024年02月19日
    浏览(114)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包