百度地图自定义标注、信息窗口、多种类聚合、主题(一篇呕心沥血的博客…)

框架

浏览数:157

2019-6-20

AD:资源代下载服务

一、序  

  最近做百度地图的图形化定制。略有心得,在此和大家分享一下,少走弯路。先看目录,大致介绍一下都写了些啥。我会从最基本的来,一点点往下写,同志们可以看目录自己去找需要的部分。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。

  喜欢交流技术的朋友可以给我留言。后序还会再补充一些百度地图别的功能,这个看时间吧。。。

 

作者:Mr.聂