百度地图拖拽覆盖物思路

百度地图拖拽覆盖物思路



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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值