Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 3.6
github "mapbox/MapboxDirections.swift" ~> 0.10.5
github "mapbox/MapboxDirections.swift" ~> 0.11
github "mapbox/turf-swift" ~> 0.0.3
github "52inc/Pulley" == 1.4
github "rs/SDWebImage" ~> 4.1
github "Project-OSRM/osrm-text-instructions.swift" ~> 0.3.5
github "Project-OSRM/osrm-text-instructions.swift" ~> 0.4
github "frederoni/aws-sdk-ios" ~> 2.6
github "mapbox/mapbox-telemetry-ios" ~> 0.2
github "1ec5/Solar" "scheme-test-only"
6 changes: 3 additions & 3 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" "3.6.4"
github "1ec5/Solar" "5ce2ca7baaa82b1abb0467642ae237faf674b645"
github "52inc/Pulley" "1.4"
github "Project-OSRM/osrm-text-instructions.swift" "v0.3.5"
github "Project-OSRM/osrm-text-instructions.swift" "v0.4.0"
github "facebook/ios-snapshot-test-case" "2.1.4"
github "frederoni/aws-sdk-ios" "2.6.0"
github "mapbox/MapboxDirections.swift" "v0.10.6"
github "mapbox/MapboxDirections.swift" "v0.11.2"
github "mapbox/mapbox-telemetry-ios" "v0.2.11"
github "mapbox/turf-swift" "v0.0.3"
github "raphaelmor/Polyline" "v4.1.1"
github "rs/SDWebImage" "4.1.0"
github "rs/SDWebImage" "4.1.2"
22 changes: 3 additions & 19 deletions Examples/Objective-C/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,20 @@ - (IBAction)didLongPress:(UILongPressGestureRecognizer *)sender {
}

- (void)resumeNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertLevelDidChange:) name:MBRouteControllerAlertLevelDidChange object:_navigation];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertLevelDidChange:) name:MBRouteControllerDidPassSpokenInstructionPoint object:_navigation];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressDidChange:) name:MBRouteControllerNotificationProgressDidChange object:_navigation];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willReroute:) name:MBRouteControllerWillReroute object:_navigation];
}

- (void)suspendNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MBRouteControllerAlertLevelDidChange object:_navigation];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MBRouteControllerDidPassSpokenInstructionPoint object:_navigation];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MBRouteControllerNotificationProgressDidChange object:_navigation];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MBRouteControllerWillReroute object:_navigation];
}

- (void)alertLevelDidChange:(NSNotification *)notification {
MBRouteProgress *routeProgress = (MBRouteProgress *)notification.userInfo[MBRouteControllerProgressDidChangeNotificationProgressKey];
MBRouteStep *upcomingStep = routeProgress.currentLegProgress.upComingStep;

NSString *text = nil;
if (upcomingStep) {
MBAlertLevel alertLevel = routeProgress.currentLegProgress.alertUserLevel;
if (alertLevel == MBAlertLevelHigh) {
text = upcomingStep.instructions;
} else {
text = [NSString stringWithFormat:@"In %@ %@",
[self.lengthFormatter stringFromMeters:routeProgress.currentLegProgress.currentStepProgress.distanceRemaining],
upcomingStep.instructions];
}
} else {
text = [NSString stringWithFormat:@"In %@ %@",
[self.lengthFormatter stringFromMeters:routeProgress.currentLegProgress.currentStepProgress.distanceRemaining],
routeProgress.currentLegProgress.currentStep.instructions];
}
NSString *text = routeProgress.currentLegProgress.currentStepProgress.currentSpokenInstruction.text;

[self.speechSynth speakUtterance:[AVSpeechUtterance speechUtteranceWithString:text]];
}
Expand Down
15 changes: 7 additions & 8 deletions Examples/Swift/CustomViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ class CustomViewController: UIViewController, MGLMapViewDelegate, AVSpeechSynthe
var routeController: RouteController!

let textDistanceFormatter = DistanceFormatter(approximate: true)
let voiceDistanceFormatter = SpokenDistanceFormatter(approximate: true)
lazy var speechSynth = AVSpeechSynthesizer()
var userRoute: Route?
var simulateLocation = false
let visualInstructionFormatter = VisualInstructionFormatter()
let spokenInstructionFormatter = SpokenInstructionFormatter()

@IBOutlet var mapView: MGLMapView!
@IBOutlet weak var arrowView: UILabel!
Expand Down Expand Up @@ -61,13 +59,13 @@ class CustomViewController: UIViewController, MGLMapViewDelegate, AVSpeechSynthe
}

func resumeNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(alertLevelDidChange(_ :)), name: RouteControllerAlertLevelDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(shouldSpeak(_:)), name: RouteControllerDidPassSpokenInstructionPoint, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_ :)), name: RouteControllerProgressDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(rerouted(_:)), name: RouteControllerWillReroute, object: nil)
}

func suspendNotifications() {
NotificationCenter.default.removeObserver(self, name: RouteControllerAlertLevelDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: RouteControllerDidPassSpokenInstructionPoint, object: nil)
NotificationCenter.default.removeObserver(self, name: RouteControllerProgressDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: RouteControllerWillReroute, object: nil)
}
Expand All @@ -76,10 +74,11 @@ class CustomViewController: UIViewController, MGLMapViewDelegate, AVSpeechSynthe
addRouteToMap()
}

// When the alert level changes, this signals the user is ready for a voice announcement
func alertLevelDidChange(_ notification: NSNotification) {
let routeProgress = notification.userInfo![RouteControllerAlertLevelDidChangeNotificationRouteProgressKey] as! RouteProgress
let text = spokenInstructionFormatter.string(routeProgress: routeProgress, userDistance: routeProgress.currentLegProgress.currentStepProgress.distanceRemaining, markUpWithSSML: false)
// When an instruction should be given
func shouldSpeak(_ notification: NSNotification) {
let routeProgress = notification.userInfo![MBRouteControllerDidPassSpokenInstructionPointRouteProgressKey] as! RouteProgress

guard let text = routeProgress.currentLegProgress.currentStepProgress.currentSpokenInstruction?.text else { return }

let utterance = AVSpeechUtterance(string: text)
speechSynth.delegate = self
Expand Down
4 changes: 2 additions & 2 deletions MapboxCoreNavigation.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.module_name = "MapboxCoreNavigation"

s.dependency "MapboxDirections.swift", "~> 0.10.5"
s.dependency "OSRMTextInstructions", "~> 0.3"
s.dependency "MapboxDirections.swift", "~> 0.11"
s.dependency "OSRMTextInstructions", "~> 0.4"
s.dependency "MapboxMobileEvents", "~> 0.2"
s.dependency "Turf", "~> 0.0.3"

Expand Down
29 changes: 7 additions & 22 deletions MapboxCoreNavigation/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@ public let RouteControllerProgressDidChangeNotificationLocationKey = MBRouteCont
*/
public let RouteControllerProgressDidChangeNotificationSecondsRemainingOnStepKey = MBRouteControllerProgressDidChangeNotificationSecondsRemainingOnStepKey

/**
Key used for accessing the `RouteProgress` object from a `RouteControllerAlertLevelDidChange` notification's `userInfo` dictionary.
*/
public let RouteControllerAlertLevelDidChangeNotificationRouteProgressKey = MBRouteControllerAlertLevelDidChangeNotificationRouteProgressKey

/**
Key used for accessing the user's snapped distance to the end of the maneuver (CLLocationDistance) from a `RouteControllerAlertLevelDidChange` notification's `userInfo` dictionary.
*/
public let RouteControllerAlertLevelDidChangeNotificationDistanceToEndOfManeuverKey = MBRouteControllerAlertLevelDidChangeNotificationDistanceToEndOfManeuverKey

/**
Key used for accessing the user's current `CLLocation` from a `RouteControllerWillReroute` notification's `userInfo` dictionary.
*/
Expand All @@ -53,9 +43,14 @@ public let RouteControllerDidFindFasterRouteKey = MBRouteControllerDidFindFaster
public let RouteControllerProgressDidChange = Notification.Name(MBRouteControllerNotificationProgressDidChange)

/**
Emitted when the alert level changes. This indicates the user should be notified about the upcoming maneuver.
Emitted when the user passes an ideal point for saying an instruction aloud.
*/
public let RouteControllerAlertLevelDidChange = Notification.Name(MBRouteControllerAlertLevelDidChange)
public let RouteControllerDidPassSpokenInstructionPoint = Notification.Name(MBRouteControllerDidPassSpokenInstructionPoint)

/**
Key for accessing the `RouteProgress` key emitted when `RouteControllerDidPassSpokenInstructionPoint` is fired.
*/
public let RouteControllerDidPassSpokenInstructionPointRouteProgressKey = MBRouteControllerDidPassSpokenInstructionPointRouteProgressKey

/**
Emitted when the user has gone off-route and the `RouteController` is about to reroute.
Expand Down Expand Up @@ -104,16 +99,6 @@ public var RouteControllerHighAlertInterval: TimeInterval = 15
*/
public var RouteControllerManeuverZoneRadius: CLLocationDistance = 40

/**
Remaing distance on a motorway at which the `AlertLevel.high` `AlertLevel` will be given. This overrides `RouteControllerHighAlertInterval` only when the current step is a motorway. Default value is a half mile.
*/
public var RouteControllerMotorwayHighAlertDistance: CLLocationDistance = 0.25 * milesToMeters

/**
Remaing distance on a motorway at which the `AlertLevel.medium` `AlertLevel` will be given. This overrides `RouteControllerMediumAlertInterval` only when the current step is a motorway. Defauly value is 2 miles.
*/
public var RouteControllerMotorwayMediumAlertDistance: CLLocationDistance = 2 * milesToMeters

/**
When calculating whether or not the user is on the route, we look where the user will be given their speed and this variable.
*/
Expand Down
14 changes: 3 additions & 11 deletions MapboxCoreNavigation/DistanceFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,6 @@ public class DistanceFormatter: LengthFormatter {

let nonFractionalLengthFormatter = LengthFormatter()

var usesMetric: Bool {
let locale = numberFormatter.locale as NSLocale
guard let measurementSystem = locale.object(forKey: .measurementSystem) as? String else {
return false
}
return measurementSystem == "Metric"
}

/**
Intializes a new `DistanceFormatter`.

Expand All @@ -57,15 +49,15 @@ public class DistanceFormatter: LengthFormatter {
}

func maximumFractionDigits(for distance: CLLocationDistance) -> Int {
if usesMetric {
if Locale.usesMetric {
return distance < 3_000 ? 1 : 0
} else {
return distance.miles < 3 ? 1 : 0
}
}

func roundingIncrement(for distance: CLLocationDistance, unit: LengthFormatter.Unit) -> Double {
if usesMetric {
if Locale.usesMetric {
if distance < 25 {
return 5
} else if distance < 100 {
Expand Down Expand Up @@ -120,7 +112,7 @@ public class DistanceFormatter: LengthFormatter {

func formattedDistance(_ distance: CLLocationDistance, modify unit: inout LengthFormatter.Unit) -> String {
var formattedDistance: String
if usesMetric {
if Locale.usesMetric {
let roundedDistance: CLLocationDistance = numberFormatter.number(from: numberFormatter.string(from: distance as NSNumber)!)?.doubleValue ?? distance
numberFormatter.roundingIncrement = roundingIncrement(for: roundedDistance, unit: unit) as NSNumber

Expand Down
8 changes: 8 additions & 0 deletions MapboxCoreNavigation/Locale.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ extension Locale {
Returns a `Locale` from `preferredLocalLanguageCountryCode`.
*/
public static var nationalizedCurrent = Locale(identifier: preferredLocalLanguageCountryCode)

public static var usesMetric: Bool {
let locale = self.current as NSLocale
guard let measurementSystem = locale.object(forKey: .measurementSystem) as? String else {
return false
}
return measurementSystem == "Metric"
}
}
5 changes: 2 additions & 3 deletions MapboxCoreNavigation/MBRouteController.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ extern NSString *const MBRouteControllerProgressDidChangeNotificationProgressKey
extern NSString *const MBRouteControllerProgressDidChangeNotificationLocationKey;
extern NSString *const MBRouteControllerProgressDidChangeNotificationSecondsRemainingOnStepKey;

extern NSString *const MBRouteControllerAlertLevelDidChangeNotificationRouteProgressKey;
extern NSString *const MBRouteControllerAlertLevelDidChangeNotificationDistanceToEndOfManeuverKey;
extern NSString *const MBRouteControllerDidPassSpokenInstructionPointRouteProgressKey;
extern NSString *const MBRouteControllerDidPassSpokenInstructionPoint;

extern NSString *const MBRouteControllerNotificationLocationKey;
extern NSString *const MBRouteControllerNotificationRouteKey;
extern NSString *const MBRouteControllerNotificationErrorKey;

extern NSString *const MBRouteControllerNotificationProgressDidChange;
extern NSString *const MBRouteControllerAlertLevelDidChange;
extern NSString *const MBRouteControllerWillReroute;
extern NSString *const MBRouteControllerDidReroute;
extern NSString *const MBRouteControllerDidFailToReroute;
Expand Down
5 changes: 2 additions & 3 deletions MapboxCoreNavigation/MBRouteController.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
NSString *const MBRouteControllerProgressDidChangeNotificationLocationKey = @"location";
NSString *const MBRouteControllerProgressDidChangeNotificationSecondsRemainingOnStepKey = @"seconds";

NSString *const MBRouteControllerAlertLevelDidChangeNotificationRouteProgressKey = @"progress";
NSString *const MBRouteControllerAlertLevelDidChangeNotificationDistanceToEndOfManeuverKey = @"distance";
NSString *const MBRouteControllerDidPassSpokenInstructionPointRouteProgressKey = @"progress";

NSString *const MBRouteControllerNotificationLocationKey = @"location";
NSString *const MBRouteControllerNotificationRouteKey = @"route";
NSString *const MBRouteControllerNotificationErrorKey = @"error";

NSString *const MBRouteControllerNotificationProgressDidChange = @"RouteControllerProgressDidChange";
NSString *const MBRouteControllerAlertLevelDidChange = @"RouteControllerAlertLevelDidChange";
NSString *const MBRouteControllerDidPassSpokenInstructionPoint = @"RouteControllerDidPassSpokenInstructionPoint";
NSString *const MBRouteControllerWillReroute = @"RouteControllerWillReroute";
NSString *const MBRouteControllerDidReroute = @"RouteControllerDidReroute";
NSString *const MBRouteControllerDidFailToReroute = @"RouteControllerDidFailToReroute";
Expand Down
23 changes: 12 additions & 11 deletions MapboxCoreNavigation/NavigationRouteOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import MapboxDirections

/**
A `NavigationRouteOptions` object specifies turn-by-turn-optimized criteria for results returned by the Mapbox Directions API.

`NavigationRouteOptions` is a subclass of `RouteOptions` that has been optimized for navigation. Pass an instance of this class into the `Directions.calculate(_:completionHandler:)` method.
*/
@objc(MBNavigationRouteOptions)
open class NavigationRouteOptions: RouteOptions {

/**
Initializes a navigation route options object for routes between the given waypoints and an optional profile identifier optimized for navigation.

- SeeAlso:
[RouteOptions](https://www.mapbox.com/mapbox-navigation-ios/directions/0.10.1/Classes/RouteOptions.html)
*/
Expand All @@ -23,31 +23,32 @@ open class NavigationRouteOptions: RouteOptions {
includesSteps = true
routeShapeResolution = .full
attributeOptions = [.congestionLevel, .expectedTravelTime]
includesExitRoundaboutManeuver = true
includesSpokenInstructions = true
distanceMeasurementSystem = Locale.current.usesMetricSystem ? .metric : .imperial
}


/**
Initializes a navigation route options object for routes between the given locations and an optional profile identifier optimized for navigation.

- SeeAlso:
[RouteOptions](https://www.mapbox.com/mapbox-navigation-ios/directions/0.10.1/Classes/RouteOptions.html)
*/
public convenience init(locations: [CLLocation], profileIdentifier: MBDirectionsProfileIdentifier? = .automobileAvoidingTraffic) {
self.init(waypoints: locations.map { Waypoint(location: $0) }, profileIdentifier: profileIdentifier)
}


/**
Initializes a route options object for routes between the given geographic coordinates and an optional profile identifier optimized for navigation.

- SeeAlso:
[RouteOptions](https://www.mapbox.com/mapbox-navigation-ios/directions/0.10.1/Classes/RouteOptions.html)
*/
public convenience init(coordinates: [CLLocationCoordinate2D], profileIdentifier: MBDirectionsProfileIdentifier? = .automobileAvoidingTraffic) {
self.init(waypoints: coordinates.map { Waypoint(coordinate: $0) }, profileIdentifier: profileIdentifier)
}

public required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
}
Expand Down
Loading