8

一 前言

在使用百度地图开发的过程中,查阅百度地图官网demo基本上就能满足开发的需求,但是有时候需要设置一些东西,很难在官网上查阅到相关的方法技巧。笔者特意把开发过程中遇到的一些疑难杂症和解决方式总结出来写成这篇文章,供大家参考。

二 正文

1.设置完全透明

测试实例:多边形(polygon) 圆(circle)
出现的问题:配置对象(PolygonOptions)fillOpacity设置为0; 仍然会出线白色填充,没有实现完全透明:


const points = [ ... ];//一系列百度坐标
const opts = {fillOpacity:0,strokeColor:balck,strokeOpacity:1};
const polygon = new BMap.Polygon(points,opts);

图片描述

结果:
图片描述

方法:使用setFillColor设置填充

const polygon = new BMap.Polygon(...opts);//创建多边形实例
polygon.setFillColor('');//设置多边形填充完全透明

图片描述

2.添加地面叠加层

测试实例:地面叠加层(GroundOverlay)
出现的问题:按照类参考的参数配置(GroundOverlayOptions),并没有加载出图片。

图片描述

  const opts = {
    opacity: 1,
    imageURL:'http://lbsyun.baidu.com/jsdemo/img/si-huan.png',
    displayOnMinLevel: 0,
    displayOnMaxLevel: 20,
  };
  const groundOverlay = new BMap.GroundOverlay(bounds, opts);
  

后来查看官方demo才发现如何配置:setImageURL

  // 西南角和东北角
  var SW = new BMap.Point(116.29579,39.837146);
  var NE = new BMap.Point(116.475451,39.9764);

  groundOverlayOptions = {
    opacity: 1,
    displayOnMinLevel: 10,
    displayOnMaxLevel: 14
  }
  // 初始化GroundOverlay
  var groundOverlay = new BMap.GroundOverlay(new BMap.Bounds(SW, NE), groundOverlayOptions);
  // 设置GroundOverlay的图片地址     groundOverlay.setImageURL('http://lbsyun.baidu.com/jsdemo/img/si-huan.png');

3.跟随地图放缩

百度地图上Marker类型设置简单,可以使用自己定义的图标,还支持对图标的偏移和旋转,但是因为它只根据了一个中心点,造成了一个问题,设置的图标自身不支持跟随地图进行放缩。这样就造成了在特定场景下无法满足业务的需求。
百度地图地面叠加层GroundOverlay可以设置自己的图标,因为它是根据经纬度范围设置的,所以支持跟随地图放缩。但是在javascript开发中它并不支持对图形的旋转。图形的旋转可以用C++或者JAVA对图形矩阵做变换得到。所以想要支持旋转的就无法实现了。
如果我想设计一个既支持放缩,又能设置旋转的旗标,那该怎么办呢?
有一种方案:
Marker + addEventListener('zoomEnd',function(){});使用Marker类型,并且监听地图放缩事件,动态设置图标大小。

4.覆盖物重叠时的层级显示问题

正如百度地图人员回答的那样,百度地图在覆盖物重叠时会有一个默认的层级显示顺序,目前并不支持对任何单个实例设置显示层级。
但是事实上也没有那么悲惨,百度还是提供了两种覆盖物类型Marker(setZIndex)和Label(setZIndex),一种自定义图层(TileLayer)来支持设置ZIndex,但是需要注意的是这是针对一类中不同实例的,如果不同类型重叠的话,还是解决不了。

对于Marker和Label:setZIndex
对于TileLayer:zIndex

它们会根据这个值的大小来排列显示层次的优先级,值越大,就会显示在越上层。

在marker实例中,有时需要放大一个正在被选中的图标(始终保持一个放大),这就要求这个选中的实例始终出现在最顶层,这时候有一个非常实用的方法:setTop(isTop: Boolean) 详情>>

图片描述

5.在vue中使用外链的百度地图

在vue组件中使用百度地图很多人会选择使用第三方库,例如:vue-baidu-map
如果在使用中出现了无法逾越的问题,请看这里:直接用百度地图库在vue组件中完美运行。
参考文章:vue调用百度地图api时Bmap没有定义的解决办法

引入百度地图:

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥">

解决Eslint对BMap等地图相关变量报错的问题:

.eslintrc文件:

module.exports = {
 ... ...
    "globals": {
      //为百度地图设置规则
      "BMap": true,
      "BMAP_NORMAL_MAP": true,
      "BMAP_HYBRID_MAP":true,
      "BMAP_ANCHOR_TOP_LEFT":true,
      "BMAP_ANCHOR_TOP_RIGHT":true,
      ...
  },
}

