Skip to content

Commit

Permalink
Merge pull request #2694 from mapbox/vk/552-route-alerts
Browse files Browse the repository at this point in the history
Route Alerts
  • Loading branch information
Udumft authored Dec 14, 2020
2 parents ae18aaa + 5515683 commit 49e4bfb
Show file tree
Hide file tree
Showing 21 changed files with 288 additions and 27 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## v1.2.0

### Packaging

* Increased the minimum versions of `MapboxNavigationNative` to v26.3, `MapboxCommon` to v9.1.0 and `MapboxDirections` to v1.2. ([#2694](https://github.com/mapbox/mapbox-navigation-ios/pull/2694))

### User interface

* Fixed an issue which was causing clear map button disappearance in the example app when selecting the route. ([#2718](https://github.com/mapbox/mapbox-navigation-ios/pull/2718))
Expand All @@ -25,6 +29,7 @@
* Added Ukrainian localization. ([#2735](https://github.com/mapbox/mapbox-navigation-ios/pull/2735))
* Created the `UserHaloCourseView` similar to `UserCourseView` for approximate location on iOS 14 during the navigation to represent user location. Allow the switch between `UserHaloCourseView` and `UserCourseView` when precise mode is changed. ([#2664](https://github.com/mapbox/mapbox-navigation-ios/pull/2664))
* Added the ability to provide more detailed `Speed limit incorrect` feedback during turn-by-turn navigation. ([#2725](https://github.com/mapbox/mapbox-navigation-ios/pull/2725))
* Added the `RouteProgress.upcomingRouteAlerts` property to track upcoming points along the route experiencing conditions that may require the user’s attention. The `UpcomingRouteAlertInfo.alert` property contains one of the following types with more details about the alert: `Incident`, `TunnelInfo`, `BorderCrossingInfo`, `TollCollection`, and `RestStop`. ([#2694](https://github.com/mapbox/mapbox-navigation-ios/pull/2694)

## v1.1.0

Expand Down
6 changes: 3 additions & 3 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
binary "https://www.mapbox.com/ios-sdk/MapboxAccounts.json" ~> 2.3.0
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-navigation-native/MapboxNavigationNative.json" ~> 22.0
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-navigation-native/MapboxNavigationNative.json" ~> 26.3
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-maps/mapbox-ios-sdk-dynamic.json" ~> 6.0
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon-ios.json" == 7.1.2
github "mapbox/mapbox-directions-swift" ~> 1.0
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon-ios.json" == 9.1.0
github "mapbox/mapbox-directions-swift" ~> 1.2.0-alpha.3
github "mapbox/turf-swift" ~> 1.0
github "mapbox/mapbox-events-ios" ~> 0.10.2
github "ceeK/Solar" ~> 2.1.0
Expand Down
9 changes: 5 additions & 4 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon-ios.json" "7.1.2"
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon-ios.json" "9.1.0"
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-maps/mapbox-ios-sdk-dynamic.json" "6.3.0"
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-navigation-native/MapboxNavigationNative.json" "22.0.5"
binary "https://api.mapbox.com/downloads/v2/carthage/mobile-navigation-native/MapboxNavigationNative.json" "26.3.1"
binary "https://www.mapbox.com/ios-sdk/MapboxAccounts.json" "2.3.0"
github "CedarBDD/Cedar" "v1.0"
github "Quick/Nimble" "v8.1.2"
github "Quick/Quick" "v2.2.1"
github "Udumft/SnappyShrimp" "66f3e3ba70370ad5e889ac8ed72a8730ca79958e"
github "Udumft/SwiftCLI" "da19d2a16cd5aa838d8fb7256e28c171bc67dd82"
github "ceeK/Solar" "2.1.0"
github "linksmt/OHHTTPStubs" "563f48d3fab84ef04639649c770b00f4fa502cca"
github "mapbox/MapboxGeocoder.swift" "v0.10.2"
github "mapbox/mapbox-directions-swift" "v1.1.0"
github "mapbox/mapbox-events-ios" "v0.10.6"
github "mapbox/mapbox-directions-swift" "v1.2.0-alpha.3"
github "mapbox/mapbox-events-ios" "v0.10.7"
github "mapbox/mapbox-speech-swift" "v1.0.0"
github "mapbox/turf-swift" "v1.1.0"
github "raphaelmor/Polyline" "v5.0.2"
Expand Down
6 changes: 3 additions & 3 deletions MapboxCoreNavigation.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.module_name = "MapboxCoreNavigation"

s.dependency "MapboxNavigationNative", "~> 22.0"
s.dependency "MapboxNavigationNative", "~> 26.3"
s.dependency "MapboxAccounts", "~> 2.3.0"
s.dependency "MapboxDirections", "~> 1.0"
s.dependency "MapboxDirections", "~> 1.2.0-alpha.3"
s.dependency "MapboxMobileEvents", "~> 0.10.2" # Always specify a patch release if pre-v1.0
s.dependency "Turf", "~> 1.0"

s.swift_version = "5.0"

# https://github.com/mapbox/mapbox-navigation-ios/issues/2665
# https://github.com/mapbox/mapbox-navigation-ios/issues/2665
s.user_target_xcconfig = {
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => '$(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))',
'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200' => 'arm64 arm64e armv7 armv7s armv6 armv8'
Expand Down
23 changes: 23 additions & 0 deletions MapboxCoreNavigation/BorderCrossing.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

import Foundation
import MapboxNavigationNative
import MapboxDirections

extension AdministrativeRegion {
init(_ adminInfo: RouteAlertAdminInfo) {
self.init(countryCode: adminInfo.iso_3166_1, countryCodeAlpha3: adminInfo.iso_3166_1_alpha3)
}
}

/**
`BorderCrossingInfo` encapsulates a border crossing, specifying crossing region codes.
*/
public struct BorderCrossing {
public let from: AdministrativeRegion
public let to: AdministrativeRegion

init(_ borderCrossing: RouteAlertBorderCrossingInfo) {
from = AdministrativeRegion(borderCrossing.from)
to = AdministrativeRegion(borderCrossing.to)
}
}
53 changes: 53 additions & 0 deletions MapboxCoreNavigation/Incident.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

import Foundation
import MapboxNavigationNative
import MapboxDirections

extension Incident {
init?(_ incidentInfo: RouteAlertIncidentInfo) {
var incidentType: Incident.Kind!
switch incidentInfo.type {
case .kAccident:
incidentType = .accident
case .kCongestion:
incidentType = .congestion
case .kConstruction:
incidentType = .construction
case .kDisabledVehicle:
incidentType = .disabledVehicle
case .kLaneRestriction:
incidentType = .laneRestriction
case .kMassTransit:
incidentType = .massTransit
case .kMiscellaneous:
incidentType = .miscellaneous
case .kOtherNews:
incidentType = .otherNews
case .kPlannedEvent:
incidentType = .plannedEvent
case .kRoadClosure:
incidentType = .roadClosure
case .kRoadHazard:
incidentType = .roadHazard
case .kWeather:
incidentType = .weather
}

guard incidentType != nil else {
return nil
}

self.init(identifier: incidentInfo.id,
type: incidentType,
description: incidentInfo.description ?? "",
creationDate: incidentInfo.creationTime ?? Date.distantPast,
startDate: incidentInfo.startTime ?? Date.distantPast,
endDate: incidentInfo.endTime ?? Date.distantPast,
impact: incidentInfo.impact ?? "",
subtype: incidentInfo.subType,
subtypeDescription: incidentInfo.subTypeDescription,
alertCodes: Set(incidentInfo.alertcCodes.map { $0.intValue }),
lanesBlocked: BlockedLanes(descriptions: incidentInfo.lanesBlocked),
shapeIndexRange: -1 ..< -1)
}
}
15 changes: 15 additions & 0 deletions MapboxCoreNavigation/RestStop.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import Foundation
import MapboxNavigationNative
import MapboxDirections

extension RestStop {
init(_ serviceArea: RouteAlertServiceAreaInfo) {
switch serviceArea.type {
case .kRestArea:
self.init(type: .restArea)
case .kServiceArea:
self.init(type: .serviceArea)
}
}
}
95 changes: 95 additions & 0 deletions MapboxCoreNavigation/RouteAlert.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import Foundation
import CoreLocation
import MapboxNavigationNative
import MapboxDirections

/**
`RouteAlert` encapsulates information about various incoming events. Common attributes like location, distance to the event, length and other is provided for each POI, while specific meta data is supplied via `alert` property.
*/
public struct RouteAlert {
/// Enumeration used for encapsulating additional details to describe specific type of alert
public enum Alert {
/// Incident alert with details
case incident(Incident)
/// Tunnel alert with details
case tunnel(Tunnel)
/// Border alert crossing with details
case borderCrossing(BorderCrossing)
/// Toll collect alert with details
case tollCollection(TollCollection)
/// Service area alert with details
case serviceArea(RestStop)
/// Restricted area alert
case restrictedArea
}

/// Alert data with specific info. Contents depend on exact alert type.
public let alert: Alert

/// Distance to route alert relative to start of the route, meters.
public let distance: CLLocationDistance
/**
Distance from current position to alert, meters.

This value can be negative if it is a spanned alert and we are somewhere in the middle of it.
*/
public let distanceToStart: CLLocationDistance
/**
Length of the alert info.

This value will be non-null for composite route alerts */
public let length: CLLocationDistance?

/// Coordinate of route alert beginning point
public let beginCoordinate: CLLocationCoordinate2D
/// Coordinate of route alert ending point
public let endCoordinate: CLLocationCoordinate2D

/// Segment index in corresponding `Route.shape` where this alert begins.
public let beginSegmentIndex: UInt32
/// Segment index in corresponding `Route.shape` where this alert ends.
public let endSegmentIndex: UInt32

init(_ upcomingAlert: UpcomingRouteAlert) {
self.distance = upcomingAlert.alert.distance
self.distanceToStart = upcomingAlert.distanceToStart
self.length = upcomingAlert.alert.length?.doubleValue
self.beginCoordinate = upcomingAlert.alert.beginCoordinate
self.endCoordinate = upcomingAlert.alert.endCoordinate
self.beginSegmentIndex = upcomingAlert.alert.beginGeometryIndex
self.endSegmentIndex = upcomingAlert.alert.endGeometryIndex

switch upcomingAlert.alert.type {
case .kIncident:
guard let incidentInfo = upcomingAlert.alert.incidentInfo else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) did not contain an info data.")
}
guard let incident = Incident(incidentInfo) else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) had unrecognized Incident type: \(incidentInfo.type).")
}
self.alert = .incident(incident)
case .kTunnelEntrance:
guard let tunnelInfo = upcomingAlert.alert.tunnelInfo else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) did not contain an info data.")
}
self.alert = .tunnel(Tunnel(tunnelInfo))
case .kBorderCrossing:
guard let adminInfo = upcomingAlert.alert.borderCrossingInfo else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) did not contain an info data.")
}
self.alert = .borderCrossing(BorderCrossing(adminInfo))
case .kTollCollectionPoint:
guard let tollInfo = upcomingAlert.alert.tollCollectionInfo else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) did not contain an info data.")
}
self.alert = .tollCollection(TollCollection(tollInfo))
case .kServiceArea:
guard let serviceAreaInfo = upcomingAlert.alert.serviceAreaInfo else {
preconditionFailure("Alert of type \(upcomingAlert.alert.type) did not contain an info data.")
}
self.alert = .serviceArea(RestStop(serviceAreaInfo))
case .kRestrictedArea:
self.alert = .restrictedArea
}
}
}
5 changes: 3 additions & 2 deletions MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ open class RouteController: NSObject {
let status = navigator.status(at: location.timestamp)

// Notify observers if the step’s remaining distance has changed.
update(progress: routeProgress, with: CLLocation(status.location), rawLocation: location)
update(progress: routeProgress, with: CLLocation(status.location), rawLocation: location, upcomingRouteAlerts: status.upcomingRouteAlerts)

let willReroute = !userIsOnRoute(location, status: status) && delegate?.router(self, shouldRerouteFrom: location)
?? DefaultBehavior.shouldRerouteFromLocation
Expand Down Expand Up @@ -336,8 +336,9 @@ open class RouteController: NSObject {
}
}

private func update(progress: RouteProgress, with location: CLLocation, rawLocation: CLLocation) {
private func update(progress: RouteProgress, with location: CLLocation, rawLocation: CLLocation, upcomingRouteAlerts routeAlerts: [UpcomingRouteAlert]) {
progress.updateDistanceTraveled(with: rawLocation)
progress.upcomingRouteAlerts = routeAlerts.map { RouteAlert($0) }

//Fire the delegate method
delegate?.router(self, didUpdate: progress, with: location, rawLocation: rawLocation)
Expand Down
7 changes: 7 additions & 0 deletions MapboxCoreNavigation/RouteProgress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ open class RouteProgress: Codable {
return currentLegProgress.upcomingStep ?? upcomingLeg?.steps.first
}

/**
Upcoming `RouteAlerts` as reported by the navigation engine.

The contents of the array depend on user's current progress along the route and are modified on each location update. This array contains only the alerts that the user has not passed. Some events may have non-zero length and are also included while the user is traversing it. You can use this property to get information about incoming points of interest.
*/
public internal(set) var upcomingRouteAlerts: [RouteAlert] = []

/**
Returns an array of `CLLocationCoordinate2D` of the coordinates along the current step and any adjacent steps.

Expand Down
15 changes: 15 additions & 0 deletions MapboxCoreNavigation/TollCollection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import Foundation
import MapboxNavigationNative
import MapboxDirections

extension TollCollection {
init(_ tollInfo: RouteAlertTollCollectionInfo) {
switch tollInfo.type {
case .kTollBooth:
self.init(type: .booth)
case .kTollGantry:
self.init(type: .gantry)
}
}
}
14 changes: 14 additions & 0 deletions MapboxCoreNavigation/Tunnel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import Foundation
import MapboxNavigationNative

/**
`Tunnel` is used for naming incoming tunnels, together with route alerts.
*/
public struct Tunnel {
public let name: String

init(_ tunnelInfo: RouteAlertTunnelInfo) {
name = tunnelInfo.name
}
}
24 changes: 12 additions & 12 deletions MapboxCoreNavigationTests/CocoaPodsTest/PodInstall/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ PODS:
- Mapbox-iOS-SDK (6.3.0):
- MapboxMobileEvents (~> 0.10.4)
- MapboxAccounts (2.3.0)
- MapboxCommon (7.1.2)
- MapboxCommon (9.1.0)
- MapboxCoreNavigation (1.2.0-alpha.3):
- MapboxAccounts (~> 2.3.0)
- MapboxDirections (~> 1.0)
- MapboxDirections (~> 1.2.0-alpha.3)
- MapboxMobileEvents (~> 0.10.2)
- MapboxNavigationNative (~> 22.0)
- MapboxNavigationNative (~> 26.3)
- Turf (~> 1.0)
- MapboxDirections (1.1.0):
- MapboxDirections (1.2.0-alpha.3):
- Polyline (~> 5.0)
- Turf (~> 1.0)
- MapboxMobileEvents (0.10.7)
Expand All @@ -19,8 +19,8 @@ PODS:
- MapboxMobileEvents (~> 0.10.2)
- MapboxSpeech (~> 1.0)
- Solar (~> 2.1)
- MapboxNavigationNative (22.0.5):
- MapboxCommon (= 7.1.2)
- MapboxNavigationNative (26.3.1):
- MapboxCommon (= 9.1.0)
- MapboxSpeech (1.0.0)
- Polyline (5.0.2)
- Solar (2.1.0)
Expand Down Expand Up @@ -50,19 +50,19 @@ EXTERNAL SOURCES:
:path: "../../../"

SPEC CHECKSUMS:
Mapbox-iOS-SDK: 6a67397df2bcafe5d2851604192aa8de6f8d6c89
Mapbox-iOS-SDK: 2563ed87ead6ec08f1c2090873977b8a7be335a8
MapboxAccounts: 84abfdde95d9dc483f604c1b0fe1861edf691ce7
MapboxCommon: e469f6c62de29e1906c37e0bce65f6826e7fb9ac
MapboxCoreNavigation: bc0dc2f48ad7a8551039095fc6dc1ae530c24a86
MapboxDirections: f47e5648051967c502897cf808090874e3f81c5d
MapboxCommon: 2de699add978635b5373f6e1ace3d10df12b8459
MapboxCoreNavigation: e4d1a93bd80dbb2cb3b29fbbd2c812272f65544c
MapboxDirections: 193dfc86136b599e9a20fc41d6a8d81ed239854d
MapboxMobileEvents: d0a581dedd8f47411cc65ea520b965e83914316e
MapboxNavigation: 9b7d154a6d79e49c7867d40e797d014a24d7e0c0
MapboxNavigationNative: 88f243e0460fc7d1d50035bf13583355da6e4c26
MapboxNavigationNative: 685b378d938ca9c2e597818c79b25f5d0066a156
MapboxSpeech: 4b3aea42e35d056fae1d7ad847a9fc0f412d911e
Polyline: fce41d72e1146c41c6d081f7656827226f643dff
Solar: 2dc6e7cc39186cb0c8228fa08df76fb50c7d8f24
Turf: 62a818ddce6c1af8d54da9d56232088d170ab27b

PODFILE CHECKSUM: d4084fe664fbacd0cffd88ab45eaed1ad907ad1d

COCOAPODS: 1.10.0.rc.1
COCOAPODS: 1.10.0
Loading

0 comments on commit 49e4bfb

Please sign in to comment.