Как вызвать iPhone карты для направлений с текущим местоположением в качестве начального адреса - PullRequest
72 голосов
/ 23 февраля 2009

Я знаю, что можно запустить приложение карт iPhone, вызвав openURL по URL-адресу карт Google с параметрами saddr и daddr со строками местоположения или широтой / долготой (см. Пример ниже).

Но мне интересно, возможно ли сделать начальный адрес закладкой "Текущее местоположение" карт, чтобы я мог использовать код обработки местоположения приложения Карты . Мой поиск в Google оказался довольно бесплодным.

Например:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat: @"http://maps.google.com/maps?saddr=%@&daddr=%@", myLatLong, latlong]]];

За исключением чего-то, чтобы вызвать текущую закладку местоположения вместо myLatLong.

Ответы [ 16 ]

133 голосов
/ 08 июня 2009

пред iOS 6

Вам нужно использовать Базовое местоположение, чтобы получить текущее местоположение, но с этой парой широта / длинна вы можете получить Карты, чтобы направить вас оттуда, к адресу или адресу улицы. Вот так:

CLLocationCoordinate2D currentLocation = [self getCurrentLocation];
// this uses an address for the destination.  can use lat/long, too with %f,%f format
NSString* address = @"123 Main St., New York, NY, 10001";
NSString* url = [NSString stringWithFormat: @"http://maps.google.com/maps?saddr=%f,%f&daddr=%@",
                    currentLocation.latitude, currentLocation.longitude,
                    [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];

Наконец, если вы хотите избежать использования CoreLocation для явного поиска текущего местоположения и хотите использовать вместо него @"http://maps.google.com/maps?saddr=Current+Location&daddr=%@" url, тогда см. Ссылку, которую я предоставил в комментариях ниже , чтобы узнать, как локализуйте строку Current + Location . Однако вы используете еще одну недокументированную функцию, и, как отметил ниже Джейсон МакКрири, в будущих версиях она может работать ненадежно.


Обновление для iOS 6

Изначально Карты использовали карты Google, но теперь Apple и Google имеют отдельные приложения для карт.

1) Если вы хотите выполнить маршрутизацию с помощью приложения Google Maps, используйте схему URL-адреса comgooglemaps :

