安卓百度地图(六)鹰眼轨迹的上传,历史轨迹的显示

其他文章:
安卓百度离线地图的下载以及使用
安卓百度地图(一)定位功能的实现、周边POI的检索
安卓百度地图(二)地图显示以及离线地图的下载使用
安卓百度地图(三)绘制点、线等图层信息
安卓百度地图(四)城市,周边,区域检索
安卓百度地图(五)百度地图路线规划
安卓百度地图(七)地理围栏的建立与使用

本文整理关于百度鹰眼SDK中轨迹的上传,以及获取历史轨迹然后展示

关百度地图使用鹰眼轨迹SDK的配置,前面的配置与百度定位等基本一致,在这里简单整理下新增加的配置。

  • 先在轨迹管理台中创建鹰眼服务,获得servie_id后方可正式使用鹰眼轨迹。
  • 下载相关库文件,,将lib下的文件copy至app下的lib中
  • 声明SERVICE组件,在Application标签中声明SERVICE组件,每个APP拥有自己独立的鹰眼追踪service
<service 
   android:name="com.baidu.trace.LBSTraceService" 
   android:enabled="true"
   android:process=":remote"> 
</service>

一 上传轨迹

1.1 初始化服务

输入注册的轨迹服务ID,设备表示码可以使用手机唯一表示码UUID

//轨迹服务ID
long serviceId = 0;
// 设备标识
String entityName = "myTrace";
// 是否需要对象存储服务,默认为:false,关闭对象存储服务。
// 注:鹰眼 Android SDK v3.0以上版本支持随轨迹上传图像等对象数据,若需使用此功能,该参数需设为 true,且需导入bos-android-sdk-1.0.2.jar。
boolean isNeedObjectStorage = false;
// 定位周期(单位:秒)
int gatherInterval = 5;
// 打包回传周期(单位:秒)
int packInterval = 10;

// 初始化轨迹服务
mTrace = new Trace(serviceId, entityName, isNeedObjectStorage);
// 初始化轨迹服务客户端
mTraceClient = new LBSTraceClient(getApplicationContext());
// 设置定位和打包周期
mTraceClient.setInterval(gatherInterval, packInterval);

1.2 开启服务,开启采集

// 开启服务
mTraceClient.startTrace(mTrace, mTraceListener);
// 停止服务
mTraceClient.stopTrace(mTrace, mTraceListener);
// 开启采集
mTraceClient.startGather(mTraceListener);
// 停止采集
mTraceClient.stopGather(mTraceListener);

1.3 设置监听

