Tạo kiểu bản đồ mới sắp xuất hiện trên Nền tảng Google Maps. Bản cập nhật này để tạo kiểu bản đồ bao gồm một bảng màu mặc định mới và các cải tiến về trải nghiệm bản đồ cũng như khả năng hữu dụng. Tất cả kiểu bản đồ sẽ được cập nhật tự động vào tháng 3 năm 2025. Để biết thêm thông tin về phạm vi cung cấp và cách chọn tham gia sớm hơn, hãy xem bài viết Kiểu bản đồ mới cho Nền tảng Google Maps.
Hãy dùng hướng dẫn này để cho phép ứng dụng của bạn nghe và phản hồi nhiều sự kiện
sự thay đổi đó khi người dùng di chuyển dọc theo một tuyến đường. Hướng dẫn này không bao gồm
xác định một tuyến đường, chỉ phản hồi các sự kiện dọc theo một tuyến đường.
Tổng quan
SDK điều hướng dành cho iOS cung cấp cho bạn trình nghe
được liên kết với vị trí của người dùng và các điều kiện dọc theo tuyến đường và
dữ liệu quan trọng về thời gian và khoảng cách. Trên trình điều khiển chế độ xem của bản đồ, ứng dụng của bạn
cần phải áp dụng giao thức cho những trình nghe này:
GMSRoadSnappedLocationProviderListener
và
GMSNavigatorListener.
Danh sách này cho biết các phương thức trình nghe có sẵn cho sự kiện điều hướng:
/*
* 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)
}
}
Hiện/ẩn mã Target-C cho một trình nghe sự kiện.
/*
* 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
Khai báo tuân thủ các giao thức bắt buộc
Trước khi triển khai các phương thức điều hướng, trình điều khiển chế độ xem phải áp dụng
giao thức:
Swift
class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
Bạn cần cập nhật vị trí để hiển thị tiến trình của người dùng trên bản đồ.
Thực thể location hiển thị các thuộc tính sau:
Thuộc tính vị trí
Mô tả
độ cao
Cao độ hiện tại.
coordinate.latitude
Toạ độ theo vĩ độ hiện tại của đường.
coordinate.longitude
Toạ độ theo kinh độ hiện tại trên đường đã xác định.
khoá học
Góc phương vị hiện tại tính bằng độ.
tốc độ
Tốc độ hiện tại.
dấu thời gian
Ngày/giờ của lần đọc hiện tại.
Để liên tục nhận thông tin cập nhật vị trí, hãy gọi
mapView.roadSnappedLocationProvider.startUpdatingLocation và sử dụng
GMSRoadSnappedLocationProviderListener để xử lý didUpdateLocation
sự kiện.
Ví dụ sau đây cho thấy cách gọi startUpdatingLocation:
Ứng dụng của bạn dùng sự kiện didArriveAtWaypoint để phát hiện thời điểm một đích đến có
. Bạn có thể tiếp tục hướng dẫn và chuyển đến điểm tham chiếu tiếp theo bằng cách
gọi continueToNextDestination(), sau đó bật lại hướng dẫn. Ứng dụng của bạn
phải bật lại hướng dẫn sau khi gọi continueToNextDestination().
Sau khi ứng dụng gọi continueToNextDestination, trình điều hướng không còn
dữ liệu về đích đến trước đó. Nếu muốn phân tích thông tin về một
chặng đi, bạn phải truy xuất chặng này từ trình điều hướng trước khi gọi
continueToNextDestination().
Ví dụ về mã sau đây cho thấy một phương thức để xử lý didArriveAtWaypoint
sự kiện:
Đang nhận thông tin cập nhật về việc thay đổi tuyến đường
Để nhận thông báo mỗi khi tuyến đường thay đổi, hãy tạo một phương thức để
xử lý sự kiện navigatorDidChangeRoute. Bạn có thể truy cập tuyến đường mới bằng cách
bằng cách sử dụng thuộc tính routeLegs và currentRouteLeg của GMSNavigator.
Swift
func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has
changed.") }
Objective-C
- (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route
has changed."); }
Nhận thông tin cập nhật về thời gian tới điểm đến
Để nhận được thông tin cập nhật liên tục về điểm đến, hãy tạo một phương thức để xử lý
Sự kiện didUpdateRemainingTime. Tham số time cung cấp giá trị ước tính
tính bằng giây cho đến khi đạt được điểm đến tiếp theo.
Swift
func navigator(_ navigator: GMSNavigator, didUpdateRemainingTime time:
TimeInterval) { print("Time to next destination: \(time)") }
Objective-C
- (void)navigator:(GMSNavigator *)navigator
didUpdateRemainingTime:(NSTimeInterval)time { NSLog(@"Time to next
destination: %f", time); }
Để đặt thay đổi tối thiểu về thời gian dự kiến cho điểm đến tiếp theo, hãy đặt giá trị
Tài sản timeUpdateThreshold trên GMSNavigator. Giá trị được chỉ định trong
giây. Nếu bạn không đặt thuộc tính này, các dịch vụ sẽ sử dụng giá trị mặc định là 1
giây.
Swift
navigator?.timeUpdateThreshold = 10
Objective-C
navigator.timeUpdateThreshold = 10;
Đang nhận thông tin cập nhật về khoảng cách tới điểm đến
Để nhận thông tin cập nhật về quãng đường liên tục đến điểm đến, hãy tạo một phương thức để xử lý
sự kiện didUpdateRemainingDistance. Tham số distance cung cấp
khoảng cách ước tính (tính bằng mét) tới điểm đến tiếp theo.
Swift
func navigator(_ navigator: GMSNavigator, didUpdateRemainingDistance distance:
CLLocationDistance) { let miles = distance * 0.00062137 print("Distance to next
destination: \(miles) miles.") }
Objective-C
- (void)navigator:(GMSNavigator *)navigator
didUpdateRemainingDistance:(CLLocationDistance)distance { double miles =
distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"Distance to
next destination: %.2f.", miles]); }
Để đặt thay đổi tối thiểu về khoảng cách ước tính đến điểm đến tiếp theo, hãy đặt
Thuộc tính distanceUpdateThreshold trên GMSNavigator (giá trị được chỉ định trong
mét). Nếu bạn không đặt thuộc tính này, các dịch vụ sẽ sử dụng giá trị mặc định là 1
định mức.
Swift
navigator?.distanceUpdateThreshold = 100
Objective-C
navigator.distanceUpdateThreshold = 100;
Đang nhận thông tin cập nhật về lưu lượng truy cập
Để nhận được thông tin cập nhật liên tục về luồng giao thông cho tuyến đường còn lại,
tạo một phương thức để xử lý sự kiện didUpdateDelayCategory. Cuộc gọi đến
delayCategoryToNextDestination trả về GMSNavigationDelayCategory
cung cấp giá trị từ 0 đến 3. Nội dung cập nhật cho danh mục dựa trên dữ liệu hiện tại
vị trí của người dùng ứng dụng. Nếu không có dữ liệu lưu lượng truy cập,
GMSNavigationDelayCategory trả về 0. Các con số, từ 1 đến 3, cho biết mức tăng
chuyển từ nhẹ đến to.
Swift
func navigator(_ navigator: GMSNavigator, didUpdate delayCategory:
GMSNavigationDelayCategory) { print("Traffic flow to next destination:
\(delayCategory)") }
Objective-C
- (void)navigator:(GMSNavigator *)navigator
didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
NSLog(@"Traffic flow to next destination: %ld", (long)delayCategory); }
Thuộc tính GMSNavigationDelayCategory đưa ra các mức độ trễ sau đây:
Danh mục độ trễ
Mô tả
GMSNavigationDelayCategoryNoData
0 – Không có sẵn, không có dữ liệu về lưu lượng truy cập hoặc :
tuyến đường đó.
GMSNavigationDelayCategoryHeavy
1 – Nhiều.
GMSNavigationDelayCategoryMedium
2 – Trung bình.
GMSNavigationDelayCategoryLight
3 – Ít.
Đang nhận bản cập nhật tốc độ
Để nhận thông tin cập nhật khi người lái xe vượt quá giới hạn tốc độ, hãy tạo một phương thức
để xử lý sự kiện didUpdateSpeedingPercentage.
Swift
// Listener to handle speeding events. func navigator( _ navigator:
GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) {
print("Speed is \(percentageAboveLimit) above the limit.") }
Objective-C
// Listener to handle speeding events. - (void)navigator:(GMSNavigator
*)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit); }
Thay đổi chế độ ánh sáng đề xuất
Để nhận thông tin cập nhật về những thay đổi ước tính về ánh sáng, hãy tạo một phương thức để xử lý
sự kiện didChangeSuggestedLightingMode.
Swift
// 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 }
Objective-C
// 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; }