百度地图BMap API的应用实例

2024-01-14 19:08

本文主要是介绍百度地图BMap API的应用实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前几天,帮朋友做了几款地图API接口调研,推荐他使用百度BMap和谷歌GMap API,后来又直接交由我来替他做

一来上周帮研究生部老师做的学位证书精准打印系统基本完工,晚上有点时间研究下js

二来去年刚到百度实习头1个月,做的正是js,因此对BMap部分源码、API接口风格以及文档也都有些了解

花了一天两夜,基本功能需求都已经实现(自定义标注、精确和模糊查询、个性化添加、右键菜单等),先贴出效果图:

上图布局,最上面是测试通过的浏览器及其版本,左侧是动态加载的数据源和查询功能,右侧则是调用BMap API实现自己的应用

知识拓展:关于js和css的浏览器兼容性问题,请参见我在百度空间的博客 Javascript 和 CSS 的浏览器兼容总结


设计思路:接口是BMap API,内部功能采用模块化设计,搜索模块、自定义添加、右键菜单事件等,这样设计方便扩展和维护,后期将考虑加入谷歌的GMap

下面,详细介绍内部功能是如何设计和实现的

1、数据源格式

数据源格式是比较规整的,具体格式如下:

var data = [ { id: 100, point: "116.397128|39.916527", addr: "紫金天子城", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 101, point: "116.422792|40.009471", addr: "十里村", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 202, point: "116.484289|39.97936", addr: "杨家大湾", mainFlow: 13, subFlow: 19.9, press: 14, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 303, point: "116.454494|39.964011", addr: "赵鹏", mainFlow: 3, subFlow: 69.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 404, point: "116.394601|39.987925", addr: "王店", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 500, point: "116.469899|39.87684", addr: "刘村", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 501, point: "116.331292|39.949031", addr: "西子营", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 602, point: "116.374561|39.894302", addr: "马甲镇", mainFlow: 13, subFlow: 19.9, press: 14, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 703, point: "116.419527|39.945374", addr: "大牛集市", mainFlow: 3, subFlow: 69.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 804, point: "116.394601|39.987925", addr: "小牛峡湾", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" }, { id: 905, point: "116.368099|39.942332", addr: "徐家水库", mainFlow: 3, subFlow: 169.9, press: 4, voltage: 13.3, flashFlow: 1, isEle: "有市电", time: "2011-7-13 16:30:00" } ];

目前数据源采用的text文本格式进行存储与加载,随着需求和应用的扩大,后期将会使用MySQL数据库进行保存与提取


2、动态加载数据源(左侧table)

function init_MiddleLeft() { var top_div = document.getElementById("id_middle_left"); var table = document.createElement("table"); table.setAttribute("border", 1); table.setAttribute("width", 280); for (var i = 0; i < data.length; i++) { var tr = document.createElement("tr"); var td = document.createElement("td"); var str = data[i].id; var msg = document.createTextNode(str); td.appendChild(msg); tr.appendChild(td); td = document.createElement("td"); str = data[i].addr; msg = document.createTextNode(str); td.appendChild(msg); tr.appendChild(td); td = document.createElement("td"); var img = document.createElement("img"); img.src = "./info.gif"; img.value = this.data[i]; img.onclick = function(){return click(this)}; // img.οnclick=Function("click(this.value)"); td.appendChild(img); tr.appendChild(td); table.appendChild(tr); } top_div.appendChild(table); }

左侧动态加载数据源效果图:



3、精准与模糊查询(正则式实现)

// search类原型 function searchClass(data) { this.datas = data; } // 设置数据源 searchClass.prototype.setData = function (data) { this.datas = data; } // 去掉字符串空格 searchClass.prototype.trim = function (str) { if (null == str) { str = ""; } else { str = str.toString(); } return str.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+$)/g, ""); } // search原型查询模块 // rule = {id: "id", key: "keyword", query: "single|more", show: "one|all"} searchClass.prototype.search = function (rule) { if (null == this.datas) { alert("数据源不存在!"); return false; } if ("" == this.trim(rule) || "" == this.trim(rule.id) || "" == this.trim(rule.key) || "" == this.trim(rule.query)) { alert("请指定要搜索内容!"); return false; } var reval = []; // 返回值,object数组类型 var datas = this.datas; // search类,成员变量 me = this; // 全局this,getData中me // 添加查询结果 var addData = function (data) { reval.push(data); } // 获取查询数据源串 var getData = function (data, id) { var _id = me.trim(id); var d = "data"; if (0 == _id.length) { return data; } else { d += '["' + _id + '"]'; return eval(d); } } // 检索遍历 for (var i = 0; i < datas.length; i++) { var data = datas[i]; var d = getData(data, rule.id); var dReg = new RegExp(this.trim(rule.key)); if ("one" == rule.show) { // 显示查询标记 if ("single" == rule.query && d == rule.key) { // 精准查询(single) addData(data); } else if ("more" == rule.query && dReg.test(d)) { // 模糊查询(正则式实现) addData(data); } } else if ("all" == rule.show) { // 显示全部标记 addData(data); } } // 返回结果 return reval; }

4、标记查询的结果

// 标记查询结果 window.addMarker = function (data_a) { map.clearOverlays(); // 首先清理已有标记 // 遍历查询结果数据(data_a) for (var i = 0; i < data_a.length; i++) { // 获取坐标(经度、纬度),在地图map上显示 var px = data_a[i].point.split("|")[0]; var py = data_a[i].point.split("|")[1]; var point = new BMap.Point(px, py); var marker = new BMap.Marker(point); map.addOverlay(marker); //marker.enableDragging(true); // 生成标记信息(table) var content = "<table>"; content = content + "<tr><td> 设备编号:" + data_a[i].id + "</td></tr>"; content = content + "<tr><td> 安装地点:" + data_a[i].addr + "</td></tr>"; content = content + "<tr><td> 主表流量:" + data_a[i].mainFlow + "</td></tr>"; content = content + "<tr><td> 副表流量:" + data_a[i].subFlow + "</td></tr>"; content = content + "<tr><td> 管网压力:" + data_a[i].press + "</td></tr>"; content = content + "<tr><td> 设备电压:" + data_a[i].voltage + "</td></tr>"; content = content + "<tr><td> 瞬时流量:" + data_a[i].flashFlow + "</td></tr>"; content = content + "<tr><td> 有无市电:" + data_a[i].isEle + "</td></tr>"; content = content + "<tr><td> 记录时间:" + data_a[i].time + "</td></tr>"; content += "</table>"; // 捕获标记点击事件,并且显示信息 // 函数闭包,总是执行 (function () { var infoWindow = new BMap.InfoWindow(content); marker.addEventListener("click", function () { this.openInfoWindow(infoWindow); }); })() } }

标记效果图:



5、右键菜单的实现

// 添加右键菜单 var contextMenu = new BMap.ContextMenu(); var txtMenuItem = [ { text: "放大", callback: function () { map.zoomIn() } }, { text: "缩小", callback: function () { map.zoomOut() } }, { text: '查看北京', callback: function () { map.centerAndZoom("北京") } }, { text: '放置到最大', callback: function () { map.zoomTo(18) } }, { text: '获取改点坐标', callback: function(p){ var px = p.lng; var py = p.lat; alert("该点坐标:\n经度:" + px + "; \n纬度:" + py); } }, { text: '添加该店标注', callback: function (p) { var marker = new BMap.Marker(p), px = map.pointToPixel(p); map.addOverlay(marker); marker.enableDragging(true); } } ]; // 遍历菜单items,添加进菜单 for (var i = 0; i < txtMenuItem.length; i++) { contextMenu.addItem(new BMap.MenuItem(txtMenuItem[i].text, txtMenuItem[i].callback, 100)); if (i == 1 || i == 3) { contextMenu.addSeparator(); } } map.addContextMenu(contextMenu); // 添加菜单到map

菜单效果图:



6、模糊查询结果


左侧,输入“1”,模糊匹配查询和显示查询结果

右侧,输出3个标记结果

校验:100、101、501三项,都含有查询关键字"1“,查询结果正确


7、关注细节,改善体验

在实现过程中,也考虑了一些细节处理,这里举两个示例

a、输入框自动提示

当用户没有输入时,输入框显示提示信息"input id",当用户鼠标点击后,提示信息自动清除(是不是很像AJAX的水印效果 哈哈)

其实,其内部实现也不复杂,但不经意的设计,体现的却是很人性化

具体实现(onmousedown和onmouseout

<input type="text" name="keyword" id="id_keyword" value="input id" οnmοusedοwn="clearKeyword('keyword')" οnmοuseοut="showKeyword('keyword')" /> // 用户按下鼠标,提示信息清除 function clearKeyword(keyword) { var input = document.getElementsByName(keyword); input[0].value = ""; // 清除提示 } // 鼠标移走,如果内容为空,则重新提示 function showKeyword(keyword) { var input = document.getElementsByName(keyword); var value = input[0].value; if ("" == value) { // 判断是否为空 input[0].value = "input id"; } }

b、左侧查询高亮显示

点击查询小图标后,此栏背景色高亮显示,是用户一目了然


实现代码如下:

// 点击左侧查询小图标 function click(obj) { // 先清理所有td元素,擦除上次高亮显示脚印 var td_a = document.getElementsByTagName("td"); for (var i = 0; i < td_a.length; i++) { td_a[i].setAttribute("bgcolor", "#ffffff"); } // 高亮标记本次查询信息 obj.parentNode.setAttribute("bgcolor", "#ff0000"); var data_a = []; var data = obj.value; data_a.push(data); addMarker(data_a); }


好啦,就到这里

后期计划,想把谷歌的地图API也扩展进来,实现百度和谷歌地图自由选择

再有时间的话,将会尝试加入更新、更酷的技术,打造一些HTML5和CSS3高级应用特效



这篇关于百度地图BMap API的应用实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/606212

相关文章

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/