Introduction
近年来,人们越来越注重运动锻炼,运动相关App层出不穷。其中运动路径追踪是一个重要的功能点。可以很容易的使用MKPolyline实现单色路径追踪。更进一步,如果想通过路径的不同颜色反映出运动过程中的速度变化,如Nike+类似的效果,需要更多的工作。本文主要讨论如何绘制平滑渐变的运动路径。
上图为优化后的渐变色路径,图下方红色曲线为运动过程的速度曲线。
主要流程
- 获取运动过程中GPS信息及对应的速度值;
- 使用低通滤波处理速度数据;
- 通过MKMapView转换坐标至对应大小的UIView;
- 使用CAGradientLayer及CAShaperLayer分段绘制渐变路径;
获取运动过程中GPS信息及对应的速度值
可以使用CoreLocation获取GPS信息并计算对应的速度值。关于GPS坐标在中国大陆偏移及GPS坐标是否在中国大陆的判断方法,请参考另一篇博文。本文着重探讨路径的绘制,所以模拟产生随机的GPS和速度数据。
使用低通滤波处理速度数据
因为所绘路径的颜色不同,所以只能分段绘制。
如果各分段为纯色,则绘制出的路径略显生硬,无法体现出过渡效果(如下图)。
如果根据速度直接绘制成渐变色,因为速度波动的原因,渐变效果并不理想(如下图)。
所以需要预先处理速度数据,使速度数据变得平滑,渐变的效果才好。本人分别使用了滑动窗口滤波和低通滤波,对比之下,低通滤波表现更好。
上图为原数据效果。
上图为滑动窗口平滑效果。
上图为低通滤波平滑效果,滤波参数可以根据需要调整。
通过MKMapView转换坐标至对应大小的UIView
首先需要说明的是,本文的方法将路径绘制在与MKMapView大小一致的UIView上,而非直接以MKOverlay的形式绘制在MKMapView上,所以只能看到路径大致的轮廓而不能像地图一样缩放。如果想要在地图上直接绘制渐变路径,需要自定义MKOverlayPathRenderer,如有需要我再放出来。
坐标转换方法,调用MKMapView的convertCoordinate:toPointToView:
方法,即可把地图上的GPS坐标,转换为与地图大小相同的CGPoint,为绘制路径做准备。
使用CAGradientLayer及CAShaperLayer分段绘制渐变路径
在CAGradientLayer上绘制对应的渐变颜色;
1、渐变方向需要根据路径方向计算;
1 2 3 4 5 6 |
|
2、渐变颜色为路径两端速度值映射后的颜色,推荐使用HSB颜色值映射;
1 2 3 4 5 |
|
3、渐变起止可按需要自行控制;
1
|
|
在CAShapeLayer上绘制对应的路径;
1、路径的起止坐标为转换后的CGPoint;
2、注意设置shapeLayer.lineCap = kCALineCapRound;
,否则路径会断;
3、注意shapeLayer.strokeColor
不能为透明色,否则无法mask;
设置gradientLayer.mask = shapeLayer
;
总结
绘制平滑渐变路径的关键在于速度数据的处理,大家可以尝试不同的滤波算法改进绘制效果。绘制路径的技巧也在文中列出,如有问题可以和我交流,大家共同探讨学习。