不用匯入SDK就可實現導航--URI方式跳轉到各類地圖進行導航

zhaoName發表於2016-04-19

最近在做導航,所以把自己找到的資料總結一下!

無論是百度地圖、高德地圖、谷歌地圖還是騰訊地圖它們都有自己的SDK,我們只需要在自己的工程中匯入SDK並檢視相應的官方文件,基本上就可以實現導航。但是這樣每個地圖的SDK都匯入不但麻煩而且佔用APP的記憶體。最關鍵的是我們上傳到AppStore的包檔案是有限制的。所以我的原則是能不匯入的SDK 就不匯入。

還有一種方式就是是以URI跳轉的方式(在iOS中就是以URL Scheme的方式),直接跳到對應的地圖APP中,直接利用對方的功能來導航。缺點是使用者沒有安裝對應的APP就不能使用其進行導航。
點選導航按鈕會出現如下的彈窗, 當然手機上未安裝的地圖 其名稱就不會出現在彈窗上。

這裡寫圖片描述

iOS9之後 若想用URI方式跳轉到百度地圖、高德地圖、騰訊地圖、谷歌地圖,需要你在info.plist加入這些東西。(ps:LSApplicationQueriesSchemes,短的自己手打吧,另外注意型別!)

這裡寫圖片描述


下面進入正題

以下出行的預設方式都是駕車

一、百度地圖

說到百度地圖,就不得不說它很坑爹。因為百度地圖獲取的經緯度,是在GCJ-02(火星座標)進行偏移得到的經緯度,而高德、谷歌、騰訊都是使用GCJ-02座標體系得到的經緯度。這樣使用百度地圖獲取到的經緯度在高德、谷歌、騰訊上導航都會出現很大的偏差。所以自己做的APP中需要地圖功能最好不要匯入百度地圖的SDK(使用上面三個中任何一個地圖獲取到的經緯度都可以很容易的轉換成百度地圖需要的經緯度),如果你是像我這樣中途接手的專案,百度地圖的相應功能已經做好了,那你可以用下面的方式換算一下經緯度(最下方)。

程式碼如下 :需傳入起點和終點的經緯度

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://map/"]])
    {
        UIAlertAction *baiduMapAction = [UIAlertAction actionWithTitle:@"百度地圖" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

            NSString *baiduParameterFormat = @"baidumap://map/direction?origin=latlng:%f,%f|name:我的位置&destination=latlng:%f,%f|name:終點&mode=driving";
            NSString *urlString = [[NSString stringWithFormat:baiduParameterFormat,
                                    userLocation.location.coordinate.latitude,
                                    userLocation.location.coordinate.longitude,
                                    self.destinationCoordinate.latitude,
                                    self.destinationCoordinate.longitude]
                                   stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ;

            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString]];
        }];
        [actionSheet addAction:baiduMapAction];
    }

各個引數代表的含義可參考百度地圖官方文件


二、高德地圖

只需傳入終點經緯度
高德地圖能夠跳轉回你的APP,前提是backScheme=%@(你的APP的URL)要填寫。程式碼如下

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://map/"]])
    {
        UIAlertAction *gaodeMapAction = [UIAlertAction actionWithTitle:@"高德地圖" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

            NSString *gaodeParameterFormat = @"iosamap://navi?sourceApplication=%@&backScheme=%@&poiname=%@&lat=%f&lon=%f&dev=1&style=2";
            NSString *urlString = [[NSString stringWithFormat:gaodeParameterFormat,
                                    @"yourAppName",
                                    @"yourAppUrlSchema",
                                    @"終點",
                                    self.destinationCoordinate.latitude,
                                    self.destinationCoordinate.longitude]
                                   stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString]];
        }];
        [actionSheet addAction:gaodeMapAction];
    }

各個引數的含義可參考高德地圖官方文件


三、蘋果地圖

需傳入起點和終點的經緯度,並匯入標頭檔案#import MapKit/MKMapItem.h>

[actionSheet addAction:[UIAlertAction actionWithTitle:@"蘋果地圖" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

        //起點
        MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];

        CLLocationCoordinate2D desCorrdinate = CLLocationCoordinate2DMake(self.destinationCoordinate.latitude, self.destinationCoordinate.longitude);
        //終點
        MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:desCorrdinate addressDictionary:nil]];
        //預設駕車
        [MKMapItem openMapsWithItems:@[currentLocation, toLocation]
                       launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,
                                       MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];
    }]];

各個引數的含義可參考蘋果地圖官方文件


四、谷歌地圖

只需傳入終點的經緯度

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://map/"]])
{
    [actionSheet addAction:[UIAlertAction actionWithTitle:@"蘋果地圖"style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

   NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",
   appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}]];
}

各個引數的含義可參考谷歌地圖官方文件


五、騰訊地圖

if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://map/"]])
    {
        [actionSheet addAction:[UIAlertAction actionWithTitle:@"騰訊地圖" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

            NSString *QQParameterFormat = @"qqmap://map/routeplan?type=drive&fromcoord=%f, %f&tocoord=%f,%f&coord_type=1&policy=0&refer=%@";

            NSString *urlString = [[NSString stringWithFormat:QQParameterFormat,
                                    userLocation.location.coordinate.latitude,
                                    userLocation.location.coordinate.longitude,
                                    self.destinationCoordinate.latitude,
                                    self.destinationCoordinate.longitude,
                                    @"yourAppName"]
                                   stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
        }]];
    }

各個引數的含義可參考騰訊地圖官方文件


修改於2016-10-20:

GCJ-02座標轉換成BD-09座標 和逆轉換

/**
 *  將GCJ-02座標轉換為BD-09座標 即將高德地圖上獲取的座標轉換成百度座標
 */
- (CLLocationCoordinate2D)gcj02CoordianteToBD09:(CLLocationCoordinate2D)gdCoordinate
{
    double x_PI = M_PI * 3000 /180.0;
    double gd_lat = gdCoordinate.latitude;
    double gd_lon = gdCoordinate.longitude;

    double z = sqrt(gd_lat * gd_lat + gd_lon * gd_lon) + 0.00002 * sin(gd_lat * x_PI);
    double theta = atan2(gd_lat, gd_lon) + 0.000003 * cos(gd_lon * x_PI);

    return CLLocationCoordinate2DMake(z * sin(theta) + 0.006, z * cos(theta) + 0.0065);
}

/**
 *  將BD-09座標轉換為GCJ-02座標 即將百度地圖上獲取的座標轉換成高德地圖的座標
 */
- (CLLocationCoordinate2D)bd09CoordinateToGCJ02:(CLLocationCoordinate2D)bdCoordinate
{
    double x_PI = M_PI * 3000 /180.0;
    double bd_lat = bdCoordinate.latitude - 0.006;
    double bd_lon = bdCoordinate.longitude - 0.0065;

    double z = sqrt(bd_lat * bd_lat + bd_lon * bd_lon) + 0.00002 * sin(bd_lat * x_PI);
    double theta = atan2(bd_lat, bd_lon) + 0.000003 * cos(bd_lon * x_PI);

    return CLLocationCoordinate2DMake(z * cos(theta), z * sin(theta));
}

另外無論你匯入的是百度SDK還是高德SDK,他們內部都封裝了將目標經緯度轉換為高德座標系或百度座標系(文件上的介面可能被棄用沒有及時更新,是不是很坑爹),但是沒有將高德或百度座標轉換為別的座標系下的座標的介面。所以感覺情不自禁想問一下這個介面還有毛用。。。。

設定URL Scheme:http://blog.csdn.net/wm9028/article/details/49995329

相關文章