一、百度地图API调用
- 百度地图API地址:lbsyun.baidu.com/index.php?t…
- 需要先申请密钥
- 进入官网,找到【申请密钥(ak)】,并点击进去;
- 根据开发需求选择【更为个人开发者】还是【成为企业开发者】;
- 按照步骤提示进行注册;
- 注册完成后,在个人控制台,找到【应用管理】-【我的应用】-【创建应用】,填写创建应用信息;
- 创建应用完成,会生成一个【访问应用AK】,然后我们就可以用这个AK去调用百度API了。
- 通过script标签实现百度Api文件在index.html的头部引入,之后就可以调用百度API了,简单初始化地图demo。(vue下实现的例子,例子中的ak需要替换成自己的申请下来的ak)
loadMap () { return new Promise((resolve, reject) => { const script = document.createElement('script') script.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${this.ak}&callback=initialize` document.body.appendChild(script) window.initialize = function () { setTimeout(() => { // eslint-disable-next-line resolve(BMapGL) }, 3000) } }) }
二、地图主题更改
- 进入百度api官网,lbsyun.baidu.com/index.php?t… ,选择【友情链接】-【个性化地图编辑器】,跳转至【个性化地图编辑平台】,点击【开始使用】
- 进入【个性化地图】-【新建】
- 进入样式新建/编辑页面,通过【样式模版】【配色推荐】【识图配色】来配置合适的样式;也可以通过编辑JSON,直接更改样式,如果需要UI同学帮忙配置地图主题,通过JSON是很方便的交流方式。配置完成,点击【发布样式】,即可生成样式ID,复制后,在代码中引入即可。备注:再次编辑更新样式,样式ID不变。
map.setMapStyleV2({ styleId: 'XXXXXXXXXXXXXXXXXXX30084627' })
三、高亮选中城市
- 通过点击事件,给当前城市添加一个棱柱覆盖物,从而实现高亮当前城市的效果。百度地图棱柱参数:mapopen-pub-jsapi.bj.bcebos.com/jsapi/refer…
- 核心实现代码
// 地图添加点击事件 map.addEventListener('click', e => { this.addPrism(e) }) // 高亮当前点击城市 addPrism (e, custom) { // 获取点击位置经纬度 const pt = e.latlng // 根据经纬度确定在哪个城市 const geocode = new this.BMapGL.Geocoder() geocode.getLocation(pt, rs => { const addComp = custom || rs.addressComponents // 如果当前城市是已选中城市,不做处理 if (addComp.city === this.pickCity && this.prisms && this.prisms.length) { return } this.pickCity = addComp.city for (const prismOld of this.prisms) { this.map.removeOverlay(prismOld) } const boundary = new this.BMapGL.Boundary() boundary.get(addComp.city, rs => { const boundaries = rs.boundaries // 颜色根据需求定制化 const boundariesTop = [] const boundariesDashed = [] boundaries.forEach(bound => { const arr = bound.split(';') let top = '' let dashed = '' arr.forEach((item, index) => { const a = item.split(', ') const comma = index === arr.length - 1 ? '' : ';' top = top + `${a[0]}, ${Number(a[1]) + 0.03}${comma}` dashed = dashed + `${a[0]}, ${Number(a[1]) + 0.015}${comma}` }) boundariesTop.push(top) boundariesDashed.push(dashed) }) const prismTop = new this.BMapGL.Polygon(boundariesTop, { fillColor: 'rgba(164,227,206,0.005)', fillOpacity: 0, strokeColor: 'rgba(164,227,206)', strokeWeight: 2 }) const prismDashed = new this.BMapGL.Polygon(boundariesDashed, { fillColor: 'rgba(164,227,206,0.005)', fillOpacity: 0, strokeStyle: 'dashed', strokeColor: 'rgba(164,227,206)', strokeWeight: 1, strokeOpacity: 0.8 }) const prismBottom = new this.BMapGL.Polygon(boundaries, { fillColor: 'rgba(164,227,206,0.005)', fillOpacity: 0.46, strokeColor: 'rgba(164,227,206)', strokeWeight: 1, strokeOpacity: 0.3 }) this.prisms.push(prismTop) this.prisms.push(prismDashed) this.prisms.push(prismBottom) this.map.addOverlay(prismBottom) this.map.addOverlay(prismDashed) this.map.addOverlay(prismTop) }) }) }
- 实现效果
四、自定义工具栏
- 自定义工具类,调用百度api的ZoomControl类,根据我们需要的功能和样式排版,给我们的地图添加自定义的工具栏,官方demo实例地址:lbsyun.baidu.com/jsdemo.htm#…
- 核心代码实现
addControl () { // 定义一个控件类 function ZoomControl (that) { this.defaultAnchor = 'BMAP_ANCHOR_TOP_LEFT' this.defaultOffset = new that.BMapGL.Size(10, 10) } // 通过JavaScript的prototype属性继承于BMap.Control ZoomControl.prototype = new this.BMapGL.Control() // 自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回 // 在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中 ZoomControl.prototype.initialize = map => { // 工具层 const mapTool = document.createElement('div') mapTool.className = 'map-tool-buttons' const tools = [ { class: 'focus tool-btn', text: '定位', method: () => { map.centerAndZoom(this.pickCity, 10) }}, { class: 'zoomIn tool-btn', text: '放大', method: () => { map.setZoom(map.getZoom() + 1) } }, { class: 'zoomOut tool-btn', text: '缩小', method: () => { map.setZoom(map.getZoom() - 1) } } ] tools.forEach(item => { const btn = document.createElement('div') btn.className = item.class btn.textContent = item.text btn.onclick = item.method mapTool.appendChild(btn) }) // 添加DOM元素到地图中 map.getContainer().appendChild(mapTool) // 将DOM元素返回 return mapTool } // 创建控件元素 const myZoomCtrl = new ZoomControl(this) // 添加到地图中 this.map.addControl(myZoomCtrl) }
- 实现效果
五、实现涟漪点
-
实现涟漪图,需要引入mapvgl依赖文件,code.bdstatic.com/npm/mapvgl@…
loadMap () { return new Promise((resolve, reject) => { const mapvglScript = document.createElement('script') mapvglScript.type = 'text/javascript' mapvglScript.src = 'https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.152/dist/mapvgl.min.js' mapvglScript.onerror = reject document.head.appendChild(mapvglScript) const baiduApi = document.createElement('script') baiduApi.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${this.ak}&callback=initialize` document.body.appendChild(baiduApi) window.initialize = function () { // eslint-disable-next-line resolve(BMapGL) } }) }
-
涟漪图官网demo参考:mapv.baidu.com/gl/docs/Cir…
-
核心代码实现
addCircle () { // eslint-disable-next-line const view = new mapvgl.View({ map: this.map }) // eslint-disable-next-line const waveLayer = new mapvgl.CircleLayer({ // 绘制带波纹扩散的圆 type: 'wave', // 扩散半径,支持直接设置和回调两种形式 radius: r => 6 * r, // 周期影响扩散速度,越小越快 duration: 1 / 3, // 时间 random: true, // 拖尾影响波纹数,越大越多 trail: 2, enablePicked: true, onClick: e => { // 点击事件 console.log(e) } }) const data = [] for (let i = 0; i < 2000; i++) { const point = [this.randomNumber(80, 120), this.randomNumber(28, 44)] data.push({ geometry: { type: 'Point', coordinates: point }, color: '#D05428', // 圆的半径 size: 2 }) } view.addLayer(waveLayer) waveLayer.setData(data) }, // 随机经纬度 randomNumber (min, max) { const range = max - min const rand = Math.random() * 100 return min + rand * range / 100 }
-
实现效果(存在bug,如果涟漪点过多,会有部分涟漪点没有动画效果,只显示一个小点,应该是高并发动画存在的bug)
六、代码及文档地址
- gitee:gitee.com/wanglixiang…
- demo在线地址:wanglixiang_z.gitee.io/bmap-gl/#/
- 百度地图api官网:lbsyun.baidu.com/index.php?t…
- 地图核心类参数地址:mapopen-pub-jsapi.bj.bcebos.com/jsapi/refer…
- mapvgl官网:mapv.baidu.com/gl/docs/Cir…