平滑移动

该demo主要是向开发者展示如何在地图上实现轨迹点的平滑移动效果。
下载源代码
00:00 / 00:12
体验移动端 扫码体验移动端

使用场景

出行、运动等类别的app中常常会需要展示车辆或用户的行程轨迹、实时移动轨迹等数据,相应效果需要车辆在地图上平滑移动。该demo展示了如何实现该效果。

用到产品

iOS 地图 SDK

核心类/接口

接口

说明

版本

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
            })
        }
    }
下载源代码
00:00 / 00:12
体验移动端 扫码体验移动端

使用场景

出行、运动等类别的app中常常会需要展示车辆或用户的行程轨迹、实时移动轨迹等数据,相应效果需要车辆在地图上平滑移动。该demo展示了如何实现该效果。

用到产品

Android 地图 SDK

核心类/接口

接口

说明

版本

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);
}

 

返回顶部 示例中心 常见问题 智能客服 公众号
二维码