【前端实践系列之八】百度地图自定义标注的实现

689 阅读2分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战 !

👽 概论

昨天和大家分享了《百度地图热力图开发及区域边界线的实现》,今天就趁热打铁,再和大家分享下地图上自定义标注的方法,先上完成后的效果图。

image.png

👻 开发准备

开发准备与之前基本一样,只是去掉了暂时用不到的热力图库及数据。

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>百度热力地图</title>
    <style>
      html,
      body {
        height: 100%;
        padding: 0;
      }
      #map {
        height: 1200px;
        width: 100%;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>
  </body>
  

  <!-- 百度地图API -->
  <script
    type="text/javascript"
    src="http://api.map.baidu.com/api?v=3.0&ak=xxxxxxxxx"
  ></script>

  <!-- 区块边界数据 -->
  <script type="text/javascript" src="./data/features.js"></script>
  <!-- 逻辑JS -->
  <script type="text/javascript" src="index.js"></script>
</html>

👽 初始化百度地图

这块不多说了,有疑惑的请看我概论提到的那篇文章。

👽 自定义标注的实现

这里的自定义标注有两层含义:一是在任意位置上实现标注;二是自定义标注的样式。百度地图上的标注类型有很多,但其实用起来都差不多。我们此次选用其中的Label类型来实现(主要是看重该类型可以添加文本内容,如不需要也可以使用其他类型的标注)。

下面我们就通过一个例子来同时实现。

function initMap(domID, centerPoint, styleId) {
  let mapInstance = new BMap.Map(domID); // 创建地图实例

  mapInstance.centerAndZoom(centerPoint, 13); //设置中心点及缩放级别

  mapInstance.setMapStyleV2({ styleId }); //设置样式ID

  mapInstance.enableScrollWheelZoom();
  mapInstance.enableDragging();
  mapInstance.disableDoubleClickZoom();

  return mapInstance;
}

function generateDistrictBoundary(mapInstance, districtName, style) {
  let bdary = new BMap.Boundary();
  bdary.get(districtName, function (res) {
    let boundaries = res.boundaries;

    let points = [];
    //之所以用循环,是因为部分行政区存在飞地,区划会分为多块,所以需要遍历生成
    boundaries.forEach(boundary => {
      let polygon = generateBoundary(mapInstance, boundary, style);

      let path = polygon.getPath();
      points = points.concat(path);
    });
  });
}

function generateBoundary(mapInstance, points, style) {
  let polygon = new BMap.Polygon(points, style); //创建多边形

  // 添加覆盖物
  mapInstance.addOverlay(polygon); //增加多边形

  return polygon;
}

const iconList = [
  'url(./icon/五角星.png)',
  'url(./icon/正方形.png)',
  'url(./icon/圆形.png)',
  'url(./icon/三角形.png)',
  'url(./icon/六边形.png)',
  'url(./icon/五边形.png)',
];

function generateLabel(point) {
  /** 第一步 定义label实体 */
  const label = new BMap.Label();

  /** 第二步 定义label的样式及位置 */
  label.setPosition(point.position); //自定义label的坐标
  //值得注意的是,position应该是百度的Point类实例,而不是见得经纬数值
  label.setContent(point.content); //设置label的文本内容

  //自定义label样式(这一块可发挥的空间非常大,基本上所有css属性都可在此使用
  //只需注意将原本的连字符属性名换为小驼峰即可
  label.setStyle({
    width: '8px',
    height: '8px',
    lineHeight: '8px',
    textAlign: 'center',
    backgroundImage: iconList[point.type], //最最关键的就是背景图片属性,据此我们可以实现任意样式
    backgroundSize: 'contain',
    backgroundPosition: 'center center',
    backgroundRepeat: 'no-repeat',
    backgroundColor: 'transparent',
    color: '#000',
    borderColor: 'transparent',
  });

  /** 第三步 将label实体添加到图上 */
  mapInstance.addOverlay(label);
}

window.onload = function () {
  let centerPoint = new BMap.Point(104.084207, 30.695243);
  let styleId = '02f2d7d1f52e7261479d4a9755a8485e';

  let mapInstance = initMap('map', centerPoint, styleId);

  let style = {
    strokeWeight: 3,
    strokeColor: '#2c2a2a',
    strokeStyle: 'dashed',
    fillColor: '#fff',
  };

  generateDistrictBoundary(mapInstance, '金牛区', style);


  /** data数据结构
   *  data = [
   *    ···
   *      { posotion: new BMap.Point(104.068551, 30.723895), type: 1,content:1, }
   *    ···
   * ]
  */

  data.forEach(point => generateLabel(point));
};

最终效果如下:

image.png

👽 结语

有一说一,百度地图做图还是挺好用的。大家快尝试起来。