一、问题描述及原因分析
大屏按照1920:1080的设计稿设计,前端一般采用对最外层组件使用transfrom:scale的方式对整个容器进行缩放来实现。但是对于百度地图,猜测其有自己的一套坐标体系,在点击地图时,会出现点击位置不准确的问题,导致想要对事件监听并做操作时,操作事件无法正常进行
二、问题解决方案
2.1前提
需求是在百度地图点击时,在点击处展示该区域的某项数据。本文以百度地图绘制杭州市地图为例。地图绘制时,是通过遍历杭州市的每个区域,为其添加背景色和边界色绘制地图的,在绘制的过程中,需给每块区域的Ploygon的实例对象添加一些数据,以供后面鼠标点击时使用,并将每块区域对象添加到一个数组中,以供后续遍历。
2.2准备工具
在线地图需引入对应的BMapGLLib文件及GeoUtils文件,离线地图需保证有前述文件。注意:GeoUtils.js文件主要是在BMapGlLib上添加各种方法,该文件需直接去github上下载并引入
<script src="//mapopen.bj.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.js"></script>
<script src="./js/GeoUtils.js"></script>
2.3 关键代码实现
map.on('click', (params) => {
// 1.获取缩放比例
const xScale = localStorage.getItem('xScale')
const yScale = localStorage.getItem('yScale')
// 2.获取点击时的像素坐标,还原缩放并转为经纬度
const { x, y } = params.pixel
const pixel2 = new BMapGL.Pixel(x / xScale, y / yScale)
const point = map.pixelToPoint(pixel2)
// 3.判断点是否在多边形内,以获得点击项的数据
plgArr.forEach(item => {
if(BMapGLLib.GeoUtils.isPointInPolygon(point, item)) {
const name = item.customData.name
const target = this.heatData.find(item => item.name === name)
this.coverData = {
name: target.name,
value: Math.ceil(Number(target.value) * 100)
}
}
})
// 4.展示图表时,定位的位置也需经过偏移量的转化
const currentX = params.pixel.x / xScale
const currentY = params.pixel.y / yScale
this.coverEchartStyle = {
left: currentX + 30 + 'px',
top: currentY + 30 + 'px'
}
this.$nextTick(() => {
this.isShowCoverChart = true
this.$nextTick(() => {
//地图点击时在点击附近处展示Echarts弹窗
this.$refs.coverChart.openDialog(this.coverData)
})
})
})
//后发现改方法只针对在线地图使用,离线地图不适用的方法后续还需探究。
// 后续优化方法 如果地图上有**区这种覆盖物的,那么可以将监听事件改为对覆盖物的监听。这样就可以省略第三步,并且数据改为根据当前点击事件的参数中获得
label.on('click', (params) => {
const xScale = localStorage.getItem('xScale')
const yScale = localStorage.getItem('yScale')
const target = this.heatData.find(item => item.name === params.currentTarget.content)
this.coverData = {
name: target.name,
value: Math.ceil(Number(target.value) * 100)
}
const currentX = params.pixel.x / xScale
const currentY = params.pixel.y / yScale
this.coverEchartStyle = {
left: currentX + 30 + 'px',
top: currentY + 30 + 'px'
}
this.$nextTick(() => {
this.isShowCoverChart = true
this.$nextTick(() => {
this.$refs.coverChart.openDialog(this.coverData)
})
})
})