14

Géolocalisation avec le MapKit

Le SDK fournit à l’utilisateur un ensemble de classes utilisant les coordonnées de géolocalisation et manipulant des cartes. Tous ces outils sont regroupés au sein d’un framework, le MapKit. À partir de la version iOS 6, le système ne s’appuie plus sur les cartes fournies par Google, mais sur une cartographie développée conjointement par Apple et TomTom. Du fait du niveau d’abstraction apporté par le Framework iOS, le code reste identique. Seul les images satellites et la gestion des points d’intérêts est différente.

Le MapKit permet d’effectuer les opérations suivantes de façon conviviale.

1 Se déplacer et zoomer en utilisant la carte affichée à l’écran.

2 Placer des punaises (appelées annotations) sur une carte.

3 Localiser des éléments.

4 Superposer des éléments à la carte.

Le MapKit se présente comme un framework qu’on ajoute à son projet et qui est basé sur des cartes. Le SDK iOS fournit les interfaces présentant et manipulant ces cartes.

L’élément principal du framework est la classe MKMapView qui est une sous-classe de UIView. Les cartes à l’écran sont présentées sous forme soit de cartes standards, soit de vues satellite, soit de vues hybrides où la vue satellite se superpose à la carte standard. La région affichée est positionnée par l’utilisateur à l’aide des gestes habituels ou à l’aide des coordonnées GPS.

Les régions ainsi affichées se déforment légèrement, car l’échelle de présentation est donnée en degrés d’angle suivant la projection de Mercator. On peut aussi utiliser la classe MKMapRect qui manipule les coordonnées du rectangle affiché.

Zone affichée à l’écran (région)

La zone affichée à l’écran est appelée une région. Elle possède un centre (avec une longitude et une latitude), une largeur et une hauteur d’affichage. Cette hauteur s’allonge au fur et à mesure qu’on s’éloigne de l’équateur.

image

Figure 14–1 Une région dans le MapKit

Création d’un projet basé sur MapKit

On commence par créer un nouveau projet de type Empty Based auquel on ajoute un storyboard qu’on lie au projet comme dans les exemples précédents. (Vérifiez le bon fonctionnement de cet ensemble.)

Ajout du framework

Ajoutez le framework MapKit qui va nous apporter les classes nécessaires à notre projet.

Sélectionnez le projet dans la navigation à droite, puis l’onglet du canevas intitulé Build Phases.

Ouvrez la rubrique intitulée Link Binary With Libraries et en appuyant sur le signe +, ajoutez le framework MapKit.framework. Vous disposez d’un petit champ de recherche pour retrouver plus vite le framework dans la liste assez longue fournie par le SDK iOS. Placez le framework ajouté dans le groupe intitulé Frameworks prévu à cet effet.

Ajout d’une vue de type MKMapView

Ajoutez un nouveau fichier de type ViewController dans la partie navigation. Appelez-le RootViewController_iPhone. Dans le storyboard, ajoutez un nouveau ViewController, une barre d’outils (toolbar) en bas et une MapView.

Dans le fichier RootViewController_iPhone.h, déclarez une toolbar et une MapView de la façon suivante :

#import <UIKit/UIKit.h>

#import <MapKit/MapKit.h>

@interface RootViewController_iPhone : UIViewController

<MKMapViewDelegate> {

MKMapView *mapView;

UIToolbar *toolbar;

}

@property (nonatomic,strong) IBOutlet MKMapView *mapView;

@property (nonatomic,strong) IBOutlet UIToolbar *toolbar;

@end

Vous pouvez noter l’importation du nouveau framework MapKit qui donne accès à de nouvelles classes, dont la classe MKMapView qui nous intéresse plus particulièrement.

On peut aussi constater qu’on implémente le protocole <MKMapViewDelegate> pour répondre aux interactions avec la carte présentée à l’utilisateur.

Dans le fichier RootViewController_iPhone.m, synthétisez les valeurs.

#import "RootViewController_iPhone.h"

@implementation RootViewController_iPhone

#pragma mark - Propriétés

@synthesize mapView;

@synthesize toolbar;

…<Le reste du code reste inchangé>…

Revenez au storyboard. Associez le ViewController à la classe créée et, en sélectionnant le ViewController dans la partie navigation et l’inspecteur de connexions, associez la MapView et la toolbar à leurs outlets respectifs.

On obtient le résultat de la figure 14-2.

image

Figure 14–2 Le storyboard de notre application

Géolocalisation de la vue

Pour que la vue se positionne sur la localisation actuelle de l’utilisateur, ajoutez tout simplement un booléen dans la méthode viewDidLoad: du RootViewController_iPhone.m.

- (void)viewDidLoad

