• 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据


    有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画。可是,百度地图的道路数据没有公开。所以,应该怎么办呢?

    一、

    我们先来学习如何把百度地图“弄”出来。把下面这段代码保存为htm格式,用浏览器打开,就能看到百度地图了。 

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>点沿直线运动</title>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2&services=true"></script>
    </head>
    <body>
    <div style="520px;height:340px;border:1px solid gray" id="container"></div>
    </body>
    </html>
    <script type="text/javascript">
    var map = new BMap.Map("container"); //创建地图容器
    map.centerAndZoom(new BMap.Point(116.404, 39.915), 15); //设置中心点和地图级别
    </script>

    二、

    再分析一下汽车导航制作者的这个需求:

    1、车辆——用自定义图片的marker实现

    var carMk = new BMap.Marker(pts[0],{icon:myIcon});
    var myIcon = new BMap.Icon("Mario.png", new BMap.Size(32, 70), { //小车图片
    //offset: new BMap.Size(0, -5), //相当于CSS精灵
    imageOffset: new BMap.Size(0, 0) //图片的偏移量。为了是图片底部中心对准坐标点。
    });

    2、获取道路数据——虽然百度地图API并未公开道路层数据,但我们可以巧妙的“拿到”。具体请往下看。

    三、

    如何利用百度地图API拿到道路层的数据呢?

    答案很简单:驾车导航。

    首先讨论一下,为什么要用驾车导航,而不用步行和公交导航?

    1、步行导航:步行导航显然能“穿越”公园、甚至小区,得到的肯定不是道路层的数据;

    2、公交导航:公交导航虽然都是道路层的数据,但很局限,因为只有有公交车的地方,才有公交方案。并且,公交方法是包含了地铁线路的。

    3、驾车导航:拥有所有道路层的数据,并且没有地铁、小区里、花园内这样的无效数据。

    驾车导航示例:

    var myP1 = new BMap.Point(116.380967,39.913285); //起点
    var myP2 = new BMap.Point(116.424374,39.914668); //终点
    var driving2 = new BMap.DrivingRoute(map, {renderOptions:{map: map, autoViewport: true}}); //驾车实例
    driving2.search(myP1, myP2); //显示一条公交线路

    四、

    那么,如何获得道路层的数据呢?

    我们可以想象一下,驾车导航的路线,在API中是属于折线。

    折线是由无数的点构成的。

    也就是说,只要找到这些点,我们就能获取道路层的数据了。

    我们发现,Route里有个接口getPath,可以获得路线的地理坐标点数组。并且,以point数组的形式返回。

    Route类参考:http://dev.baidu.com/wiki/map/index.php?title=Class:%E6%9C%8D%E5%8A%A1%E7%B1%BB/Route

    利用创建好的驾车实例DrivingRoute,先search,得到一个驾车方案;

    驾车方案中,选择第一条Route;

    最后获得该Route的全部点。

    注意,由于ajax的异步加载机制,我们需要利用搜索后的回调函数setSearchCompleteCallback,来进行道路数据的获得。

    driving.setSearchCompleteCallback(function(){
    var pts = driving.getResults().getPlan(0).getRoute(0).getPath(); //通过驾车实例,获得一系列点的数组
    var paths = pts.length; //获得有几个点
    }

    五、

    道路数据获取完毕。接下来是汽车图片的展示。可以通过改变marker的坐标点来实现,改变marker坐标的接口setPosition。

    我们假设每100毫秒改变一次,利用延时函数setTimeout。

    同样,由于ajax异步加载原因,需要异步给i赋值。

    i=0;
    function resetMkPoint(i){
    carMk.setPosition(pts[i]);
    if(i < paths){
    setTimeout(
    function(){
    i
    ++;
    resetMkPoint(i);
    },
    100);
    }
    }
    setTimeout(
    function(){
    resetMkPoint(
    1);
    console.log(i);
    },
    100)

    六、

    接下来,可以点击这里,运行示例

    点击左侧的“开始”按钮,动画开始播放。

    点击下侧的“获取代码”按钮,可得到全部源代码。

    七、

    最后,放出全部源代码:

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>点沿直线运动</title>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2&services=true"></script>
    </head>
    <body>
    <div style="520px;height:340px;border:1px solid gray" id="container"></div>
    <input type="button" value="开始" onclick="run();" />
    </body>
    </html>
    <script type="text/javascript">
    var map = new BMap.Map("container");
    map.centerAndZoom(
    new BMap.Point(116.404, 39.915), 15);
    var myP1 = new BMap.Point(116.380967,39.913285); //起点
    var myP2 = new BMap.Point(116.424374,39.914668); //终点
    var myIcon = new BMap.Icon("Mario.png", new BMap.Size(32, 70), { //小车图片
    //offset: new BMap.Size(0, -5), //相当于CSS精灵
    imageOffset: new BMap.Size(0, 0) //图片的偏移量。为了是图片底部中心对准坐标点。
    });
    var driving2 = new BMap.DrivingRoute(map, {renderOptions:{map: map, autoViewport: true}}); //驾车实例
    driving2.search(myP1, myP2); //显示一条公交线路

    function run(){
    var driving = new BMap.DrivingRoute(map); //驾车实例
    driving.search(myP1, myP2);
    driving.setSearchCompleteCallback(
    function(){
    var pts = driving.getResults().getPlan(0).getRoute(0).getPath(); //通过驾车实例,获得一系列点的数组
    var paths = pts.length; //获得有几个点

    var carMk = new BMap.Marker(pts[0],{icon:myIcon});
    map.addOverlay(carMk);
    i
    =0;
    function resetMkPoint(i){
    carMk.setPosition(pts[i]);
    if(i < paths){
    setTimeout(
    function(){
    i
    ++;
    resetMkPoint(i);
    },
    100);
    }
    }
    setTimeout(
    function(){
    resetMkPoint(
    5);
    console.log(i);
    },
    100)

    });
    }
    </script>
  • 相关阅读:
    安装SQL sever2008时显示重新启动计算机规则失败,应该怎么解决?
    C#获取当前日期时间(转)
    使用JQUERY实现页面局部刷新
    Metal渲染:实现画面比例功能
    Metal渲染:实现旋转/翻转功能
    依赖注入浅析
    iOS 消息推送实现 APNS
    使用#pragma阻止一些warnings
    github 多帐户使用
    Swift 实现Bitmask Option(Enum)
  • 原文地址:https://www.cnblogs.com/milkmap/p/2104212.html
Copyright © 2020-2023  润新知