/*
* 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 {