{

[super viewDidLoad];

self.mapView.showsUserLocation = YES; // Position de l’utilisateur

La localisation actuelle de l’utilisateur se matérialise alors à l’aide d’un point bleu à l’écran.

image

Figure 14–3 Géolocalisation de l’utilisateur

Dans le simulateur, en cas d’absence de localisation, les coordonnées GPS sont situées à Infinity Loop, le siège d’Apple, en Californie.

Positionnement de la région

On peut ajouter un nouveau bouton dans la toolbar située en bas de l’écran, pour repositionner la région, par exemple à l’emplacement de la tour Eiffel.

On crée un BarButtonItem, on le place dans un tableau d’objets et on associe ce tableau d’objets à la toolbar :

- (void)positionParis:(id)sender {

MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };

region.center.latitude = 48.8587 ; // Coordonnée de la tour Eiffel

region.center.longitude = 2.29461; // Coordonnée de la tour Eiffel

region.span.longitudeDelta = 0.01f;

region.span.latitudeDelta = 0.01f;

[self.mapView setRegion:region animated:YES];

}

- (void)viewDidLoad

{

[super viewDidLoad];

self.mapView.showsUserLocation = YES; // Position de l’utilisateur

UIBarButtonItem *boutonTour = [[UIBarButtonItem alloc]

initWithTitle:@"Paris"

style:UIBarButtonItemStyleBordered

target:self

action:@selector(positionParis:)];

NSArray *listeDesBoutons = [[NSArray alloc]

  initWithObjects:boutonTour, nil];

//

self.toolbar.items = listeDesBoutons;

Lorsque l’utilisateur clique sur le bouton intitulé Paris, la carte se repositionne avec une animation et se place au-dessus de la tour Eiffel en mode plan.

image

Figure 14–4 Modification des coordonnées de la région

Modification du style de carte

On peut, de la même façon, créer un nouveau bouton pour utiliser l’un ou l’autre des styles de vue : vue standard en mode plan, vue satellite ou vue hybride.

- (void)changerDeStyle:(id)sender {

if (mapView.mapType == MKMapTypeStandard)

mapView.mapType = MKMapTypeHybrid;

else

mapView.mapType = MKMapTypeStandard;

}

UIBarButtonItem *boutonStyle = [[UIBarButtonItem alloc]

  initWithTitle:@"Style"

  style:UIBarButtonItemStyleBordered

  target:self

action:@selector(changerDeStyle:)];

NSArray *listeDesBoutons = [[NSArray alloc]

  initWithObjects:boutonStyle, boutonTour, nil];

Modification de la valeur du zoom

Enfin, on peut modifier la valeur de zoom de la région, en proposant bien entendu de pincer la vue (pinch) pour zoomer manuellement sur la carte.

- (void)zoomer:(id)sender {

MKCoordinateRegion region =

MKCoordinateRegionMakeWithDistance

(self.mapView.centerCoordinate, 500, 500);

[self.mapView setRegion:region animated:NO];

}

UIBarButtonItem *boutonZoom = [[UIBarButtonItem alloc]

initWithTitle:@"Zoom"

style:UIBarButtonItemStyleBordered

target:self

action:@selector(zoomer:)];

NSArray *listeDesBoutons = [[NSArray alloc]

  initWithObjects:boutonZoom, boutonStyle,

  boutonTour, nil];

toolbar.items = listeDesBoutons;

Positionner une annotation

On peut positionner des annotations sur la carte, matérialisées par des punaises (ou par des images personnalisées). Si on utilise la classe d’annotation fournie par défaut, il est possible de préciser un titre et un sous-titre, et de positionner l’annotation sur la carte.

On peut également ajouter un bouton à l’annotation qui déclenche une action lorsque l’utilisateur clique dessus.

// Positionnement de la tour Eiffel

CLLocationCoordinate2D annotationCoord;

annotationCoord.latitude = 48.8587;

annotationCoord.longitude = 2.29461;

MKPointAnnotation *annotationPoint =

[[MKPointAnnotation alloc] init];

annotationPoint.coordinate = annotationCoord;

annotationPoint.title = @"Tour Eiffel";

annotationPoint.subtitle = @"Paris";

[self.mapViewaddAnnotation:annotationPoint];

Le résultat est visible sur la figure 14-5.

image

Figure 14–5 Projet terminé

Suivre le mouvement de l’utilisateur

Lorsque l’utilisateur se déplace, le GPS enregistre ses mouvements, mais il faut les transmettre à l’application. Pour cela, on doit s’assurer qu’on obtient bien la délégation de la MapView et qu’on implémente la méthode delegate de la façon suivante.

Pour obtenir la délégation de la MapView, on sélectionne la MapView dans le storyboard et on clique sur l’inspecteur de connexions. On relie alors le delegate au ViewController de la scène.

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(

MKUserLocation *)userLocation {

self.mapView.centerCoordinate =

userLocation.location.coordinate;

labelLatitude.text = [NSString stringWithFormat:@"lat. %.4f",

userLocation.coordinate.latitude];

labelLongitude.text = [NSString stringWithFormat:@"lon. %.4f",

userLocation.coordinate.longitude];

}

On récupère ici les coordonnées latitude et longitude du GPS et on les affiche sous forme de label.

Conclusion

Dans ce chapitre, nous avons vu comment mettre en place une MapView, la positionner et placer des annotations.

Nous avons également expliqué comment récupérer les informations de latitude et de longitude ramenées par le GPS des iPhone ou iPad.

Enfin, nous avons présenté comment ajouter un bouton dans la barre d’outils et comment modifier le zoom de positionnement.

Propriété de Marie Richie <FB1245387-C111754-prod@customers.feedbooks.com>