出行、运动等类别的app中常常会需要展示车辆或用户的行程轨迹、实时移动轨迹等数据,相应效果需要车辆在地图上平滑移动。该demo展示了如何实现该效果。
核心类/接口
类 | 接口 | 说明 | 版本 |
---|---|---|---|
MAMapview | - (void)addOverlay:(id )overlay; | 添加轨迹线 | V4.0.0起 |
MAMapview | - (void)addAnnotation:(id )annotation; | 添加汽车 | V4.0.0起 |
MovingAnnotationView | - (void)addTrackingAnimationForPoints:(NSArray *)points duration:(CFTimeInterval)duration; | 添加动画 | ---- |
CACoordLayer | - (void)display; | 显示当前帧 | ---- |
1、MovingAnnotationView 自定义annotationview,其layer是自定义的CACoordLayer
/**
动画AnnotationView,只试用于高德3D地图SDK。
*/
@interface MovingAnnotationView : MAAnnotationView
/*!
@brief 添加动画
@param points 轨迹点串,每个轨迹点为TracingPoint类型
@param duration 动画时长,包括从上一个动画的终止点过渡到新增动画起始点的时间
*/
- (void)addTrackingAnimationForPoints:(NSArray *)points duration:(CFTimeInterval)duration;
@end
+ (Class)layerClass
{
return [CACoordLayer class];
}
func initRoute() {
let count: Int = s_coords.count
self.fullTraceLine = MAPolyline(coordinates: &s_coords, count: UInt(count))
self.mapView.add(self.fullTraceLine)
var routeAnno = [Any]()
for i in 0..<count {
let a = MAPointAnnotation()
a.coordinate = s_coords[i]
a.title = "route"
routeAnno.append(a)
}
self.mapView.addAnnotations(routeAnno)
self.mapView.showAnnotations(routeAnno, animated: false)
self.car1 = MAAnimatedAnnotation()
self.car1.title = "Car1"
self.mapView.addAnnotation(self.car1)
weak var weakSelf = self
self.car2 = CustomMovingAnnotation()
self.car2.stepCallback = {() -> Void in
weakSelf?.updatePassedTrace()
}
self.car2.title = "Car2"
self.mapView.addAnnotation(self.car2)
self.car1.coordinate = s_coords[0]
self.car2.coordinate = s_coords[0]
}
2、CACoordLayer,每次显示时根据mapPoint计算屏幕坐标
- (void)display
{
CACoordLayer * layer = [self presentationLayer];
MAMapPoint mappoint = MAMapPointMake(layer.mapx, layer.mapy);
CGPoint center = [self.mapView pointForMapPoint:mappoint];
center.x += self.centerOffset.x;
center.y += self.centerOffset.y;
self.position = center;
}
func mov() {
let speed_car1: Double = 120.0 / 3.6
//80 km/h
let count: Int = s_coords.count
self.car1.coordinate = s_coords[0]
let duration = self.sumDistance / speed_car1;
self.car1.addMoveAnimation(withKeyCoordinates: &s_coords, count: UInt(count), withDuration: CGFloat(duration), withName: nil, completeCallback: {(_ isFinished: Bool) -> Void in
})
//小车2走过的轨迹置灰色, 采用添加多个动画方法
let speed_car2: Double = 100.0 / 3.6
//60 km/h
weak var weakSelf = self
self.car2.coordinate = s_coords[0]
self.passedTraceCoordIndex = 0
for i in 1..<count {
let num = self.distanceArray[i - 1]
let tempDuration = num / speed_car2
self.car2.addMoveAnimation(withKeyCoordinates: &(s_coords[i]), count: 1, withDuration: CGFloat(tempDuration), withName: nil, completeCallback: {(_ isFinished: Bool) -> Void in
weakSelf?.passedTraceCoordIndex = i
})
}
}
出行、运动等类别的app中常常会需要展示车辆或用户的行程轨迹、实时移动轨迹等数据,相应效果需要车辆在地图上平滑移动。该demo展示了如何实现该效果。
核心类/接口
类 | 接口 | 说明 | 版本 |
---|---|---|---|
AMap | public final Marker addMarker(MarkerOptions options) | 加一个Marker(标记)到地图上。 | V2.0.0版本起 |
AMap | public final Polyline addPolyline(PolylineOptions options) | 加一个多段线对象(Polyline)对象在地图上。 | V2.0.0版本起 |
1、计算斜率
/**
* 算斜率
*/
privatedouble getSlope(LatLng fromPoint, LatLng toPoint) {
if (toPoint.longitude == fromPoint.longitude) {
return Double.MAX_VALUE;
}
double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));
return slope;
}
2、计算移动距离
/**
* 计算每次移动的距离
*/
private double getMoveDistance(double slope) {
if (slope == Double.MAX_VALUE||slope==0) {
return DISTANCE;
}
return Math.abs((DISTANCE * slope) / Math.sqrt(1 + slope * slope));
}
3、计算marker角度
/**
* 根据点获取图标转的角度
*/
private double getAngle(int startIndex) {
if ((startIndex + 1) >= mVirtureRoad.getPoints().size()) {
throw new RuntimeException("index out of bonds");
}
LatLng startPoint = mVirtureRoad.getPoints().get(startIndex);
LatLng endPoint = mVirtureRoad.getPoints().get(startIndex + 1);
return getAngle(startPoint, endPoint);
}