如下內容轉載自麪糊的文章《實現物流場景的小車Marker指向目的地》做者:麪糊git
連接:https://www.jianshu.com/p/f79...ide
來源:簡書函數
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。ui
快遞物流相關APP中,如快遞、送餐,能夠讓快遞車Marker的車頭,在途經點始終指向目的地,以下圖所示:
使用技術:騰訊地圖iOS SDK,點標記和繪製線spa
核心點:3d
一、操做QPointAnnotation的座標代理
二、從mapView中獲取途經點QPointAnnotation的座標code
三、經過三角函數計算途經點座標與終點座標的角度orm
四、操做QAnnotationView的transform屬性blog
代碼示例以下:
一、示例展現福州送至北京,途徑西安、西寧、濟南、太原、天津,先將這幾個點的maker添加到地圖中:
// 福州 locations[0] = CLLocationCoordinate2DMake(26.101797,119.415539); // 西安 locations[1] = CLLocationCoordinate2DMake(34.475422,109.0005); // 西寧 locations[2] = CLLocationCoordinate2DMake(36.69099,101.749523); // 濟南 locations[3] = CLLocationCoordinate2DMake(36.761434,117.174328); // 太原 locations[4] = CLLocationCoordinate2DMake(37.949064,112.56007); // 天津 locations[5] = CLLocationCoordinate2DMake(39.117802,117.174328); // 北京 locations[6] = CLLocationCoordinate2DMake(39.897614,116.383312); // 福州 QPointAnnotation *nnAnnotation = [[QPointAnnotation alloc] init]; nnAnnotation.coordinate = locations[0]; [self.mapView addAnnotation:nnAnnotation]; ....
二、添加小車marker,以福州爲起始點:
_carAnnotation = [[QPointAnnotation alloc] init]; _carAnnotation.coordinate = locations[0]; // 指定userData自定義數據,用於判斷marker的類型 _carAnnotation.userData = @"car"; [self.mapView addAnnotation:_carAnnotation];
三、實現mapView代理方法,根據userData來區分不一樣的Marker
- (QAnnotationView *)mapView:(QMapView *)mapView viewForAnnotation:(id<QAnnotation>)annotation { static NSString *reuse = @"annotation"; static NSString *reuseCar = @"annotationCar"; QPinAnnotationView *annotationView = (QPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuse]; if (annotationView == nil) { if (annotation == _carAnnotation) { annotationView = [[QPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseCar]; annotationView.image = [UIImage imageNamed:@"car"]; // 將小車的AnnotationView保存爲屬性,用於操做轉向 _carAnnotationView = annotationView; } else { annotationView = [[QPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuse]; } } return annotationView; }
四、根據三角函數,計算起點和終點的角度,並調整小車Marker的角度
- (void)annotationRotate { // 取出終點座標位置 CLLocationCoordinate2D toCoord = _bjAnnotation.coordinate; double fromLat = _carAnnotation.coordinate.latitude; double fromlon = _carAnnotation.coordinate.longitude; double toLat = toCoord.latitude; double tolon = toCoord.longitude; double slope = ((toLat - fromLat) / (tolon - fromlon)); double radio = atan(slope); double angle = 180 * (radio / M_PI); if (slope > 0) { if (tolon < fromlon) { angle = -90 - angle; } else { angle = 90 - angle; } } else if (slope == 0) { if (tolon < fromlon) { angle = -90; } else { angle = 90; } } else { if (toLat < fromLat) { angle = 90 - angle; } else { angle = -90 - angle; } } // 這裏要注意,計算出來的是角度,而旋轉則須要先轉換爲弧度 _carAnnotationView.transform = CGAffineTransformMakeRotation((M_PI * (angle) / 180.0)); }
在這個基礎上,我在navigationItem中添加了一個切換當前途徑點的功能,每次點擊按鈕就會將小車移動到下一個途經點,示例代碼以下:
- (void)handleTestAction { _index++; if (_index == self.mapView.annotations.count - 2) { _index = 0; } QPointAnnotation *annotation = self.mapView.annotations[_index]; _carAnnotation.coordinate = annotation.coordinate; [self annotationRotate]; }
效果示例以下圖所示: