微信小程序实现跑步轨迹回放入门教程

一、先看效果

跑步轨迹回放

二、实现功能

【跑步运动助手】是一款微信小程序,主要实现了跑步轨迹记录、历史轨迹、轨迹纠偏、轨迹回放和轨迹排名等功能。本文主要讲如何实现轨迹动画回放功能。更多干货请关注公众号:小蝇工作室

1.获取GPS数据

queryData = function(url, data) {
    var p = new Promise(function(resolve, reject) {
	    $.post(url, data, function(data) {
		     resolve(data)
	     })
    })
    return p;
}

2.优化GPS数据

//计算距离
function calculationDistance(point1, point2) {
	let lat1 = point1.latitude;
	let lat2 = point2.latitude;
	let lng1 = point1.longitude;
	let lng2 = point2.longitude;
	let radLat1 = lat1 * Math.PI / 180.0;
	let radLat2 = lat2 * Math.PI / 180.0;
	let a = radLat1 - radLat2;
	let b = (lng1 * Math.PI / 180.0) - (lng2 * Math.PI / 180.0);
	let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
		Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
	return s * 6370996.81;
};
//计算垂距
function distToSegment(start, end, center) {
	//下面用海伦公式计算面积
	let a = Math.abs(calculationDistance(start, end));
	let b = Math.abs(calculationDistance(start, center));
	let c = Math.abs(calculationDistance(end, center));
	let p = (a + b + c) / 2.0;
	let s = Math.sqrt(Math.abs(p * (p - a) * (p - b) * (p - c)));
	return s * 2.0 / a;
};
//递归方式压缩轨迹
function compressLine(coordinate, result, start, end, dMax) {
	if (start < end) {
		let maxDist = 0;
		let currentIndex = 0;
		let startPoint = coordinate[start];
		let endPoint = coordinate[end];
		for (let i = start + 1; i < end; i++) {
			let currentDist = distToSegment(startPoint, endPoint, coordinate[i]);
			if (currentDist > maxDist) {
				maxDist = currentDist;
				currentIndex = i;
			}
		}
		if (maxDist >= dMax) {
			//将当前点加入到过滤数组中
			result.push(coordinate[currentIndex]);
			//将原来的线段以当前点为中心拆成两段,分别进行递归处理
			compressLine(coordinate, result, start, currentIndex, dMax);
			compressLine(coordinate, result, currentIndex, end, dMax);
		}
	}
	return result;
};
/**
 *
 *@param coordinate 原始轨迹Array<{latitude,longitude}>
 *@param dMax 允许最大距离误差
 *@return douglasResult 抽稀后的轨迹
 *
 */
function douglasPeucker(coordinate, dMax) {
	if (!coordinate || !(coordinate.length > 2)) {
		return null;
	}
	coordinate.forEach((item, index) => {
		item.key = index;
	});
	let result = compressLine(coordinate, [], 0, coordinate.length - 1, dMax);
	result.push(coordinate[0]);
	result.push(coordinate[coordinate.length - 1]);
	let resultLatLng = result.sort((a, b) => {
		if (a.key < b.key) {
			return -1;
		} else if (a.key > b.key)
			return 1;
		return 0;
	});
	resultLatLng.forEach((item) => {
		item.key = undefined;
	});
	return resultLatLng;
}

3.加载地图

var center = new TMap.LatLng(paths[0].latitude, paths[0].longitude);
// 初始化地图
var map = new TMap.Map("container", {
							zoom: 17,
							pitch: 50,
							mapStyleId: 'style4',
							baseMap: {
								type: "satellite",
								features: ["base",
									"building3d"
								],
							},
							center,
						});

map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM);

4.回放轨迹数据

marker.on('move_ended', function() {
	isMoving = false;
	marker.updateGeometries([{
		id: "end",
		styleId: "end",
		position: new TMap
			.LatLng(
				paths[
					paths
					.length -
					1]
				.latitude,
				paths[
					paths
					.length -
					1]
				.longitude
			),
	}, ]);

	//创建LatLngBounds实例
	var latlngBounds = new TMap
		.LatLngBounds();
	//将坐标逐一做为参数传入extend方法,latlngBounds会根据传入坐标自动扩展生成
	for (var i = 0; i < path
		.length; i++) {
		latlngBounds.extend(path[i]);
	}
	//调用fitBounds自动调整地图显示范围
	map.easeTo({
		rotation: 0,
		pitch: 0
	}, {
		duration: 450,
	});

	setTimeout(() => {
		map.fitBounds(latlngBounds);
		marker.remove("whiteDot")
	}, 500)
});

你可能感兴趣的:(微信小程序,小程序,uni-app)