Android百度地图轨迹回放

效果图:具体实现可参考以下项目代码。

1.导入jar包、so包。去百度地图开发者平台里面申请key写在功能清单文件里。具体申请地址http://wiki.lbsyun.baidu.com/index.php?title=androidsdk/guide/create-map/showmap

获取密钥的时候会要求提供SHA1,获取方式:点击studio 右侧Gradle,双击android下的signingReport可查看到SHA1.

获取到密钥后,在清单文件里面用key替换value。

 <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="1lVTzY7mMaf63GrKDCuKf9Tj0ZuGf5aC" />

        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
        </service>

2.布局,这里是用ImageView改变图标控制播放、暂停。下方的ProgressBar同步显示绘制进度。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </com.baidu.mapapi.map.MapView>

    <ImageView
        android:id="@+id/location_ivPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:contentDescription="@null"
        android:src="@mipmap/play" />

    <ProgressBar
        android:id="@+id/progressBar1"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:layout_marginBottom="48dp"
        android:max="100"/>


</FrameLayout>

3.初始化代码,Application里面进行地图初始化,记得在功能清单里加上BaseApplication的全类名。

public class BaseApplication extends Application {
	@Override
	public void onCreate() {
		super.onCreate();
		SDKInitializer.initialize(BaseApplication.this);// 初始化百度地图
	}
}

4.实现核心代码。

  private fun initBaiduMap() {
        mBaiduMap = bmapView.map
        mBaiduMap?.isMyLocationEnabled = true
        mBaiduMap?.setMapStatus(MapStatusUpdateFactory.zoomTo(12.0f))
        addRouteLine(routeList) // 添加路线
    }

显示出地图,zoomTo()是设置地图缩放级别,我这里写的是5公里。

    private fun parseJson() {
        try {
            val jObject = JSONObject(routeJson)
            val jArray = jObject.getJSONArray("list")
            println(jArray.length())
            var `object`: JSONObject? = null
            routeList = ArrayList()
            for (i in 0 until jArray.length()) {
                `object` = jArray.getJSONObject(i)
                routeList!!.add(
                    LatLng(
                        `object`.getDouble("lat"), `object`
                            .getDouble("lon")
                    )
                )
            }
            println("latlng size=" + routeList!!.size)
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

解析json,自己写的json字符串,里面包含了很多点的经纬度。"{\"list\":[{\"lon\":122.235502,\"lat\":37.330564},{\"lon\":122.235727,\"lat\":37.328527}]}"这种形式。

  private fun addRouteLine(routeList: List<LatLng>?) {
        var routeList = routeList
        mBaiduMap!!.clear()
        // 百度最多支持10000个点连线
        if (routeList!!.size > 10000) {
            routeList = routeList.subList(0, 10000)
        }
        mBaiduMap!!.addOverlay(
            PolylineOptions().width(5).color(-0xe96b01)
                .points(routeList)
        )
        moveToLocation(routeList[routeList.size / 2], true)
    }

    /**
     * 移动到指定位置 并缩放
     * @param latlng
     */
    private fun moveToLocation(latlng: LatLng, flag: Boolean) {
        val u = MapStatusUpdateFactory.newLatLng(latlng) // 设置新的中心点
        mBaiduMap!!.animateMapStatus(u)
        if (flag && mBaiduMap!!.mapStatus.zoom < 12.0f) {
            // 加个延时播放的效果,就可以有先平移 ,再缩放的效果
            mTimer.start()
        }
    }

添加路线,moveToLocation里的第一个参数是表示以哪个点作为地图中心点,我想让线大概在中间的位置,就取了集合的中间点。

 override fun onClick(v: View) {
        if (v.id == R.id.location_ivPlay) {
            if (routeList == null || routeList!!.size <= 0) {
                return
            }
            routeFlag = !routeFlag
            location_ivPlay.setImageResource(if (routeFlag) R.mipmap.pause else R.mipmap.play)
            if (routeFlag) {
                if (routeIndex == 0) {
                    mBaiduMap!!.clear()
                    routeMarker = null
                }
                mHandler.sendEmptyMessageDelayed(ROUTE, 0)
            } else {
                mHandler.removeMessages(ROUTE)
            }
        }
    }

routeFlag表示是否在回放,默认为false。routeIndex表示绘制点的位置。点击了播放按钮,用handler发消息,再点击一次,说明暂停,则移除此消息。

 private val mHandler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            if (msg.what == ROUTE) {
                sendEmptyMessage(PROGRESS)
                if (routeIndex == routeList!!.size - 1) {
                    routeFlag = false
                    location_ivPlay.setImageResource(R.mipmap.play)
                    Toast.makeText(this@MainActivity, "播放完毕", Toast.LENGTH_LONG)
                        .show()
                    routeIndex = 0
                    if (routeMarker != null) {
                        routeMarker!!.remove()
                        routeMarker = null
                    }
                    addRouteLine(routeList)
                    return
                }
                if (routeIndex != 0) {
                    val polyLine = PolylineOptions()
                        .width(5)
                        .color(-0xe96b01)
                        .points(
                            routeList!!.subList(
                                routeIndex - 1,
                                routeIndex + 1
                            )
                        )
                    mBaiduMap!!.addOverlay(polyLine)
                }
                // 页面跟随移动,注掉这行就是在原图上绘制
                // moveToLocation(routeList.get(routeIndex), false);
                if (routeMarker == null) {
                    val cur = MarkerOptions()
                        .position(routeList!![routeIndex++])
                        .perspective(false).anchor(0.5f, 0.5f).zIndex(10)
                } else {
                    routeMarker!!.position = routeList!![routeIndex++]
                }
                sendEmptyMessageDelayed(ROUTE, ROUTETIME.toLong())
            }
            if (msg.what == PROGRESS) {
                if (routeIndex == 0) { // 因为播放完毕时routeIndex被赋值成了0,不写进度条会直接跳到0的位置
                    setProgss(100)
                } else {
                    setProgss((routeIndex + 1) * 100 / routeList!!.size)
                }
            }
        }
    }

处理handler消息,当接到了ROUTE消息之后发PROGRESS消息是为了通知progressbar同步显示进度。mHandler.sendEmptyMessageDelayed(ROUTE, ROUTETIME);是循环执行这个画线的操作,时间间隔为ROTERTIME的值。除非再点击变成了暂停,则停止此操作。routeIndex等于最后一个点的时候,说明回放完成。

下面附上源码下载链接:http://download.youkuaiyun.com/detail/xkyh941/9599050(时隔许久,这是当初使用eclipse写的)

可以去github下载:https://github.com/liuyangxiao/RouteHistoryDemo.git 

学习的每一天都会充实而美好,希望技术无边界,能帮助到大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值