實現物流場景中小車Marker指向目的地

如下內容轉載自麪糊的文章《實現物流場景的小車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];
}

效果示例以下圖所示:

相關文章
相關標籤/搜索