Skip to content

Commit

Permalink
Support multiple road classes in RouteOptions.roadClassesToAvoid an…
Browse files Browse the repository at this point in the history
…d `RouteOptions.roadClassesToAllow` properties (#664)

* Support multiple `.roadClassesToAvoid` and `.roadClassesToAllow` parameters

* Update changelog

* Update documentation for road classes.

* Update documentation for `.restricted` and `.tunnel` RoadClasses

* Remove hardcoded supported road classes and assertions

* Update changelog

* Fix route options tests
  • Loading branch information
azarovalex committed Mar 18, 2022
1 parent 2db7fda commit eb7b3b4
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 13 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes to Mapbox Directions for Swift

## v2.4.0

* Fixed a crash that occurred when `RouteOptions.roadClassesToAvoid` or `RouteOptions.roadClassesToAllow` properties contained multiple road classes.
* `RoadClasses.tunnel` and `RoadClasses.restricted` are no longer supported in `RouteOptions.roadClassesToAvoid` or `RouteOptions.roadClassesToAllow` properties

## v2.3.0

* Added `VisualInstruction.Component.ShieldRepresentation` struct and the `VisualInstruction.Component.ImageRepresentation.shield` property containing metadata for displaying a highway shield consistent with map styles used by the Mapbox Maps SDK. ([#644](https://github.com/mapbox/mapbox-directions-swift/pull/644), [#647](https://github.com/mapbox/mapbox-directions-swift/pull/647))
Expand Down
8 changes: 4 additions & 4 deletions Sources/MapboxDirections/RoadClasses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public struct RoadClasses: OptionSet, CustomStringConvertible {
The road segment has access restrictions.
A road segment may have this class if there are [general access restrictions](https://wiki.openstreetmap.org/wiki/Key:access) or a [high-occupancy vehicle](https://wiki.openstreetmap.org/wiki/Key:hov) restriction.
This option can only be used with `RouteOptions.roadClassesToAvoid`.
This option **cannot** be used with `RouteOptions.roadClassesToAvoid` or `RouteOptions.roadClassesToAllow`.
*/
public static let restricted = RoadClasses(rawValue: 1 << 2)

Expand All @@ -48,8 +48,8 @@ public struct RoadClasses: OptionSet, CustomStringConvertible {

/**
The user must travel this segment of the route through a [tunnel](https://wiki.openstreetmap.org/wiki/Key:tunnel).
This option can only be used with `RouteOptions.roadClassesToAvoid`.
This option **cannot** be used with `RouteOptions.roadClassesToAvoid` or `RouteOptions.roadClassesToAllow`.
*/
public static let tunnel = RoadClasses(rawValue: 1 << 5)

Expand Down
16 changes: 7 additions & 9 deletions Sources/MapboxDirections/RouteOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,17 +348,15 @@ open class RouteOptions: DirectionsOptions {
if let speed = speed {
params.append(URLQueryItem(name: CodingKeys.speed.stringValue, value: String(speed)))
}

if !roadClassesToAvoid.isEmpty && roadClassesToAvoid.isDisjoint(with: [.highOccupancyVehicle2, .highOccupancyVehicle3, .highOccupancyToll]) {
let allRoadClasses = roadClassesToAvoid.description.components(separatedBy: ",").filter { !$0.isEmpty }
precondition(allRoadClasses.count < 2, "You can only avoid one road class at a time.")
if let firstRoadClass = allRoadClasses.first {
params.append(URLQueryItem(name: CodingKeys.roadClassesToAvoid.stringValue, value: firstRoadClass))
}

if !roadClassesToAvoid.isEmpty {
let roadClasses = roadClassesToAvoid.description
params.append(URLQueryItem(name: CodingKeys.roadClassesToAvoid.stringValue, value: roadClasses))
}

if !roadClassesToAllow.isEmpty && roadClassesToAllow.isSubset(of: [.highOccupancyVehicle2, .highOccupancyVehicle3, .highOccupancyToll]) {
params.append(URLQueryItem(name: CodingKeys.roadClassesToAllow.stringValue, value: roadClassesToAllow.description))
if !roadClassesToAllow.isEmpty {
let parameterValue = roadClassesToAllow.description
params.append(URLQueryItem(name: CodingKeys.roadClassesToAllow.stringValue, value: parameterValue))
}

if refreshingEnabled && profileIdentifier == .automobileAvoidingTraffic {
Expand Down
12 changes: 12 additions & 0 deletions Tests/MapboxDirectionsTests/RouteOptionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,18 @@ class RouteOptionsTests: XCTestCase {
XCTAssertTrue(options.urlQueryItems.contains(URLQueryItem(name: "max_width", value: String(widthValue))))
XCTAssertTrue(options.urlQueryItems.contains(URLQueryItem(name: "max_height", value: String(heightValue))))
}

func testExcludeAndIncludeRoadClasses() {
let options = RouteOptions(coordinates: [])
options.roadClassesToAvoid = [.toll, .motorway, .ferry, .unpaved, .cashTollOnly]
options.roadClassesToAllow = [.highOccupancyVehicle2, .highOccupancyVehicle3, .highOccupancyToll]

let expectedExcludeQueryItem = URLQueryItem(name: "exclude", value: "toll,motorway,ferry,unpaved,cash_only_toll")
XCTAssertTrue(options.urlQueryItems.contains(expectedExcludeQueryItem))

let expectedIncludeQueryItem = URLQueryItem(name: "include", value: "hov2,hov3,hot")
XCTAssertTrue(options.urlQueryItems.contains(expectedIncludeQueryItem))
}
}

fileprivate let testCoordinates = [
Expand Down

0 comments on commit eb7b3b4

Please sign in to comment.