Gunakan panduan ini untuk memungkinkan aplikasi Anda memproses dan merespons berbagai peristiwa yang berubah saat pengguna menavigasi di sepanjang rute. Panduan ini tidak membahas menentukan rute, hanya merespons peristiwa di sepanjang rute.
Ringkasan
Navigation SDK for iOS memberi Anda pemroses yang terkait dengan lokasi pengguna dan kondisi di sepanjang rute serta data waktu dan jarak yang penting. Pada pengontrol tampilan peta, aplikasi Anda
harus mengadopsi protokol untuk pemroses ini:
GMSRoadSnappedLocationProviderListener
dan
GMSNavigatorListener
.
Daftar ini menunjukkan metode pemroses yang tersedia untuk peristiwa navigasi:
GMSNavigatorListener.didArriveAtWaypoint
, terpicu saat tujuan tercapai.GMSNavigatorListener.navigatorDidChangeRoute
, terpicu saat rute berubah.GMSNavigatorListener.didUpdateRemainingTime
, dipanggil berulang kali saat waktu ke tujuan berikutnya berubah, saat panduan aktif.GMSNavigatorListener.didUpdateRemainingDistance
, dipanggil berulang kali saat jarak ke tujuan berikutnya berubah, saat panduan aktif.GMSNavigatorListener.didUpdateDelayCategory
, dipanggil saat kategori keterlambatan ke tujuan berikutnya berubah, saat panduan aktif.GMSNavigatorListener.didChangeSuggestedLightingMode
, terpicu saat perkiraan kondisi pencahayaan diperbarui. Misalnya, saat malam tiba di lokasi pengguna saat ini, pencahayaan akan berubah.GMSNavigatorListener.didUpdateSpeedingPercentage
, terpicu saat pengemudi melebihi batas kecepatan.GMSRoadSnappedLocationProviderListener.didUpdateLocation
, dipanggil berulang kali saat lokasi pengguna berubah.
Melihat kode
Tampilkan/Sembunyikan kode Swift untuk pemroses peristiwa.
/* * 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) } }
Menampilkan/Menyembunyikan kode Objective-C untuk pemroses peristiwa.
/* * 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
Mendeklarasikan kepatuhan terhadap protokol yang diperlukan
Sebelum menerapkan metode navigasi, pengontrol tampilan harus mengadopsi protokol:
class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
@interface ViewController () <GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener>
@end
Setelah mengadopsi protokol navigasi, tetapkan pemroses ke pengontrol
tampilan. Misalnya, Anda dapat menambahkan kode berikut ke metode
viewDidLoad()
.
mapView.navigator?.add(self) mapView.roadSnappedLocationProvider?.add(self)
[_mapView.navigator addListener:self]; [_mapView.roadSnappedLocationProvider
addListener:self];
Menerima atau menghentikan pembaruan lokasi
Pembaruan lokasi diperlukan untuk menampilkan progres pengguna di peta.
Instance location
mengekspos properti berikut:
Properti lokasi | Deskripsi |
---|---|
ketinggian | Ketinggian saat ini. |
coordinate.latitude | Koordinat lintang saat ini yang diambil dari jalan. |
coordinate.longitude | Koordinat bujur saat ini yang diambil dari jalan. |
kursus | Arah saat ini dalam derajat. |
kecepatan | Kecepatan saat ini. |
timestamp | Tanggal/waktu pembacaan saat ini. |
Untuk menerima pembaruan lokasi berkelanjutan, panggil
mapView.roadSnappedLocationProvider.startUpdatingLocation
, dan gunakan
GMSRoadSnappedLocationProviderListener
untuk menangani peristiwa
didUpdateLocation
.
Contoh berikut menunjukkan cara memanggil startUpdatingLocation
:
mapView.roadSnappedLocationProvider.startUpdatingLocation()
[_mapView.roadSnappedLocationProvider startUpdatingLocation];
Kode berikut membuat GMSRoadSnappedLocationProviderListener
yang
menangani peristiwa didUpdateLocation
.
func locationProvider(_ locationProvider: GMSRoadSnappedLocationProvider,
didUpdate location: CLLocation) { print("Location: \(location.description)") }
- (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider
didUpdateLocation:(CLLocation *)location { NSLog(@"Location: %@",
location.description); }
Untuk menerima pembaruan lokasi saat aplikasi berada di latar belakang, tetapkan
allowsBackgroundLocationUpdates
ke true:
mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = true
_mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = YES;
Mendeteksi peristiwa kedatangan
Aplikasi Anda menggunakan peristiwa didArriveAtWaypoint
untuk mendeteksi saat tujuan telah
tercapai. Anda dapat melanjutkan panduan dan melanjutkan ke titik jalan berikutnya dengan
memanggil continueToNextDestination()
, lalu mengaktifkan kembali panduan. Aplikasi Anda
harus mengaktifkan kembali panduan setelah memanggil continueToNextDestination()
.
Setelah aplikasi memanggil continueToNextDestination
, navigator tidak lagi memiliki
data tentang tujuan sebelumnya. Jika ingin menganalisis informasi tentang
segmen rute, Anda harus mengambilnya dari navigator sebelum memanggil
continueToNextDestination()
.
Contoh kode berikut menunjukkan metode untuk menangani peristiwa
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; }
Menerima info terbaru perubahan rute
Untuk menerima notifikasi setiap kali rute diubah, buat metode untuk
menangani peristiwa navigatorDidChangeRoute
. Anda dapat mengakses rute baru dengan
menggunakan properti routeLegs
dan currentRouteLeg
dari GMSNavigator
.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has
changed.") }
- (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route
has changed."); }
Menerima pembaruan waktu ke tujuan
Untuk menerima pembaruan waktu ke tujuan secara berkelanjutan, buat metode untuk menangani
peristiwa didUpdateRemainingTime
. Parameter time
memberikan estimasi
waktu, dalam detik, hingga tujuan berikutnya tercapai.
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); }
Untuk menetapkan perubahan minimum estimasi waktu ke tujuan berikutnya, tetapkan
properti timeUpdateThreshold
di GMSNavigator
. Nilainya ditentukan dalam
detik. Jika properti ini tidak ditetapkan, layanan akan menggunakan nilai default satu
detik.
navigator?.timeUpdateThreshold = 10
navigator.timeUpdateThreshold = 10;
Menerima pembaruan jarak ke tujuan
Untuk menerima pembaruan jarak ke tujuan secara berkelanjutan, buat metode untuk menangani
peristiwa didUpdateRemainingDistance
. Parameter distance
memberikan
perkiraan jarak, dalam meter, ke tujuan berikutnya.
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]); }
Untuk menetapkan perubahan minimum estimasi jarak ke tujuan berikutnya, tetapkan
properti distanceUpdateThreshold
di GMSNavigator
(nilai ditentukan dalam
meter). Jika properti ini tidak ditetapkan, layanan akan menggunakan nilai default satu
meter.
navigator?.distanceUpdateThreshold = 100
navigator.distanceUpdateThreshold = 100;
Menerima info lalu lintas terbaru
Untuk menerima pembaruan berkelanjutan tentang alur traffic untuk rute yang tersisa,
buat metode untuk menangani peristiwa didUpdateDelayCategory
. Panggilan ke
delayCategoryToNextDestination
menampilkan GMSNavigationDelayCategory
yang
memberikan nilai 0 hingga 3. Pembaruan pada kategori didasarkan pada posisi
pengguna aplikasi saat ini. Jika data traffic tidak tersedia,
GMSNavigationDelayCategory
akan menampilkan 0. Angka 1-3 menunjukkan peningkatan
aliran dari ringan ke berat.
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); }
Properti GMSNavigationDelayCategory
mengekspos tingkat penundaan berikut:
Kategori penundaan | Deskripsi |
---|---|
GMSNavigationDelayCategoryNoData | 0 - Tidak tersedia, tidak ada data untuk traffic atau : |
rute. | |
GMSNavigationDelayCategoryHeavy | 1 - Berat. |
GMSNavigationDelayCategoryMedium | 2 - Sedang. |
GMSNavigationDelayCategoryLight | 3 - Terang. |
Menerima info terbaru tentang kecepatan
Untuk menerima update saat pengemudi melebihi batas kecepatan, buat metode untuk menangani peristiwa 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); }
Mengubah mode pencahayaan yang disarankan
Untuk menerima update estimasi perubahan pencahayaan, buat metode untuk menangani
peristiwa 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; }