使用Leaflet.rotatedMaker进行航班飞行航向模拟的实践

目录

前言

一、Leaflet的不足

1、方向插件

 2、方向控制脚本说明

二、实时航向可视化实现

1、创建主体框架

2、飞机展示

3、位置和方位模拟

三、成果及分析

1、成果展示

2、方向绑定解读

总结


前言

        众所周知,物体在空间中的运动(比如飞行、跑步、开车、轮渡)等等,随着时间的推移,不仅仅是时空位置在不断的发生变化,同时其方向也是在发生变化。以飞机为例,在不同的时刻,某一时刻其是保持45度角飞行,其它时刻又是保持15度飞行。而在战斗过程当中,飞机的航向将变得更加的迅速。在航海或者自驾过程也是的,会随着河流、洋流或者道路而转向。在这些发生在时空中的运动过程当中,除了将地理空间位置结合WebGIS进行展示,同时还能展示其飞行的航向。这是今天的博文想要讲解的主题。

        上述是一张全球实时航班轨迹系统的截图,传送门, 这里就很好行的表达了此时飞机的飞行情况。通过飞机实时位置的跟踪,掌握飞机的运行状态。本文以模拟实现上述场景为例,重点讲解在Leaflet当中,如何实现飞机的航线展示,同时在不同的时刻可以展示其飞行方向。

一、Leaflet的不足

        假如没有飞行航向的需求,在一般的WebGIS系统的实现中,我们应该如何来实现上述的需求呢?在Leaflet当中,展示一条飞行航线和展示一个位置是非常简单的。只需要把PolyLine和Marker就可以实现,如果要把飞机展示出来,需要找一个飞机的小图标。在Leaflet当中,并没有对保持航向的实现进行说明。本节主要对方向控制的插件进行简单介绍。

1、方向插件

        这里我们介绍一款基于Leaflet的方向可调整插件,Leaflet Rotated Marker插件地址,这里给出的地址是基于gitee的一个版本。可以用作学习使用。

        使用git命令,将源代码clone到本地之后可以看到,其源码还是非常简单的。最主要的一个插件就是leaflet.rotatedMarker.js。脚本大小3KB,还是比较简单的。

 2、方向控制脚本说明

        为了让大家对leaflet.rotatedMarker.js有一个简单的认识,这里对其做一个简单的分析。leaflet.rotatedMarker.js是一个继承与Leaflet的marker插件。是marker的一个子类。通过扩展marker的一些属性来进行对象能力扩展。

// save these original methods before they are overwritten
var proto_initIcon = L.Marker.prototype._initIcon;
var proto_setPos = L.Marker.prototype._setPos;

          其对Marker的方法做了以下的扩展。

L.Marker.addInitHook(function () {
    var iconOptions = this.options.icon && this.options.icon.options;
    var iconAnchor = iconOptions && this.options.icon.options.iconAnchor;
    if (iconAnchor) {
       iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px');
    }
    this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom' ;
    this.options.rotationAngle = this.options.rotationAngle || 0;

    // Ensure marker keeps rotated during dragging
    this.on('drag', function(e) { e.target._applyRotation(); });
 });
参数类型默认值描述
rotationAngleNumber0Rotation angle, in degrees, clockwise,单位是度
rotationOriginStringbottom centerThe rotation center, as a [`transform-origin`]CSS rule

        与新增的属性控制相同,与此一并新增还有控制的方法:

setRotationAngle: function(angle) {
    this.options.rotationAngle = angle;
    this.update();
    return this;
 },

setRotationOrigin: function(origin) {
    this.options.rotationOrigin = origin;
    this.update();
    return this;
}

        这两个方法主要是用于控制航向的参数。对核心展示方法的介绍到此。代码比较简单,容易掌握。下面进行实例的开发。

二、实时航向可视化实现

        本节主要以实战的方式对航向可视化进行重点讲解。对于一些重复的代码不进行过多的讲述。这里展示的数据为模拟的虚拟数据,不代表实际运行数据。如果大家有公开的飞行数据,可以在评论区告知一下博主,万分感谢。