OnTraceListener mTraceListener = new OnTraceListener() {
        public int notifyId = 0;

        @Override
        public void onBindServiceCallback(int i, String s) {
            if (i == StatusCodes.SUCCESS) {
                Toast.makeText(TraceActivity.this, "绑定服务成功:" + "\r\n消息编码:" + i +
                        "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onStartTraceCallback(int i, String s) {
            Toast.makeText(TraceActivity.this, "绑定服务成功:" + "\r\n消息编码:" + i +
                    "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            if (StatusCodes.SUCCESS == i || StatusCodes.START_TRACE_NETWORK_CONNECT_FAILED <= i) {
                Toast.makeText(TraceActivity.this, "绑定服务成功:" + "\r\n消息编码:" + i +
                        "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onStopTraceCallback(int i, String s) {
            if (StatusCodes.SUCCESS == i || StatusCodes.CACHE_TRACK_NOT_UPLOAD == i) {
                Toast.makeText(TraceActivity.this, "停止服务成功:" + "\r\n消息编码:" + i +
                        "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onStartGatherCallback(int i, String s) {
            if (StatusCodes.SUCCESS == i || StatusCodes.GATHER_STARTED == i) {
                Toast.makeText(TraceActivity.this, "开启采集成功:" + "\r\n消息编码:" + i +
                        "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onStopGatherCallback(int i, String s) {
            if (StatusCodes.SUCCESS == i || StatusCodes.GATHER_STOPPED == i) {
                Toast.makeText(TraceActivity.this, "停止采集成功:" + "\r\n消息编码:" + i +
                        "\r\n消息内容:" + s, Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onPushCallback(byte messageType, PushMessage pushMessage) {
            if (messageType < 0x03 || messageType > 0x04) {
                Toast.makeText(TraceActivity.this, pushMessage.getMessage(), Toast.LENGTH_SHORT).show();
                return;
            }
            FenceAlarmPushInfo alarmPushInfo = pushMessage.getFenceAlarmPushInfo();
            if (null == alarmPushInfo) {
                Toast.makeText(TraceActivity.this, "onPushCallback:" + "\r\n状态码:" + messageType +
                        "\r\n消息内容:" + pushMessage, Toast.LENGTH_SHORT).show();
                return;
            }
            StringBuffer alarmInfo = new StringBuffer();
            alarmInfo.append("您于")
                    .append(CommonUtil.getHMS(alarmPushInfo.getCurrentPoint().getLocTime() * 1000))
                    .append(alarmPushInfo.getMonitoredAction() == MonitoredAction.enter ? "进入" : "离开")
                    .append(messageType == 0x03 ? "云端" : "本地")
                    .append("围栏:").append(alarmPushInfo.getFenceName());

           //获取信息
            Toast.makeText(RailActivity.this, alarmInfo.toString(), Toast.LENGTH_SHORT).show();

            alarmPushInfo.getFenceId();//获取围栏id
            alarmPushInfo.getMonitoredPerson();//获取监控对象标识
            alarmPushInfo.getFenceName();//获取围栏名称
            alarmPushInfo.getPrePoint();//获取上一个点经度信息
            AlarmPoint alarmPoin = alarmPushInfo.getCurrentPoint();//获取报警点经纬度等信息
            alarmPoin.getCreateTime();//获取此位置上传到服务端时间
            alarmPoin.getLocTime();//获取定位产生的原始时间

        }

        @Override
        public void onInitBOSCallback(int i, String s) {

        }
    };

二 获取历史轨迹并显示

2.1 初始化服务

// 创建历史轨迹请求实例
HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest(tag, serviceId, entityName);
//设置轨迹查询起止时间
// 开始时间(单位:秒)
long startTime = System.currentTimeMillis() / 1000 - 12 * 60 * 60;
// 结束时间(单位:秒)
long endTime = System.currentTimeMillis() / 1000;
long timeMillis = System.currentTimeMillis();
// 设置开始时间
historyTrackRequest.setStartTime(startTime);
// 设置结束时间
historyTrackRequest.setEndTime(endTime);

historyTrackRequest.setPageSize(1000);
historyTrackRequest.setPageIndex(1);

// 查询历史轨迹
mTraceClient.queryHistoryTrack(historyTrackRequest, mHistoryListener);

2.2 历史轨迹回调

 OnTrackListener mHistoryListener = new OnTrackListener() {
        // 历史轨迹回调
        @Override
        public void onHistoryTrackCallback(HistoryTrackResponse response) {
            int total = response.getTotal();
            if (StatusCodes.SUCCESS != response.getStatus()) {
                Toast.makeText(TraceActivity.this, "结果为:" + response.getMessage(), Toast.LENGTH_SHORT).show();
            } else if (0 == total) {
                Toast.makeText(TraceActivity.this, "未查询到历史轨迹", Toast.LENGTH_SHORT).show();
            } else {
                List<TrackPoint> points = response.getTrackPoints();
                if (null != points) {
                    for (TrackPoint trackPoint : points) {
                        if (!TraceUtil.isZeroPoint(trackPoint.getLocation().getLatitude(),
                                trackPoint.getLocation().getLongitude())) {
                            trackPoints.add(TraceUtil.convertTrace2Map(trackPoint.getLocation()));
                        }
                    }
                }
            }
            TraceUtil traceUtil=new TraceUtil();
            traceUtil.drawHistoryTrack(mBaiduMap,trackPoints, SortType.asc);
       }
};

绘制使用的工具类

import android.graphics.Color;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.trace.model.SortType;
import com.example.cs_android.baidumap.R;

import java.util.List;

/**
 * Created by cs_android on 2018/1/15.
 */

public class TraceUtil {
    private Overlay polylineOverlay;
    private BaiduMap mBaiduMap;
    private MapStatus mapStatus;

    /**
     * 绘制历史轨迹
     */
    public void drawHistoryTrack(BaiduMap baiduMap,List<LatLng> points, SortType sortType) {
        mBaiduMap=baiduMap;
        // 绘制新覆盖物前,清空之前的覆盖物
        baiduMap.clear();
        if (points == null || points.size() == 0) {
            if (null != polylineOverlay) {
                polylineOverlay.remove();
                polylineOverlay = null;
            }
            return;
        }

        if (points.size() == 1) {
            OverlayOptions startOptions = new MarkerOptions().position(points.get(0)).icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_start))
                    .zIndex(9).draggable(true);
            mBaiduMap.addOverlay(startOptions);
            animateMapStatus(points.get(0), 18.0f);
            return;
        }


        LatLng startPoint;
        LatLng endPoint;
        if (sortType == SortType.asc) {
            startPoint = points.get(0);
            endPoint = points.get(points.size() - 1);
        } else {
            startPoint = points.get(points.size() - 1);
            endPoint = points.get(0);
        }

        // 添加起点图标
        OverlayOptions startOptions = new MarkerOptions()
                .position(startPoint).icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_start))
                .zIndex(9).draggable(true);
        // 添加终点图标
        OverlayOptions endOptions = new MarkerOptions().position(endPoint)
                .icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_end)).zIndex(9).draggable(true);

        // 添加路线(轨迹)
        OverlayOptions polylineOptions = new PolylineOptions().width(10)
                .color(Color.BLUE).points(points);

        mBaiduMap.addOverlay(startOptions);
        mBaiduMap.addOverlay(endOptions);
        polylineOverlay = mBaiduMap.addOverlay(polylineOptions);

        OverlayOptions markerOptions =
                new MarkerOptions().flat(true).anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_point))
                        .position(points.get(points.size() - 1))
                        .rotate((float) getAngle(points.get(0), points.get(1)));
        mBaiduMap.addOverlay(markerOptions);

        animateMapStatus(points);
    }

    public void animateMapStatus(LatLng point, float zoom) {
        MapStatus.Builder builder = new MapStatus.Builder();
        mapStatus = builder.target(point).zoom(zoom).build();
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
    }

    public void animateMapStatus(List<LatLng> points) {
        if (null == points || points.isEmpty()) {
            return;
        }
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (LatLng point : points) {
            builder.include(point);
        }
        MapStatusUpdate msUpdate = MapStatusUpdateFactory.newLatLngBounds(builder.build());
        mBaiduMap.animateMapStatus(msUpdate);
    }

    /**
     * 根据两点算取图标转的角度
     */
    public double getAngle(LatLng fromPoint, LatLng toPoint) {
        double slope = getSlope(fromPoint, toPoint);
        if (slope == Double.MAX_VALUE) {
            if (toPoint.latitude > fromPoint.latitude) {
                return 0;
            } else {
                return 180;
            }
        }
        float deltAngle = 0;
        if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {
            deltAngle = 180;
        }
        double radio = Math.atan(slope);
        return 180 * (radio / Math.PI) + deltAngle - 90;
    }

    /**
     * 算斜率
     */
    public static double getSlope(LatLng fromPoint, LatLng toPoint) {
        if (toPoint.longitude == fromPoint.longitude) {
            return Double.MAX_VALUE;
        }
        return (toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude);
    }

    /**
     * 将轨迹坐标对象转换为地图坐标对象
     *
     * @param traceLatLng
     * @return
     */
    public static LatLng convertTrace2Map(com.baidu.trace.model.LatLng traceLatLng) {
        return new LatLng(traceLatLng.latitude, traceLatLng.longitude);
    }

    public static boolean isZeroPoint(double latitude, double longitude) {
        return isEqualToZero(latitude) && isEqualToZero(longitude);
    }

    /**
     * 校验double数值是否为0
     *
     * @param value
     * @return
     */
    public static boolean isEqualToZero(double value) {
        return Math.abs(value - 0.0) < 0.01 ? true : false;
    }
}

2.3 设置纠偏

// 设置需要纠偏
historyTrackRequest.setProcessed(true);

// 创建纠偏选项实例
ProcessOption processOption = new ProcessOption();
// 设置需要去噪
processOption.setNeedDenoise(true);
// 设置需要抽稀
processOption.setNeedVacuate(true);
// 设置需要绑路
processOption.setNeedMapMatch(true);
// 设置精度过滤值(定位精度大于100米的过滤掉)
processOption.setRadiusThreshold(100);
// 设置交通方式为驾车
processOption.setTransportMode(TransportMode.driving);
// 设置纠偏选项
historyTrackRequest.setProcessOption(processOption);


// 设置里程填充方式为驾车
historyTrackRequest.setSupplementMode(SupplementMode.driving);

本文主要做于收集整理笔记使用,关于文章的源码,请移步我的GitHub

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343