Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Route Alerts Refinement #506

Merged
merged 15 commits into from
Dec 10, 2020
Merged
Show file tree
Hide file tree
Changes from 14 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* `Intersection.regionCode` - A 2-letter region code to identify corresponding country that this intersection lies in.
* `RouteLeg.regionCode(atStepIndex:, intersectionIndex:)` - Returns the ISO 3166-1 alpha-2 region code for the administrative region through which the given intersection passes.
* Added `RouteStep.segmentIndicesByIntersection` for navigating `Intersection`s segments along the step; ([#490](https://github.com/mapbox/mapbox-directions-swift/pull/490))
* Added support for encoding and decoding `Route Alerts` data coming from `Directions API`. Includes `TollCollection`, `RestStop` and `AdministrationRegion`. Also added `Incident` struct for reflecting incoming incidents along the route ([#466](https://github.com/mapbox/mapbox-directions-swift/pull/466), [#506](https://github.com/mapbox/mapbox-directions-swift/pull/506))
1ec5 marked this conversation as resolved.
Show resolved Hide resolved

## v1.1.0

Expand Down
18 changes: 18 additions & 0 deletions MapboxDirections.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
2B674DC22541AF2E0026CE4B /* Polyline.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F448F83A1DDCC6EB000BC343 /* Polyline.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
2B674DCB2541AF410026CE4B /* Turf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B674DCA2541AF410026CE4B /* Turf.framework */; };
2B674DCC2541AF410026CE4B /* Turf.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2B674DCA2541AF410026CE4B /* Turf.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
2BA2E746257A667500D7AFC6 /* incidents.json in Resources */ = {isa = PBXBuildFile; fileRef = 2BA2E745257A667500D7AFC6 /* incidents.json */; };
2BA2E747257A667500D7AFC6 /* incidents.json in Resources */ = {isa = PBXBuildFile; fileRef = 2BA2E745257A667500D7AFC6 /* incidents.json */; };
2BA2E748257A667500D7AFC6 /* incidents.json in Resources */ = {isa = PBXBuildFile; fileRef = 2BA2E745257A667500D7AFC6 /* incidents.json */; };
2BBBD08D257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */; };
2BBBD08E257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */; };
2BBBD08F257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */; };
2BBBD090257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */; };
35828C9E217A003F00ED546E /* OfflineDirections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35828C9D217A003F00ED546E /* OfflineDirections.swift */; };
35828C9F217A003F00ED546E /* OfflineDirections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35828C9D217A003F00ED546E /* OfflineDirections.swift */; };
35828CA0217A003F00ED546E /* OfflineDirections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35828C9D217A003F00ED546E /* OfflineDirections.swift */; };
Expand Down Expand Up @@ -450,7 +457,9 @@
2B540804245B09E1006C820B /* routeRefreshRoute.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = routeRefreshRoute.json; sourceTree = "<group>"; };
2B540808245B23BE006C820B /* incorrectRouteRefreshResponse.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = incorrectRouteRefreshResponse.json; sourceTree = "<group>"; };
2B674DCA2541AF410026CE4B /* Turf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Turf.framework; path = Carthage/Build/Mac/Turf.framework; sourceTree = "<group>"; };
2BA2E745257A667500D7AFC6 /* incidents.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = incidents.json; sourceTree = "<group>"; };
2BA98970253F007600B643F6 /* mapbox-directions-swift */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mapbox-directions-swift"; sourceTree = BUILT_PRODUCTS_DIR; };
2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedLanes.swift; sourceTree = "<group>"; };
2BFD4D962540604000D0E14D /* SwiftCLI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCLI.framework; path = Carthage/Build/Mac/SwiftCLI.framework; sourceTree = "<group>"; };
3556CE9922649CF2009397B5 /* MapboxDirectionsTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "MapboxDirectionsTests-Bridging-Header.h"; path = "../objc/MapboxDirectionsTests-Bridging-Header.h"; sourceTree = "<group>"; };
35828C9D217A003F00ED546E /* OfflineDirections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineDirections.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -812,6 +821,7 @@
F4F508372524D6F10044F2D0 /* RestStop.swift */,
F4F5084A2524DC280044F2D0 /* AdministrativeRegion.swift */,
F457FA79252B9E29007DAEB1 /* Incident.swift */,
2BBBD08C257FA1CD004EB3D6 /* BlockedLanes.swift */,
);
name = MapboxDirections;
path = Sources/MapboxDirections;
Expand Down Expand Up @@ -858,6 +868,7 @@
DA6C9DAD1CAEC93800094FBC /* Fixtures */ = {
isa = PBXGroup;
children = (
2BA2E745257A667500D7AFC6 /* incidents.json */,
2B540803245B09B2006C820B /* RouteRefresh */,
35DBF017217F387F0009D2AE /* Offline */,
C5DAACB2201AA97D001F9261 /* Match */,
Expand Down Expand Up @@ -1255,6 +1266,7 @@
buildActionMask = 2147483647;
files = (
DA737EE51D05F91E005BDA16 /* v5_driving_dc_geojson.json in Resources */,
2BA2E747257A667500D7AFC6 /* incidents.json in Resources */,
DA1A10CF1D00F975009F82FA /* v5_driving_dc_polyline.json in Resources */,
2B54080A245B23BE006C820B /* incorrectRouteRefreshResponse.json in Resources */,
C5C0D63520586419003A3B1D /* null-tracepoint.json in Resources */,
Expand Down Expand Up @@ -1286,6 +1298,7 @@
buildActionMask = 2147483647;
files = (
DA737EE61D05F91E005BDA16 /* v5_driving_dc_geojson.json in Resources */,
2BA2E748257A667500D7AFC6 /* incidents.json in Resources */,
DA1A10F31D010251009F82FA /* v5_driving_dc_polyline.json in Resources */,
2B54080B245B23BE006C820B /* incorrectRouteRefreshResponse.json in Resources */,
C5C0D6362058641B003A3B1D /* null-tracepoint.json in Resources */,
Expand Down Expand Up @@ -1324,6 +1337,7 @@
buildActionMask = 2147483647;
files = (
DA737EE41D05F91E005BDA16 /* v5_driving_dc_geojson.json in Resources */,
2BA2E746257A667500D7AFC6 /* incidents.json in Resources */,
DAC05F1C1CFC1E5300FA0071 /* v5_driving_dc_polyline.json in Resources */,
2B540809245B23BE006C820B /* incorrectRouteRefreshResponse.json in Resources */,
C5C0D6342058523E003A3B1D /* null-tracepoint.json in Resources */,
Expand Down Expand Up @@ -1444,6 +1458,7 @@
8D381B6B1FDB3D8A008D5A58 /* String.swift in Sources */,
F457FA7B252B9E29007DAEB1 /* Incident.swift in Sources */,
F4F5084C2524DC280044F2D0 /* AdministrativeRegion.swift in Sources */,
2BBBD08E257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */,
438BFEC3233D854D00457294 /* DirectionsProfileIdentifier.swift in Sources */,
F4CF2C582523B66300A6D0B6 /* TollCollection.swift in Sources */,
F4F508392524D6F10044F2D0 /* RestStop.swift in Sources */,
Expand Down Expand Up @@ -1530,6 +1545,7 @@
8D381B6C1FDB3D8B008D5A58 /* String.swift in Sources */,
F457FA7C252B9E29007DAEB1 /* Incident.swift in Sources */,
F4F5084D2524DC280044F2D0 /* AdministrativeRegion.swift in Sources */,
2BBBD08F257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */,
438BFEC4233D854D00457294 /* DirectionsProfileIdentifier.swift in Sources */,
F4CF2C592523B66300A6D0B6 /* TollCollection.swift in Sources */,
F4F5083A2524D6F10044F2D0 /* RestStop.swift in Sources */,
Expand Down Expand Up @@ -1616,6 +1632,7 @@
8D381B6D1FDB3D8B008D5A58 /* String.swift in Sources */,
F457FA7D252B9E29007DAEB1 /* Incident.swift in Sources */,
F4F5084E2524DC280044F2D0 /* AdministrativeRegion.swift in Sources */,
2BBBD090257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */,
438BFEC5233D854D00457294 /* DirectionsProfileIdentifier.swift in Sources */,
F4CF2C5A2523B66300A6D0B6 /* TollCollection.swift in Sources */,
F4F5083B2524D6F10044F2D0 /* RestStop.swift in Sources */,
Expand Down Expand Up @@ -1669,6 +1686,7 @@
C58EA7AA1E9D7EAD008F98CE /* Congestion.swift in Sources */,
F457FA7A252B9E29007DAEB1 /* Incident.swift in Sources */,
F4F5084B2524DC280044F2D0 /* AdministrativeRegion.swift in Sources */,
2BBBD08D257FA1CD004EB3D6 /* BlockedLanes.swift in Sources */,
8D381B6A1FDB101F008D5A58 /* String.swift in Sources */,
F4CF2C572523B66300A6D0B6 /* TollCollection.swift in Sources */,
F4F508382524D6F10044F2D0 /* RestStop.swift in Sources */,
Expand Down
7 changes: 6 additions & 1 deletion Sources/MapboxDirections/AdministrativeRegion.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import Foundation

/**
:nodoc:
`AdministrativeRegion` describes corresponding object on the route.
Udumft marked this conversation as resolved.
Show resolved Hide resolved

You can also use `Intersection.regionCode` or `RouteStep.regionCode(atStepIndex:, intersectionIndex:)` to retrieve ISO 3166-1 country code

- seealso: `Intersection.regionCode`, `RouteStep.regionCode(atStepIndex:, intersectionIndex:)`
*/
public struct AdministrativeRegion: Codable, Equatable {

Expand All @@ -11,7 +14,9 @@ public struct AdministrativeRegion: Codable, Equatable {
case countryCode = "iso_3166_1"
}

/// ISO 3166-1 alpha-3 country code
public var countryCodeAlpha3: String?
/// ISO 3166-1 country code
public var countryCode: String

public init(countryCode: String, countryCodeAlpha3: String) {
Expand Down
116 changes: 116 additions & 0 deletions Sources/MapboxDirections/BlockedLanes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

import Foundation

/// Defines a lane affected by the `Incident`
public struct BlockedLanes: OptionSet, CustomStringConvertible {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool, thanks for taking care of turning this type into an option set.

public var rawValue: Int
var stringKey: String?

public init(rawValue: Int) {
self.init(rawValue: rawValue, key: nil)
}

init(rawValue: Int, key: String?) {
self.rawValue = rawValue
self.stringKey = key
}

/// Left lane
public static let left = BlockedLanes(rawValue: 1 << 0, key: "LEFT")
/// Left center lane
///
/// Usually refers to the second lane from left on a four-lane highway
public static let leftCenter = BlockedLanes(rawValue: 1 << 1, key: "LEFT CENTER")
/// Left turn lane
public static let leftTurnLane = BlockedLanes(rawValue: 1 << 2, key: "LEFT TURN LANE")
/// Center lane
public static let center = BlockedLanes(rawValue: 1 << 3, key: "CENTER")
/// Right lane
public static let right = BlockedLanes(rawValue: 1 << 4, key: "RIGHT")
/// Right center lane
///
/// Usually refers to the second lane from right on a four-lane highway
public static let rightCenter = BlockedLanes(rawValue: 1 << 5, key: "RIGHT CENTER")
/// Right turn lane
public static let rightTurnLane = BlockedLanes(rawValue: 1 << 6, key: "RIGHT TURN LANE")
/// High occupancy vehicle lane
public static let highOccupancyVehicle = BlockedLanes(rawValue: 1 << 7, key: "HOV")
/// Side lane
public static let side = BlockedLanes(rawValue: 1 << 8, key: "SIDE")
/// Shoulder lane
public static let shoulder = BlockedLanes(rawValue: 1 << 9, key: "SHOULDER")
/// Median lane
public static let median = BlockedLanes(rawValue: 1 << 10, key: "MEDIAN")
/// 1st Lane.
public static let lane1 = BlockedLanes(rawValue: 1 << 11, key: "1")
/// 2nd Lane.
public static let lane2 = BlockedLanes(rawValue: 1 << 12, key: "2")
/// 3rd Lane.
public static let lane3 = BlockedLanes(rawValue: 1 << 13, key: "3")
/// 4th Lane.
public static let lane4 = BlockedLanes(rawValue: 1 << 14, key: "4")
/// 5th Lane.
public static let lane5 = BlockedLanes(rawValue: 1 << 15, key: "5")
/// 6th Lane.
public static let lane6 = BlockedLanes(rawValue: 1 << 16, key: "6")
/// 7th Lane.
public static let lane7 = BlockedLanes(rawValue: 1 << 17, key: "7")
/// 8th Lane.
public static let lane8 = BlockedLanes(rawValue: 1 << 18, key: "8")
/// 9th Lane.
public static let lane9 = BlockedLanes(rawValue: 1 << 19, key: "9")
/// 10th Lane.
public static let lane10 = BlockedLanes(rawValue: 1 << 20, key: "10")

static var allLanes: [BlockedLanes] {
return [.left, .leftCenter, .leftTurnLane, .center, .right, .rightCenter, .rightTurnLane, .highOccupancyVehicle, .side, .shoulder, .median, .lane1, .lane2, .lane3, .lane4, .lane5, .lane6, .lane7, .lane8, .lane9, .lane10]
}

/**
Creates a `BlockedLanes` given an array of strings.

Resulting options set will only contain known values. If string description does not match any known `Blocked Lane` identifier - it will be ignored.
*/
public init?(descriptions: [String]) {
var blockedLanes: BlockedLanes = []
Self.allLanes.forEach {
if descriptions.contains($0.stringKey!) {
blockedLanes.insert($0)
}
}
self.init(rawValue: blockedLanes.rawValue)
}

/**
String representation of `BlockedLanes` options set.

Resulting description contains only texts for known options. Custom options will be ignored if any.
*/
public var description: String {
var descriptions: [String] = []
Self.allLanes.forEach {
if contains($0) {
descriptions.append($0.stringKey!)
}
}
return descriptions.joined(separator: ",")
}
}

extension BlockedLanes: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(description.components(separatedBy: ",").filter { !$0.isEmpty })
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let descriptions = try container.decode([String].self)
if let roadClasses = BlockedLanes(descriptions: descriptions){
self = roadClasses
}
else{
throw DirectionsError.invalidResponse(nil)
}
}
}
Loading