Skip to content

Commit

Permalink
Merge pull request #721 from mapbox/pad-snapping
Browse files Browse the repository at this point in the history
Add support for Waypoint.allowsSnappingToStaticallyClosedRoad property
  • Loading branch information
chezzdev committed Aug 15, 2022
2 parents fe7fe98 + 6b63578 commit 51781a4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to Mapbox Directions for Swift

## main

* Added `Waypoint.allowsSnappingToStaticallyClosedRoad` property to allow snapping the waypoint’s location to a statically (long-term) closed part of a road. ([#721](https://github.com/mapbox/mapbox-directions-swift/pull/721))

## v2.6.0

* MapboxDirections now requires [Turf v2.4](https://github.com/mapbox/turf-swift/releases/tag/v2.4.0). ([#703](https://github.com/mapbox/mapbox-directions-swift/pull/703))
Expand Down
25 changes: 20 additions & 5 deletions Sources/MapboxDirections/DirectionsOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ open class DirectionsOptions: Codable {
mappedQueryItems["bearings"]?.components(separatedBy: ";"),
mappedQueryItems["radiuses"]?.components(separatedBy: ";"),
mappedQueryItems["waypoint_names"]?.components(separatedBy: ";"),
mappedQueryItems["snapping_include_closures"]?.components(separatedBy: ";")
mappedQueryItems["snapping_include_closures"]?.components(separatedBy: ";"),
mappedQueryItems["snapping_include_static_closures"]?.components(separatedBy: ";")
] as [[String]?]

let getElement: ((_ array: [String]?, _ index: Int) -> String?) = { array, index in
Expand All @@ -209,6 +210,10 @@ open class DirectionsOptions: Codable {
if let snaps = getElement(waypointsData[4], $0.offset) {
$0.element.allowsSnappingToClosedRoad = snaps == "true"
}

if let snapsToStaticallyClosed = getElement(waypointsData[5], $0.offset) {
$0.element.allowsSnappingToStaticallyClosedRoad = snapsToStaticallyClosed == "true"
}
}

waypoints.filter { $0.separatesLegs }.enumerated().forEach {
Expand Down Expand Up @@ -497,6 +502,10 @@ open class DirectionsOptions: Codable {
if let snapping = self.closureSnapping {
queryItems.append(URLQueryItem(name: "snapping_include_closures", value: snapping))
}

if let staticClosureSnapping = self.staticClosureSnapping {
queryItems.append(URLQueryItem(name: "snapping_include_static_closures", value: staticClosureSnapping))
}

return queryItems
}
Expand Down Expand Up @@ -560,10 +569,16 @@ open class DirectionsOptions: Codable {
}

internal var closureSnapping: String? {
guard waypoints.contains(where: \.allowsSnappingToClosedRoad) else {
return nil
}
return waypoints.map { $0.allowsSnappingToClosedRoad ? "true": ""}.joined(separator: ";")
makeStringFromBoolProperties(of: waypoints, for: \.allowsSnappingToClosedRoad)
}

internal var staticClosureSnapping: String? {
makeStringFromBoolProperties(of: waypoints, for: \.allowsSnappingToStaticallyClosedRoad)
}

private func makeStringFromBoolProperties<T>(of elements: [T], for keyPath: KeyPath<T, Bool>) -> String? {
guard elements.contains(where: { $0[keyPath: keyPath] }) else { return nil }
return elements.map { $0[keyPath: keyPath] ? "true" : "" }.joined(separator: ";")
}

internal var httpBody: String {
Expand Down
7 changes: 7 additions & 0 deletions Sources/MapboxDirections/Waypoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ public class Waypoint: Codable, ForeignMemberContainerClass {
If `true`, the waypoint may be snapped to a road segment that is closed due to a live traffic closure. This property is `false` by default. This property corresponds to the [`snapping_include_closures`](https://docs.mapbox.com/api/navigation/directions/#optional-parameters-for-the-mapboxdriving-traffic-profile) query parameter in the Mapbox Directions API.
*/
public var allowsSnappingToClosedRoad: Bool = false

/**
A Boolean value indicating whether the waypoint may be snapped to a statically (long-term) closed road in the resulting `RouteResponse`.
If `true`, the waypoint may be snapped to a road segment statically closed, that is long-term (for example, road under construction). This property is `false` by default. This property corresponds to the [`snapping_include_static_closures`](https://docs.mapbox.com/api/navigation/directions/#optional-parameters-for-the-mapboxdriving-traffic-profile) query parameter in the Mapbox Directions API.
*/
public var allowsSnappingToStaticallyClosedRoad: Bool = false

/**
The straight-line distance from the coordinate specified in the query to the location it was snapped to in the resulting `RouteResponse`.
Expand Down
2 changes: 2 additions & 0 deletions Tests/MapboxDirectionsTests/RouteOptionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class RouteOptionsTests: XCTestCase {
$0.element.targetCoordinate = $0.element.coordinate
}
$0.element.allowsSnappingToClosedRoad = $0.offset == 1
$0.element.allowsSnappingToStaticallyClosedRoad = $0.offset == 1
}

let url = Directions(credentials: BogusCredentials).url(forCalculating: originalOptions)
Expand All @@ -157,6 +158,7 @@ class RouteOptionsTests: XCTestCase {

zip(decodedWaypoints, originalOptions.waypoints).forEach {
XCTAssertEqual($0.0.allowsSnappingToClosedRoad, $0.1.allowsSnappingToClosedRoad)
XCTAssertEqual($0.0.allowsSnappingToStaticallyClosedRoad, $0.1.allowsSnappingToStaticallyClosedRoad)
XCTAssertEqual($0.0.allowsArrivingOnOppositeSide, $0.1.allowsArrivingOnOppositeSide)
XCTAssertEqual($0.0.targetCoordinate, $0.1.targetCoordinate)
XCTAssertEqual($0.0.separatesLegs, $0.1.separatesLegs)
Expand Down
23 changes: 20 additions & 3 deletions Tests/MapboxDirectionsTests/WaypointTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,30 @@ class WaypointTests: XCTestCase {
let from = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))
let to = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))
let through = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))

let routeOptions = RouteOptions(waypoints: [from, through, to])
let matchOptions = MatchOptions(waypoints: [from, through, to], profileIdentifier: nil)

through.allowsSnappingToClosedRoad = true

through.allowsSnappingToStaticallyClosedRoad = true

XCTAssertEqual(routeOptions.urlQueryItems.first { $0.name == "snapping_include_closures" }?.value, ";true;")
XCTAssertEqual(matchOptions.urlQueryItems.first { $0.name == "snapping_include_closures" }?.value, ";true;")
XCTAssertEqual(routeOptions.urlQueryItems.first { $0.name == "snapping_include_static_closures" }?.value, ";true;")
XCTAssertEqual(matchOptions.urlQueryItems.first { $0.name == "snapping_include_static_closures" }?.value, ";true;")
}

func testClosedRoadSnappingNotSet() {
let from = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))
let to = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))
let through = Waypoint(coordinate: LocationCoordinate2D(latitude: 0, longitude: 0))

let routeOptions = RouteOptions(waypoints: [from, through, to])
let matchOptions = MatchOptions(waypoints: [from, through, to], profileIdentifier: nil)

XCTAssertEqual(routeOptions.urlQueryItems.first { $0.name == "snapping_include_closures" }?.value, nil)
XCTAssertEqual(matchOptions.urlQueryItems.first { $0.name == "snapping_include_closures" }?.value, nil)
XCTAssertEqual(routeOptions.urlQueryItems.first { $0.name == "snapping_include_static_closures" }?.value, nil)
XCTAssertEqual(matchOptions.urlQueryItems.first { $0.name == "snapping_include_static_closures" }?.value, nil)
}
}

0 comments on commit 51781a4

Please sign in to comment.