mapbox / mapbox/mapbox-directions-swift
Add option to avoid specific geometries
- Dominant language
- Swift
- Stars
- 206
- Forks
- 99
- Avg merge
- 7h 54m
- Merged PRs (30d)
- 3
Description
The Directions API recently overloaded the `exclude` query parameter with an option to specify a list of point geometries in [WKT format](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry). We should add support for this syntax to serve certain use cases that require arbitrary avoidance. This would also help us achieve platform parity with the Java SDK, which implemented the feature in mapbox/mapbox-java#1362. However, it should not be implemented until the new `exclude` syntax leaves beta and becomes a formal part of the API contract.
## Design
The overloading of `exclude` is particularly problematic for this library, which has always exposed `exclude` as an option set. But now it can hold arbitrary geometry data, which needs to be typed as a Geometry. Unfortunately, an OptionSet struct can’t store associated values, so there’s no way for us to support this syntax without breaking backwards compatibility. Besides, a geometry is semantically different than a road class.
https://github.com/mapbox/mapbox-directions-swift/blob/2b14b8c276523a01dc730897593990ef83c71320/Sources/MapboxDirections/RouteOptions.swift#L57 https://github.com/mapbox/mapbox-directions-swift/blob/2b14b8c276523a01dc730897593990ef83c71320/Sources/MapboxDirections/RouteOptions.swift#L152-L157 https://github.com/mapbox/mapbox-directions-swift/blob/2b14b8c276523a01dc730897593990ef83c71320/Sources/MapboxDirections/RoadClasses.swift#L3-L6
Perhaps this conflation in the API can be revisited in light of the semantic awkwardness that becomes apparent in Swift. Regardless, we can implement a parallel property, `shapeToAvoid`, declared as type `Geometry?`, with the expectation of being set to a `MultiPoint` until more geometry types are implemented on the server side. RouteOptions’ Codable implementation can switch between `roadClassesToAvoid` and `shapeToAvoid` depending on the value. This feature depends on Turf adding support for converting between WKT and GeoJSON: mapbox/turf-swift#185.
## Workaround
Until we’re able to formally add support for this syntax, a developer can [hook into the beta parameter themselves](https://docs.mapbox.com/ios/navigation/examples/beta-query-parameters/):
```swift
/**
Route options for avoiding known [pedestrian scrambles](https://en.wikipedia.org/wiki/Pedestrian_scramble).
*/
class UnscrambledRouteOptions: RouteOptions {
/// The locations of some known pedestrian scrambles to avoid.
let scrambles = MultiPoint([
.init(latitude: 39.3184214, longitude: -84.3689036),
.init(latitude: 39.3109335, longitude: -84.3798639),
.init(latitude: 37.3383465, longitude: -121.8807453),
.init(latitude: 37.3330494, longitude: -121.8796307),
])
override var urlQueryItems: [URLQueryItem] {
var items = super.urlQueryItems
let wktToAvoid = scrambles.coordinates
.map { "point(\($0.longitude) \($0.latitude)" }
.joined(separator: ",")
items.append(.init(name: "exclude", value: wktToAvoid))
return items
}
}
```
/cc @ShrayKhullarMX @Guardiola31337
Contributor guide
Research direction
Start with RouteOptions.swift and RoadClasses.swift at the linked definitions, then check the Turf Swift issue for WKT and GeoJSON conversion support. This should wait until the Directions API syntax is formalized; done means exposing the geometry option without breaking existing road-class exclusions and supporting the documented encoding.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- api
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100