- 高德地圖點平滑移動
今天給大家?guī)淼氖琼椖恐杏龅降男谐誊壽E,就是小車在地圖上面根據(jù)路線平滑移動。為啥要特意寫一下這個,因為在網(wǎng)上找了好久的資源都沒有找到暫停再移動的方法。接下來就給大家看看怎么暫停再移動吧。由于之前都是用的自己項目中的代碼。這次為了方便大家看,我就自己寫了一個demo。首先,點平滑移動的demo 是直接拷貝的源碼,這部分相信大家也不注重。暫停之后再移動才是重點。
廢話不多說,直接貼代碼:
暫停后繼續(xù)移動的重要代碼
- (void)button2 { // 點擊stop 按鈕
//結(jié)束未完成動畫
for (MAAnnotationMoveAnimation *animation in [self.annotation allMoveAnimations]) {
[animation cancel];
self.animationDurationTime += animation.elapsedTime; // 這里為啥要用 += ,是因為他每次開啟動畫都是一個新的 動畫。
self.passedPointCount += (int)animation.passedPointCount; // 將動畫的時間和動畫經(jīng)過的點記錄一下。
}
}
下面是繼續(xù)滑動
- (void)button3{
// 獲取走過的點的個數(shù),再進行動畫
int passCount = self.passedPointCount;
CLLocationCoordinate2D commonPolyLineCoords[5- passCount]; // 這里的5 是你之前線路的點的個數(shù)
for (int i = 0; i < 5 - passCount; i++) {
commonPolyLineCoords[i].latitude = coords1[i + passCount].latitude;
commonPolyLineCoords[i].longitude = coords1[i + passCount].longitude;
}
// 這樣新的移動的點集合就拿到了。
self.annotation.coordinate = CLLocationCoordinate2DMake(coords1[passCount].latitude, coords1[passCount].longitude);
[self.annotation addMoveAnimationWithKeyCoordinates:commonPolyLineCoords count:5 - passCount withDuration:10 - self.animationDurationTime withName:nil completeCallback:^(BOOL isFinished) {
// 注意這里面是需要使用weak self 的 ---完成回調(diào)
} stepCallback:^(MAAnnotationMoveAnimation *currentAni) {
// 每一個點的回調(diào)
}];
}
下面是整個控制器的代碼,有點多,有不懂的,下面mark 一下。希望能幫助大家。
#import "MovingAnnotationViewController.h"
#import <MAMapKit/MAMapKit.h>
@interface MovingAnnotationViewController () <MAMapViewDelegate>
{
CLLocationCoordinate2D coords1[5];
CLLocationCoordinate2D coords2[6];
CLLocationCoordinate2D coords3[10];//五角星
}
@property (nonatomic, strong) MAMapView *mapView;
@property (nonatomic, strong) MAAnimatedAnnotation* annotation;
@property (nonatomic,assign) int passedPointCount; // 移動過的點count
@property (nonatomic,assign) CGFloat animationDurationTime; // 動畫開始了的時間
@end
@implementation MovingAnnotationViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initCoordinates];
self.mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.mapView.delegate = self;
[self.view addSubview:self.mapView];
//add overlay
MAPolyline *polyline1 = [MAPolyline polylineWithCoordinates:coords1 count:sizeof(coords1) / sizeof(coords1[0])];
MAPolyline *polyline2 = [MAPolyline polylineWithCoordinates:coords2 count:sizeof(coords2) / sizeof(coords2[0])];
MAPolyline *polyline3 = [MAPolyline polylineWithCoordinates:coords3 count:sizeof(coords3) / sizeof(coords3[0])];
[self.mapView addOverlays:@[polyline1, polyline2, polyline3]];
MAAnimatedAnnotation *anno = [[MAAnimatedAnnotation alloc] init];
anno.coordinate = coords1[0];
self.annotation = anno;
[self.mapView addAnnotation:self.annotation];
[self initButton];
}
- (void)initCoordinates {
///1
coords1[0].latitude = 39.852136;
coords1[0].longitude = 116.30095;
coords1[1].latitude = 39.852136;
coords1[1].longitude = 116.40095;
coords1[2].latitude = 39.932136;
coords1[2].longitude = 116.40095;
coords1[3].latitude = 39.932136;
coords1[3].longitude = 116.40095;
coords1[4].latitude = 39.982136;
coords1[4].longitude = 116.48095;
///2
coords2[0].latitude = 39.982136;
coords2[0].longitude = 116.48095;
coords2[1].latitude = 39.832136;
coords2[1].longitude = 116.42095;
coords2[2].latitude = 39.902136;
coords2[2].longitude = 116.42095;
coords2[3].latitude = 39.902136;
coords2[3].longitude = 116.44095;
coords2[4].latitude = 39.932136;
coords2[4].longitude = 116.44095;
///3
[self generateStarPoints:coords3 pointsCount:10 atCenter:CLLocationCoordinate2DMake(39.800892, 116.293413)];//生成多角星的坐標(biāo)
coords2[5] = coords3[0];
}
/*!
@brief 生成多角星坐標(biāo)
@param coordinates 輸出的多角星坐標(biāo)數(shù)組指針。內(nèi)存需在外申請,方法內(nèi)不釋放,多角星坐標(biāo)結(jié)果輸出。
@param pointsCount 輸出的多角星坐標(biāo)數(shù)組元素個數(shù)。
@param starCenter 多角星的中心點位置。
*/
- (void)generateStarPoints:(CLLocationCoordinate2D *)coordinates pointsCount:(NSUInteger)pointsCount atCenter:(CLLocationCoordinate2D)starCenter
{
#define STAR_RADIUS 0.05
#define PI 3.1415926
NSUInteger starRaysCount = pointsCount / 2;
for (int i =0; i<starRaysCount; I++)
{
float angle = 2.f*i/starRaysCount*PI;
int index = 2 * I;
coordinates[index].latitude = STAR_RADIUS* sin(angle) + starCenter.latitude;
coordinates[index].longitude = STAR_RADIUS* cos(angle) + starCenter.longitude;
index++;
angle = angle + (float)1.f/starRaysCount*PI;
coordinates[index].latitude = STAR_RADIUS/2.f* sin(angle) + starCenter.latitude;
coordinates[index].longitude = STAR_RADIUS/2.f* cos(angle) + starCenter.longitude;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)initButton
{
UIButton *button1=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(10, 80, 70,25);
button1.backgroundColor = [UIColor redColor];
[button1 setTitle:@"Go" forState:UIControlStateNormal];
[button1 addTarget:self action:@selector(button1) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button1];
UIButton *button2=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectMake(10, 120,70,25);
button2.backgroundColor = [UIColor redColor];
[button2 setTitle:@"Stop" forState:UIControlStateNormal];
[button2 addTarget:self action:@selector(button2) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button2];
UIButton *button3=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button3.frame = CGRectMake(10, 160,70,25);
button3.backgroundColor = [UIColor redColor];
[button3 setTitle:@"Continue" forState:UIControlStateNormal];
[button3 addTarget:self action:@selector(button3) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button3];
}
- (void)button1 {
self.annotation.coordinate = coords1[0];
// MAAnimatedAnnotation *anno = self.annotation;
// [anno addMoveAnimationWithKeyCoordinates:coords1 count:sizeof(coords1) / sizeof(coords1[0]) withDuration:5 withName:nil completeCallback:^(BOOL isFinished) {
// }];
//
// [anno addMoveAnimationWithKeyCoordinates:coords2 count:sizeof(coords2) / sizeof(coords2[0]) withDuration:5 withName:nil completeCallback:^(BOOL isFinished) {
// }];
//
//
// [anno addMoveAnimationWithKeyCoordinates:coords3 count:sizeof(coords3) / sizeof(coords3[0]) withDuration:5 withName:nil completeCallback:^(BOOL isFinished) {
// }];
self.annotation.title = @"濤胖子帶你飛";
[self.mapView setSelectedAnnotations:@[self.annotation]];
// 點在 coords1 的這條線上面平滑移動
[self.annotation addMoveAnimationWithKeyCoordinates:coords1 count:sizeof(coords1) / sizeof(coords1[0]) withDuration:10 withName:nil completeCallback:^(BOOL isFinished) { // 完成回調(diào)
} stepCallback:^(MAAnnotationMoveAnimation *currentAni) { // 當(dāng)前點的回調(diào)
}];
}
- (void)button2 {
//結(jié)束未完成動畫
for (MAAnnotationMoveAnimation *animation in [self.annotation allMoveAnimations]) {
[animation cancel];
self.animationDurationTime += animation.elapsedTime; // 這里為啥要用 += ,是因為他每次開啟動畫都是一個新的 動畫。
self.passedPointCount += (int)animation.passedPointCount;
}
}
- (void)button3{
// 獲取走過的點的個數(shù),再進行動畫
int passCount = self.passedPointCount;
CLLocationCoordinate2D commonPolyLineCoords[5- passCount]; // 這里的5 是你之前線路的點的個數(shù)
for (int i = 0; i < 5 - passCount; i++) {
commonPolyLineCoords[i].latitude = coords1[i + passCount].latitude;
commonPolyLineCoords[i].longitude = coords1[i + passCount].longitude;
}
// 這樣新的移動的點集合就拿到了。
self.annotation.coordinate = CLLocationCoordinate2DMake(coords1[passCount].latitude, coords1[passCount].longitude);
// 這里的時間就要改成這個動畫的總時間 - 用了的時間
[self.annotation addMoveAnimationWithKeyCoordinates:commonPolyLineCoords count:5 - passCount withDuration:10 - self.animationDurationTime withName:nil completeCallback:^(BOOL isFinished) {
} stepCallback:^(MAAnnotationMoveAnimation *currentAni) {
}];
}
#pragma mark - mapview delegate
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
if ([overlay isKindOfClass:[MAPolyline class]])
{
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
polylineRenderer.lineWidth = 8.f;
polylineRenderer.strokeImage = [UIImage imageNamed:@"arrowTexture"];
return polylineRenderer;
}
return nil;
}
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
if ([annotation isKindOfClass:[MAPointAnnotation class]])
{
NSString *pointReuseIndetifier = @"myReuseIndetifier";
MAAnnotationView *annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier];
if (annotationView == nil)
{
annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:pointReuseIndetifier];
UIImage *imge = [UIImage imageNamed:@"jj_bt_praise_s"];
annotationView.image = imge;
}
annotationView.canShowCallout = YES;
annotationView.draggable = NO;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[annotationView setSelected:YES animated:NO];
return annotationView;
}
return nil;
}
運行:
IMG_0355.PNG
總結(jié):因為高德大佬沒有給我們動畫暫停的API,那我們就先將動畫取消,再找到取消動畫之后的點,還有就是取消動畫時用了的時間。然后再拿到剩下的點的集合。。最后進行動畫。OK。。完美。
這個代碼可能會有小伙伴在運行的時候發(fā)現(xiàn),我擦,說好的平滑移動呢,為啥沒有平滑移動,那么這里要說明一下,代碼中的點距離都很大,實際開發(fā)中我們拿到的點肯定是很密集的,所以不用擔(dān)心這個問題。
希望能幫助到大家。。
---來自濤胖子的工作筆記
點平滑移動的API