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é.
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.
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.)
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.
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.
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.
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.
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.
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];
…
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;
…
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.
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.
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>