美文网首页
百度地图小车平滑移动

百度地图小车平滑移动

作者: shadow123 | 来源:发表于2022-06-14 16:21 被阅读0次

最近有个需求,要做百度地图 覆盖物平滑移动,记录下

// 初始值
var pointX = 116.3806;
var pointY = 39.943523;
var nowPoint
var nowMarker

var map = new BMap.Map("map_canvas");
var point = new BMap.Point(pointX, pointY);

map.centerAndZoom(point, 18);
// 初始化
var imgUrl = "./img/car.png"

// map.addControl(new BMap.ZoomControl());
map.enableScrollWheelZoom();
var scaleCtrl = new BMap.ScaleControl();  // 添加比例尺控件
map.addControl(scaleCtrl);
var mapStyle = {
    features: ["road", "building", "water", "land", "point"],//隐藏地图上的"point" 兴趣点,
    style: 'googlelite' // normal:系统默认,light:清新蓝风格 dark:黑夜风格 redalert:红色警戒风格 
    // googlelite: 精简风格,grassgreen:自然绿风格,midnight:午夜蓝风格,pink:浪漫粉风格,darkgreen:青春绿风格
    // bluish:清新蓝绿风格 grayscale:高端灰风格 hardedge:强边界风格
};
map.setMapStyle(mapStyle);

let isScroll = false

// 下一个
function nextOne(point) {
    _move(nowPoint, point, nowMarker);
    nowPoint = point;
};
function _move(initPos, targetPos, nowMarker) {
    var me = this,
        //当前的帧数
        currentCount = 0,
        //步长,米/秒
        timer = 10,
        step = 400 / (1000 / timer),
        //初始坐标
        init_pos = map.getMapType().getProjection().lngLatToPoint(initPos),
        //获取结束点的(x,y)坐标
        target_pos = map.getMapType().getProjection().lngLatToPoint(targetPos),
        //总的步长
        count = Math.round(_getDistance(init_pos, target_pos) / step);


    me._intervalFlag = setInterval(function () {

        //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
        if (currentCount >= count) {

            clearInterval(me._intervalFlag);
            return;
        } else {

            currentCount++;
            var x = tweenLinear(init_pos.x, target_pos.x, currentCount, count),
                y = tweenLinear(init_pos.y, target_pos.y, currentCount, count),
                pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
            //设置marker
            if (currentCount == 1) {

                var proPos = null;
                setRotation(proPos, initPos, targetPos, nowMarker);
            }
            //正在移动
            nowMarker.setPosition(pos);
        }
    }, timer);
}

/**
 * 计算两点间的距离
 * @param {Point} poi 经纬度坐标A点.
 * @param {Point} poi 经纬度坐标B点.
 * @return 无返回值.
 */
function _getDistance(pxA, pxB) {
    return Math.sqrt(Math.pow(pxA.x - pxB.x, 2) + Math.pow(pxA.y - pxB.y, 2));
};

/**
 * 在每个点的真实步骤中设置小车转动的角度
 */
function setRotation(prePos, curPos, targetPos, nowMarker) {

    var me = this;
    var deg = 0;
    //start!
    curPos = map.pointToPixel(curPos);
    targetPos = map.pointToPixel(targetPos);

    if (targetPos.x != curPos.x) {
        var tan = (targetPos.y - curPos.y) / (targetPos.x - curPos.x),
            atan = Math.atan(tan);
        deg = atan * 360 / (2 * Math.PI);
        //degree  correction;
        if (targetPos.x < curPos.x) {
            deg = -deg + 90 + 90;
        } else {
            deg = -deg;
        }

        nowMarker.setRotation(-deg);

    } else {

        var disy = targetPos.y - curPos.y;
        var bias = 0;
        if (disy > 0)
            bias = -1
        else
            bias = 1
        nowMarker.setRotation(-bias * 90);
    }
    return;
}

// 缓动效果 : 初始坐标,目标坐标,当前的步长,总的步长
function tweenLinear(initPos, targetPos, currentCount, count) {
    var b = initPos, c = targetPos - initPos, t = currentCount,
        d = count;
    return c * t / d + b;
}

function baiduMap(x, y, name) {
    let _point = new BMap.Point(x, y);
    //坐标转换完之后的回调函数

    translateCallback = function (data) {
        console.log("data", data)
        if (data.status === 0) {

            let new_point = data.points[0]
            var myIcon = new BMap.Icon(imgUrl, new BMap.Size(52, 26));
            // 创建Marker标注,使用小车图标
            // 测试
            // new_point.lng += Math.random() * 0.001
            // new_point.lat += Math.random() * 0.001
            let _nextPoint = new BMap.Point(new_point.lng, new_point.lat);

            if (!nowPoint) {
                nowMarker = new BMap.Marker(new_point, {
                    title: name,
                    icon: myIcon,
                    mydata: "marker"
                });
                // nowMarker.setRotation(90);
                // 将标注添加到地图
                map.addOverlay(nowMarker);
                let label = new BMap.Label(name, { offset: new BMap.Size(0, 22) });
                label.setStyle({
                    backgroundColor: 'rgba(0, 0,0, 0.5)',
                    border: 'none',
                    padding: '5px 6px',
                    whiteSpace: 'nowrap',
                    fontSize: '12px',
                    zIndex: 0,
                    userSelect: 'none',
                    color: 'rgba(255, 255, 255)',
                    borderRadius: '3px',
                    boxShadow: 'rgb(0 0 0 / 20 %) 0px 2px 6px 0px'
                })
                nowMarker.setLabel(label); //添加百度label

                nowPoint = _nextPoint
            } else {
                nextOne(_nextPoint)
            }

            if (!isScroll) {
                map.setCenter(new_point);
            }
        }
    }

    var convertor = new BMap.Convertor();
    var pointArr = [];
    pointArr.push(_point);
    convertor.translate(pointArr, 1, 5, translateCallback)

    setTimeout(function () {
        ajaxFn()
    }, 5000);
}
function ajaxFn() {
    // 模拟请求
    setTimeout(() => {
        let pointsData = [{
            lng: "116.3806", lat: "39.943523"
        }, {
            lng: "116.382542", lat: "39.942474"
        }, {
            lng: "116.381882", lat: "39.9427"
        }, {
            lng: "116.383486", lat: "39.942223"
        }, {
            lng: "116.385165", lat: "39.941836"
        }]
        let index = Math.floor(Math.random() * pointsData.length)
        var x = pointsData[index].lng
        var y = pointsData[index].lat
        var name = "car"
        baiduMap(x, y, name)
    }, 1000)
}

function backSchoolbus() {
    if (nowPoint) {
        isScroll = false
        map.setCenter(nowPoint);
    }
}
$(document).ready(function () {
    ajaxFn()
});
map.addEventListener('mousedown', function () {
    isScroll = true
})


map.addEventListener('mouseup', function () {
    setTimeout(() => {
        isScroll = false
    }, 5000)
})

示例代码:https://github.com/wang7211401/baidumapcarmove

相关文章

网友评论

      本文标题:百度地图小车平滑移动

      本文链接:https://www.haomeiwen.com/subject/aspzmrtx.html