Navigation SDK זמין כרגע רק ללקוחות נבחרים. למידע נוסף, אפשר לפנות למחלקת המכירות.
עיצוב חדש של מפות יהיה זמין בקרוב בפלטפורמה של מפות Google. העדכון הזה בסגנון המפה כולל לוח צבעים חדש שמוגדר כברירת מחדל ושיפורים בחוויית השימוש במפות ובנוחות השימוש. כל סגנונות המפה יעודכנו באופן אוטומטי במרץ 2025. אפשר לקרוא מידע נוסף על זמינות ועל האפשרות להצטרף בשלב מוקדם יותר במאמר בנושא סגנון מפה חדש לפלטפורמה של מפות Google.
מדריך זה מאפשר לאפליקציה לקלוט ולהגיב למגוון אירועים המשתנים כשמשתמש מנווט לאורך המסלול. המדריך הזה לא עוסק בהגדרת מסלול, אלא רק בתגובה לאירועים לאורך המסלול.
סקירה
ערכת הניווט ב-SDK ל-iOS מספקת מאזינים המשויכים למיקום המשתמש ולתנאים לאורך המסלול, וכן נתונים חשובים על הזמן והמרחק. בבקר התצוגה של המפה, האפליקציה צריכה לאמץ את הפרוטוקולים עבור המאזינים הבאים: GMSRoadSnappedLocationProviderListener ו-GMSNavigatorListener.
ברשימה הזו מוצגות שיטות ההאזנה הזמינות לאירועי ניווט:
/*
* 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 עבור האזנה לאירוע.
/*
* 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
הצהרת תאימות לפרוטוקולים הנדרשים
לפני הטמעת שיטות הניווט, בקר התצוגה צריך לאמץ את הפרוטוקולים:
Swift
class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
עדכוני מיקום נדרשים כדי להציג את התקדמות המשתמש במפה.
המופע של location חושף את המאפיינים הבאים:
נכס מיקום
תיאור
גובה
הגובה הנוכחי.
coordinate.latitude
קואורדינטת הרוחב של הכביש הנוכחי.
coordinate.longitude
קואורדינטת קו האורך הנוכחית במצב אופליין.
קורס
הכיוון הנוכחי במעלות.
מהירות
המהירות הנוכחית.
חותמת זמן
התאריך והשעה של הקריאה הנוכחית.
כדי לקבל עדכוני מיקום רציפים, צריך להתקשר למספר mapView.roadSnappedLocationProvider.startUpdatingLocation ולהשתמש ב-GMSRoadSnappedLocationProviderListener על מנת לטפל באירוע didUpdateLocation.
האפליקציה משתמשת באירוע didArriveAtWaypoint כדי לזהות מתי הגעה ליעד. אפשר להמשיך את ההנחיה ולהתקדם לנקודת הציון הבאה על ידי קריאה ל-continueToNextDestination(), ואז הפעלה מחדש של ההנחיות. צריך להפעיל מחדש את ההנחיות באפליקציה אחרי ההתקשרות אל continueToNextDestination().
אחרי שמפעילים את האפליקציה continueToNextDestination, ל-ניווט אין יותר נתונים על היעד הקודם. אם רוצים לנתח מידע על קטע מסלול, צריך לאחזר אותו מהניווט לפני שמפעילים את continueToNextDestination().
הקוד לדוגמה הבא מציג שיטה לטיפול באירוע didArriveAtWaypoint:
Swift
Func navigator(_ navigator: GMSNavigator, didBeforeAt Waypoint:
GMSNavigationWaypoint) {print("You have been at: (waypoint.title)")
mapView.navigator?.continueToNextDestination()
mapView.navigator?.isGuidanceActive = true }
כדי לקבל התראה בכל פעם שהמסלול משתנה, צריך ליצור שיטה לטיפול באירוע navigatorDidChangeRoute. אפשר לגשת למסלול החדש באמצעות המאפיינים routeLegs ו-currentRouteLeg של GMSNavigator.
(void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The path
has changed."); }
מתקבלים עדכונים לגבי הזמן עד ליעד
כדי לקבל עדכוני זמן רציפים ליעד, צריך ליצור שיטה לטיפול באירוע didUpdateRemainingTime. הפרמטר time מספק את הזמן המשוער בשניות עד שמגיעים ליעד הבא.
Swift
Func navigator(_ navigator: GMSNavigator, didUpdateUpdateTime time:
TimeInterval) { Print("Time to next destination: (time)") }
Objective-C
(void)navigator:(GMSNavigator *)navigator
didUpdateUpdateTime:(NSTimeInterval)time { NSLog(@"Time to next
destination: %f", time); }
כדי להגדיר את השינוי המינימלי בזמן המשוער ליעד הבא, צריך להגדיר את המאפיין timeUpdateThreshold ב-GMSNavigator. הערך מצוין בשניות. אם המאפיין לא מוגדר, השירותים ישתמשו בערך ברירת המחדל של שנייה אחת.
Swift
navigator?.timeUpdateThreshold = 10
Objective-C
navigator.timeUpdateThreshold = 10;
מתקבלים עדכונים לגבי המרחק ליעד
על מנת לקבל עדכונים לגבי מרחק רציף ליעד, צריך ליצור שיטה לטיפול באירוע didUpdateRemainingDistance. הפרמטר distance מציג את המרחק המשוער במטרים אל היעד הבא.
Swift
unc navigator(_ navigator: GMSNavigator, didUpdateLeftDuration:
CLLocation לצבור) { Let miles = נוהג * 0.00062137 Print("מרחק אל היעד הבא: (miles) miles.") }
Objective-C
(EV)navigator:(GMSNavigator *)navigator
didUpdateDuration to:(CLLocationDuration)distance { double miles =
distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"מרחק to
היעד הבא: %.2f.", miles]); }
כדי לקבוע את השינוי המינימלי במרחק המשוער ליעד הבא, מגדירים את המאפיין distanceUpdateThreshold כ-GMSNavigator (הערך מצוין במטרים). אם המאפיין הזה לא מוגדר, השירותים ישתמשו בערך ברירת המחדל של מטר אחד.
Swift
navigator?.distanceUpdateThreshold = 100
Objective-C
navigator.distanceUpdateThreshold = 100;
קבלת עדכוני תנועה
כדי לקבל עדכונים שוטפים של זרימת התנועה במסלול הנותר, צריך ליצור שיטה לטיפול באירוע didUpdateDelayCategory. קריאה ל-delayCategoryToNextDestination מחזירה GMSNavigationDelayCategory שמספקת את הערך בין 0 ל-3. העדכונים בקטגוריה מבוססים על המיקום הנוכחי של המשתמש באפליקציה. אם נתוני התנועה לא זמינים, הפונקציה GMSNavigationDelayCategory מחזירה את הערך 0. המספרים 1-3 מציינים את העלייה בזרימה בין קל לכבד.
Swift
Func navigator(_ navigator: GMSNavigator, didUpdate pausedCategory:
GMSNavigationDelayCategory) { Print("Trafficflow to next destination:
(delayCategory)") }
Objective-C
(void)navigator:(GMSNavigator *)navigator
didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
NSLog(@"Traffic flow to next destination: %ld", (long)delayCategory); }
הנכס GMSNavigationDelayCategory חושף את רמות העיכוב הבאות:
קטגוריית העיכוב
תיאור
GMSNavigationDelayCategoryNoData
0 – לא זמין, אין נתונים לגבי תנועה או :
את המסלול.
GMSNavigationDelayCategoryHeavy
1 – כבד.
GMSNavigationDelayCategoryMedium
2 – בינוני.
GMSNavigationDelayCategoryLight
3 – בהיר.
מתקבלים עדכוני מהירות
כדי לקבל עדכונים כשנהג חורג מהמהירות המותרת, צריך ליצור שיטה לטיפול באירוע didUpdateSpeedingPercentage.
Swift
// Listener לטיפול באירועי מהירות. Func navigator( _ navigator:
GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) {
print("Speed is (percentageAboveLimit) מעל המגבלה.") }
Objective-C
// Listener to Care to find search events. - (void)navigator:(GMSNavigator
*)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit); }
שינוי מצב התאורה המוצע
כדי לקבל עדכונים לגבי שינויים משוערים בתאורה, צריך ליצור שיטה לטיפול באירוע didChangeSuggestedLightingMode.