百度离线地图示例之十三:动态运行轨迹实现(附源码)
前言介绍:主要是基于v3.0的API版本进行的离线,纯内网可操作,基本上实现了现有90%以上的功能点,能兼容jpg和png格式的瓦片图层,实现了原生和基于Vue两个版本(包含常用的55个示例),文末有个人微信二维码,有不完善的地方,可加微信一起探讨交流,实现的功能点概要如下:地图示例:地图展示同时加载两个地图设置地图最大及最小级别移动地图缩放地图拖拽地图设置地图显示范围获取地图显示范围测距地图控件
前言介绍:
主要是基于v3.0的API版本进行的离线,纯内网可操作,基本上实现了现有90%以上的功能点,能兼容jpg和png格式的瓦片图层,实现了原生和基于Vue两个版本(包含常用的55个示例),文末有个人微信二维码,有不完善的地方,可加微信一起探讨交流,实现的功能点概要如下:
地图示例:
地图展示
同时加载两个地图
设置地图最大及最
小级别移动地图
缩放地图
拖拽地图
设置地图显示范围
获取地图显示范围
测距
地图控件:
工具条、比例尺控件 地图类型
缩略图控件
添加版权控件
添加自定义控件
覆盖物示例:
添加/删除覆盖物
折线上添加方向箭头
添加动画标注点
设置点的新图标
设置点是否可拖拽 设置线、面可编辑
设置覆盖物的显示与隐藏
文本标注
带文字标签的覆盖物
获取覆盖物的信息
添加多个标注点
从多个点删除指定点
加载闪烁点
加载海量点 添加弧线
画椭圆
添加自定义覆盖物
点聚合
添加/删除地面叠加层
热力图功能示例
矢量图
添加自定义控件
信息窗口示例:
纯文本的信息窗口
添加复杂内容的信息窗口
给多个点添加信息窗口
获取信息窗口的信息
右键菜单示例:
给地图添加右键菜单
给覆盖物添加右键菜单
鼠标操作示例
设置地图默认的鼠标样式
鼠标滚轮缩放地图
鼠标拖拽地图
鼠标测距
单击获取点击的经纬度
鼠标绘制工具
添加层示例:
添加清华校园微观图
自定义网格
事件示例
图块加载完毕
地图单击事件
给覆盖物注册事件
传递事件参数
为多个点注册单击事件
注销事件
除了离线了官方API外,还对一些操作工具类进行了离线(总计11个工具),比如:
Heatmap
作用:热力图
SearchInfoWindow
作用:百度地图样式”的信息窗口工具。该工具为用户提供带搜索框的信息窗口,该窗口内容可自由定制多种风格。同时,用户可以将信息窗口标题以短信方式发送到手机上。
MarkerClusterer
作用:多标注聚合器。此工具解决加载大量点要素到地图上造成缓慢,且产生覆盖现象的问题。
RectangleZoom
作用:区域缩放工具。此工具将根据用户拖拽绘制的矩形区域大小对地图进行放大或缩小操作。
TextIconOverlay
作用:自定义覆盖物工具。用户可以使用该工具在地图上添加文字和图标样式的覆盖物。
LuShu
作用:路书,轨迹运动工具。此工具用以实现marker沿路线运动,并有暂停等功能。
GeoUtils
作用:几何运算工具。此工具提供判断点与矩形、 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。
DistanceTool
作用:测距。
DrawingManager
作用:矢量图绘制。
代码示例实现:
html引用示例代码如下:
1、百度地图离线API下载地址
2、百度地图离线工具类集合下载地址
可以看出全部是离线引用,当然哪些工具类可以在组件内用的时候再引用也可以
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>百度离线地图</title>
<!-- 百度地图3.0 API Begin -->
<script src="static/offlineMapLib/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="static/offlineMapLib/map3.0_init.js"></script>
<script type="text/javascript" src="static/offlineMapLib/map3.0.js"></script>
<script type="text/javascript" src="static/offlineMapLib/layer.js"></script>
<script type="text/javascript" src="static/offlineMapLib/demo.js"></script>
<!-- 热力图 -->
<script type="text/javascript" src="static/offlineMapLib/library/Heatmap_min.js"></script>
<!-- 画弧线 -->
<script type="text/javascript" src="static/offlineMapLib/library/CurveLine.min.js"></script>
<!-- 点聚合 -->
<script type="text/javascript" src="static/offlineMapLib/library/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="static/offlineMapLib/library/MarkerClusterer_min.js"></script>
<!-- 测距 -->
<script type="text/javascript" src="static/offlineMapLib/library/DistanceTool_min.js"></script>
<!-- 鼠标绘制 -->
<link rel="stylesheet" href="static/offlineMapLib/library/DrawingManager_min.css" />
<script type="text/javascript" src="static/offlineMapLib/library/DrawingManager_min.css"></script>
<!-- 百度地图3.0 End -->
</head>
<body>
<div id="app"></div>
</body>
</html>
要求:一个基于离线百度地图(此方法在线也适用)实时展示车或者其他对象的运行轨迹,且在运行过程中需要车头方向随着角度进行变化。
相关绘制数据如下:
var PointArr = [
{"lng":116.36239048877775,"lat":39.938322220559},
{"lng":116.36239048877775,"lat":39.93793496684673},
{"lng":116.36239048877775,"lat":39.93760303333522},
{"lng":116.36246235321855,"lat":39.936883838492925},
{"lng":116.36246235321855,"lat":39.93627528306042},
{"lng":116.36246235321855,"lat":39.93577737001302},
{"lng":116.36246235321855,"lat":39.93527945331416},
{"lng":116.36260608210014,"lat":39.93472620825511},
{"lng":116.36260608210014,"lat":39.933785681309004},
{"lng":116.36274981098174,"lat":39.9334537275117},
{"lng":116.36267794654094,"lat":39.93295579377289},
{"lng":116.36267794654094,"lat":39.932402529780596},
{"lng":116.36267794654094,"lat":39.93184926128044},
{"lng":116.36267794654094,"lat":39.93063205471247},
{"lng":116.36274981098174,"lat":39.92902752181022},
{"lng":116.36282167542254,"lat":39.92841889596463},
{"lng":116.36282167542254,"lat":39.92781026466464},
{"lng":116.36289353986334,"lat":39.92703563512155},
{"lng":116.36289353986334,"lat":39.926260996743295},
{"lng":116.36282167542254,"lat":39.925541681766745},
{"lng":116.36289353986334,"lat":39.92449036155915},
{"lng":116.36296540430413,"lat":39.92410302895963},
{"lng":116.36332472650813,"lat":39.9228303491527},
{"lng":116.36382777759371,"lat":39.9228303491527},
{"lng":116.36469015088329,"lat":39.922775014707135},
{"lng":116.36619930414005,"lat":39.922719680216495},
{"lng":116.36655862634404,"lat":39.92288568355318},
{"lng":116.36627116858085,"lat":39.9242690289156},
{"lng":116.36670235522564,"lat":39.924324362144105},
{"lng":116.36742099963362,"lat":39.924324362144105},
{"lng":116.3684989662456,"lat":39.924324362144105},
{"lng":116.36943320397597,"lat":39.92437969532753},
{"lng":116.37029557726555,"lat":39.92437969532753},
{"lng":116.37094235723274,"lat":39.92437969532753},
{"lng":116.37158913719992,"lat":39.92449036155915},
{"lng":116.3723796460487,"lat":39.92443502846588},
{"lng":116.37302642601588,"lat":39.92449036155915},
{"lng":116.37360134154227,"lat":39.92460102761046},
{"lng":116.37439185039105,"lat":39.924545694607346},
{"lng":116.37496676591743,"lat":39.924545694607346},
{"lng":116.37546981700302,"lat":39.92460102761046},
{"lng":116.37582913920701,"lat":39.924656360568505},
{"lng":116.37669151249659,"lat":39.924656360568505},
{"lng":116.37719456358218,"lat":39.92471169348146},
{"lng":116.37776947910857,"lat":39.924767026349365},
{"lng":116.37848812351655,"lat":39.924822359172175},
{"lng":116.37906303904293,"lat":39.924767026349365},
{"lng":116.37963795456932,"lat":39.924822359172175},
{"lng":116.38006914121411,"lat":39.924767026349365},
{"lng":116.38006914121411,"lat":39.92443502846588},
{"lng":116.38006914121411,"lat":39.923992362096946},
{"lng":116.3801410056549,"lat":39.92332835713435},
{"lng":116.3801410056549,"lat":39.9229410179086},
{"lng":116.3802128700957,"lat":39.92227700266861},
{"lng":116.3802847345365,"lat":39.92155764550042},
{"lng":116.3802847345365,"lat":39.92089361673764},
{"lng":116.3803565989773,"lat":39.920229581483945},
{"lng":116.3803565989773,"lat":39.91962087679934},
{"lng":116.3803565989773,"lat":39.918956829104815},
{"lng":116.3803565989773,"lat":39.91829277491945},
{"lng":116.3804284634181,"lat":39.91762871424328},
{"lng":116.3804284634181,"lat":39.91696464707632},
{"lng":116.3805721922997,"lat":39.91524911018613},
{"lng":116.3805003278589,"lat":39.914806383957064},
{"lng":116.3805003278589,"lat":39.914363654843264},
{"lng":116.3803565989773,"lat":39.9136442138807},
{"lng":116.38186575223406,"lat":39.91331216163647},
{"lng":116.38315931216843,"lat":39.913422845898175},
{"lng":116.3844528721028,"lat":39.913422845898175},
{"lng":116.38553083871477,"lat":39.91331216163647},
{"lng":116.38739931417552,"lat":39.913422845898175},
{"lng":116.3885491452283,"lat":39.913367503789864},
{"lng":116.38977084072187,"lat":39.91358887195269},
{"lng":116.39092067177464,"lat":39.91353352997958},
{"lng":116.39199863838661,"lat":39.9136442138807},
{"lng":116.39415457161057,"lat":39.9136442138807},
{"lng":116.39551999598574,"lat":39.91381023939432},
{"lng":116.3967416914793,"lat":39.913754897601514},
{"lng":116.39774779365048,"lat":39.913865581142055},
{"lng":116.39810711585447,"lat":39.913920922844696},
{"lng":116.39817898029527,"lat":39.91469570194906},
{"lng":116.39817898029527,"lat":39.915304450761944},
{"lng":116.39810711585447,"lat":39.91624523365416},
{"lng":116.39810711585447,"lat":39.91707532538824},
{"lng":116.39796338697288,"lat":39.91773939147339},
{"lng":116.39803525141367,"lat":39.9184587890743},
{"lng":116.39796338697288,"lat":39.91912284163695},
{"lng":116.39789152253208,"lat":39.92045092728972},
{"lng":116.39774779365048,"lat":39.9212256319304},
{"lng":116.39774779365048,"lat":39.92200032773621},
{"lng":116.39774779365048,"lat":39.922719680216495},
{"lng":116.39767592920968,"lat":39.923605026657604},
{"lng":116.39753220032809,"lat":39.92460102761046},
{"lng":116.39753220032809,"lat":39.925541681766745},
{"lng":116.39746033588729,"lat":39.92637165990969},
{"lng":116.39746033588729,"lat":39.928474225812344},
{"lng":116.39896948914405,"lat":39.92958081330031},
{"lng":116.39997559131523,"lat":39.92958081330031},
{"lng":116.40148474457199,"lat":39.92974679986831},
{"lng":116.40292203338795,"lat":39.92980212863415},
{"lng":116.40443118664471,"lat":39.92980212863415},
{"lng":116.40579661101988,"lat":39.92980212863415},
{"lng":116.40716203539505,"lat":39.92991278603061},
{"lng":116.40852745977021,"lat":39.92985745735493},
{"lng":116.4088867819742,"lat":39.92991278603061},
{"lng":116.4090305108558,"lat":39.929470155362914},
{"lng":116.4091023752966,"lat":39.928861533484174},
{"lng":116.4091023752966,"lat":39.92786559500822},
{"lng":116.4092461041782,"lat":39.92637165990969},
{"lng":116.40946169750059,"lat":39.92388169505393},
{"lng":116.40953356194139,"lat":39.92244300708714},
{"lng":116.40938983305979,"lat":39.92161298093767},
{"lng":116.40938983305979,"lat":39.92039559090589},
{"lng":116.40938983305979,"lat":39.919178179057525},
{"lng":116.40960542638219,"lat":39.91685396858412},
{"lng":116.40960542638219,"lat":39.91574717374566},
{"lng":116.40960542638219,"lat":39.914751042975595},
{"lng":116.40974915526378,"lat":39.91419763068185},
{"lng":116.40802440868462,"lat":39.91414228920457},
{"lng":116.40665898430946,"lat":39.91419763068185},
{"lng":116.40594033990148,"lat":39.91408694768221},
{"lng":116.40594033990148,"lat":39.91309079257217},
{"lng":116.40579661101988,"lat":39.9118179064571},
{"lng":116.40608406878307,"lat":39.91087706226448},
{"lng":116.40615593322387,"lat":39.91010223961911},
{"lng":116.40629966210547,"lat":39.909272062695706},
{"lng":116.40608406878307,"lat":39.90871860577934},
{"lng":116.40615593322387,"lat":39.90766702522079},
{"lng":116.40601220434228,"lat":39.90689216597646},
{"lng":116.4050061021711,"lat":39.90667077599834},
{"lng":116.40320949115115,"lat":39.90667077599834},
{"lng":116.40134101569039,"lat":39.90661542839114},
{"lng":116.39904135358485,"lat":39.90683681854954},
{"lng":116.39746033588729,"lat":39.90667077599834}]
展示实时画线的效果,我们将数组300毫秒取出一个,这里时间间隔可以根据自己需求设定。然后将取出值存储到新的数组里,通过数组拿出前后两个值进行画线。
var carMk;//先将终点坐标展示的mark对象定义
//小车行驶图标
var drivingPoint = new BMap.Icon('map/images/car.png', new BMap.Size(52,26), {
anchor : new BMap.Size(27, 13),
imageSize:new BMap.Size(52,26)
});
//终点图标
var terminalPoint = new BMap.Icon('map/images/marker_red_hd.png', new BMap.Size(45,45), {
anchor : new BMap.Size(20, 45),
imageSize:new BMap.Size(45,45)
});
var i = 0;
var interval = setInterval(function () {
if (i >= PointArr.length) {
clearInterval(interval);
return;
}
drawLine(map,PointArr[i],PointArr[i+1]);//画线调用
i = i + 1;
}, 300);
绘制运动路径调用方法:
// 划线
function drawLine(map,PointArr,PointArrNext) {
debugger
if(PointArrNext!=undefined) {
var polyline = new BMap.Polyline(
[
new BMap.Point(PointArr.lng, PointArr.lat),
new BMap.Point(PointArrNext.lng, PointArrNext.lat)
],
{
strokeColor: "red",
strokeWeight: 7,
strokeOpacity: 1
}); //创建折线
map.addOverlay(polyline);
addMarkerEnd(new BMap.Point(PointArrNext.lng, PointArrNext.lat), '小车行驶', map, PointArrNext, new BMap.Point(PointArr.lng, PointArr.lat));//添加图标
}else {
addMarkerEnd(new BMap.Point(PointArr.lng, PointArr.lat), '终点', map);//添加终点图标
}
}
为了模拟出运动效果,且交互没关,在画下一次图标时候先将前一个图标清除掉,重新绘制新位置的图标;如下:
function addMarkerEnd(point, name,mapInit,trackUnit,prePoint) {
if(name=="小车行驶"){
if(carMk){//先判断第一次进来的时候这个值有没有定义,有的话就清除掉上一次的。然后在进行画图标。第一次进来时候没有定义也就不走这块,直接进行画图标
mapInit.removeOverlay(carMk);
}
carMk = new BMap.Marker(point,{icon:drivingPoint}); // 创建标注
getCarAngle(point,prePoint);// js求解两点之间的角度
carMk.setRotation(getCarAngle(point,prePoint)-90);// 旋转的角度
mapInit.addOverlay(carMk); // 将标注添加到地图中
//carMk.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
}else {
mapInit.removeOverlay(carMk);
// carMk = new BMap.Marker(point,{icon:terminalPoint}); // 创建标注
// mapInit.addOverlay(carMk);
}
}
比如汽车运动时,图标肯定是有朝向的,比如车头永远朝前面,所以我们需要对角度方向进行调整,所以我们就根据点的经纬度调整方向,代码如下:
//获得角度的函数
function getCarAngle(n,next){
var ret
var w1 = n.lat/180 * Math.PI
var j1 = n.lng/180 * Math.PI
var w2 = next.lat/180 * Math.PI
var j2 = next.lng/180 * Math.PI
ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2) - Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
ret = Math.sqrt(ret);
// var temp = Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2));
var temp = Math.sin((j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2));
console.log(temp)
ret = ret/temp;
ret = Math.atan(ret) / Math.PI * 180 ;
ret += 90;
// 这里用如此臃肿的if..else是为了判定追踪单个点的具体情况,从而调整ret的值
if(j1-j2 < 0){
if(w1-w2 < 0){
ret;
}else{
ret = -ret+180;
}
}else{
if(w1-w2 < 0){
ret = 180+ret;
}else{
ret = -ret;
}
}
return ret ;
}
地图实现效果展示:
本节源码:下载
上一篇:百度离线地图示例之十二:混合图(街道图、卫星图)实现路径及打点
下一篇:百度离线地图示例之十四:实现动态迁徙图(附源码,在线也可用)
系列文章后续一直有进行更新,有不完善的地方,可加微信一起交流:
更多推荐
所有评论(0)