1、创建主体框架

        需要对地图展示对象及飞行航线及实时轨迹进行展示的主体框架。关键代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

    <title>leaflet.rotatedMarker实现飞行航向跟踪</title>
    <link rel="stylesheet" href="/2d/leaflet/leaflet.css" />
    <style>
        * { margin: 0; padding: 0; }
        html, body { height: 100%; }
        #map { width:100%; height:100%; }
    </style>
    <script src="/2d/leaflet/leaflet.js?v=1.0.0"></script>
    <script src="leaflet.rotatedMarker.js"></script>
    </head>
    <body>
        <div id="map"></div>
		 <script>
			var map = L.map('map', {
					center: [29.113775, 112.609863],
					zoom: 6,
					layers: [L.tileLayer('http://localhost:8086/data/xxgc/q0403/{z}/{x}/{y}.png', {
							attribution: '&copy; <a href="http://osm.org/copyright">yelangking</a> contributors'
						})
					]
				});
    </body>
</html>

        在上述的代码中,将地图对象和展示的map容器绑定在了一起。同时通过代码创建了一个map对象,并进行了基础图层的绑定设置。

2、飞机展示

        在leaflet中,我们可以自定义marker对象的icon属性来设置不同的图表。可以到icon网站上下载飞机的png图片,png背景是透明的,叠加到地图上效果比较好。通过下面的代码进行定义。

var blueIcon = L.icon({
	iconUrl: './air1.png',
	iconSize:     [30, 30], // icon的大小
	iconAnchor:   [16, 15], // icon的渲染的位置(相对与marker)
	shadowAnchor: [0, 0],  // shadow的渲染的位置(相对于marker)
	popupAnchor:  [0, 0] //若是绑定了popup的popup的打开位置(相对于icon)
});

3、位置和方位模拟

        这里采用模拟数据的方式对位置和方位进行模拟,在实际项目中,如果可以接入实时位置,就可以实现动态位置和方位了。模拟数据包含两个部分,第一个是模拟一条飞行航线的所有点,代表是从【昆明】飞往【温州】的一条航线,另一个是实时的飞机位置和方位数据。

//航线飞行
var data = [{'lat':24.846565,'lng':102.65625,'name':"昆明市",'ang':75,"title":"东航6523"},
			{'lat':26.470573,'lng':106.655273,'name':"贵阳市",'ang':80,"title":"东航6523"},
			{'lat':27.469287,'lng':110.01709,'name':"怀化市",'ang':80,"title":"东航6523"},
			{'lat':28.149503,'lng':112.983398,'name':"长沙市",'ang':80,"title":"东航6523"},
			{'lat':28.632747,'lng':115.883789,'name':"南昌市",'ang':100,"title":"东航6523"},
			{'lat':27.858504,'lng':120.739746,'name':"温州市",'ang':120,"title":"东航6523"}
			];
 //实时位置
var currentFly =[{'lat':29.53523,'lng':106.54541,'ang':25,"title":"国航3265"},
				{'lat':30.637912,'lng':104.040527,'ang':-32,"title":"川航2369"},
				{'lat':26.352498,'lng':111.665039,'ang':-80,"title":"东航6573"},
				{'lat':24.706915,'lng':113.598633,'ang':-50,"title":"上航6023"},
				{'lat':30.183122,'lng':120.256348,'ang':100,"title":"海航5002"},
				{'lat':30.543339,'lng':114.279785,'ang':120,"title":"厦航6523"} 
				];

        位置添加和方位展示核心代码如下:

var lineArray = new Array();
for(var i = 0;i<data.length;i++){
		var item = data[i];
		var m = L.marker(L.latLng(item.lat, item.lng),{icon: blueIcon,title:item.title,rotationAngle: item.ang,draggable: true});
		lineArray.push([item.lat, item.lng]);
		m.addTo(map).bindPopup("飞行城市:" +item.name + "<br/>位置:【" + item.lng + "," + item.lat +"】" );
}
			
var polyline = L.polyline(lineArray, {color: 'red'}).addTo(map);
for(var i = 0;i<currentFly.length;i++){
	var item = currentFly[i];
	var m = L.marker(L.latLng(item.lat, item.lng),{icon: blueIcon,title:item.title,rotationAngle: item.ang,draggable: true});
	m.addTo(map).bindPopup("位置:【" + item.lng + "," + item.lat +"】" );
}

        rotationAngle这个属性即表示最重要的方向。通过这个属性就能展示实时方向。以上代码就完成了飞行航线和方向的可视化。下面来看一下实际的效果与最开始我们的期望是否一致。

三、成果及分析

        这是本文的第三节,将对实例的最终成果进行展示,同时结合代码进行简单的分析。让读者更详细的掌握实现原理。

1、成果展示

飞行航线整体展示示意图 

点击信息提示示意图 