先看看普通使用方式(没有使用异步加载)带来的错误:

图片描述

在百度地图还未加载完成时就调用了百度地图的方法。
实现方案:类似于异步加载

map.js文件:

export default {   
    const BMap_URL = "https://api.map.baidu.com/api?v=2.0&ak=您的密钥";
    //console.log("初始化百度地图脚本...");   
    return new Promise((resolve, reject) => {  
      // 如果已加载直接返回  
      if(typeof BMap !== "undefined") {  
        resolve(BMap);  
        return true;  
      }  
      // 百度地图异步加载回调处理  
      window.onBMapCallback = function () {  
        console.log("百度地图脚本初始化成功...");  
        resolve(BMap);  
      };  
  
      // 插入script脚本  
      let scriptNode = document.createElement("script");  
      scriptNode.setAttribute("type", "text/javascript");  
      scriptNode.setAttribute("src", BMap_URL);  
      document.body.appendChild(scriptNode);  
    });  
}  

组件中调用方式:

import {MP} from './map.js';

mounted(){  
            this.$nextTick(function(){  
              var _this = this;  
              MP(_this.ak).then(BMap => {  
                          //在此调用api  
  
  })

这样就可以完美运行了。

6.地图项目在测试或者线上环境出现跨域访问问题

你在本地测试都OK,到了远程服务器上就出错了。这里可能是服务器在安全策略上做了限制。
你检查一下script src 的地址 协议是http还是https,如果是http就会出错,直接改成https就好了。和http一样都支持地图方法,并且更安全。

7.地图绘制图层映射到地图上的地理位置

在使用地图进行绘图的时候,通常采用的方案是在地图上面放一个图层用来让用户选择绘制的位置,当用户确在此处绘制时就需要开发员拿到此处的经纬度来作为图标中心点进行调用百度地图API绘制各种类型的实例。
那么如何确定这个经纬度呢?这里需要引用一个相对运动的方法:将地图和view图层放在同一个容器里,让view图层始终在容器的中心点上(内水平垂直居中),保持view图层位置不变,让用户拖动地图--这样就能让view层保持在地图的中心位置。然后可以调用百度地图API getCenter方法拿到当前的中心点坐标,也就是需要画上去的图标的中心经纬度。

8.慎用GroundOverlay类型

先说一下常用到的Marker和GroundOverlay类型。
(1)Marker

特点:支持ICON的旋转
缺点:改变zoom值时ICON不会缩放

(2)GroundOverlay

特点:改变zoom值时ICON会自动缩放
缺点:不支持ICON的旋转

为什么说慎用GroundOverlay类型?其实所有的GroundOverlay类型都可以用Marker来替代,可以使用本文标题3介绍的方法控制Marker的缩放。还有其他原因如下:
(1)由于GroundOverlay类型ICON的缩放由百度地图自己控制,在有些情况下总会有个别ICON会缩放失效。(做过的项目中遇到过这个问题)
(2)无法逐级控制在哪个zoom下显示多大
(3)经纬度范围并不容易控制

9.一些非常有用的库

map库是最基本的库,用它来实例话一个map对象,在页面上展示一幅地图。除了这个地图库之外,还有很多实用的库。具体参考:开源库

下面就我用到过的几个来说明一下:
(1)鼠标绘制工具条库
提供鼠标绘制点、线、面、多边形(矩形、圆)的编辑,用户可使用JavaScript API对应覆盖物(点、线、面等)类接口对其进行属性(如颜色、线宽等)设置、编辑(如开启线顶点编辑等)等功能。
也就是说用户有自主绘制的权利,并且在完成绘制的时刻,开发者是能获取到经纬度的,这就足够了。

(2)几何运算
GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。 主入口类是GeoUtils。
最实用的就是使用库里的类方法可以判断点在不在多边形内啦~~~

(3)聚合marker
MarkerClusterer标记聚合器用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。 主入口类是MarkerClusterer。
当marker数量特变多,十分密集的时候,会产生性能问题和堆积问题,这时候做个聚合是十分有用的方式。

(4)还有更多等待探索。。。

三 后记

使用百度地图就要遵守百度地图的上支持的方法方式,目前百度地图在图层重叠时的层级显示问题并没有做出用户自定义设置方案,对于label和marker倒是暴露了setZindex方法设置自己的层级。希望百度地图能够越来越强大,这样开发者就可以愉快的开发了~


specialcoder
2.2k 声望170 粉丝

前端 设计 摄影 文学