1. 程式人生 > >百度地圖自定義標註、資訊視窗、多種類聚合、主題(一篇嘔心瀝血的部落格...)

百度地圖自定義標註、資訊視窗、多種類聚合、主題(一篇嘔心瀝血的部落格...)

一、序  

  最近做百度地圖的圖形化定製。略有心得,在此和大家分享一下,少走彎路。先看目錄,大致介紹一下都寫了些啥。我會從最基本的來,一點點往下寫,同志們可以看目錄自己去找需要的部分。ps:注意,我用的是百度地圖 2.0 版本,例子也都是。

  這個完整程式碼,我會上傳到 github 上,覺得有用記得給個 star 哈,下載

 

二、目錄

    1、百度地圖基本使用,以及主題的配置

  2、點標註,自定義點標註的樣式,動畫、文字標籤等

  3、資訊視窗,完全自定義點標註資訊視窗,定製樣式功能

  4、圖形標註。定製圖形標註,也就是圖形覆蓋物

  5、聚合。聚合的定製,多種聚合同時出現的配置

 

三、百度地圖基本使用,以及主題的配置

   這裡,為了方便,全部用 html + js 來實現,首先是基本用法,引入百度地圖的原始檔,注意,這裡我用的 2.0 的版本,祕鑰大家需要自己去申請。沒祕鑰肯定用不了的,申請流程很簡單,請自行百度。關於 css、js 檔案的引入,用到的我全部引入了,後面分開說各是做什麼的。

  做好準備工作,就開始新建一個dom,初始化 地圖例項。然後 清除覆蓋物 設定顯示的中心點、設定 最大最小層級,設定預設顯示層級。具體的直接看程式碼,都有註釋。

  到此,就已經可以看到地圖了。然後我們換一些地圖的 主題 。主題有2種,一種預設的,預設的註釋裡面都有寫,也可以去官網自己查。一種是我們自定義的。自定義的方法: http://lbsyun.baidu.com/custom/  到這個連結去配置,配置完了複製配置資訊,在我們的地圖中使用。具體複製哪一塊,程式碼裡面怎麼用這個配置,請看程式碼,都有註釋。但是怎麼用這個百度的工具,自己搗鼓去吧,都是圖形化的東西,也不難。

  

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>百度地圖用法示例</title>
  <link rel="stylesheet" media="all" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css">
  <style>
    #myMap {
      width: 700px;
      height: 400px;
      margin: 100px auto;
    }
    #myMap .grayInfo{
      background-color: white;
      width: 220px;
      border-radius: 5px 5px;
    }
    #myMap .grayInfo .title {
      padding: 0 10px;
      height: 35px;
      line-height: 35px;
      background-color: #444444;
      border-radius: 5px 5px 0px 0px;
      color: white;
    }
    #myMap .grayInfo .content {
      padding: 10px;
      min-height: 50px;
    }
  </style>
</head>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=********"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/CurveLine/1.5/src/CurveLine.min.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"></script>
<script type="text/javascript" src="./js/InfoBox_main.js"></script>
<script type="text/javascript" src="./js/constants.js"></script>
<body>
  <div id="myMap"></div>
</body>
<script type="text/javascript">
//1、 基本配置
  const BMap = window.BMap
//例項化,並設定最大最小縮放層級 const map = new BMap.Map("myMap", { minZoom: 3, maxZoom: 20, });
//清楚覆蓋物 map.clearOverlays();
//設定中心點、預設縮放層級 map.centerAndZoom(new BMap.Point(120.08469, 30.301904), 13);
//可以滑鼠縮放 map.enableScrollWheelZoom(true); //2、 設定 預設主題 和 自定義主題 // 預設主題 normal blueSky light dark googlelite grassgreen midnight pink bluish grayscale // 還有幾個預設主題,但是發現並不好使 map.setMapStyle({ style: 'bluish' }); // 自定義主題, http://lbsyun.baidu.com/custom/ 自定義,完事匯出json配置 map.setMapStyle({   styleJson: THEME_CUS }); </script> </html>

 

  然後貼個圖,看看效果

  

 

四、點標註,自定義點標註的樣式,動畫、文字標籤等

  現在我們來新增一下標註,首先你得有幾個經緯度座標點,可以用這個  http://api.map.baidu.com/lbsapi/getpoint/   百度的座標拾取系統。蠻好用的 ps: 在這插一嘴,百度、騰訊、谷歌等等亂七八糟地圖,他們用的座標系不一樣,如果座標是別得地方來的,最好仔細看看,不同座標系需要轉換之後才能用,否則差距很大,此類外掛也很多,這裡不多說,有需要的可以評論處@我。

   廢話不多說,我這裡有個點資料,有幾個別的屬性,是為了我寫例子方便的,不必在意。準備工作完成後,首先我們把座標例項化成點、有需要的在定製一下點的樣式大小,動畫、事件、文字標籤等等。具體的請看程式碼。

 

 

