[iOS]应用内跳转到各类地图进行路线规划

[iOS]应用内跳转到各类地图进行路线规划

Demo:https://download.csdn.net/download/u012881779/10500492

首先,使用苹果自带的地图规划路线,需要开启定位权限获取当前位置。

另外,iOS9之后,需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。我们需要根据判断是否安装,选择是否在弹出的表单中展示相应的地图跳转。

LSApplicationQueriesSchemes
高德地图    iosamap
百度地图    baidumap
腾讯地图    qqmap
谷歌地图    comgooglemaps


Model

#import <Foundation/Foundation.h>

@interface GAAddressModel : NSObject
@property (strong, nonatomic) NSString *dShopName;  // 商铺名称
@property (strong, nonatomic) NSString *dAddress;   // 地址
@property (strong, nonatomic) NSString *dLng;       // 经度
@property (strong, nonatomic) NSString *dLat;       // 纬度

@end

UIViewController

#import <UIKit/UIKit.h>
#import "GAMapDetailsViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotationView.h>
#import "QYAnnotation.h"
#import "MKMapView+ZoomLevel.h"
#import "DestinationMode.h"
#import "GAAddressModel.h"

@interface GAMapDetailsViewController : UIViewController <MKMapViewDelegate> {
    UIView            *uiView;
    CLLocationManager *locationManager;
    MKMapView         *maMapView;
    MKAnnotationView  *annotationView;
    DestinationMode   *destinationMode;
}
@property (weak, nonatomic) GAAddressModel *dataModel;

@end

@implementation GAMapDetailsViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initMap];
}

// 初始化地图
- (void)initMap {
    destinationMode = [DestinationMode new];
    destinationMode.destinationName = _dataModel.dShopName;
    destinationMode.destinationDesc = _dataModel.dAddress;
    destinationMode.destinationLongitude = _dataModel.dLng;
    destinationMode.destinationLatitude = _dataModel.dLat;
    maMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
    [self.view addSubview:maMapView];
    // 设置代理
    maMapView.delegate = self;
    // 请求定位服务
    locationManager = [[CLLocationManager alloc] init];
    if (![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!=kCLAuthorizationStatusAuthorizedWhenInUse) {
        [locationManager requestWhenInUseAuthorization];
    }
    // 用户位置追踪(用户位置追踪用于标记用户当前位置,此时会调用定位服务)
    maMapView.userTrackingMode = MKUserTrackingModeFollow;
    // 设置地图类型
    maMapView.mapType = MKMapTypeStandard;
    [self addAnnotation];
    [self.view bringSubviewToFront:_returnBut];
}

// 添加大头针
- (void)addAnnotation {
    CLLocationCoordinate2D location1 = CLLocationCoordinate2DMake(destinationMode.destinationLatitude.floatValue, destinationMode.destinationLongitude.floatValue);
    QYAnnotation *annotation1 = [[QYAnnotation alloc] init];
    annotation1.title = destinationMode.destinationName;
    annotation1.subtitle = destinationMode.destinationDesc;
    annotation1.coordinate = location1;
    [maMapView setCenterCoordinate:location1 zoomLevel:10 animated:NO];
    [maMapView addAnnotation:annotation1];
    [maMapView selectAnnotation:annotation1 animated:YES];
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    // 由于当前位置的标注也是一个大头针,所以此时需要判断,此代理方法返回nil使用默认大头针视图
    if ([annotation isKindOfClass:[QYAnnotation class]]) {
        static NSString *key1 = @"QYAnnotation";
        annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:key1];
        // 如果缓存池中不存在则新建
        if (!annotationView) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:key1];
            // 允许交互点击
            annotationView.canShowCallout = true;
            // 定义详情视图偏移量
            annotationView.calloutOffset = CGPointMake(0, 1);
            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];
            [btn setBackgroundImage:[UIImage imageNamed:@"common_green_line"] forState:UIControlStateNormal];
            [btn setTitle:@"到这去" forState:UIControlStateNormal];
            [btn addTarget:self action:@selector(turnAction:) forControlEvents:UIControlEventTouchUpInside];
            // 定义详情左侧视图
            annotationView.rightCalloutAccessoryView = btn;
            annotationView.selected = YES;
        }
        // 修改大头针视图
        // 重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的,位置是放到缓存池时的位置)
        annotationView.annotation = annotation;
        // 设置大头针视图的图片
        annotationView.image = [UIImage imageNamed:@"common_map_site"];
        return annotationView;
    } else {
        return nil;
    }
}

