web-dev-qa-db-fra.com

Comment appeler des cartes iPhone pour les directions avec la position actuelle comme adresse de départ

Je sais qu'il est possible de démarrer l'application de cartes iPhone en appelant openURL sur une URL google maps avec les paramètres saddr et daddr avec des chaînes d'emplacement ou Lat/Long (voir l'exemple ci-dessous). 

Mais je me demande s’il est possible de faire en sorte que l’adresse de départ soit le signet "Emplacement actuel" maps afin que je puisse utiliser le code de traitement de l’emplacement Maps app. Ma recherche sur Google a été plutôt infructueuse.

Par exemple:

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

Sauf avec quelque chose à invoquer le signet d'emplacement actuel à la place de myLatLong.

72
eriaac

Pré iOS 6

Vous devez utiliser l’emplacement principal pour obtenir l’emplacement actuel, mais avec cette paire lat/long, vous pouvez obtenir des cartes qui vous dirigeront de là, à une adresse ou à un emplacement. Ainsi:

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]];

Enfin, si vous souhaitez éviter d'utiliser CoreLocation pour rechercher explicitement l'emplacement actuel et souhaitez plutôt utiliser l'URL @"http://maps.google.com/maps?saddr=Current+Location&daddr=%@", puis consultez le lien que j'ai fourni dans les commentaires ci-dessous pour savoir comment localiser Current + Location. chaîne. Cependant, vous tirez parti d'une autre fonctionnalité non documentée et, comme le souligne Jason McCreary ci-dessous, il est possible que cela ne fonctionne pas de manière fiable dans les versions ultérieures.


Mise à jour pour iOS 6

À l'origine, Maps utilisait Google Maps, mais Apple et Google disposent désormais d'applications de cartes distinctes. 

1) Si vous souhaitez router à l'aide de l'application Google Maps, utilisez le schéma d'URL de comgooglemaps :

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

2) Pour utiliser Apple Maps, vous pouvez utiliser la nouvelle classe MKMapItem pour iOS 6. Consultez la documentation Apple API ici

Fondamentalement, vous utiliserez quelque chose comme ceci, si le routage vers la destination coordonnées _ (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];

Afin de prendre en charge à la fois iOS 6+ et la version antérieure à iOS 6 dans le même code, je vous recommanderais d'utiliser un code similaire à celui d'Apple sur la page de documentation de l'API MKMapItem:

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

Cela supposerait que votre SDK Xcode Base est iOS 6 (ou Latest iOS).

133
Nate
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];

Cela fonctionne, mais uniquement lorsque la langue de l'iPhone/iPod est définie en anglais. Si vous souhaitez prendre en charge d'autres langues, vous devrez utiliser une chaîne localisée pour correspondre au nom du signet Maps.

21
Tchettane
11
bob

Vous pouvez utiliser un préprocesseur #define comme:

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

pour comprendre votre version d'iOS. Ensuite, je peux utiliser ce code pour prendre en charge 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];
10
TheInterestedOne

En raison de la mise en sandbox, vous n'avez pas accès aux signets de l'application Carte.

Utilisez plutôt Emplacement principal pour déterminer vous-même l'emplacement actuel. Utilisez ensuite cet emplacement (lat et long) dans l'URL que vous créez pour ouvrir Maps.

5
August

Je recommande de vérifier CMMapLauncher , une mini-bibliothèque que j'ai construite pour lancer Apple, Google et d'autres applications de cartographie iOS avec une demande de mappage spécifique. Avec CMMapLauncher, le code pour obtenir les instructions dans votre question serait:

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

Comme vous pouvez le constater, il intègre également la vérification de version requise entre iOS 6 et les autres.

4
Joe Hughes

Salut, iOS6 est sorti!

Apple a fait quelque chose de remarquable d'une mauvaise manière (de mon point de vue). 

Les cartes Apple sont lancées et pour les appareils exécutant iOS 6, vous ne devez pas utiliser maps.google.com/?q= si vous souhaitez que iDevice ouvre l'application native Plan. Maintenant ce serait maps.Apple.com/?q=.

Pour que les développeurs n'aient pas à travailler beaucoup, le serveur convivial maps.Apple.com redirige tous les appareils non Apple vers maps.google.com afin que le changement soit transparent.

De cette façon, nous, les développeurs, devons simplement passer toutes les chaînes de requête Google à celles d'Apple .. C'est ce que je n'aime pas beaucoup. 

Je devais mettre en œuvre cette fonctionnalité aujourd'hui, donc je l'ai fait. Mais j’ai pensé que je ne devrais pas simplement réécrire toutes les URL présentes sur le site Web mobile pour cibler le serveur de cartes d’Apple; Je pensais partager.

