web技術分享| 【地圖】實現自定義的軌跡回放
實現(軌跡回放)方式有兩種:
- 第一種是使用
JS API
和AMap.PolyLine
(折線)等圖形配合實現。 - 第二種是使用
JS API
和AMapUI 元件庫
配合使用,利用PathSimplifier
(軌跡展示元件)繪製出行動軌跡。
方案選擇
以上兩種實現方式我們可以根據兩個因素 來決定哪一種更加適合自己:節點數量 的多少、排布的密集度 。
前者適合節點數量較少,排布比較稀鬆,例如,計程車軌跡回放,計程車行駛速度快,週期上報的時間也會相對較長。後者更加針對節點數量巨大、排布密集的路徑,按秒記錄位置的飛機行進軌跡,精細的地理邊界等等。
實現流程
無論選擇兩種方式,我們都需要先收集到客戶端上報的資訊,這些資訊可以自定義,通常我們會包含:經緯度、速度、逆編碼之後的地理位置、方向、海拔 等基本地理資訊,同時我們也可以加入一些自定義 的資訊,例如:人員資訊(頭像暱稱等)、出行資訊(訂單等)。
實現的流程:
- 客戶端按(時間)週期上報地理資訊以及自定義資訊。
- 服務端按時間軸儲存客戶上報的資訊。
- 按(時間等)條件查詢出使用者的軌跡,並通過簡化演算法去除一部分節點(例如,節點距離十分微小、或者多個點都在同一條直線、3點之間,其中一點略有偏差無法繪製成直線等等),最終獲得適合繪製的路徑(陣列)。
- 根據路徑去繪製使用者的行動軌跡。
路徑簡化演算法(可選)
客戶端上報的資料是按時間週期上報的,也就是說每個時間都對應了一個經緯度,經緯度在地圖上就是一個又一個點,將這些點連線時,我們會得到 N 多條折線,為了繪製的軌跡更加美觀,行動路線更加明確平滑,通常我們需要一個演算法來簡化折線。
例如:
A
點和B
點,兩者距離不到1
畫素,則可以去掉B
點,只留A
點。A
,B
,C
三點在一條直線上,或者,B
點僅僅稍微偏離A
點和C
點構成的線段,那麼B
點就可以去掉。
這裡官方也推薦了一種演算法庫 simplify.js
供大家參考,這裡不做過多的闡述。
實現示例
車輛軌跡回放
這裡我們使用第一種方式來實現 - 利用 JS API
和 AMap.PolyLine
。
實現原理:
- 在地圖上繪製車輛標記(
AMap.Marker
)。 - 利用
AMap.PolyLine
繪製出兩條軌跡:歷史軌跡和駕駛途徑過的軌跡,以顏色區分。 - 按照一定的速度使車輛前進,並監聽
Maker
移動的事件,在事件回撥中,將車輛(Marker
)位置設定為地圖中心點,給使用者視覺主觀上一種車輛在前進的感覺,同時延長駕駛途徑過的軌跡。 - 對於實現場景比較複雜的,需要進行自定義處理的比如:
- 檢視每個節點的資料,我們可以把每個節點給繪製出來,節點被點選時顯示該節點的資料。
- 移動倍速播放,首先按上報的時間間隔來播放,選擇倍速之後,改變
MarKer
移動的duration
。 - 其他自定義。
自定義 API
我們可以讓車輛:
- 開始移動
- 暫停移動
- 恢復移動
- 停止移動
程式碼示例
``` AMap.plugin('AMap.MoveAnimation', function(){ var marker, lineArr = [[116.478935,39.997761],[116.478939,39.997825],[116.478912,39.998549],[116.478912,39.998549],[116.478998,39.998555],[116.478998,39.998555],[116.479282,39.99856],[116.479658,39.998528],[116.480151,39.998453],[116.480784,39.998302],[116.480784,39.998302],[116.481149,39.998184],[116.481573,39.997997],[116.481863,39.997846],[116.482072,39.997718],[116.482362,39.997718],[116.483633,39.998935],[116.48367,39.998968],[116.484648,39.999861]];
var map = new AMap.Map("container", { resizeEnable: true, center: [116.397428, 39.90923], zoom: 17 });
marker = new AMap.Marker({ map: map, position: [116.478935,39.997761], icon: "http://a.amap.com/jsapi_demos/static/demo-center-v2/car.png", offset: new AMap.Pixel(-13, -26), });
// 繪製歷史軌跡
var polyline = new AMap.Polyline({
map: map,
path: lineArr,
showDir:true,
strokeColor: "#28F", //線顏色
// strokeOpacity: 1, //線透明度
strokeWeight: 6, //線寬
// strokeStyle: "solid" //線樣式
});
// 駕駛途徑過的軌跡
var passedPolyline = new AMap.Polyline({
map: map,
strokeColor: "#AF5", //線顏色
strokeWeight: 6, //線寬
});
// 監聽車輛移動事件
marker.on('moving', function (e) { // 延長駕駛途徑過的軌跡 passedPolyline.setPath(e.passedPath); // 將車輛位置設定為地圖中心點 map.setCenter(e.target.getPosition(),true) });
map.setFitView();
// 開始移動
window.startAnimation = function startAnimation () { marker.moveAlong(lineArr, { // 每一段的時長 duration: 500,//可根據實際採集時間間隔設定 // JSAPI2.0 是否延道路自動設定角度在 moveAlong 裡設定 autoRotation: true, }); }; // 暫停移動 window.pauseAnimation = function () { marker.pauseMove(); }; // 恢復移動 window.resumeAnimation = function () { marker.resumeMove(); }; // 停止移動 window.stopAnimation = function () { marker.stopMove(); }; }); ```
參考:http://lbs.amap.com/demo/jsapi-v2/example/marker/replaying-historical-running-data
飛機航班的軌跡回放
使用 JS API
和 AMapUI 元件庫
配合使用,利用 PathSimplifier
(軌跡展示元件)繪製出行動軌跡,這種方案比較簡單,只需要進行一些配置即可,例如說方案一中的倍速播放就需要計算,同時還存在不能動態改變倍速的弊端,但是方案二卻不會存在。
實現原理:
- 在地圖上繪製飛機標記(
AMap.Marker
)。 - 利用
AMap.PolyLine
繪製出兩條軌跡:歷史軌跡和駕駛途徑過的軌跡,以顏色區分。 - 配置軌跡的顏色,動畫的速度等等。
- 對於實現場景比較複雜的,需要進行自定義處理的,可以在
PathSimplifier
提供的回撥中進行配置及處理。
示例程式碼
``` //載入PathSimplifier,loadUI的路徑引數為模組名中 'ui/' 之後的部分 AMapUI.load(['ui/misc/PathSimplifier'], function(PathSimplifier) {
if (!PathSimplifier.supportCanvas) {
alert('當前環境不支援 Canvas!');
return;
}
//啟動頁面
initPage(PathSimplifier);
});
function initPage(PathSimplifier) { //建立元件例項 var pathSimplifierIns = new PathSimplifier({ zIndex: 100, map: map, //所屬的地圖例項 getPath: function(pathData, pathIndex) { //返回軌跡資料中的節點座標資訊,[AMap.LngLat, AMap.LngLat...] 或者 [[lng|number,lat|number],...] return pathData.path; }, getHoverTitle: function(pathData, pathIndex, pointIndex) { //返回滑鼠懸停時顯示的資訊 if (pointIndex >= 0) { //滑鼠懸停在某個軌跡節點上 return pathData.name + ',點:' + pointIndex + '/' + pathData.path.length; } //滑鼠懸停在節點之間的連線上 return pathData.name + ',點數量' + pathData.path.length; }, renderOptions: { //軌跡線的樣式 pathLineStyle: { strokeStyle: 'red', lineWidth: 6, dirArrowStyle: true } } });
//這裡構建兩條簡單的軌跡,僅作示例
pathSimplifierIns.setData([{
name: '軌跡0',
path: [
[100.340417, 27.376994],
[108.426354, 37.827452],
[113.392174, 31.208439],
[124.905846, 42.232876]
]
}, {
name: '大地線',
//建立一條包括500個插值點的大地線
path: PathSimplifier.getGeodesicPath([116.405289, 39.904987], [87.61792, 43.793308], 500)
}]);
//建立一個巡航器
var navg0 = pathSimplifierIns.createPathNavigator(0, //關聯第1條軌跡
{
loop: true, //迴圈播放
speed: 1000000
});
navg0.start();
} ```
參考:http://lbs.amap.com/demo/amap-ui/demos/amap-ui-pathsimplifier/index
- Android技術分享| ViewPager2離屏載入,實現抖音上下視訊滑動
- Android技術分享| Activity 過渡動畫 — 讓切換更加炫酷
- Linux下玩轉nginx系列(七)---nginx如何實現限流功能
- 技術分享| 如何部署安裝分散式序列號生成器系統
- web技術分享| 【地圖】實現自定義的軌跡回放
- 解決方案| 快對講綜合排程系統
- 實時訊息RTM| 多活架構中的資料一致性問題
- Android技術分享| Context淺析
- Android技術分享| Context淺析
- 螢幕共享的實現與應用
- 技術分析| 即時通訊和實時通訊的區別
- IOS技術分享| ARCallPlus 開源專案(二)
- Android技術分享| Android 中部分記憶體洩漏示例及解決方案
- Android技術分享| 安卓3行程式碼,實現整套音視訊通話功能
- 行業分析| 快對講Poc方案的優勢
- Android技術分享|【自定義View】實現Material Design的Loading效果
- IOS技術分享| ARCallPlus 開源專案(一)
- web技術分享| WebRTC控制攝像機平移、傾斜和縮放
- Android技術分享| anyLive 開源專案
- Android技術分享| 【Android 自定義View】多人視訊通話控制元件