百度地图拖拽覆盖物思路
class DragMap{
//共用的地图实例
@observable map = null
//实时更新的坐标点的数据的数组
@observable newPointData = []
//画圆覆盖物的数据
@observable circlePointData = []
//画多边形
@observable polygonPointData = []
//初始化地图
@action mapInit = () => {
//改变this指向,在覆盖物注册的事件中使用
const _this = this
//创建地图实例
const map = new BMap.Map("map", {
minZoom: 3,
maxZoom: 19,
enableMapClick: false
})
//把地图实例赋值给共用地图实例
_this.map = map
//设置默认中心点和缩放等级
_this.map.centerAndZoom('北京', 13)
//设置默认样式
_this.map.setMapStyle({ style: "midnight" })
//开启鼠标滚轮缩放
_this.map.enableScrollWheelZoom()
//如果是圆的数据
if (circlePoint) {
//更改数据格式
this.changePointData(circlePoint.mapDevelopData, this.circlePointData)
//执行画覆盖物方法
this.drawOverlays('circle', this.circlePointData)
}
}
/**
* @description 修改数据格式的方法
* @params data: 要被处理的数据
*/
@action changePointData = (data, arrays) => {
//处理数据前清空数据数组,避免缓存
this.pointData = []
//要被处理经纬度数据的数组
let pointArr = []
//从数据源取出要处理的经纬度数据
data.forEach(item => {
pointArr.push(item.points)
})
//遍历要处理的数据
pointArr.forEach(item => {
//处理好格式的经纬度数据的数组
let beforePointArr = []
//把每一个以逗号分隔的经纬度字符串处理成{lng:xxx,lat:xxx}的对象
item.forEach(item1 => {
let obj = {}
obj.lng = item1.split(',')[0]
obj.lat = item1.split(',')[1]
beforePointArr.push(obj)
})
//把处理好的对象放到最终要画覆盖物的数组
arrays.push(beforePointArr)
})
}
/**
* @description 画覆盖物的方法
* @params data: 画覆盖物的经纬度数据(已处理好格式)
* name: 画的是什么覆盖物
*/
@action drawOverlays = (name, data) => {
//遍历处理好的数据
toJS(data).forEach((item, index) => {
//BMap.Point用的点
let pointArr = []
//遍历每一个经纬度对象处理成地图要用的点
item.forEach(BMapPoint => {
//使用百度地图处理经纬度的方法处理数据
pointArr.push(new BMap.Point(BMapPoint.lng, BMapPoint.lat))
})
//实例化覆盖物
let ply = new BMap.Polygon(pointArr,
{
//边线
strokeWeight: 0.5,
strokeColor: "#ccc",
//填充
fillColor: '#000',
fillOpacity: 0.5
}
)
//区别是什么覆盖物的标识
ply.flag = name + index
//添加覆盖物
this.map.addOverlay(ply)
})
//执行获取中心点的方法
this.getCircleCenter(name)
}
/**
* @description 获取中心点的方法
* @params name: 画的是什么覆盖物 (为坐标点添加标识以匹配对应的覆盖物)
*/
@action getCircleCenter = (name) => {
//获取所有覆盖物的数组
let allOverlays = this.map.getOverlays()
//遍历所有覆盖物数组
allOverlays.forEach((item, index) => {
let point
//通过drawOverlays方法中定义的flag判断符合条件的覆盖物
if (item.flag === (name + index)) {
//全部lng坐标的数组
let lngArr = []
//全部lat坐标的数组
let latArr = []
//从覆盖物实例中取出全部经纬度
item.Tn.forEach((item, index) => {
lngArr.push(item.lng)
latArr.push(item.lat)
})
//取最大最小经纬度
let minLng = Math.min(...lngArr)
let maxLng = Math.max(...lngArr)
let minLat = Math.min(...latArr)
let maxLat = Math.max(...latArr)
//取最大最小经纬度平均值
let cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2
let cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2
//定义中心点信息及标识
point = {}
point.lng = cenLng
point.lat = cenLat
point.flag = name + index
}
//添加坐标点(在遍历中添加,有几个覆盖物实例添加几个坐标点)
this.addCenterMarker(point)
})
}
/**
* @description 添加中心点坐标及拖拽的方法
* @params point: 添加的点的坐标
*/
@action addCenterMarker = (point) => {
//修改拖拽事件中的this指向
let _this = this
//使用百度地图Point方法处理经纬度数据
let markerPoint = new BMap.Point(point.lng, point.lat)
//实例化坐标点
let marker = new BMap.Marker(markerPoint)
//开启可拖拽功能
marker.enableDragging()
let markerIcon = new BMap.Icon(
require(`./larger_black.png`),
new BMap.Size(20, 20),
{ imageSize: new BMap.Size(20, 20) })
marker.setIcon(markerIcon)
//去掉marker的阴影方法
let icon = marker.getIcon()
marker.setShadow(icon)
//定义初始参照坐标
marker.beforeLng = point.lng
marker.beforeLat = point.lat
//定义匹配对应覆盖物的标识
marker.markerFlag = point.flag
//注册拖拽时间
marker.addEventListener('dragging', function (e) {
//实时跟新的坐标点数组(坐标点数据来自计算之后),初始化要清空
_this.newPointData = []
//获取全部覆盖物
let allOverlays = _this.map.getOverlays()
//计算移动了多少距离
let newLng = e.target.point.lng - e.target.beforeLng
let newLat = e.target.point.lat - e.target.beforeLat
//更新参照坐标
e.target.beforeLng = newLng + e.target.beforeLng
e.target.beforeLat = newLat + e.target.beforeLat
//遍历全部覆盖物数组
allOverlays.forEach((item, index) => {
//通过标识判断对应覆盖物
if (item.flag === e.target.markerFlag) {
//获取全部覆盖物并计算新的坐标
item.Tn.forEach(item => {
let obj = {}
obj.lng = item.lng + newLng
obj.lat = item.lat + newLat
_this.newPointData.push(obj)
})
//清除之前的覆盖物
_this.map.removeOverlay(item)
}
})
//处理好格式的坐标点
let pointArr = []
_this.newPointData.forEach(item => {
pointArr.push(new BMap.Point(item.lng, item.lat))
})
//实例化多边形覆盖物实例(新的多边形)
let ply = new BMap.Polygon(pointArr,
{
//边线
strokeWeight: 0.5,
strokeColor: "#ccc",
//填充
fillColor: '#000',
fillOpacity: 0.5
}
)
//保持标识不变与相应的marker一致
ply.flag = e.target.markerFlag
//添加新覆盖物
_this.map.addOverlay(ply)
})
//添加坐标点
this.map.addOverlay(marker)
}
}
export default new DragMap()