2、方向绑定解读

        这里结合源码对方向的绑定和初始化进行简单解读,依然采用熟悉的debug调试的模式。

        在点进行初始化的时候,会自动将方向传入到初始方法中,直接对属性进行赋值。 

         在展示过程中,会对浏览器进行识别,需要调用不同的样式设置对方向进行设置来完成飞机航向的控制。

总结

         以上就是本文的主要内容,本文以模拟实现上述场景为例,重点讲解在Leaflet当中,如何实现飞机的航线展示,同时在不同的时刻可以展示其飞行方向。行文仓促,难免有不足之处,欢迎各位专家朋友批评指正。

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

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

相关文章

基于微信小程序的考研交流平台的设计与实现

3 系统需求分析与设计 3.1 系统需求分析 本系统基于微信小程序&#xff0c;实现教学互动软件系统是本文的目标&#xff0c;主要涉及到的系统角色分为学生、教师、管理员。系统角色主要有管理员&#xff0c;普通用户两种角色构成。 普通用户有如下几个核心需求&#xff1a; …

JUC:synchronized优化——锁的升级过程(偏向锁->轻量级锁->重量级锁)以及内部实现原理

文章目录 锁的类型轻量级锁重量级锁自旋优化偏向锁偏向锁的细节偏向锁的撤销批量重偏向批量撤销锁消除 锁的类型 重量级锁、轻量级锁、偏向锁。 加锁过程&#xff1a;偏向->轻量级->重量级 轻量级锁 轻量级锁的使用场景&#xff1a;如果一个对象虽然有多线程要加锁&am…

Django详细教程(一)

文章目录 一、安装Django二、创建项目1.终端创建项目2.Pycharm创建项目&#xff08;专业版才可以&#xff09;3.默认文件介绍 三、创建app1.app介绍2.默认文件介绍 四、快速上手1.写一个网页步骤1&#xff1a;注册app 【settings.py】步骤2&#xff1a;编写URL和视图函数对应关…

sort函数对vector一维或者二维数组排序

目录 sort对一维数组排序 1、sort对一位数组升序排序 2、sort对一维数组降序排序 sort对二维数组排序 1、sort默认对横坐标进行升序排序&#xff0c;如下&#xff1a; 2、使用自定义排序对纵坐标进行升序排序&#xff1a; 额外知识&#xff1a; 对横坐标进行降序排列,当…

【全栈小5】我的创作纪念日

目录 前言机缘收获粉丝和原创个人成就六边形战士 回顾文章原代码代码优化 憧憬 前言 全栈小5 &#xff0c;有幸再次遇见你&#xff1a; 还记得 2019 年 03 月 29 日吗&#xff1f; 你撰写了第 1 篇技术博客&#xff1a; 《前端 - 仿动态效果 - 展开信息图标》 在这平凡的一天&…

CSS(三)---【盒子模型、边框、外边距合并】

零.前言 本篇主要介绍CSS中最重要的一种概念模型&#xff1a;“盒子模型”。 关于CSS的更多内容&#xff0c;可以查看作者之前的文章&#xff1a; CSS(一)---【CSS简介、导入方式、八种选择器、优先级】-CSDN博客 CSS(二)---【常见属性、复合属性使用】-CSDN博客 一.盒子模…

基于AI网关的光伏电站在线监测方案

光伏电站作为利用太阳能的重要方式&#xff0c;凭借其环保、高效和可持续性的优势&#xff0c;在全球范围内得到广泛应用。然而&#xff0c;光伏电站的运营和维护也面临着诸多难点和痛点。在这一背景下&#xff0c;AI智能网关的应用为光伏电站的运营和维护带来了新的突破。 光伏…

天梯算法Day3整理

浮点数解析 炸鱼题掠过 冲突值 题面 解析 方法一 —— 并查集 按照边值排序&#xff0c;然后按边值从大到小遍历&#xff0c;通过并查集判断能否将所有点无冲突地归于两个集合。在判断时&#xff0c;若有两个点不得不产生冲突&#xff0c;则输出这两个点之间的边值并结束。…

linux 网卡配置 vlan/bond/bridge/macvlan/ipvlan/macvtap 模式

linux 网卡模式 linux网卡支持非vlan模式、vlan模式、bond模式、bridge模式&#xff0c;macvlan模式、ipvlan模式等&#xff0c;下面介绍交换机端及服务器端配置示例。 前置要求&#xff1a; 准备一台物理交换机&#xff0c;以 H3C S5130 三层交换机为例准备一台物理服务器&…

