zoukankan      html  css  js  c++  java
  • 实现物流场景中小车Marker指向目的地

    以下内容转载自面糊的文章《实现物流场景的小车Marker指向目的地》

    作者:面糊

    链接:https://www.jianshu.com/p/f794b02a81f5

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    场景需求

    快递物流相关APP中,如快递、送餐,可以让快递车Marker的车头,在途经点始终指向目的地,如下图所示:

    使用技术:腾讯地图iOS SDK点标记绘制线

    核心点

    1、操作QPointAnnotation的坐标

    2、从mapView中获取途经点QPointAnnotation的坐标

    3、通过三角函数计算途经点坐标与终点坐标的角度

    4、操作QAnnotationView的transform属性

    代码示例如下:

    1、示例展示福州送至北京,途径西安、西宁、济南、太原、天津,先将这几个点的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];
    
    ....
    

    2、添加小车marker,以福州为起始点:

    _carAnnotation = [[QPointAnnotation alloc] init];
    _carAnnotation.coordinate = locations[0];
    // 指定userData自定义数据,用于判断marker的类型
    _carAnnotation.userData = @"car";
    [self.mapView addAnnotation:_carAnnotation];
    

    3、实现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;
    }
    

    4、根据三角函数,计算起点和终点的角度,并调整小车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];
    }
    

    效果示例如下图所示:

  • 相关阅读:
    Python 学习日记 第七天
    Python 学习日记 第六天
    Python 学习日记 第五天
    Python 学习日记 第四天
    Redis 中的数据类型及基本操作
    Asp.net mvc 中View 的呈现(二)
    Asp.net mvc 中View的呈现(一)
    Asp.net mvc 中Action 方法的执行(三)
    Asp.net mvc 中Action 方法的执行(二)
    Asp.net mvc 中Action 方法的执行(一)
  • 原文地址:https://www.cnblogs.com/Dreamholder/p/13030315.html
Copyright © 2011-2022 走看看