J'utilise PHP et j'ai donc utilisé la bibliothèque opensource Mobile Detect: http://code.google.com/p/php-mobile-detect/

Utilisez simplement la pseudo-méthode isiPad comme un getter booléen et vous avez terminé, vous ne convertirez pas Google en Apple ;-)

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

À votre santé!

3
Armel Larcier

La vraie solution peut être trouvée ici. Extrait de code de développement iOS pour Z5 Concepts

Cela nécessite juste un peu d'encodage.

- (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]];
}
2
Deege

Si vous ne souhaitez pas demander d'autorisations d'emplacement et que vous n'avez pas les lat et lng, utilisez ce qui suit.

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]];
}

Pour ios5, l'emplacement actuel doit être dans la langue correcte. J'utilise le LocalizedCurrentLocation de cet article http://www.martip.net/blog/localized-current-location-string-for-iphone-apps

Pour ios6, j'utilise le CLGeocoder pour obtenir le repère, puis ouvre la carte avec lui et l'emplacement actuel.

N'oubliez pas d'ajouter CoreLocation.framework et MapKit.framework

2
Roland Keesom

Pour iOS6, les documents Apple recommandent l'utilisation du schéma de mappage équivalent maps.Apple.com.

alors utilisez

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

au lieu de

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

pour être rétro-compatible le code serait

    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]];

de nombreux paramètres pris en charge pour le schéma d'URL Apple Maps: Référence du schéma d'URL Apple

vous pouvez utiliser ces macros de détection de version iOS si vous avez du code conditionnel dans d'autres parties de votre code. Macros de version iOS

2
joneswah

Vous pouvez le faire maintenant en HTML uniquement à partir d'une URL sur votre appareil mobile uniquement. Voici un exemple . Ce qui est cool, c’est que si vous transformez ce code en code QR, vous avez la possibilité d’obtenir un itinéraire pour vous, où que vous soyez, simplement en le scannant sur leur téléphone.

2
mal

Ma suggestion serait d'utiliser OpenInGoogleMaps-iOS puisqu'il s'agit d'un choix à jour (d'ici novembre 2015), il prend en charge l'installation de cosses de cacao et vous êtes prêt à partir en quelques clics.

Installer avec: pod "OpenInGoogleMaps"

Exiger dans le fichier d'en-tête à l'aide de: #import "OpenInGoogleMapsController.h"

Exemple de code ci-dessous:

/*In case the user does NOT have google maps, then Apple maps shall open*/
[OpenInGoogleMapsController sharedInstance].fallbackStrategy = kGoogleMapsFallbackAppleMaps;    

/*Set the coordinates*/
GoogleMapDefinition *definition = [[GoogleMapDefinition alloc] init];   
CLLocationCoordinate2D metsovoMuseumCoords;     //coordinates struct
metsovoMuseumCoords.latitude = 39.770598;
metsovoMuseumCoords.longitude = 21.183215;
definition.zoomLevel = 20;
definition.center = metsovoMuseumCoords;        //this will be the center of the map

/*and here we open the map*/
[[OpenInGoogleMapsController sharedInstance] openMap:definition];       
1
SudoPlz

Dans la version actuelle de Google Maps, omettez simplement le paramètre sadr:

saddr: ... Si la valeur est laissée en blanc, l'emplacement actuel de l'utilisateur sera utilisé. 

https://developers.google.com/maps/documentation/ios/urlscheme

1
user123444555621

Pour iOS6 Maps App, vous pouvez simplement utiliser la même URL publiée ci-dessus http://maps.google.com/maps?saddr=%f,%f&daddr=%@ 

mais au lieu de l'URL de Google Maps, vous utilisez l'URL avec maps://, ce qui donne l'URL suivante: maps://saddr=%f,%f&daddr=%@.

Utiliser "Emplacement actuel" ne semble pas fonctionner, alors je suis resté avec les coordonnées.

Une autre bonne chose: il est rétrocompatible: sur iOS5, il lance l'application Google Maps.

1
Jacco

J'ai répondu à cela sur un autre fil. ( L'emplacement actuel ne fonctionne pas avec Apple Maps IOS 6 ). Vous devez d’abord obtenir les coordonnées de l’emplacement actuel, puis l’utiliser pour créer l’URL de la carte. 

0
Xiaochen Du

Si vous ne fournissez pas l'emplacement source, il utilisera l'emplacement actuel comme source. Essayez ci-dessous code-

let urlString = " http://maps.Apple.com/maps?daddr=(destinationLocation.latitude),(destinationLocation.longitude)&dirflg=d " }

UIApplication.shared.openURL (URL (chaîne: urlString)!)

0
Vishwas Singh