mapbox / mapbox/mapbox-directions-swift

Add option to avoid specific geometries

Open
#662 2 comments 0 reactions 0 assignees View on GitHub
blocked feature jira-sync-complete platform parity
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.