百度地图BMAP API的应用实例 --by snake_hand

本文介绍了一款基于BMapAPI的地图应用设计,包括数据源加载、动态查询、标记显示和右键菜单等功能,实现精准与模糊查询,提供用户体验优化如输入框自动提示和左侧查询高亮显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章出处:http://snake-hand.iteye.com/blog/1523034



效果图:

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

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


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

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

1、数据源格式

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

Javascript代码 复制代码
  1. var data = [   
  2.                 { 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" },   
  3.                 { 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" },   
  4.                 { 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" },   
  5.                 { 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" },   
  6.                 { 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" },   
  7.                 { 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" },   
  8.                 { 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" },   
  9.                 { 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" },   
  10.                 { 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" },   
  11.                 { 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" },   
  12.                 { 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" }   
  13.             ];  

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


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

Javascript代码 复制代码
  1. function init_MiddleLeft() {   
  2.         var top_div = document.getElementById("id_middle_left");   
  3.   
  4.         var table = document.createElement("table");   
  5.         table.setAttribute("border", 1);   
  6.         table.setAttribute("width", 280);   
  7.         for (var i = 0; i < data.length; i++) {   
  8.             var tr = document.createElement("tr");   
  9.   
  10.             var td = document.createElement("td");   
  11.             var str = data[i].id;   
  12.             var msg = document.createTextNode(str);   
  13.             td.appendChild(msg);   
  14.             tr.appendChild(td);   
  15.   
  16.             td = document.createElement("td");   
  17.             str = data[i].addr;   
  18.             msg = document.createTextNode(str);   
  19.             td.appendChild(msg);   
  20.             tr.appendChild(td);   
  21.   
  22.             td = document.createElement("td");   
  23.             var img = document.createElement("img");   
  24.             img.src = "./info.gif";   
  25.             img.value = this.data[i];   
  26.             img.onclick = function(){return click(this)};     //  img.onclick=Function("click(this.value)");  
  27.   
  28.             td.appendChild(img);   
  29.             tr.appendChild(td);   
  30.   
  31.             table.appendChild(tr);   
  32.         }   
  33.   
  34.   
  35.         top_div.appendChild(table);   
  36.     }  

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



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

Javascript代码 复制代码
  1. // search类原型   
  2. function searchClass(data) {   
  3.     this.datas = data;   
  4. }   
  5.   
  6. // 设置数据源   
  7. searchClass.prototype.setData = function (data) {   
  8.     this.datas = data;   
  9. }   
  10.   
  11. // 去掉字符串空格   
  12. searchClass.prototype.trim = function (str) {   
  13.     if (null == str) {   
  14.         str = "";   
  15.     } else {   
  16.         str = str.toString();   
  17.     }   
  18.   
  19.     return str.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+$)/g, "");    
  20. }   
  21.   
  22. // search原型查询模块   
  23. // rule = {id: "id", key: "keyword", query: "single|more", show: "one|all"}  
  24. searchClass.prototype.search = function (rule) {   
  25.     if (null == this.datas) {   
  26.         alert("数据源不存在!");   
  27.         return false;   
  28.     }   
  29.   
  30.     if ("" == this.trim(rule) || "" == this.trim(rule.id) || "" == this.trim(rule.key) || "" == this.trim(rule.query)) {   
  31.         alert("请指定要搜索内容!");   
  32.         return false;   
  33.     }   
  34.   
  35.     var reval = [];              // 返回值,object数组类型  
  36.     var datas = this.datas;      // search类,成员变量  
  37.     me = this;                   // 全局this,getData中me  
  38.   
  39.     // 添加查询结果   
  40.     var addData = function (data) {   
  41.         reval.push(data);   
  42.     }   
  43.   
  44.     // 获取查询数据源串   
  45.     var getData = function (data, id) {   
  46.         var _id = me.trim(id);   
  47.         var d = "data";   
  48.         if (0 == _id.length) {   
  49.             return data;   
  50.         } else {   
  51.             d += '["' + _id + '"]';   
  52.             return eval(d);   
  53.         }   
  54.     }   
  55.   
  56.     // 检索遍历   
  57.     for (var i = 0; i < datas.length; i++) {   
  58.         var data = datas[i];   
  59.         var d = getData(data, rule.id);   
  60.         var dReg = new RegExp(this.trim(rule.key));   
  61.   
  62.         if ("one" == rule.show) {                                // 显示查询标记  
  63.             if ("single" == rule.query && d == rule.key) {       // 精准查询(single)  
  64.                 addData(data);   
  65.             } else if ("more" == rule.query && dReg.test(d)) {   // 模糊查询(正则式实现)  
  66.                 addData(data);   
  67.             }   
  68.         } else if ("all" == rule.show) {                         // 显示全部标记        
  69.             addData(data);   
  70.         }   
  71.     }   
  72.   
  73.     // 返回结果   
  74.     return reval;   
  75. }  

4、标记查询的结果

Javascript代码 复制代码
  1. // 标记查询结果   
  2. window.addMarker = function (data_a) {   
  3.     map.clearOverlays();    // 首先清理已有标记   
  4.   
  5.     // 遍历查询结果数据(data_a)   
  6.     for (var i = 0; i < data_a.length; i++) {   
  7.         // 获取坐标(经度、纬度),在地图map上显示   
  8.         var px = data_a[i].point.split("|")[0];   
  9.         var py = data_a[i].point.split("|")[1];   
  10.   
  11.         var point = new BMap.Point(px, py);   
  12.         var marker = new BMap.Marker(point);   
  13.         map.addOverlay(marker);   
  14.         //marker.enableDragging(true);   
  15.   
  16.         // 生成标记信息(table)   
  17.         var content = "<table>";   
  18.         content = content + "<tr><td> 设备编号:" + data_a[i].id + "</td></tr>";   
  19.         content = content + "<tr><td> 安装地点:" + data_a[i].addr + "</td></tr>";   
  20.         content = content + "<tr><td> 主表流量:" + data_a[i].mainFlow + "</td></tr>";   
  21.         content = content + "<tr><td> 副表流量:" + data_a[i].subFlow + "</td></tr>";   
  22.         content = content + "<tr><td> 管网压力:" + data_a[i].press + "</td></tr>";   
  23.         content = content + "<tr><td> 设备电压:" + data_a[i].voltage + "</td></tr>";   
  24.         content = content + "<tr><td> 瞬时流量:" + data_a[i].flashFlow + "</td></tr>";   
  25.         content = content + "<tr><td> 有无市电:" + data_a[i].isEle + "</td></tr>";   
  26.         content = content + "<tr><td> 记录时间:" + data_a[i].time + "</td></tr>";   
  27.         content += "</table>";   
  28.   
  29.         // 捕获标记点击事件,并且显示信息   
  30.         // 函数闭包,总是执行   
  31.         (function () {   
  32.             var infoWindow = new BMap.InfoWindow(content);   
  33.             marker.addEventListener("click"function () {   
  34.                 this.openInfoWindow(infoWindow);   
  35.             });   
  36.         })()   
  37.     }   
  38. }  

标记效果图:



5、右键菜单的实现

Javascript代码 复制代码
  1. // 添加右键菜单   
  2. var contextMenu = new BMap.ContextMenu();   
  3. var txtMenuItem = [   
  4.     {   
  5.         text: "放大",   
  6.         callback: function () { map.zoomIn() }   
  7.     },   
  8.     {   
  9.         text: "缩小",   
  10.         callback: function () { map.zoomOut() }   
  11.     },   
  12.     {   
  13.         text: '查看北京',   
  14.         callback: function () { map.centerAndZoom("北京") }   
  15.     },   
  16.     {   
  17.         text: '放置到最大',   
  18.         callback: function () { map.zoomTo(18) }   
  19.     },   
  20.     {   
  21.         text: '获取改点坐标',   
  22.         callback: function(p){   
  23.             var px = p.lng;   
  24.             var py = p.lat;   
  25.             alert("该点坐标:\n经度:" + px + "; \n纬度:" + py);   
  26.         }   
  27.     },   
  28.     {   
  29.         text: '添加该店标注',   
  30.         callback: function (p) {   
  31.             var marker = new BMap.Marker(p), px = map.pointToPixel(p);   
  32.             map.addOverlay(marker);   
  33.             marker.enableDragging(true);   
  34.         }   
  35.     }   
  36. ];   
  37.   
  38. // 遍历菜单items,添加进菜单   
  39. for (var i = 0; i < txtMenuItem.length; i++) {   
  40.     contextMenu.addItem(new BMap.MenuItem(txtMenuItem[i].text, txtMenuItem[i].callback, 100));   
  41.     if (i == 1 || i == 3) {   
  42.         contextMenu.addSeparator();   
  43.     }   
  44. }   
  45. map.addContextMenu(contextMenu);    // 添加菜单到map  

菜单效果图:



6、模糊查询结果


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

右侧,输出3个标记结果

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


7、关注细节,改善体验

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

a、输入框自动提示

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

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

具体实现(onmousedown和onmouseout

Javascript代码 复制代码
  1. <input type="text" name="keyword" id="id_keyword" value="input id" onmousedown="clearKeyword('keyword')"  
  2.                     onmouseout="showKeyword('keyword')" />  
Javascript代码 复制代码
  1. // 用户按下鼠标,提示信息清除   
  2. function clearKeyword(keyword) {   
  3.     var input = document.getElementsByName(keyword);   
  4.     input[0].value = "";    // 清除提示  
  5.   
  6. }   
  7.   
  8. // 鼠标移走,如果内容为空,则重新提示   
  9. function showKeyword(keyword) {   
  10.     var input = document.getElementsByName(keyword);   
  11.     var value = input[0].value;   
  12.     if ("" == value) {  // 判断是否为空  
  13.         input[0].value = "input id";   
  14.     }   
  15. }  

b、左侧查询高亮显示

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


实现代码如下:

Javascript代码 复制代码
  1. // 点击左侧查询小图标   
  2. function click(obj) {   
  3.     // 先清理所有td元素,擦除上次高亮显示脚印   
  4.     var td_a = document.getElementsByTagName("td");   
  5.     for (var i = 0; i < td_a.length; i++) {   
  6.         td_a[i].setAttribute("bgcolor""#ffffff");   
  7.     }   
  8.   
  9.     // 高亮标记本次查询信息   
  10.     obj.parentNode.setAttribute("bgcolor""#ff0000");   
  11.   
  12.     var data_a = [];   
  13.     var data = obj.value;   
  14.     data_a.push(data);   
  15.     addMarker(data_a);   
  16. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值