变分信息瓶颈

变分信息瓶颈和互信息的定义 1 变分信息瓶颈 定义&#xff1a;变分信息瓶颈&#xff08;Variational Information Bottleneck&#xff09;是一种用于学习数据表示的方法&#xff0c;它旨在通过最小化输入和表示之间的互信息来实现数据的压缩和表示学习。这种方法通常用于无监…

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序

ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;可将模拟信号转换成对应的数字信号&#xff0c;便于存储与计算等操作。除电源线和地线之外&#xff0c;ADC只需要1根线与被测量的设备进行连接。 一、案例简介 该程序是基于…

Java基础语法(三)| 循环语句

前言 Hello&#xff0c;大家好&#xff01;很开心与你们在这里相遇&#xff0c;我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩&#xff0c;想与你们共同学习、探索关于IT的相关知识&#xff0c;希望我们可以一路陪伴~ 1. if语句 1.1 格式一 if (关系表达式) …

探讨企业邮箱安全问题:必须关注的四个关键要点

近年来&#xff0c;虽然出现了微信、企微等沟通方式&#xff0c;但电子邮件无疑仍然是公司对内对外沟通的首选方式。根据Statista的研究&#xff0c;每天大约有3330亿封电子邮件被发送和接收&#xff0c;预计这一数字在未来几年还会增长。然而&#xff0c;邮件诈骗的问题也一直…

SiameseRPN原理详解(个人学习笔记)

参考资源&#xff1a; 视觉目标跟踪SiamRPNSiameseRPN详解CVPR2018视觉目标跟踪之 SiameseRPN 目录&#xff09; 1. 模型架构1.1 Siamese Network1.2 RPN 2. 模型训练2.1 损失函数2.2 端到端训练2.3 正负样本选择 3. 跟踪阶段总结 SiamRPN是在SiamFC的基础上进行改进而得到的一…

web布局——说清楚fixed布局

极限省流 想要fixed做导航页面&#xff1a;指定清楚top、left、right、bottom&#xff0c;没指定清楚布局位置就会采用默认的方式&#xff1a; 0&#xff09;父元素的padding&#xff1a;fixed元素相对位移 1&#xff09;同级元素是fixed元素&#xff1a;覆盖 2&#xff09…

unrealbuildtool 无法找到,执行 Generate Visual Studio Project 错误

参考链接 Generate cpp project Couldnt find UnrealBuildTool - Pipeline & Plugins / Plugins - Epic Developer Community Forums (unrealengine.com) 错误提示如下图&#xff1a; 解决方案&#xff1a; 打开 UnrealBuildTool&#xff0c;生成解决方案就可以了

解决Veeam做replication复制或备份任务时速度很慢问题

在网络层面配置无问题&#xff0c;比如都是万兆网情况下&#xff0c;发现对一个10T大小Linux虚拟机执行replication复制任务时&#xff0c;每次都需要30几个小时才可以跑完。如下图&#xff1a; 如何能让它更快一点跑完任务呢&#xff1f; 解决方法&#xff1a;登录Veeam,进入…

Verilog语法回顾--门级和开关级模型

目录 门和开关的声明 门和开关类型 支持驱动强度的门 延迟 实例数组 and&#xff0c;nand&#xff0c;nor&#xff0c;or&#xff0c;xor&#xff0c;xnor buf&#xff0c;not bufif1&#xff0c;bufif0&#xff0c;notif1&#xff0c;notif0 MOS switches Bidirecti…

Ubuntu20.04LTS+uhd3.15+gnuradio3.8.1源码编译及安装

文章目录 前言一、卸载本地 gnuradio二、安装 UHD 驱动三、编译及安装 gnuradio四、验证 前言 本地 Ubuntu 环境的 gnuradio 是按照官方指导使用 ppa 的方式安装 uhd 和 gnuradio 的&#xff0c;也是最方便的方法&#xff0c;但是存在着一个问题&#xff0c;就是我无法修改底层…

2013年认证杯SPSSPRO杯数学建模A题(第一阶段)护岸框架全过程文档及程序

2013年认证杯SPSSPRO杯数学建模 A题 护岸框架 原题再现&#xff1a; 在江河中&#xff0c;堤岸、江心洲的迎水区域被水流长期冲刷侵蚀。在河道整治工程中&#xff0c;需要在受侵蚀严重的部位设置一些人工设施&#xff0c;以减弱水流的冲刷&#xff0c;促进该处泥沙的淤积&…