In diesem Leitfaden erfahren Sie, wie Sie Ihre App so konfigurieren, dass sie auf eine Vielzahl von Ereignissen reagiert, die sich ändern, während sich ein Nutzer auf einer Route bewegt. In diesem Leitfaden wird nicht beschrieben, wie eine Route definiert wird, sondern nur, wie auf Ereignisse entlang einer Route reagiert wird.
Übersicht
Das Navigation SDK for iOS bietet Ihnen Listener, die mit dem Standort des Nutzers und den Bedingungen entlang der Route sowie wichtigen Zeit- und Entfernungsdaten verknüpft sind. Im View Controller der Karte muss Ihre App die Protokolle für diese Listener übernehmen: GMSRoadSnappedLocationProviderListener
und GMSNavigatorListener
.
In dieser Liste sind die Listenermethoden aufgeführt, die für Navigationsereignisse verfügbar sind:
GMSNavigatorListener.didArriveAtWaypoint
, wird ausgelöst, wenn ein Ziel erreicht wird.GMSNavigatorListener.navigatorDidChangeRoute
, wird ausgelöst, wenn sich die Route ändert.GMSNavigatorListener.didUpdateRemainingTime
, wird wiederholt aufgerufen, wenn sich die Zeit bis zum nächsten Ziel ändert, während die Navigation aktiv ist.GMSNavigatorListener.didUpdateRemainingDistance
, wird wiederholt aufgerufen, wenn sich die Entfernung zum nächsten Ziel ändert, während die Navigation aktiv ist.GMSNavigatorListener.didUpdateDelayCategory
: Wird aufgerufen, wenn sich die Verzögerungskategorie zum nächsten Ziel ändert, während die Navigation aktiv ist.GMSNavigatorListener.didChangeSuggestedLightingMode
: wird ausgelöst, wenn die geschätzten Lichtverhältnisse aktualisiert werden. Wenn es beispielsweise am aktuellen Standort des Nutzers dunkel wird, ändert sich die Beleuchtung.GMSNavigatorListener.didUpdateSpeedingPercentage
, wird ausgelöst, wenn der Fahrer die zulässige Höchstgeschwindigkeit überschreitet.GMSRoadSnappedLocationProviderListener.didUpdateLocation
, wird wiederholt aufgerufen, wenn sich der Standort des Nutzers ändert.
Code
Swift-Code für einen Ereignis-Listener ein- oder ausblenden
/* * 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) } }
Objective-C-Code für einen Ereignis-Listener ein- oder ausblenden
/* * 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
Konformität mit den erforderlichen Protokollen erklären
Bevor die Navigationsmethoden implementiert werden, muss der View Controller die folgenden Protokolle übernehmen:
class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
@interface ViewController () <GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener>
@end
Nachdem Sie die Navigationsprotokolle übernommen haben, legen Sie die Listener auf den Ansichtscontroller fest. Sie können der Methode viewDidLoad()
beispielsweise den folgenden Code hinzufügen.
mapView.navigator?.add(self) mapView.roadSnappedLocationProvider?.add(self)
[_mapView.navigator addListener:self]; [_mapView.roadSnappedLocationProvider
addListener:self];
Standortaktualisierungen erhalten oder beenden
Standortaktualisierungen sind erforderlich, um den Fortschritt des Nutzers auf der Karte anzuzeigen.
Die location
-Instanz stellt die folgenden Eigenschaften bereit:
Standort-Property | Beschreibung |
---|---|
Höhe | Aktuelle Höhe. |
coordinate.latitude | Aktuelle Breitengradkoordinate, die an Straßen ausgerichtet ist. |
coordinate.longitude | Aktuelle Längengradkoordinate, die an einer Straße angehängt ist. |
Kurs | Aktueller Kurs in Grad. |
speed | Aktuelle Geschwindigkeit. |
timestamp | Datum und Uhrzeit der aktuellen Messung. |
Wenn Sie kontinuierliche Standortaktualisierungen erhalten möchten, rufen Sie mapView.roadSnappedLocationProvider.startUpdatingLocation
auf und verwenden Sie GMSRoadSnappedLocationProviderListener
, um das Ereignis didUpdateLocation
zu verarbeiten.
Hier sehen Sie, wie startUpdatingLocation
aufgerufen wird:
mapView.roadSnappedLocationProvider.startUpdatingLocation()
[_mapView.roadSnappedLocationProvider startUpdatingLocation];
Im folgenden Code wird eine GMSRoadSnappedLocationProviderListener
erstellt, die das didUpdateLocation
-Ereignis verarbeitet.
func locationProvider(_ locationProvider: GMSRoadSnappedLocationProvider,
didUpdate location: CLLocation) { print("Location: \(location.description)") }
- (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider
didUpdateLocation:(CLLocation *)location { NSLog(@"Location: %@",
location.description); }
Wenn Sie Standortaktualisierungen erhalten möchten, während die App im Hintergrund ausgeführt wird, setzen Sie allowsBackgroundLocationUpdates
auf „true“:
mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = true
_mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = YES;
Ankunftsereignisse erkennen
Ihre App verwendet das Ereignis didArriveAtWaypoint
, um zu erkennen, wenn ein Ziel erreicht wurde. Sie können die Navigation fortsetzen und zum nächsten Wegpunkt wechseln, indem Sie continueToNextDestination()
drücken und dann die Navigation wieder aktivieren. Ihre App muss die Navigation nach dem Aufruf von continueToNextDestination()
wieder aktivieren.
Nachdem die App continueToNextDestination
aufgerufen hat, hat der Navigationsgerät keine Daten mehr zum vorherigen Ziel. Wenn Sie Informationen zu einem Streckenabschnitt analysieren möchten, müssen Sie diese vom Navigationssystem abrufen, bevor Sie continueToNextDestination()
aufrufen.
Das folgende Codebeispiel zeigt eine Methode zum Bearbeiten des didArriveAtWaypoint
-Ereignisses:
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; }
Updates zu Routenänderungen erhalten
Wenn Sie jedes Mal eine Benachrichtigung erhalten möchten, wenn sich die Route ändert, erstellen Sie eine Methode zum Bearbeiten des Ereignisses navigatorDidChangeRoute
. Sie können über die Attribute routeLegs
und currentRouteLeg
von GMSNavigator
auf die neue Route zugreifen.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has
changed.") }
- (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route
has changed."); }
Aktualisierungen zur voraussichtlichen Ankunftszeit erhalten
Wenn Sie kontinuierliche Updates zur Zeit bis zum Ziel erhalten möchten, erstellen Sie eine Methode zum Bearbeiten des Ereignisses didUpdateRemainingTime
. Der Parameter time
gibt die geschätzte Zeit in Sekunden bis zum Erreichen des nächsten Ziels an.
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); }
Wenn Sie die minimale Änderung der geschätzten Zeit bis zum nächsten Ziel festlegen möchten, legen Sie die Eigenschaft timeUpdateThreshold
auf GMSNavigator
fest. Der Wert wird in Sekunden angegeben. Wenn diese Property nicht festgelegt ist, verwenden die Dienste den Standardwert „1 Sekunde“.
navigator?.timeUpdateThreshold = 10
navigator.timeUpdateThreshold = 10;
Aktualisierungen der Entfernung zum Ziel erhalten
Wenn Sie kontinuierliche Aktualisierungen der Entfernung zum Ziel erhalten möchten, erstellen Sie eine Methode zum Bearbeiten des Ereignisses didUpdateRemainingDistance
. Der Parameter distance
gibt die geschätzte Entfernung in Metern zum nächsten Ziel an.
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]); }
Wenn Sie die minimale Änderung der geschätzten Entfernung zum nächsten Ziel festlegen möchten, legen Sie die Property distanceUpdateThreshold
auf GMSNavigator
fest. Der Wert wird in Metern angegeben. Wenn diese Eigenschaft nicht festgelegt ist, verwenden die Dienste den Standardwert „1 Meter“.
navigator?.distanceUpdateThreshold = 100
navigator.distanceUpdateThreshold = 100;
Verkehrsinformationen erhalten
Wenn Sie kontinuierliche Updates des Verkehrsflusses für die verbleibende Route erhalten möchten, erstellen Sie eine Methode zum Bearbeiten des didUpdateDelayCategory
-Ereignisses. Ein Aufruf von delayCategoryToNextDestination
gibt GMSNavigationDelayCategory
zurück, der einen Wert von 0 bis 3 liefert. Aktualisierungen der Kategorie basieren auf der aktuellen Position des App-Nutzers. Wenn keine Zugriffsdaten verfügbar sind, wird für GMSNavigationDelayCategory
der Wert 0 zurückgegeben. Die Zahlen 1–3 geben den zunehmenden Fluss von leicht nach stark an.
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); }
Die GMSNavigationDelayCategory
-Eigenschaft gibt die folgenden Verzögerungsstufen an:
Verzögerungskategorie | Beschreibung |
---|---|
GMSNavigationDelayCategoryNoData | 0 – Nicht verfügbar, keine Daten für den Traffic oder : |
der Route. | |
GMSNavigationDelayCategoryHeavy | 1 – Schwer. |
GMSNavigationDelayCategoryMedium | 2 – Mittel. |
GMSNavigationDelayCategoryLight | 3 – Leuchtend |
Geschwindigkeitswarnungen erhalten
Wenn Sie Updates erhalten möchten, wenn ein Fahrer das Tempolimit überschreitet, erstellen Sie eine Methode zum Verarbeiten des didUpdateSpeedingPercentage
-Ereignisses.
// 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); }
Vorgeschlagenen Beleuchtungsmodus ändern
Wenn Sie Updates zu den geschätzten Änderungen der Beleuchtung erhalten möchten, erstellen Sie eine Methode zum Bearbeiten des Ereignisses 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; }