// 到这去
- (void)turnAction:(id)sender {
    NSString *tempMsg = @"导航到店铺的位置";
    if (![destinationMode.destinationName isEqualToString:@""]) {
        tempMsg = [NSString stringWithFormat:@"导航到“%@”的位置",destinationMode.destinationName];
    }
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:tempMsg preferredStyle:UIAlertControllerStyleActionSheet];
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"http://maps.apple.com/"]]) {
        UIAlertAction *appleMapAction = [UIAlertAction actionWithTitle:@"苹果地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self doAppleNavigation];
        }];
        [alert addAction:appleMapAction];
    }
    
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]]) {
        UIAlertAction *baiduMapAction = [UIAlertAction actionWithTitle:@"百度地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self doBaiduNavigation];
        }];
        [alert addAction:baiduMapAction];
    }
    
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]) {
        UIAlertAction *gaodeMapAction = [UIAlertAction actionWithTitle:@"高德地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self doGaodeNavigation];
        }];
        [alert addAction:gaodeMapAction];
    }

    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://"]]) {
        UIAlertAction *googleMapAction = [UIAlertAction actionWithTitle:@"腾讯地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self doQQNavigation];
        }];
        [alert addAction:googleMapAction];
    }

    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]]) {
        UIAlertAction *googleMapAction = [UIAlertAction actionWithTitle:@"谷歌地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self doGoogleNavigation];
        }];
        [alert addAction:googleMapAction];
    }

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    }];
    [alert addAction:cancelAction];
    [self presentViewController:alert animated:YES completion:nil];
}

/**
 * 苹果地图路线规划
 * 文档:https://developer.apple.com/documentation/mapkit/mkmapitem
 */
- (void)doAppleNavigation {
    NSDictionary *options = @{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard),MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving};
    CLLocationCoordinate2D fromCoordinate = maMapView.userLocation.location.coordinate;
    CLLocationCoordinate2D toCoordinate = CLLocationCoordinate2DMake(destinationMode.destinationLatitude.floatValue, destinationMode.destinationLongitude.floatValue);
    MKPlacemark *fromPlacemark = [[MKPlacemark alloc] initWithCoordinate:fromCoordinate
                                                       addressDictionary:nil];
    MKPlacemark *toPlacemark = [[MKPlacemark alloc] initWithCoordinate:toCoordinate
                                                       addressDictionary:nil];
    MKMapItem *fromItem = [[MKMapItem alloc] initWithPlacemark:fromPlacemark];
    fromItem.name = @"我的位置";
    MKMapItem *toItem = [[MKMapItem alloc] initWithPlacemark:toPlacemark];
    toItem.name = destinationMode.destinationName;
    [MKMapItem openMapsWithItems:@[fromItem,toItem] launchOptions:options];
}

/**
 * 百度地图路线规划
 * 文档:http://lbsyun.baidu.com/index.php?title=uri/api/ios
 */
- (void)doBaiduNavigation {
    NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=name:%@|latlng:%f,%f&mode=driving&coord_type=gcj02",destinationMode.destinationName,destinationMode.destinationLatitude.floatValue, destinationMode.destinationLongitude.floatValue] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

/**
 * 高德地图路线规划
 * 文档:http://lbs.amap.com/api/amap-mobile/guide/ios/route
 */
- (void)doGaodeNavigation {
    NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString *tempAppName = [NSString stringWithFormat:@"%@",infoDic[@"CFBundleDisplayName"]];
    NSString *tempUrlScheme = @"demoURL://";
    
    NSString *urlString = [[NSString stringWithFormat:@"iosamap://path?sourceApplication=%@&backScheme=%@&sname=我的位置&dlat=%lf&dlon=%lf&dname=%@&dev=0&style=2&m=0&t=0",tempAppName,tempUrlScheme,destinationMode.destinationLatitude.floatValue,destinationMode.destinationLongitude.floatValue,destinationMode.destinationName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

/**
 * 腾讯地图路线规划
 * 文档:http://lbs.qq.com/uri_v1/guide-route.html
 */
- (void)doQQNavigation {
    NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString *tempAppName = [NSString stringWithFormat:@"%@",infoDic[@"CFBundleDisplayName"]];
    NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?type=drive&from=我的位置&to=%@&tocoord=%f,%f&coord_type=1&policy=0&refer=%@",destinationMode.destinationName,   destinationMode.destinationLatitude.floatValue, destinationMode.destinationLongitude.floatValue, tempAppName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

/**
 * 谷歌地图路线规划
 * 文档:https://developers.google.com/maps/documentation/ios/urlscheme
 */
- (void)doGoogleNavigation {
    NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString *tempAppName = [NSString stringWithFormat:@"%@",infoDic[@"CFBundleDisplayName"]];
    NSString *tempUrlScheme = @"demoURL://";
    NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving", tempAppName, tempUrlScheme, destinationMode.destinationLatitude.floatValue, destinationMode.destinationLongitude.floatValue] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

@end

TO:

iOS开发:采用URI方式跳转到各类地图进行导航

iOS9AdaptationTips

iOS开发—跳转方式实现地图导航功能

URI跳转方式地图导航的代码实践

示意图:


各地图APP路线规划如下:

苹果地图


高德地图


百度地图


腾讯地图


谷歌地图  翻墙后才有展示





猜你喜欢

转载自blog.csdn.net/u012881779/article/details/80815794