安卓百度地圖(六)鷹眼軌跡的上傳,歷史軌跡的顯示

其他文章:
安卓百度離線地圖的下載以及使用
安卓百度地圖(一)定位功能的實現、周邊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閱讀 229,460評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,253評論 2 375