记录开发基于百度地图API实现在地图上绘制轨迹并拾取轨迹对应经纬度的工具说明
前言:
最近一直在做数据可视化方面的工作,其中平面可视化没什么难度,毕竟已经有很多成熟的可供使用的框架,比如百度的echart.js,highcharts.js等。还有就是3D可视化了,整体来说难度也还好,通过WEBGL技术一般的可视化效果还是很好实现,如果对于WEBGL光线渲染力不从心的话直接通过three.js来做也是很方便。
其实真正困扰我开发的是可视化项目中一般会存在很多基于地图方面的开发工作,只要是涉及到地图的可视化必然会跟经纬度相关联。如果是单纯获取地图上某个特定城市或者特定点的经纬度这个很好实现,通过 百度地图经纬度拾取系统 便可以很方便的获取到,但是这个系统只能是获取单个点的经纬度,并不能根据地图上的特定轨迹来拾取轨迹对应的经纬度信息。因为在实际开发过程中,地图可视化项目最多的还是在地图上绘制轨迹的需求。举个实际工作中遇到的需求,需要在某城市的地图上绘制出该城市所有地铁线路图,并且在对应站点展示高峰流量。这个需求中特定站点的绘制相对简单,可以通过上述讲的百度地图经纬度拾取系统来获取,但是对应的地铁轨迹的经纬度信息获取就蛋疼了,在网上查询了好久都没能够查询到(可以肯定的是网上肯定有,但是我就是查不到)。
针对上面所讲的困惑,我就有了想自己制作一个工具的想法,这个工具可以根据用户在地图上绘制的轨迹对应的将轨迹的经纬度信息保存并提供给用户,先不说这个想法是否能够帮助到其他人,至少能够满足我工作的需求。
工具原理说明:
1 用户在工具集成地图上绘制轨迹(点轨迹,圆轨迹,线轨迹,多边形轨迹,四边形轨迹);
2 工具内部调用集成地图API获取绘制轨迹的经纬度信息;
3 将集成地图API返回的经纬度信息展示在工具对应的位置中,每次绘制玩一个轨迹就生成一条经纬度信息;
4 用户通过工具提供的查看轨迹详情按钮可以查看经纬度信息并且可以直接复制到自己项目中使用;
5 为了满足项目中一个需求包含多个轨迹的可能性,因此增加了一个合并轨迹经纬度信息的功能。
集成地图选型:
目前用户群体最大的两个地图是百度和阿里旗下的高德地图,经过比对最终还是选择了百度地图,因为百度地图API中有提供鼠标绘制工具DrawingManager,并且使用简单,API文档也比较完善。
工具界面设计:
既然集成地图选择了百度地图,那工具界面也就同百度地图界面,界面效果图具体如下:
工具实现代码说明:
1 dom结构说明:
1.1 main-div 为整体显示框架;
2.2 search-frame 用于存放搜索内容;
2.3 travel-frame 用于存放轨迹;
2.4 setting-frame 用于存放地图皮肤和鼠标绘制工具配置项内容;
2.5 allmap 用于存放百度地图。
<div class="main-div">
<div class="search-frame">
<div class="search">
<input class="search-input" placeholder="请输入搜索关键字">
<button class="search-btn"><i class="fa fa-search"></i></button>
</div>
<div class="search-info" style="max-height: 122px;"></div>
</div>
<!-- 轨迹 -->
<div class="travel-frame"> </div>
<!-- 配置项 -->
<div class="setting-frame">
<div class="setting-content" style="">
<div class="setting-list map-theme">
<p>地图皮肤配置</p>
<div class="theme-content clearfix"> </div>
</div>
<div class="setting-list">
<p>地图绘制工具参数配置</p>
<div class="list-content">
<label>边线颜色</label>
</div>
<div class="list-content">
<label>填充颜色</label>
</div>
<div class="list-content">
<label>边线宽度</label>
</div>
<div class="list-content">
<label>边线类型</label>
</div>
</div>
<div class="setting-operate"><i class="fa fa-chevron-down"></i></div>
</div>
<div id="allmap"></div>
</div>
2 js代码说明:
2.1 首先在代码中引入百度地图API js文件,鼠标操作工具css文件和js文件,具体引用代码如下;
<link rel="stylesheet" href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您在百度申请的key值"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script>
2.2 百度地图初始化,地图开启滚轮缩放,默认展示区域为北京。因为实现的工具不需要展示具体点的详情信息,所以需要禁止点击地图的详情弹窗,通过设置enableMapClick = false实现。
// 百度地图初始化,其中allmap为页面中需要展示地图的id值
var map = new BMap.Map("allmap", {
enableMapClick: false
})
// 开启滚轮缩放
map.enableScrollWheelZoom(true);
// 初始化地图默认显示地点为北京
var point = new BMap.Point(120.12, 30.16);
map.centerAndZoom(point, 13);
2.3 地图初始化完成后,需要根据用户当前所在地对应的进行地图显示位置切换,该操作需要获取位置信息,需要用户授权。
// 获取当前用户所在位置信息
var geolocation = new BMap.Geolocation();
// 获取定位,如果获取成功则定位到当前位置,定位不成功使用默认的位置
geolocation.getCurrentPosition(function (r) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
map.panTo(r.point);
map.enableScrollWheelZoom(true);
} else {
layer.alert('failde' + this.getStatus());
}
}, {enableHighAccuracy: true})
2.4 鼠标绘制工具参数说明及鼠标绘制工具实例化。
// 鼠标绘制巩固配置项及说明
var styleOptions = {
strokeColor: '#ff0000', // 边线颜色。
fillColor: ‘#ff0000’, // 填充颜色,当该参数为空时,圆形/多边形/正方形将没有填充效果。
strokeWeight: 1, // 边线的宽度,以像素为单位,默认为1。
strokeOpacity: 0.8, // 边线的透明度,取值范围为0~1。
fillOpacity: 0.6, // 填充的透明度,取值范围为0~1。
strokeStyle: 'solid' // 边线的样式,可选solid和dashed。
}
// 鼠标绘制工具实例化
var drawingManger = new BMapLib.DrawingManager(map, {
isOpen: false, // 表示是否开启绘制模式
enableDrawingTool: true, // 是否显示工具栏
drawingToolOptions: {
anchor: BMAP_ANCHOR_TOP_RIGHT, // 工具栏显示在右上角
offset: new BMap.Size(5,5) // 工具栏偏移右上角位置
},
circleOptions: styleOptions, // 圆的样式
polylineOptions: styleOptions, // 线的样式
polygonOptions: styleOptions, // 多边形的样式
rectangleOptions: styleOptions, // 矩形的样式
})
2.5 鼠标绘制工具样式更改和地图皮肤更换。鼠标绘制工具样式更改通过重定义 styleOptions 对应参数来实现,其中边框颜色和填充颜色需要把颜色和透明度分开,地图皮肤切换通过 map.setMapStyle 来实现。
// 地图皮肤更改代码
$('.theme-list').click(function () {
// 获取地图皮肤类型
var themeName = $(this).data('type');
// 将皮肤类型保存到本地
localStorage.setItem('themeType', themeName);
// 执行更改皮肤操作
map.setMapStyle({
style: themeName
})
})
// 鼠标操作工具配置项更改方法
function changeOptionFun () {
var strokeColorArray = mapOption.borderColor.split(',');
var strokeColor = mapOption.borderColor.indexOf('rgba') != -1 ? 'rgb(' + [strokeColorArray[0].split('(')[1],strokeColorArray[1],strokeColorArray[2]].join(',') + ')' : mapOption.borderColor;
var strokeOpacity = strokeColorArray[3].split(')')[0];
var fillColor = mapOption.fillColor.indexOf('rgba') != -1 ? 'rgb(' + [fillColorArray[0].split('(')[1],fillColorArray[1],fillColorArray[2]].join(',') + ')' : mapOption.fillColor;
var fillOpacity = fillColorArray[3].split(')')[0];
// 参数更新
styleOptions.strokeColor = strokeColor;
styleOptions.fillColor = fillColor;
styleOptions.strokeWeight = Number(mapOption.borderWidth);
styleOptions.strokeOpacity = Number(mapOption.strokeOpacity );
styleOptions.fillOpacity= Number(mapOption.fillOpacity);
styleOptions.strokeStyle= Number(mapOption.borderType);
}
2.6 鼠标绘制工具添加轨迹绘制完成方法overlaycomplete,该方法中执行轨迹绘制完成后保存绘制轨迹数据到 markerArray 中,对应的需要更新页面中轨迹弹窗中的数据,轨迹新增完成后需要先输入保存轨迹的名称,然后才能执行以后的步骤,如果不输入名称默认不保存该轨迹。
// 鼠标绘制工具监听事件,用于获取绘制结果并同步绘制结果到页面
var overlaycomplete = function () {
// 需要添加鼠标工具绘制完成之后的逻辑
var removeBool = true;
selectArray = [];
layer.prompt({title: '输入轨迹名称,并确认', formType: 3}, function(text, index){
layer.close(index); if (e.overlay.ia) {
markersArray[new Date().getTime()] = {
location: [{
locationInfo: e.overlay.ia,
name: text
}],
name: text,
overlay: e.overlay
}
} else {
markersArray[new Date().getTime()] = {
location: [{
locationInfo: [e.overlay.point],
name: text
}],
name:text,
overlay: e.overlay
}
}
removeBool = false;
// 赋值轨迹
$('.travle-general b').html(Object.keys(markersArray).length);
// 轨迹循环
var html = '';
for (var list in markersArray) {
var travelNum = 0;
markersArray[list].location.forEach(function (item, index) {
travelNum += item.locationInfo.length;
})
html += '<div class="info-list clearfix">'
+'<div class="info-list-l">'
+' <div class="checkbox-bg"></div>'
+' <input class="checkbox" data-key=' + list + ' type="checkbox" />'
+' <i></i>'
+'</div>'
+'<div class="info-list-r">'
+' <p class="title">' + markersArray[list].name + '</p>'
+' <div class="info-frame clearfix">'
+' <p class="info">共有<span>' + travelNum + '</span>个位置经纬度信息</p>'
+' <button class="travel-info" data-key=' + list + '>详情</button>'
+' <button class="travel-delete" data-key=' + list + '>删除</button>'
+' </div>'
+'</div>'
+'</div>';
}
if (Object.keys(markersArray).length > 1) {
html += '<div class="combine-btn"><button>合并查看详情</button></div>'
}
$('.travle-info').html(html);
});
}
// 鼠标绘制工具添加监听事件
61 drawingManager.addEventListener('overlaycomplete', overlaycomplete);
2.7 地图搜索功能实现,通过百度地图API中的BMap.LocalSearch来搜索数据,自定义setSearchCompleteCallback方法来实现搜索后页面数据展示的逻辑,搜索数据最多显示十条,需要过滤掉名称一样的数据。
// 开启百度地图搜索功能
var localSearch = new BMap.LocalSearch(map);
//搜索成功后回调函数定义
localSearch.setSearchCompleteCallback(function (searchResult) {
// 用于存放过滤后的搜索数据
var filterSearchResult = [];
// 存放搜索数据title值,主要用于过滤重复数据使用
var filterSearchResultTitle = [];
// 循环处理获取到的数据,过滤title重复的数据
searchResult.Ar.forEach(function (item) {
if (filterSearchResultTitle.indexOf(item.title) == -1) {
filterSearchResultTitle.push(item.title);
filterSearchResult.push(item);
}
// 此处需要补充代码
})
})
// 搜索方法
function searchByStationName(keyword) {
localSearch.search(keyword);
}
2.8 已有轨迹删除方法,轨迹删除成功之后需要在对应的轨迹弹窗中将需要删除的轨迹移除,并且如果地图中有该轨迹也需要调用 map.removeOverlay 方法移除地图中的轨迹。
// 删除轨迹事件
$('.travel-delete').on('click', function () {
var element = $(this);
var key = element.data('key');
layer.confirm('轨迹删除不可恢复,是否删除?', {
btn: ['确认','取消'],
title: '删除轨迹'
}, function(index){
layer.close(index); map.removeOverlay(markersArray[key].overlay);
delete markersArray[key];
element.parents('.info-list').remove();
// 重新赋值轨迹
$('.travle-general b').html(Object.keys(markersArray).length);
}, function(index){
layer.close(index);
});
})
2.9 查看轨迹详情和合并查看详情需要选中至少两条轨迹,点击之后会弹出轨迹详情弹窗,会将选择的需要合并的轨迹中的数据合并到一起展示,并且通过复制粘贴便可以使用。
// 合并查看详情事件
$('.combine-btn').off().click(function () {
if (selectArray.length < 2) {
layer.alert('轨迹合并请至少选择两条轨迹');
return false;
}
layer.open({
type: 1,
title: '轨迹经纬度详情(<span style="color:#ff0000;">左边为格式化,右边为未格式化</span>),使用请直接进行复制粘贴操作',
skin: 'layui-layer-rim', //加上边框
area: ['100%', '100%'], //宽高
content: infoHtml
});
var _markersArray = [];
for (var key in markersArray) {
if (selectArray.indexOf(parseInt(key)) != -1) {
_markersArray.push(markersArray[key].location[0]);
}
} $('#code-content-str').html(JSON.stringify(_markersArray));
aceInitFun(formatJson(_markersArray).trim());
})
工具项目预览及体验地址:
基于百度地图API实现在地图上绘制轨迹并拾取轨迹对应经纬度工具
后话:
由于平时只有下班时间才能够开发,所以开发这个工具前前后后花费了有将近两周的时间,中间还有个几次通宵的情况,如果工具对您的工作有帮助,或者您对该工具有什么好的建议欢迎留言。
记录开发基于百度地图API实现在地图上绘制轨迹并拾取轨迹对应经纬度的工具说明的更多相关文章
- PHP:基于百度大脑api实现OCR文字识别
有个项目要用到文字识别,网上找了很多资料,效果不是很好,偶然的机会,接触到百度大脑.百度大脑提供了很多解决方案,其中一个就是文字识别,百度提供了三种文字识别,分别是银行卡识别.身份证识别和通用文字识别 ...
- 使用百度地图API进行Android地图应用开发(Eclipse)
随着基于位置的服务的兴起,地图类App呈现爆发趋势.随着而来的是地图供应商开放大量的API.供开发人员开发基于PC或者移动端的应用程序. 如今我们研究使用百度地图SDK进行Android项目的开发. ...
- 基于百度翻译API开发属于自己的翻译工具
你是否每天使用着网页翻译工具?你是否遇到过这种情况,上网过程中遇到一个很长的单词但是又不能复制,要开两个浏览器,一个打开百度翻译,照着另一个网页输入单词?你安装了各种翻译软件后,又删除,只因忍受不了那 ...
- 百度地图API和高德地图API资料集锦
[高德地图API]从零开始学高德JS API(五)路线规划——驾车|公交|步行 [高德地图API]从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自 ...
- 如何在网中使用百度地图API自定义个性化地图
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 百度地图API,展示地图和添加控件
1.申请百度账号和AK 点我申请 2.准备页面 根据HTML标准,每一份HTML文档都应该声明正确的文档类型,我们建议您使用最新的符合HTML5规范的文档声明: <!DOCTYPE html&g ...
- 基于百度语音识别API的Python语音识别小程序
一.功能概述 实现语音为文字,可以扩展到多种场景进行工作,这里只实现其基本的语言接收及转换功能. 在语言录入时,根据语言内容的多少与停顿时间,自动截取音频进行转换. 工作示例: 二.软件环境 操作系统 ...
- WP8.1小梦词典开发2:百度翻译API使用
原文出自:http://www.bcmeng.com/api2/ 小梦昨天和大家分享了WP8.1金山词霸API使用方法,今天继续分享windows phone 8.1中百度翻译API的使用方法.和昨天 ...
- Android开发基于百度地图的乘车助手
写在前面: 出去玩免不了挤公交.等地铁,不知道乘车方案当然不行,用官方APP吧,缺点一大堆,手机浏览器在线查的话既慢又麻烦...为了解决这些问题,我们来做一个简版的出行助手,嘛嘛再也不用担心我会迷路了 ...
随机推荐
- WPF最简单的分页控件
背景:最近在写项目的时候需要写一个简单的分页功能,因项目需要,没有改为MVVM模式,只需要在后台实现 1.呈现效果如下: 接下来就来上代码,看看怎么实现的 1.界面代码 <StackPanel ...
- 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xa)的解决方法【华为云分享】
[写在前面] 在用requests库对自己的CSDN个人博客(https://blog.csdn.net/yuzipeng)进行爬取时,发现乱码报错(\xe4\xb8\xb0\xe5\xaf\x8c\ ...
- 将Android手机打造成你的Python开发者桌面#华为云·寻找黑马程序员#
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- iOS动画浅汇
转自:http://www.cocoachina.com/ios/20160311/15660.html 在iOS开发中,制作动画效果是最让开发者享受的环节之一.一个设计严谨.精细的动画效果能给用户耳 ...
- openlayers4 入门开发系列结合 echarts4 实现散点图(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- 强化学习七 - Policy Gradient Methods
一.前言 之前我们讨论的所有问题都是先学习action value,再根据action value 来选择action(无论是根据greedy policy选择使得action value 最大的ac ...
- Oracle - 给rac创建单实例dg,并做主从切换
一.概述 本文将介绍如何给rac搭建单节点的dg,以及如何对其进行角色转换.预先具备的知识(rac搭建,单实例-单实例dg搭建) 二.实验环境介绍 主库rac(已安装rac,并已有数据库orcl)ra ...
- R语言计算IV值
更多大数据分析.建模等内容请关注公众号<bigdatamodeling> 在对变量分箱后,需要计算变量的重要性,IV是评估变量区分度或重要性的统计量之一,R语言计算IV值的代码如下: Ca ...
- 捅娄子了,写个bug被国家信息安全漏洞共享平台抓到了?
摸不了鱼了 2019 年 11 月 26 日,本来应该是无比平静的一天,开开会,改改bug,摸摸鱼之后等着下班.刷着新闻的间隙,手机的消息提示音响了起来,收到了一条邮件,平时收到邮件我都会选择稍后处理 ...
- leetcode -- 最长回文子串
题目: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: ...