1. 程式人生 > 實用技巧 >百度地圖:實現地圖找房

百度地圖:實現地圖找房

baidu API 引入:

    <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=***"></script>
    <script type="text/javascript" src="//api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils.js"></script>
    <script type="text/javascript" src="//api.map.baidu.com/library/InfoBox/1.2/src/InfoBox_min.js"></script>

html:

<div id="mapContainer"></div>

簡單實現邏輯:

(function (win, $) {
    class SearchMap {
        constructor(options, sourceData, listener) {
            this.map = undefined; //地圖例項
            this.point = undefined; //地圖中心點
            this.polygon = undefined;
            this.options = options || {}; //
引數選項 this.sourceData = sourceData; //原始資料 this.listener = listener; //地圖縮放或平移的事件監聽器 this.initMap(); } initMap() { let _this = this; this.map = new BMap.Map('mapContainer', { minZoom: 9, maxZoom: 18 }); this.point = new
BMap.Point(this.options.lng, this.options.lat); this.map.centerAndZoom(this.point, 9); this.map.enableScrollWheelZoom(true); this.addMarks(); this.map.addEventListener("zoomend", function () { var zoomLevel = _this.map.getZoom(); //獲取地圖縮放級別 if (zoomLevel <= 10) { _this.addMarks(); } else { _this.getAllLabel(); } }); } // 根據行政區劃繪製聚合點位 addMarks() { // 新增marks時先清除之前的覆蓋物 let _this = this; let _map = this.map; let _polygon = this.polygon; _map.clearOverlays(); // 模擬鄭州市聚點資料 let clusterList = [ { "name": "鄭州市", "code": "410100000", "longitude": "113.451854", "latitude": "34.556306", "count": "445" }, { "name": "開封市", "code": "410200000", "longitude": "114.356733", "latitude": "34.506238", "count": "377" }, { "name": "洛陽市", "code": "410300000", "longitude": "112.134468", "latitude": "34.263041", "count": "370" }, { "name": "平頂山市", "code": "410400000", "longitude": "112.992161", "latitude": "33.773999", "count": "300" }, { "name": "安陽市", "code": "410500000", "longitude": "114.098163", "latitude": "36.106852", "count": "290" }, { "name": "鶴壁市", "code": "410600000", "longitude": "114.208643", "latitude": "35.653125", "count": "245" }, { "name": "新鄉市", "code": "410700000", "longitude": "113.933677", "latitude": "35.31059", "count": "236" }, { "name": "焦作市", "code": "410800000", "longitude": "113.050848", "latitude": "35.124706", "count": "210" }, { "name": "濮陽市", "code": "410900000", "longitude": "115.169299", "latitude": "35.769421", "count": "225" }, { "name": "許昌市", "code": "411000000", "longitude": "113.956834", "latitude": "34.043383", "count": "155" } ]; //為了提高百度地圖效能,本篇例子點位全用label來載入點位 $.each(clusterList, function (index, data) { // 新增經緯的中心點 let point = new BMap.Point(data.longitude, data.latitude); //自定義label樣式 let template = ` <div class="circle-bubble" data-longitude="${data.longitude}" data-latitude="${data.latitude}"> <p class="name">${data.name}</p> <p class="count"><span>${data.count}</span>個樓盤</p> </div>`; let clusterLabel = new BMap.Label(template, { position: point, //label 在此處新增點位位置資訊 offset: new BMap.Size(-46, -46) }); clusterLabel.setStyle({ width: "92px", // height: "92px", //高度 border: "0", // background: "rgba(17,164,60,.9)", //背景顏色 borderRadius: "50%", cursor: "pointer" }); clusterLabel.setTitle(data.name); _map.addOverlay(clusterLabel);//新增點位 // 當滑鼠懸停在label上時顯示行政區劃邊界 clusterLabel.addEventListener("mouseover", function () { clusterLabel.setStyle({ background: "rgba(255,102,0,.9)" }); //修改覆蓋物背景顏色 var regionName = clusterLabel.getTitle(); _this.getBoundary(regionName); }); // 當滑鼠離開時在刪除邊界折線資料 clusterLabel.addEventListener("mouseout", function () { clusterLabel.setStyle({ background: "rgba(17,164,60,.9)" }); //修改覆蓋物背景顏色 if (win.polygon) { var polyPathArray = new Array(); win.polygon.setPath(polyPathArray); _map.removeOverlay(polygon);//清除折線資料 } }); clusterLabel.addEventListener("click", function () { _map.zoomIn(); _this.getAllLabel();//獲取所有點位資料 }); }) } // 根據行政區劃繪製邊界 getBoundary(regionName) { let _map = this.map; let boundary = new BMap.Boundary(); boundary.get(regionName, function (rs) { //行政區域的點有多少個 if (rs.boundaries.length === 0) { alert('未能獲取當前輸入行政區域'); return; } for (const itemBoundary of rs.boundaries) { if (!win.polygon) { win.polygon = new BMap.Polygon(itemBoundary, { strokeWeight: 2, strokeColor: "rgb(17,164,60)", fillColor: "rgba(17,164,60, .1)" }); //建立多邊形覆蓋物 _map.addOverlay(polygon); //新增覆蓋物 } else { win.polygon.setPath(itemBoundary); _map.addOverlay(polygon); //新增覆蓋物 } polygon.enableMassClear(); } }); } //繪製詳細樓盤點位資訊 getAllLabel() { let _map = this.map; _map.clearOverlays(); //模擬點位資料 var labelList = [ { "name": "樓盤一", "code": "01", "longitude": "113.515919", "latitude": "34.799769", "price": "10000" }, { "name": "樓盤二", "code": "02", "longitude": "113.509444", "latitude": "34.4475", "price": "999" }, { "name": "樓盤三", "code": "03", "longitude": "113.68175", "latitude": "34.737633", "price": "888" }, { "name": "樓盤四", "code": "04", "longitude": "113.280769", "latitude": "34.814961", "price": "777" } ]; $.each(labelList, function (index, data) { let point = new BMap.Point(data.longitude, data.latitude); let houseTemplate = ` <div class="house-bubble" data-longitude="${data.longitude}" data-latitude="${data.latitude}"> <p> <span class="price">${data.price}</span> <span class="unit">元/㎡</span> <em>|</em> <span class="name">${data.name}</span> </p> <div class="triangle-down"></div> </div>`; let houseLabel = new BMap.Label(houseTemplate, { position: point, //label 在此處新增點位位置資訊 offset: new BMap.Size(-12, -15) }); houseLabel.setStyle({ height: "30px", //高度 border: "0", // backgroundColor: "rgba(17,164,60,.9)", borderRadius: "4px", cursor: "pointer" }); houseLabel.setTitle(data.name); labelList.push(houseLabel); _map.addOverlay(houseLabel); let lastHouseLabel = null; //滑鼠點選時開啟新標籤並關閉上一個標籤內容 houseLabel.addEventListener("mouseover", function () { houseLabel.setStyle({ background: "rgba(255,102,0,.9)" }); }); houseLabel.addEventListener("mouseout", function () { houseLabel.setStyle({ background: "rgba(17,164,60,.9)" }); //修改覆蓋物背景顏色 }); //滑鼠點選時標籤一直存在 // houseLabel.addEventListener("click", function () { // houseLabel.setStyle({ background: "rgba(255,102,0,.9)" }); // }); }); //addViewLabel(labelData);//載入可視範圍點 } } win.SearchMap = SearchMap; })(window, jQuery)

資訊彈出層:

//資訊視窗模板
           var tpl="<div class='infoBox' data-longitude='"+data.longitude+"' data-latitude='"+data.latitude+"' data-id='"+data.code+"'>" +
                "<div class='infoArea'><p class='name'>"+data.name+"</p><p class='num'>均價<span class='red'> "+data.num+" </span>萬元/m3</p></div>" +
               "<i class='arrow'><i class='arrow-i'></i></i></div>";
            var infoBox = new BMapLib.InfoBox(map, tpl, {
                boxStyle: {
                    width: "160px",
                    minHeight: "50px",
                    marginBottom: "30px",
                    backgroundColor: "white"
                },
                closeIconMargin: "15px 10px 4px 4px",
                closeIconUrl: "img/icon-close.png",
                enableAutoPan: false,
                align: INFOBOX_AT_TOP
            });
            //滑鼠點選時開啟新標籤並關閉上一個標籤內容
            myLabel.addEventListener("mouseover", function () {
                if (window.lastInfoBox) {
                    //判斷上一個窗體是否存在,若存在則執行close
                    window.lastInfoBox.close();
                }
                window.lastInfoBox = infoBox;
                infoBox.open(point);
            });
           //滑鼠點選時標籤一直存在
            myLabel.addEventListener("click", function () {
                window.lastInfoBox=null;
                infoBox.open(point);
            });

//根據地圖視野動態載入資料,當資料多時此方法用來提高地圖載入效能 //由於此篇模擬點位資料較少,視野載入不明顯,當資料多時可直觀感覺

function addViewLabel(labels) {
        map.clearOverlays();
        for(var i = 0; i < labels.length; i ++){
            var result = BMapLib.GeoUtils.isPointInRect(labels[i].point, map.getBounds());
            if(result == true) {
                map.addOverlay(labels[i])
            } else{
                map.removeOverlay(labels[i]);
            }
        }
    }