Utilisez ce guide pour permettre à votre application d'écouter et de répondre à divers événements qui changent à mesure qu'un utilisateur parcourt un itinéraire. Ce guide ne traite pas de la définition d'un parcours, mais uniquement de la réponse aux événements le long d'un parcours.
Présentation
Le SDK Navigation pour iOS vous fournit des écouteurs associés à la position de l'utilisateur et aux conditions sur l'itinéraire, ainsi que des données importantes sur le temps et la distance. Sur le contrôleur de vue de la carte, votre application doit adopter les protocoles pour ces écouteurs : GMSRoadSnappedLocationProviderListener
et GMSNavigatorListener
.
Cette liste présente les méthodes d'écouteur disponibles pour les événements de navigation:
GMSNavigatorListener.didArriveAtWaypoint
, déclenché lorsqu'une destination est atteinte.GMSNavigatorListener.navigatorDidChangeRoute
, déclenché lorsque l'itinéraire change.GMSNavigatorListener.didUpdateRemainingTime
, appelé à plusieurs reprises lorsque le temps de trajet vers la prochaine destination change, lorsque les instructions sont actives.GMSNavigatorListener.didUpdateRemainingDistance
, appelé à plusieurs reprises lorsque la distance à la destination suivante change, lorsque les instructions sont actives.GMSNavigatorListener.didUpdateDelayCategory
, appelé lorsque la catégorie de retard vers la destination suivante change, lorsque les instructions sont actives.GMSNavigatorListener.didChangeSuggestedLightingMode
, déclenché lorsque les conditions d'éclairage estimées sont mises à jour. Par exemple, lorsque la nuit tombe à l'emplacement actuel de l'utilisateur, l'éclairage change.GMSNavigatorListener.didUpdateSpeedingPercentage
, déclenché lorsque le conducteur dépasse la limite de vitesse.GMSRoadSnappedLocationProviderListener.didUpdateLocation
, appelé à plusieurs reprises lorsque l'emplacement de l'utilisateur change.
Voir le code
Afficher/Masquer le code Swift pour un écouteur d'événements
/* * Copyright 2020 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import GoogleNavigation import UIKit class ViewController: UIViewController, GMSNavigatorListener, GMSRoadSnappedLocationProviderListener { var mapView: GMSMapView! var locationManager: CLLocationManager! override func loadView() { locationManager = CLLocationManager() let camera = GMSCameraPosition.camera(withLatitude: 47.67, longitude: -122.20, zoom: 14) mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera) // Add listeners for GMSNavigator and GMSRoadSnappedLocationProvider. mapView.navigator?.add(self) mapView.roadSnappedLocationProvider?.add(self) // Set the time update threshold (seconds) and distance update threshold (meters). mapView.navigator?.timeUpdateThreshold = 10 mapView.navigator?.distanceUpdateThreshold = 100 // Show the terms and conditions. let companyName = "Ride Sharing Co." GMSNavigationServices.showTermsAndConditionsDialogIfNeeded( withCompanyName: companyName ) { termsAccepted in if termsAccepted { // Enable navigation if the user accepts the terms. self.mapView.isNavigationEnabled = true // Request authorization to use location services. self.locationManager.requestAlwaysAuthorization() // Request authorization for alert notifications which deliver guidance instructions // in the background. UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { granted, error in // Handle denied authorization to display notifications. if !granted || error != nil { print("Authorization to deliver notifications was rejected.") } } } else { // Handle the case when the user rejects the terms and conditions. } } view = mapView makeButton() } // Create a route and start guidance. @objc func startNav() { var destinations = [GMSNavigationWaypoint]() destinations.append( GMSNavigationWaypoint.init( placeID: "ChIJnUYTpNASkFQR_gSty5kyoUk", title: "PCC Natural Market")!) destinations.append( GMSNavigationWaypoint.init( placeID: "ChIJJ326ROcSkFQRBfUzOL2DSbo", title: "Marina Park")!) mapView.navigator?.setDestinations(destinations) { routeStatus in guard routeStatus == .OK else { print("Handle route statuses that are not OK.") return } self.mapView.navigator?.isGuidanceActive = true self.mapView.cameraMode = .following self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute() } mapView.roadSnappedLocationProvider?.startUpdatingLocation() } // Listener to handle continuous location updates. func locationProvider( _ locationProvider: GMSRoadSnappedLocationProvider, didUpdate location: CLLocation ) { print("Location: \(location.description)") } // Listener to handle speeding events. func navigator( _ navigator: GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) { print("Speed is \(percentageAboveLimit) above the limit.") } // Listener to handle arrival events. func navigator(_ navigator: GMSNavigator, didArriveAt waypoint: GMSNavigationWaypoint) { print("You have arrived at: \(waypoint.title)") mapView.navigator?.continueToNextDestination() mapView.navigator?.isGuidanceActive = true } // Listener for route change events. func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has changed.") } // Listener for time to next destination. func navigator(_ navigator: GMSNavigator, didUpdateRemainingTime time: TimeInterval) { print("Time to next destination: \(time)") } // Delegate for distance to next destination. func navigator( _ navigator: GMSNavigator, didUpdateRemainingDistance distance: CLLocationDistance ) { let miles = distance * 0.00062137 print("Distance to next destination: \(miles) miles.") } // Delegate for traffic updates to next destination func navigator( _ navigator: GMSNavigator, didUpdate delayCategory: GMSNavigationDelayCategory ) { print("Delay category to next destination: \(String(describing: delayCategory)).") } // Delegate for suggested lighting mode changes. func navigator( _ navigator: GMSNavigator, didChangeSuggestedLightingMode lightingMode: GMSNavigationLightingMode ) { print("Suggested lighting mode has changed: \(String(describing: lightingMode))") // Change to the suggested lighting mode. mapView.lightingMode = lightingMode } // Add a button to the view. func makeButton() { // Start navigation. let navButton = UIButton(frame: CGRect(x: 5, y: 150, width: 200, height: 35)) navButton.backgroundColor = .blue navButton.alpha = 0.5 navButton.setTitle("Start navigation", for: .normal) navButton.addTarget(self, action: #selector(startNav), for: .touchUpInside) self.mapView.addSubview(navButton) } }
Afficher/Masquer le code Objective-C d'un écouteur d'événements
/* * Copyright 2020 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "ViewController.h" @import GoogleNavigation; @interface ViewController () <GMSNavigatorListener, GMSRoadSnappedLocationProviderListener> @end @implementation ViewController { GMSMapView *_mapView; CLLocationManager *_locationManager; } - (void)loadView { _locationManager = [[CLLocationManager alloc] init]; GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:47.67 longitude:-122.20 zoom:14]; _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; // Add listeners for GMSNavigator and GMSRoadSnappedLocationProvider. [_mapView.navigator addListener:self]; [_mapView.roadSnappedLocationProvider addListener:self]; // Set the time update threshold (seconds) and distance update threshold (meters). _mapView.navigator.timeUpdateThreshold = 10; _mapView.navigator.distanceUpdateThreshold = 100; // Show the terms and conditions. NSString *companyName = @"Ride Sharing Co."; [GMSNavigationServices showTermsAndConditionsDialogIfNeededWithCompanyName:companyName callback:^(BOOL termsAccepted) { if (termsAccepted) { // Enable navigation if the user accepts the terms. _mapView.navigationEnabled = YES; // Request authorization to use location services. [_locationManager requestAlwaysAuthorization]; } else { // Handle the case when the user rejects the terms and conditions. } }]; self.view = _mapView; [self makeButton]; } // Create a route and initiate navigation. - (void)startNav { NSArray<GMSNavigationWaypoint *> *destinations = @[[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJnUYTpNASkFQR_gSty5kyoUk" title:@"PCC Natural Market"], [[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJJ326ROcSkFQRBfUzOL2DSbo" title:@"Marina Park"]]; [_mapView.navigator setDestinations:destinations callback:^(GMSRouteStatus routeStatus){ _mapView.navigator.guidanceActive = YES; _mapView.navigator.sendsBackgroundNotifications = YES; _mapView.cameraMode = GMSNavigationCameraModeFollowing; [_mapView.locationSimulator simulateLocationsAlongExistingRoute]; }]; [_mapView.roadSnappedLocationProvider startUpdatingLocation]; } #pragma mark - GMSNavigatorListener // Listener for continuous location updates. - (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider didUpdateLocation:(CLLocation *)location { NSLog(@"Location: %@", location.description); } // Listener to handle speeding events. - (void)navigator:(GMSNavigator *)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit { NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit); } // Listener to handle arrival events. - (void)navigator:(GMSNavigator *)navigator didArriveAtWaypoint:(GMSNavigationWaypoint *)waypoint { NSLog(@"You have arrived at: %@", waypoint.title); [_mapView.navigator continueToNextDestination]; _mapView.navigator.guidanceActive = YES; } // Listener for route change events. - (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route has changed."); } // Listener for time to next destination. - (void)navigator:(GMSNavigator *)navigator didUpdateRemainingTime:(NSTimeInterval)time { NSLog(@"Time to next destination: %f", time); } // Listener for distance to next destination. - (void)navigator:(GMSNavigator *)navigator didUpdateRemainingDistance:(CLLocationDistance)distance { double miles = distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"Distance to next destination: %.2f.", miles]); } // Listener for traffic updates for next destination - (void)navigator:(GMSNavigator *)navigator didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory { NSLog(@"Delay category to next destination: %ld.", delayCategory); } // Listener for suggested lighting mode changes. -(void)navigator:(GMSNavigator *)navigator didChangeSuggestedLightingMode:(GMSNavigationLightingMode)lightingMode { NSLog(@"Suggested lighting mode has changed: %ld", (long)lightingMode); // Change to the suggested lighting mode. _mapView.lightingMode = lightingMode; } #pragma mark - Programmatic UI elements // Add a button to the view. - (void)makeButton { // Start navigation. UIButton *navButton = [UIButton buttonWithType:UIButtonTypeCustom]; [navButton addTarget:self action:@selector(startNav) forControlEvents:UIControlEventTouchUpInside]; [navButton setTitle:@"Navigate" forState:UIControlStateNormal]; [navButton setBackgroundColor:[UIColor blueColor]]; [navButton setAlpha:0.5]; navButton.frame = CGRectMake(5.0, 150.0, 100.0, 35.0); [_mapView addSubview:navButton]; } @end
Déclarer la conformité aux protocoles requis
Avant d'implémenter les méthodes de navigation, le contrôleur de vue doit adopter les protocoles suivants:
class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
@interface ViewController () <GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener>
@end
Après avoir adopté les protocoles de navigation, définissez les écouteurs sur le contrôleur de vue. Par exemple, vous pouvez ajouter le code suivant à la méthode viewDidLoad()
.
mapView.navigator?.add(self) mapView.roadSnappedLocationProvider?.add(self)
[_mapView.navigator addListener:self]; [_mapView.roadSnappedLocationProvider
addListener:self];
Recevoir ou arrêter les mises à jour de la position géographique
Les mises à jour de position sont nécessaires pour afficher la progression de l'utilisateur sur la carte.
L'instance location
expose les propriétés suivantes:
Propriété de lieu | Description |
---|---|
altitude | Altitude actuelle. |
coordinate.latitude | Coordonnée de latitude actuelle avec alignement sur la route. |
coordinate.longitude | Coordonnée de longitude actuelle avec alignement sur la route. |
cours | Orientation actuelle en degrés. |
speed | Vitesse actuelle. |
timestamp | Date/Heure de la lecture en cours. |
Pour recevoir des mises à jour de position continues, appelez mapView.roadSnappedLocationProvider.startUpdatingLocation
et utilisez GMSRoadSnappedLocationProviderListener
pour gérer l'événement didUpdateLocation
.
L'exemple suivant vous montre comment appeler startUpdatingLocation
:
mapView.roadSnappedLocationProvider.startUpdatingLocation()
[_mapView.roadSnappedLocationProvider startUpdatingLocation];
Le code suivant crée un GMSRoadSnappedLocationProviderListener
qui gère l'événement didUpdateLocation
.
func locationProvider(_ locationProvider: GMSRoadSnappedLocationProvider,
didUpdate location: CLLocation) { print("Location: \(location.description)") }
- (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider
didUpdateLocation:(CLLocation *)location { NSLog(@"Location: %@",
location.description); }
Pour recevoir des mises à jour de position lorsque l'application est en arrière-plan, définissez allowsBackgroundLocationUpdates
sur "true" :
mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = true
_mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = YES;
Détecter les événements d'arrivée
Votre application utilise l'événement didArriveAtWaypoint
pour détecter quand une destination a été atteinte. Vous pouvez reprendre la navigation et passer au point de cheminement suivant en appelant continueToNextDestination()
, puis en réactivant la navigation. Votre application doit réactiver les instructions après avoir appelé continueToNextDestination()
.
Une fois que l'application a appelé continueToNextDestination
, le navigateur n'a plus de données sur la destination précédente. Si vous souhaitez analyser des informations sur un tronçon d'itinéraire, vous devez les récupérer auprès du navigateur avant d'appeler continueToNextDestination()
.
L'exemple de code suivant montre une méthode permettant de gérer l'événement didArriveAtWaypoint
:
func navigator(_ navigator: GMSNavigator, didArriveAt waypoint:
GMSNavigationWaypoint) { print("You have arrived at: \(waypoint.title)")
mapView.navigator?.continueToNextDestination()
mapView.navigator?.isGuidanceActive = true }
- (void)navigator:(GMSNavigator *)navigator
didArriveAtWaypoint:(GMSNavigationWaypoint *)waypoint { NSLog(@"You have
arrived at: %@", waypoint.title); [_mapView.navigator
continueToNextDestination]; _mapView.navigator.guidanceActive = YES; }
Recevoir des informations sur les modifications d'itinéraire
Pour recevoir une notification chaque fois que l'itinéraire est modifié, créez une méthode pour gérer l'événement navigatorDidChangeRoute
. Vous pouvez accéder au nouveau parcours à l'aide des propriétés routeLegs
et currentRouteLeg
de GMSNavigator
.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has
changed.") }
- (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route
has changed."); }
Recevoir des informations sur le temps de trajet
Pour recevoir des mises à jour continues du temps de trajet, créez une méthode pour gérer l'événement didUpdateRemainingTime
. Le paramètre time
fournit le temps estimé, en secondes, jusqu'à ce que la prochaine destination soit atteinte.
func navigator(_ navigator: GMSNavigator, didUpdateRemainingTime time:
TimeInterval) { print("Time to next destination: \(time)") }
- (void)navigator:(GMSNavigator *)navigator
didUpdateRemainingTime:(NSTimeInterval)time { NSLog(@"Time to next
destination: %f", time); }
Pour définir la variation minimale du temps estimé pour la destination suivante, définissez la propriété timeUpdateThreshold
sur GMSNavigator
. La valeur est spécifiée en secondes. Si cette propriété n'est pas définie, les services utilisent une valeur par défaut d'une seconde.
navigator?.timeUpdateThreshold = 10
navigator.timeUpdateThreshold = 10;
Recevoir des informations sur la distance à parcourir jusqu'à la destination
Pour recevoir des mises à jour continues de la distance à la destination, créez une méthode pour gérer l'événement didUpdateRemainingDistance
. Le paramètre distance
fournit la distance estimée, en mètres, jusqu'à la destination suivante.
func navigator(_ navigator: GMSNavigator, didUpdateRemainingDistance distance:
CLLocationDistance) { let miles = distance * 0.00062137 print("Distance to next
destination: \(miles) miles.") }
- (void)navigator:(GMSNavigator *)navigator
didUpdateRemainingDistance:(CLLocationDistance)distance { double miles =
distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"Distance to
next destination: %.2f.", miles]); }
Pour définir la variation minimale de la distance estimée jusqu'à la destination suivante, définissez la propriété distanceUpdateThreshold
sur GMSNavigator
(la valeur est spécifiée en mètres). Si cette propriété n'est pas définie, les services utilisent une valeur par défaut de 1 mètre.
navigator?.distanceUpdateThreshold = 100
navigator.distanceUpdateThreshold = 100;
Recevoir des informations sur le trafic
Pour recevoir des informations continues sur le trafic pour le reste du trajet, créez une méthode pour gérer l'événement didUpdateDelayCategory
. Un appel à delayCategoryToNextDestination
renvoie GMSNavigationDelayCategory
, qui fournit une valeur comprise entre 0 et 3. Les mises à jour de la catégorie sont basées sur la position actuelle de l'utilisateur de l'application. Si les données de trafic ne sont pas disponibles, GMSNavigationDelayCategory
renvoie 0. Les chiffres 1 à 3 indiquent l'intensité du flux, de faible à fort.
func navigator(_ navigator: GMSNavigator, didUpdate delayCategory:
GMSNavigationDelayCategory) { print("Traffic flow to next destination:
\(delayCategory)") }
- (void)navigator:(GMSNavigator *)navigator
didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
NSLog(@"Traffic flow to next destination: %ld", (long)delayCategory); }
La propriété GMSNavigationDelayCategory
expose les niveaux de retard suivants:
Catégorie de retard | Description |
---|---|
GMSNavigationDelayCategoryNoData | 0 : indisponible, aucune donnée sur le trafic ou : |
l'itinéraire. | |
GMSNavigationDelayCategoryHeavy | 1 : Fortes. |
GMSNavigationDelayCategoryMedium | 2 : Moyen. |
GMSNavigationDelayCategoryLight | 3 : Lumière. |
Recevoir des notifications de dépassement de la vitesse
Pour recevoir des mises à jour lorsqu'un conducteur dépasse la limite de vitesse, créez une méthode pour gérer l'événement didUpdateSpeedingPercentage
.
// Listener to handle speeding events. func navigator( _ navigator:
GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) {
print("Speed is \(percentageAboveLimit) above the limit.") }
// Listener to handle speeding events. - (void)navigator:(GMSNavigator
*)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit); }
Modifier le mode d'éclairage suggéré
Pour recevoir des informations sur les changements estimés de l'éclairage, créez une méthode pour gérer l'événement didChangeSuggestedLightingMode
.
// Define a listener for suggested changes to lighting mode. func navigator(_
navigator: GMSNavigator, didChangeSuggestedLightingMode lightingMode:
GMSNavigationLightingMode) { print("Suggested lighting mode has changed:
\(String(describing: lightingMode))")
// Make the suggested change. mapView.lightingMode = lightingMode }
// Define a listener for suggested changes to lighting mode.
-(void)navigator:(GMSNavigator *)navigator didChangeSuggestedLightingMode:
(GMSNavigationLightingMode)lightingMode { NSLog(@"Suggested lighting mode has
changed: %ld", (long)lightingMode);
// Make the suggested change. _mapView.lightingMode = lightingMode; }