前言
在户外运动应用中,绘制运动速度轨迹不仅可以直观地展示用户的运动路线,还能通过颜色变化反映速度的变化,帮助用户更好地了解自己的运动状态。然而,如何在鸿蒙系统中实现这一功能呢?本文将结合实际开发经验,深入解析从数据处理到地图绘制的全过程,带你一步步掌握如何绘制运动速度轨迹。
一、核心工具:轨迹颜色与优化
绘制运动速度轨迹的关键在于两个工具类:PathGradientTool和PathSmoothTool。这两个工具类分别用于处理轨迹的颜色和优化轨迹的平滑度。
1.轨迹颜色工具类:PathGradientTool
PathGradientTool的作用是根据运动速度为轨迹点分配颜色。速度越快,颜色越接近青色;速度越慢,颜色越接近红色。以下是PathGradientTool的核心逻辑:
[code]export class PathGradientTool { /** * 获取路径染色数组 * @param points 路径点数据 * @param colorInterval 取色间隔,单位m,范围20-2000,多长距离设置一次颜色 * @returns 路径染色数组 */ static getPathColors(points: RunPoint[], colorInterval: number): string[] | null { if (!points || points.length < 2) { return null; } let interval = Math.max(20, Math.min(2000, colorInterval)); const pointsSize = points.length; const speedList: number[] = []; const colorList: string[] = []; let index = 0; let lastDistance = 0; let lastTime = 0; let maxSpeed = 0; let minSpeed = 0; // 第一遍遍历:收集速度数据 points.forEach(point => { index++; if (point.totalDistance - lastDistance > interval) { let currentSpeed = 0; if (point.netDuration - lastTime > 0) { currentSpeed = (point.netDistance - lastDistance) / (point.netDuration - lastTime); } maxSpeed = Math.max(maxSpeed, currentSpeed); minSpeed = minSpeed === 0 ? currentSpeed : Math.min(minSpeed, currentSpeed); lastDistance = point.netDistance; lastTime = point.netDuration; // 为每个间隔内的点添加相同的速度 for (let i = 0; i < index; i++) { speedList.push(currentSpeed); } // 添加屏障 speedList.push(Number.MAX_VALUE); index = 0; } }); // 处理剩余点 if (index > 0) { const lastPoint = points[points.length - 1]; let currentSpeed = 0; if (lastPoint.netDuration - lastTime > 0) { currentSpeed = (lastPoint.netDistance - lastDistance) / (lastPoint.netDuration - lastTime); } for (let i = 0; i < index; i++) { speedList.push(currentSpeed); } } // 确保速度列表长度与点数一致 if (speedList.length !== points.length) { // 调整速度列表长度 if (speedList.length > points.length) { speedList.length = points.length; } else { const lastSpeed = speedList.length > 0 ? speedList[speedList.length - 1] : 0; while (speedList.length < points.length) { speedList.push(lastSpeed); } } } // 生成颜色列表 let lastColor = ''; let hasBarrier = false; for (let i = 0; i < speedList.length; i++) { const speed = speedList; if (speed === Number.MAX_VALUE) { hasBarrier = true; continue; } const color = PathGradientTool.getAgrSpeedColorHashMap(speed, maxSpeed, minSpeed); if (hasBarrier) { hasBarrier = false; if (color.toUpperCase() === lastColor.toUpperCase()) { colorList.push(PathGradientTool.getBarrierColor(color)); continue; } } colorList.push(color); lastColor = color; } // 确保颜色列表长度与点数一致 if (colorList.length !== points.length) { if (colorList.length > points.length) { colorList.length = points.length; } else { const lastColor = colorList.length > 0 ? colorList[colorList.length - 1] : '#FF3032'; while (colorList.length < points.length) { colorList.push(lastColor); } } } return colorList; } /** * 根据速度定义不同的颜色区间来绘制轨迹 * @param speed 速度 * @param maxSpeed 最大速度 * @param minSpeed 最小速度 * @returns 颜色值 */ private static getAgrSpeedColorHashMap(speed: number, maxSpeed: number, minSpeed: number): string { const range = maxSpeed - minSpeed; if (speed |