NSString* url = [NSString stringWithFormat: @"comgooglemaps://?daddr=%@&directionsmode=driving",
                    [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
BOOL opened = [[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];

2) Для использования Apple Maps вы можете использовать новый класс MKMapItem для iOS 6. См. Документы Apple API здесь

Как правило, вы будете использовать что-то вроде этого, если маршрутизация к месту назначения координаты (latlong):

    MKPlacemark* place = [[MKPlacemark alloc] initWithCoordinate: latlong addressDictionary: nil];
    MKMapItem* destination = [[MKMapItem alloc] initWithPlacemark: place];
    destination.name = @"Name Here!";
    NSArray* items = [[NSArray alloc] initWithObjects: destination, nil];
    NSDictionary* options = [[NSDictionary alloc] initWithObjectsAndKeys:
                                 MKLaunchOptionsDirectionsModeDriving, 
                                 MKLaunchOptionsDirectionsModeKey, nil];
    [MKMapItem openMapsWithItems: items launchOptions: options];

Чтобы поддерживать iOS 6+ и pre iOS 6 в одном и том же коде, я бы рекомендовал использовать что-то вроде этого кода, который есть у Apple на странице документа API MKMapItem:

Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
   // iOS 6 MKMapItem available
} else {
   // use pre iOS 6 technique
}

Это предполагает, что ваш Xcode Base SDK является iOS 6 (или Последняя версия iOS ).

21 голосов
/ 01 декабря 2010
NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=Current Location&saddr=%@",startAddr];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
[url release];

Это работает, но только когда язык iPhone / iPod установлен на английском языке. Если вы хотите поддерживать другие языки, вам придется использовать локализованную строку, чтобы соответствовать имени закладки Карты.

11 голосов
/ 01 ноября 2010
10 голосов
/ 30 сентября 2012

Вы можете использовать препроцессор #define, например:

#define SYSTEM_VERSION_LESS_THAN(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

, чтобы понять вашу версию iOS. Затем я могу использовать этот код для поддержки iOS 6:

NSString* addr = nil;
if (SYSTEM_VERSION_LESS_THAN(@"6.0")) {
   addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
} else {
   addr = [NSString stringWithFormat:@"http://maps.apple.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
}

NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
5 голосов
/ 23 февраля 2009

Из-за изолированной среды у вас нет доступа к закладкам приложения Map.

Вместо этого используйте Базовое местоположение, чтобы определить текущее местоположение самостоятельно. Затем используйте это местоположение (лат и лонг) в URL-адресе, который вы создаете, чтобы открыть Карты.

4 голосов
/ 07 сентября 2013

Я рекомендую проверить CMMapLauncher , мини-библиотеку, которую я создал для запуска Apple, Google и других приложений сопоставления iOS для конкретного запроса сопоставления. С CMMapLauncher код для получения направления в вашем вопросе будет:

[CMMapLauncher launchMapApp:CMMapAppAppleMaps
          forDirectionsFrom:[CMMapPoint mapPointWithName:@"Origin"
                                              coordinate:myLatLong]
                         to:[CMMapPoint mapPointWithName:@"Destination"
                                              coordinate:latlong]];

Как вы видите, он также инкапсулирует проверку версии, требуемую между iOS 6 и другими.

3 голосов
/ 21 сентября 2012

Привет, поскольку iOS6 вышел!

Apple сделала что-то замечательное в плохом смысле (с моей точки зрения).

Карты Apple запущены, и для устройств под управлением iOS 6 не следует использовать maps.google.com/?q=, если вы хотите, чтобы iDevice открывал собственное приложение Plan. Теперь это будет maps.apple.com/?q=.

Чтобы разработчикам не нужно было много работать, дружественный сервер maps.apple.com перенаправляет все устройства, не принадлежащие Apple, на maps.google.com, поэтому изменение становится прозрачным.

Таким образом, мы, разработчики, просто должны переключить все строки запросов Google на яблочные. Это то, что мне очень не нравится.

Мне пришлось реализовать эту функциональность сегодня, поэтому я и сделал это. Но я чувствовал, что мне не следует просто переписывать каждый URL, лежащий на мобильном веб-сайте, на целевой сервер карт Apple, поэтому я подумал, что я просто обнаружу серверную часть iDevices и предоставлю URL-адреса яблок только для них. Я думал, что поделюсь.

Я использую PHP, поэтому я использовал библиотеку Mobile Detect с открытым исходным кодом: http://code.google.com/p/php-mobile-detect/

Просто используйте псевдо-метод isiPad в качестве логического метода получения, и все готово, вы не конвертируете Google в яблоко; -)

$server=$detect->isiPad()?"apple":"google";
$href="http://maps.{$server}.com/?q=..."

Ура!

2 голосов
/ 06 декабря 2012

Если вы не хотите запрашивать разрешения на местоположение и у вас нет лат и lng, используйте следующее.

NSString *destinationAddress = @"Amsterdam";

Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:destinationAddress completionHandler:^(NSArray *placemarks, NSError *error) {
        if([placemarks count] > 0) {

            MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];

            MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];

            MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];


            NSArray *mapItems = @[mapItem, mapItem2];

            NSDictionary *options = @{
        MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
        MKLaunchOptionsMapTypeKey:
            [NSNumber numberWithInteger:MKMapTypeStandard],
        MKLaunchOptionsShowsTrafficKey:@YES
            };

            [MKMapItem openMapsWithItems:mapItems launchOptions:options];

        } else {
            //error nothing found
        }
    }];
    return;
} else {

    NSString *sourceAddress = [LocalizedCurrentLocation currentLocationStringForCurrentLanguage];

    NSString *urlToOpen = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%@&daddr=%@",
                 [sourceAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                 [destinationAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

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

Для ios5 текущее местоположение должно быть на правильном языке. Я использую LocalizedCurrentLocation из этого поста http://www.martip.net/blog/localized-current-location-string-for-iphone-apps

Для ios6 я использую CLGeocoder, чтобы получить метку, а затем открываю карту с ней и текущим местоположением.

Не забудьте добавить CoreLocation.framework и MapKit.framework

2 голосов
/ 20 сентября 2012

В iOS6 Apple Docs рекомендует использовать эквивалентную схему URL maps.apple.com

, поэтому используйте

http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f

вместо

http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f

для обратной совместимости код будет

    NSString* versionNum = [[UIDevice currentDevice] systemVersion];
    NSString *nativeMapScheme = @"maps.apple.com";
    if ([versionNum compare:@"6.0" options:NSNumericSearch] == NSOrderedAscending)
        nativeMapScheme = @"maps.google.com";
    }
    NSString* url = [NSString stringWithFormat: @"http://%@/maps?saddr=%f,%f&daddr=%f,%f", nativeMapScheme
             startCoordinate.latitude, startCoordinate.longitude,
             endCoordinate.latitude, endCoordinate.longitude];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];

Для схемы URL-адресов Apple Maps существует множество других поддерживаемых параметров: Справочник по схемам URL-адресов Apple

вы можете использовать эти макросы определения версии iOS, если у вас есть условный код в других частях вашего кода. Макросы для iOS

2 голосов
/ 02 июня 2012

Настоящее решение можно найти здесь. Фрагмент кода разработки для Z5 Фрагмент кода iOS

Требуется немного кодирования.

- (IBAction)directions1_click:(id)sender
{
    NSString* address = @"118 Your Address., City, State, ZIPCODE";
    NSString* currentLocation = @"Current Location";
    NSString* url = [NSStringstringWithFormat: @"http://maps.google.com/maps?saddr=%@&daddr=%@",[currentLocation stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    UIApplication *app = [UIApplicationsharedApplication];
    [app openURL: [NSURL URLWithString: url]];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...