const points = [
    { lng: 120.03469, lat: 30.303904, infoWindow: 'search', func: true},
    { lng: 120.088499, lat: 30.275182,infoWindow: 'default' },
    { lng: 120.089249, lat: 30.317759, infoWindow: 'InfoBox' },

    { lng: 120.161941, lat: 30.283073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.174941, lat: 30.275073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.186941, lat: 30.297073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.198941, lat: 30.299073, infoWindow: 'InfoBox', type: 1 },
  ]
  const markerClusterers = [[], []]
  points.forEach(item => {
    //例項化點
    const point = new BMap.Point(item.lng, item.lat)
//自定義點的樣式 const icon = new BMap.Icon( './image/yellow.png', new BMap.Size(32, 32) );
//生成點標註 const marker = new BMap.Marker(point, { icon: icon }); //動畫 marker.setAnimation(BMAP_ANIMATION_BOUNCE) //文字標籤 const label = new BMap.Label( '我是文字描述', { offset: new BMap.Size( 20, 20 ) } ) label.setStyle({ color : "red", fontSize : "12px", height : "20px", lineHeight : "20px", fontFamily:"微軟雅黑" }); marker.setLabel(label);

//繫結事件 if (item.func) marker.addEventListener("click", function () {alert('你好')}); markerClusterers[item.type || 0].push(marker)
//新增點標註即新增覆蓋物 map.addOverlay(marker); })

 

  貼圖,看一下效果

  

 

五、資訊視窗,完全自定義點標註資訊視窗,定製樣式功能

  新增完標註,我們新增標註點選後的資訊視窗。資訊視窗我把他分為 3 種:簡潔型,純白 + 字,寫起來最方便省事; 功能綜合型,帶導航、搜尋等等各種功能的,功能多,但是樣式固定,應用場景不多;完全自定義型,用 InfoBox 開發的,樣式完全自定義,功能也完全自定義,可以根據自己的需求自己開發,棒棒噠! 這3種具體用法看程式碼,在這大致說一下,如果想用第二種,需要引入下面這個 js 檔案和css檔案

<script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"></script> 
<link rel="stylesheet" media="all" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css">

  如果想要第三種,需要引入我的本地的這個js檔案。這裡說明一下,百度地圖時開源的,支援各種可以擴充套件的api,也支援各種改原始碼。自定義資訊視窗這個貌似沒有一個很官方的包,不過我用的這個也是百度官方示例用的,只不過沒有公網連結,
只能自己下下來引入了。
ps: 這個自定義視窗是有api的,網上有很多瞎寫的部落格,去改原始碼的樣式,導致程式碼亂七八糟,還影響地圖其他的樣式,害群之馬,望君擦亮眼睛。

 

 

const points = [
    { lng: 120.03469, lat: 30.303904, infoWindow: 'search', func: true},
    { lng: 120.088499, lat: 30.275182,infoWindow: 'default' },
    { lng: 120.089249, lat: 30.317759, infoWindow: 'InfoBox' },

    { lng: 120.161941, lat: 30.283073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.174941, lat: 30.275073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.186941, lat: 30.297073, infoWindow: 'InfoBox', type: 1 },
    { lng: 120.198941, lat: 30.299073, infoWindow: 'InfoBox', type: 1 },
  ]
  const markerClusterers = [[], []]
  points.forEach(item => {
    //點
    const point = new BMap.Point(item.lng, item.lat)
    const icon = new BMap.Icon(
      './image/yellow.png',
      new BMap.Size(32, 32)
    );
    const marker = new BMap.Marker(point, { icon: icon });
    //動畫
    marker.setAnimation(BMAP_ANIMATION_BOUNCE)
    //文字標籤
    const label = new BMap.Label(
      '我是文字描述',
      { offset: new BMap.Size( 20, 20 ) }
    )
    label.setStyle({
      color : "red",
        fontSize : "12px",
        height : "20px",
        lineHeight : "20px",
        fontFamily:"微軟雅黑"
    });
    marker.setLabel(label);

    //資訊視窗

//簡易的資訊視窗 if (item.infoWindow === 'default') { const infoWindow = new BMap.InfoWindow('簡易的資訊視窗')
//繫結事件,顯示視窗 marker.addEventListener("click", function(){ this.map.openInfoWindow(infoWindow,point); }); } else if (item.infoWindow === 'search') {
//使用預設的綜合功能類視窗 const searchInfoWindow = new window.BMapLib.SearchInfoWindow(map, '綜合功能型資訊視窗', { width: 200, height: 80, panel: "panel", enableAutoPan : true,
//這幾個是新增導航、所有等功能的,具體每個啥意思,看官方文件 searchTypes:[ BMAPLIB_TAB_SEARCH, BMAPLIB_TAB_TO_HERE, BMAPLIB_TAB_FROM_HERE ] }); marker.addEventListener("click", function(){ searchInfoWindow.open(point) }); } else if (item.infoWindow === 'InfoBox') {
//完全自定義的 樣式、功能的視窗。第二個引數自定義html、css,以及一些js的功能,根據需要自己去寫樣式和業務功能 const customizedInfoWindow = new window.BMapLib.InfoBox(map, `<div class="grayInfo"> <div class="title">完全自定義型資訊視窗</div> <div class="content">內容</div> </div>`); marker.addEventListener("click", function(){ customizedInfoWindow.open(point) }); } if (item.func) marker.addEventListener("click", function () {alert('你好')}); markerClusterers[item.type || 0].push(marker) map.addOverlay(marker); })

 

  貼圖看一下效果

  

 

 

六、圖形標註。定製圖形標註,也就是圖形覆蓋物

  現在新增圖形標註,這個比較簡單,根據官方文件寫就是了。畫圖標註需要引入如下js包:

 

<script type="text/javascript" src="http://api.map.baidu.com/library/CurveLine/1.5/src/CurveLine.min.js"></script>

 

   不過這裡提供一個不錯的創意,就是地圖選點 和 畫電子圍欄,不做詳細說明,下邊會貼出效果,感興趣的可以自己做一做,做不出來的可以@我,評論處留言,有時間的話,我會整理一下。

 

const style = {
strokeColor: "red", // 邊線顏色
strokeWeight: 2, // 邊線寬度
strokeOpacity: 1, // 邊線透明度
fillColor: "#f8e71c", // 填充色顏色
fillOpacity: 0.3 // 填充色透明度
} const graphPoints = [{lng: 120.126973, lat: 30.30897}, {lng: 120.2822, lat: 30.326927}, {lng: 120.209186, lat: 30.225126}] let polygonPoint = graphPoints.map(point => { return new BMap.Point(point.lng, point.lat) }) let polygon = new BMap.Polygon( polygonPoint, { ...style } ) polygon.addEventListener("click",function () {alert('你好啊')}); polygon.enableEditing() // 多邊形可編輯 map.addOverlay(polygon);

 

  貼圖,看看效果

  

       然後貼一下我們專案 使用者圖形化配置百度地圖,主要是畫電子圍欄的功能

  

 

 

七、聚合。聚合的定製,多種聚合同時出現的配置

  接下來是聚合,聚合的使用很簡單。不過這裡特別說明2點:

    1、聚合點數過多,一般萬點左右,就會非常卡,這是原始碼的問題,現在不知道還有沒有這個問題,反正我以前用的時候有。

      解決方案: 直接修改原始碼,立竿見影,沒後遺症。懶得寫了,大家可以參考這位朋友的部落格  http://www.cnblogs.com/lightnull/p/6184867.html 

     2、多種類聚合。白話一點就是,1萬個點,分 蘋果、香蕉、桃子、哈密瓜等若干個種類,你需要把每個種類單獨聚合,並用不同的效果區分開。這就是所謂的多種類聚合,這個也是直接看程式碼。ps:這裡只是簡單介紹使用,如果做功能最好再加一些解釋說明的覆蓋物,大致說一下每個覆蓋物代表什麼,每個顏色代表的點數範圍。

  最後,提一下做聚合,需要引入如下2個js包:

<script type="text/javascript" src="http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
//4、 設定 聚合 markerClusterers

//清除覆蓋物 markerClusterers.forEach((item, index) => { if (window[`markerClusterer${index}`]) window[`markerClusterer${index}`].clearMarkers() // delete this.markerClusterer window[`markerClusterer${index}`] = null }) //2種聚合的實現 const size = new BMap.Size( 48, 48 ) window.markerClusterer1 = new window.BMapLib.MarkerClusterer(map, { markers: markerClusterers[1], styles: [{ url: './image/wuxing1.png', size: size, textSize: 18, textColor: 'white', }, { url: './image/wuxing.png', size: size, textSize: 18, textColor: 'white', }, { url: './image/wuxing2.png', size: size, textSize: 18, textColor: 'white', }] }) window.markerClusterer2 = new window.BMapLib.MarkerClusterer(map, { markers: markerClusterers[0] })

 

  貼圖,看一下效果

  

 

 

 

小結

  以上就是我總結的百度地圖一些常用又不是那麼好找的功能,部落格比較零散,大家可以去我的 github 下載原始碼,好用記得給個star。

  喜歡交流技術的朋友可以給我留言。後序還會再補充一些百度地圖別的功能,這個看時間吧。。。