1. 程式人生 > >百度地圖BMap API的應用例項

百度地圖BMap API的應用例項

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

前幾天,幫朋友做了幾款地圖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.onclick=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" onmousedown="clearKeyword('keyword')"                    onmouseout="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高階應用特效



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述