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

Add option to avoid specific geometries #662

Open
1ec5 opened this issue Mar 11, 2022 · 2 comments
Open

Add option to avoid specific geometries #662

1ec5 opened this issue Mar 11, 2022 · 2 comments
Labels
blocked Blocked by dependency or unclarity. feature New feature request. jira-sync-complete platform parity

Comments

@1ec5
Copy link
Contributor

1ec5 commented Mar 11, 2022

The Directions API recently overloaded the exclude query parameter with an option to specify a list of point geometries in WKT format. 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.

case roadClassesToAvoid = "exclude"
/**
The route classes that the calculated routes will avoid.
Currently, you can only specify a single road class to avoid.
*/
open var roadClassesToAvoid: RoadClasses = []
/**
Option set that contains attributes of a road segment.
*/
public struct RoadClasses: OptionSet, CustomStringConvertible {

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:

/**
  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

@1ec5 1ec5 added platform parity blocked Blocked by dependency or unclarity. feature New feature request. labels Mar 11, 2022
@Guardiola31337
Copy link

cc @VysotskiVadim for visibility

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 19, 2022

#748 introduced a CustomValueOptionSet protocol that makes it easier to specify a custom AttributeOptions that’s otherwise unsupported by this library. However, RoadClasses does not conform to this protocol, so the workaround above is still required until we implement this feature.

/cc @Udumft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked by dependency or unclarity. feature New feature request. jira-sync-complete platform parity
Projects
None yet
Development

No branches or pull requests

3 participants