Android 使用百度鹰眼实现运动轨迹功能
百度鹰眼轨迹系统是百度开放平台最新推出的高性能轨迹存储和查询解决方案。百度已开发出如此强大的功能模块,我们岂能对此无动于衷?
采用鹰眼追踪技术作为主要手段。通过充分集成百度鹰眼轨迹的SDK来实现这一目标。遵循百度官方开发文档中的指导进行操作即可。
下面将介绍第二种方法。采用本服务端进行交互的方式,在实际操作中需要注意以下几点:首先,请您在百度开放平台获取服务端ak凭证后方能完成相关操作。

第二步:在鹰眼轨迹服务中轨迹管理台创建自己的鹰眼服务。
经过这两次操作完成调用鹰眼轨迹服务端接口的过程即可获取到ak和service_id这两个字段。
通常情况下,系统仅需通过两个接口即可实现轨迹追踪功能。其中一个是上传设备的位置信息,另一个则是获取历史轨迹数据。
第一个接口:上传定位位置
请求URI
URI:http://api.map.baidu.com/trace/v2/track/addpoint
HTTP请求方式
POST
请求参数
| 参数名 | 参数含义 | 类型 | 备注 |
|---|---|---|---|
| ak | 用户的ak,授权使用 | string | 必须 |
| service_id | servicede ID,作为其唯一标识 | int | 必选 |
| latitude | 纬度 | double(-90.0 , +90.0) | 必选 |
| longitude | 经度 | double(-180.0 , +180.0) | 必选 |
| coord_type | 坐标类型 | int(1-3) | 必选,1:GPS经纬度坐标2:国测局加密经纬度坐标 3:百度加密经纬度坐标。 |
| loc_time | 轨迹点采集的GPS时间 | Unix时间戳 | 必选。输入的loc_time不能超过当前服务端时间10分钟以上。 |
| entity_name | entity唯一标识 | string(0-128) | 必选 |
| 用户自定义列的column_key | 此处值的类型须与用户自定义的column值的类型一致。 | 在track/create接口中可以为用户自定义的column赋值,当loc_time字段的值大于上一次时,如果输入了自定义的column的值,则这些值也会被更新。 |
为了确保唯一性,请自行定义一个独特的标识符用于 entity_name; cord_type 通常设置为 3;由于我们采用了百度API来进行定位服务,默认返回的地理坐标即为百度标准的经纬度格式。
为了在Android平台上集成百度地图API开发包,在项目中我们需要先下载并安装对应的SDK资源包,并按照规定的配置文件进行解压和环境变量设置操作。随后启动定位服务,并定期通过该接口提交位置数据。详细说明了核心功能的定位算法部分将随后进行讨论,并重点介绍其数学模型设计与实现细节。我们建议将此功能模块封装为一个Service类以便后续系统的扩展维护工作可以更加规范化和模块化地进行处理
private void initLocation(){
mLocationClient = new LocationClient(getApplicationContext()); // 声明LocationClient类
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(10000);// 设置发起定位请求的间隔时间这里是10秒
option.setIsNeedAddress(true);// 返回的定位结果包含地址信息
option.setOpenGps(true);
mLocationClient.setLocOption(option);
// 注册监听函数
mLocationClient.registerLocationListener(new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
try block {
if (location is null: {
open the location service.
// stop the mLocationClient.
return.
}
}
}
/*
- 位置
*/
mlocation = location.getAddrStr();
lon = location.getLongitude();
lat = location.getLatitude();
mLat = Double.toString(lat);
mLon = Double.toString(lon);
sendTrack(); // 该方法调用鹰眼轨迹上传的接口。
} catch (Exception e) {
if (mLocationClient != null) {
mLocationClient.stop();
}
}
}
});
mLocationClient.start();
}
第二个接口:获取历史轨迹
请求URI
http://api.map.baidu.com/trace/v2/track/gethistory
HTTP请求方式
GET
请求参数
| 参数名 | 参数含义 | 类型 | 备注 |
|---|---|---|---|
| ak | 用户的ak,授权使用 | string | 必须 |
| service_id | service唯一标识 | int | 必选 |
| start_time | 起始时间 | UNIX时间戳 | 必选 |
| end_time | 结束时间 | UNIX时间戳 | 必选。结束时间不超过当前时间,不能早于起始时间,且与起始时间差在24小时之内。 |
| entity_name | entity唯一标识 | string | 必选 |
| simple_return | 是否返回精简的结果 | int | 可选,默认值是0,当设为1时,返回精简结果。 |
| is_processed | 是否返回纠偏后轨迹 | int | 可选,默认值是0。0为返回原始轨迹,1为返回纠偏轨迹。注意:轨迹纠偏功能包括去噪、抽稀、绑路三个步骤,当is_processed=1时,默认仅进行去噪和抽稀处理,并不作绑路处理。若应用为车辆轨迹追踪类型,需要开通绑路操作,可发邮件至:baiduyingyan@baidu.com,注明:ak、service_id和同时在线车辆数,申请开通。 |
| page_index | 分页索引 | int(1到2^21-1)默认值为1 | 可选,与page_size一起计算从第几条结果返回,代表返回第几页。 |
| page_size | 分页大小 | int(1-5000)默认值为100 | 可选字段,返回结果最大个数与page_index一起计算从第几条结果返回,代表返回结果中每页有几条记录。 |
返回值
| 参数名 | 参数含义 | 类型 | 备注 | |
|---|---|---|---|---|
| status | 状态码 | |||
| message | 响应信息 | string | 对status的中文描述 | |
| total | 忽略掉page_index,page_size后的轨迹点数量 | 代表一共有多少条符合条件的track | ||
| size | 返回的结果条数 | int | 代表本页返回了多少条符合条件的轨迹点数量 | |
| distance | 此段轨迹的里程数,单位:米 | double | 符合条件的所有轨迹点的总里程。注意:是total个轨迹点的里程,和分页及本页显示的size无关。 | |
| points | 历史轨迹点列表 | 当simple_return=0时,返回point全部字段信息; 当simple_return=1时,返回point信息将只包含 [longitude, latitude, loc_time,speed]字段; | ||
| location | 经纬度 | Array | 百度加密坐标 | |
| loc_time | 该track实时点的上传时间 | UNIX时间戳 | 该时间为用户上传的时间 | |
| create_time | 创建时间 | 格式化时间 | 该时间为服务端时间 | |
| direction | 方向 | int | 范围为[0,365],0度为正北方向,顺时针 | |
| speed | 速度 | double | 单位:km/h | |
| radius | 定位精度 | double | 单位:m | |
| 自定义字段 | 当用户创建了track的自定义属性,且在创该属性赋有值,才会返回此字段。 |
此接口的 entity_name 即为你所需查询的对象,在默认设置下 page_size 为 100 个条目;根据具体需求可适当增大数量以满足更高负载要求。
start_time和end_time表示为UNIX时间戳的要求是将时间进行转换的方法如下
/* 将字符串转为时间戳 */
public static String getTimeToStamp(String time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd- HH:mm:ss");
Date date = new Date();
try {
date = sdf.parse(time);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String tmptime = String.valueOf(date.getTime()).substring(0, 10);
return tmptime;
}
需要注意的是end_time不得早于start_time且时间段不得超过24小时,否则请求会失败并报参数错误
关于is_processed这个参数,在默认情况下如果没有被传递,则系统会使用原始点记录;当传递值为1时,在百度系统中会自动去除一些跑偏的数据点(即去燥),从而使得整体的轨迹呈现更加平滑的状态。
该接口的返回结果示例:JSON格式
{
}
分析该JSON中的points字段即可获取百度坐标点集合。接着调用以下两个方法即可绘制轨迹
// 采用划线法
private void addTracks() {
LatLng lineLabel = null;
List
}
// 先清除
if ( mBaiduMap != null ){
mBaiduMap.clear();
}
注
if ( points.size() >= 2 && points.size() <10000 ){
OverlayOptions ooPolyline = new PolylineOptions().width(10)
.color(getResources().getColor(R.color.map_line)).points(points);
mBaiduMap.addOverlay(ooPolyline);
}
} catch (Exception e) {
}
}
}
//设置起点--终点
private void setMarkers(){
// mTrackList 坐标点集合
if (mTrackList != null && mTrackList.size() > 0){
try {
mLatitude = Double.parseDouble(mTrackList.get(mTrackList.size()-1).getLocation()[1]); // 纬度
mLongitude = Double.parseDouble(mTrackList.get(mTrackList.size()-1).getLocation()[0]); // 经度
} catch (Exception e) {
// TODO: handle exception
}
// 添加起点 -- 百度纠偏后起点是最后一个点。
LatLng limit = new LatLng(mLatitude, mLongitude);
mBaiduMap.addOverlay(new MarkerOptions().position(limit)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.track_start)));// 起点的图片
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(limit));
开始尝试捕获异常块
开始尝试从移动设备获取当前位置信息
通过构造新对象设置终点位置,并调用相关方法
最后实现的效果图:

