Em breve, vamos lançar uma nova estilização de mapas na Plataforma Google Maps. Essa atualização da estilização de mapas inclui uma nova paleta de cores padrão e melhorias nas experiências e usabilidade dos mapas. Todos os estilos de mapa vão ser atualizados automaticamente em março de 2025. Para mais informações sobre disponibilidade e como ativar o recurso antes, consulte Novo estilo de mapa para a Plataforma Google Maps.
Use este guia para permitir que o app detecte e responda a vários eventos
que mudam conforme o usuário navega ao longo de um trajeto. Neste guia, não vamos abordar a definição de um trajeto, apenas responder aos eventos ao longo dele.
Visão geral
O SDK do Navigation para iOS oferece listeners associados à localização do usuário e às condições do trajeto, além de dados importantes de tempo e distância. No controlador de visualização do mapa, seu app precisa adotar os protocolos para esses listeners: GMSRoadSnappedLocationProviderListener e GMSNavigatorListener.
Esta lista mostra os métodos do listener disponíveis para eventos de navegação:
Mostre/oculte o código Swift
de um listener de eventos.
/*
* 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)
}
}
Mostre/oculte o código Objective-C de um listener de eventos.
/*
* 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
Declarar a conformidade com os protocolos obrigatórios
Antes de implementar os métodos de navegação, o controlador de visualização precisa adotar os
protocolos:
Swift
classe ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {
Depois de adotar os protocolos de navegação, defina os listeners para o controlador
de visualização. Por exemplo, você pode adicionar o seguinte código ao método
viewDidLoad().
As atualizações de localização são necessárias para mostrar o progresso do usuário no mapa.
A instância location expõe as seguintes propriedades:
Propriedade do local
Descrição
altitude
Altitude atual.
coordinate.latitude
Coordenada de latitude atual capturada pela estrada.
coordinate.longitude
Coordenada de longitude atual capturada pela estrada.
curso
Direção atual em graus.
velocidade
Velocidade atual.
carimbo de data/hora
Data/hora da leitura atual.
Para receber atualizações contínuas de localização, chame
mapView.roadSnappedLocationProvider.startUpdatingLocation e use
GMSRoadSnappedLocationProviderListener para processar o evento
didUpdateLocation.
O exemplo a seguir mostra como chamar startUpdatingLocation:
O app usa o evento didArriveAtWaypoint para detectar quando um destino foi
chegado. Para retomar a orientação e avançar para o próximo waypoint, chame continueToNextDestination() e reative a orientação. Seu app
precisa reativar a orientação depois de chamar continueToNextDestination().
Depois que o app chamar continueToNextDestination, o navegador não terá mais
dados sobre o destino anterior. Se você quiser analisar informações sobre um trecho do trajeto, recupere-os do navegador antes de chamar continueToNextDestination().
O exemplo de código a seguir mostra um método para processar o evento
didArriveAtWaypoint:
Para receber uma notificação sempre que a rota for alterada, crie um método para
processar o evento navigatorDidChangeRoute. Você pode acessar a nova rota
usando as propriedades routeLegs e currentRouteLeg de GMSNavigator.
Swift
função NavigatorInstruçõesChangeRoute(_ Navigator: GMSNavigator) { print("A rota foi
alterada.") }
Objective-C
(void)navigatorPerformChangeRoute:(GMSNavigator *)navigator { NSLog(@"A rota
foi alterada."); }
Recebendo atualizações do horário até o destino
Para receber atualizações de tempo contínuo até o destino, crie um método para processar o
evento didUpdateRemainingTime. O parâmetro time informa o tempo estimado, em segundos, até o próximo destino ser alcançado.
Swift
função navigator(_ Navigator: GMSNavigator, didUpdateRestrictedTime time:
TimeInterval) { print("Tempo até o próximo destino: (time)") }
Objective-C
(void)navigator:(GMSNavigator *)Navigator
didUpdateStayTime:(NSTimeInterval)time { NSLog(@"Tempo até o próximo
destino: %f", time); }
Para definir a mudança mínima no tempo estimado para o próximo destino, defina a
propriedade timeUpdateThreshold em GMSNavigator. O valor é especificado em segundos. Se essa propriedade não for definida, o valor padrão de um segundo será usado pelos serviços.
Swift
navigator?.timeUpdateThreshold = 10
Objective-C
Navigator.timeUpdateThreshold = 10;
Atualizações da distância até o destino
Para receber atualizações de distância contínua até o destino, crie um método para processar
o evento didUpdateRemainingDistance. O parâmetro distance fornece a distância estimada, em metros, até o próximo destino.
Swift
func Navigator(_ Navigator: GMSNavigator, didUpdateSupportedDistancedistance:
CLLocationDistance) { let Miles = distance * 0.00062137 print("Distância até o próximo destino: (milhas) milhas.") }
Objective-C
(void)navigator:(GMSNavigator *)navigator
didUpdateAssistantDistance:(CLLocationDistance)distance { double milhas =
distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"Distância até o
próximo destino: %.2f.", milhas]); }
Para definir a mudança mínima na distância estimada até o próximo destino, defina a
propriedade distanceUpdateThreshold em GMSNavigator (o valor é especificado em
metros). Se essa propriedade não for definida, os serviços usarão o valor padrão de um
metro.
Swift
navigator?.distanceUpdateThreshold = 100
Objective-C
navigator.distanceUpdateThreshold = 100;
Recebendo atualizações de tráfego
Para receber atualizações contínuas do fluxo de tráfego para o trajeto restante,
crie um método para processar o evento didUpdateDelayCategory. Uma chamada para
delayCategoryToNextDestination retorna GMSNavigationDelayCategory, que
fornece um valor de 0 a 3. As atualizações da categoria são baseadas na posição
atual do usuário do app. Se os dados de tráfego não estiverem disponíveis, GMSNavigationDelayCategory retornará 0. Os números, de 1 a 3, indicam o aumento
do fluxo de leve para intenso.
Swift
função Navigator(_ Navigator: GMSNavigator, didUpdate delayCategory:
GMSNavigationDelayCategory) { print("Fluxo de tráfego para o próximo destino:
(delayCategory)") }
Objective-C
(void)Navigator:(GMSNavigator *)navigator
didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
NSLog(@"Traffic flow to next destination: %ld", (long)delayCategory); }
A propriedade GMSNavigationDelayCategory expõe os seguintes níveis de atraso:
Categoria de atraso
Descrição
GMSNavigationDelayCategoryNoData
0 - Indisponível, sem dados de trânsito ou :
o trajeto.
GMSNavigationDelayCategoryHeavy
1 - Intenso.
GMSNavigationDelayCategoryMedium
2 - Médio.
GMSNavigationDelayCategoryLight
3 - Leve.
Recebendo atualizações de velocidade
Para receber atualizações quando um motorista exceder o limite de velocidade, crie um método
para processar o evento didUpdateSpeedingPercentage.
Swift
// Listener para processar eventos de velocidade. função navigator( _ Navigator:
GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) {
print("A velocidade está (percentageAboveLimit) acima do limite.") }
Objective-C
// Listener para processar eventos de velocidade. - (void)navigator:(GMSNavigator
*)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
NSLog(@"A velocidade está %f por cento acima do limite.", percentageAboveLimit); }
Mudando o modo de iluminação sugerida
Para receber atualizações sobre mudanças estimadas na iluminação, crie um método para processar
o evento didChangeSuggestedLightingMode.
Swift
// Defina um listener para mudanças sugeridas no modo de iluminação. função navigator(_
navigator: GMSNavigator, didChangeSuggestedLightingMode Lighthouse:
GMSNavigationLightingMode) { print("Suggested light mode has changed:
(String(describing: lightsMode))")
// Faça a alteração sugerida. mapView.lightingMode = iluminaçãoMode }
Objective-C
// Defina um listener para as mudanças sugeridas no modo de iluminação.
-(void)Navigator:(GMSNavigator *)navigator didChangeSuggestedLightingMode:
(GMSNavigationLightingMode)lightingMode { NSLog(@"Suggested Light mode",
mudou: %ld", (long)lightingMode);
// Faça a alteração sugerida. _mapView.lightingMode = iluminaçãoMode; }