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

Expose road classes in route steps #154

Merged
merged 9 commits into from
Jul 20, 2017
Merged

Expose road classes in route steps #154

merged 9 commits into from
Jul 20, 2017

Conversation

bsudekum
Copy link

The directions API will soon return a class type: toll, restricted,highway and ferry.

This array is found on the intersections key and represents the class type in between each intersection.

The test fixtures are so large right now that working through this task is becoming cumbersome. Going to hold off on this until the API returns the actual keys I'm looking for.

/cc @1ec5 @frederoni


@objc(MBRoadClass)
public enum RoadClass: Int, CustomStringConvertible {
case toll
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, the specific classes values coming out of the Directions API are dependent on the profile, correct? If there’s a possibility that a different profile might produce exotic values, we should turn this enum into an extensible string enumeration. (MBDirectionsProfileIdentifier is an example of an extensible string enumeration.) Otherwise, we’d have to document the fact that unrecognized classes could be dropped entirely.

level = .toll
case "restricted":
level = .restricted
case "highway":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently the Directions API will use a motorway class, not a highway class.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1ec5 I've been told by @TheMarex it will be toll, restricted,highway and ferry.

@TheMarex is this the case?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Urg sorry this was my fault. motorway is correct.

@@ -50,6 +50,8 @@ public class Intersection: NSObject, NSSecureCoding {
*/
public let usableApproachLanes: IndexSet?

public let roadClasses: [RoadClass]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An array of enumeration values won’t bridge very cleanly to Objective-C. Additionally, the order of classes doesn’t matter. So we should turn the RoadClass enumeration into a RoadClasses option set (implemented using NS_OPTION in Objective-C), then change this property’s type to simply RoadClasses.

@bsudekum
Copy link
Author

@1ec5 this is ready for review (still need to document).

@1ec5 1ec5 changed the title Add RouteClass handling [WIP] Expose road classes in route steps Jul 20, 2017
@@ -0,0 +1,10 @@
typedef NS_OPTIONS(NSUInteger, MBRoadClasses) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Objective-C files need to import headers for the types they use. This header uses NSUInteger, which is part of Foundation, so import Foundation.h. (This also applies to MBAttribute.h and MBLaneIndication.h.)

@@ -0,0 +1,10 @@
typedef NS_OPTIONS(NSUInteger, MBRoadClasses) {

MBRoadClassesToll = (1 << 1),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MBRoadClasses and its types each need documentation comments.


MBRoadClassesMotorway = (1 << 3),

MBRoadClassesFerry = (1 << 4),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation comment for this value should discuss its relationship to the ferry transport type, and the documentation for that transport type should likewise refer to this road class.


extension RoadClasses: CustomStringConvertible {

public init?(descriptions: [String]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This initializer needs a documentation comment as well.


public var description: String {
if isEmpty {
return "none"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to round-trip a road class from an array of strings to a RoadClasses and back to a string. Is none a valid string that would appear in a route response? If not, maybe an empty string would be better. Unfortunately, our hands our kind of tied because CustomStringConvertible doesn’t allow for an optional description.

@@ -69,6 +69,8 @@ class V5Tests: XCTestCase {
let leg = route!.legs.first!
XCTAssertEqual(leg.name, "I 80, I 80;US 30")
XCTAssertEqual(leg.steps.count, 59)
let roadClasses = leg.steps.first!.intersections!.first!.roadClasses!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before ! force-unwrapping steps.first and intersections and intersections.first and roadClasses, we should assert that each of these things are non-nil or non-empty. Otherwise we’ll have an unhelpful assertion message when the following assertion fails.

@@ -69,6 +69,8 @@ class V5Tests: XCTestCase {
let leg = route!.legs.first!
XCTAssertEqual(leg.name, "I 80, I 80;US 30")
XCTAssertEqual(leg.steps.count, 59)
let roadClasses = leg.steps.first!.intersections!.first!.roadClasses!
XCTAssertTrue(roadClasses.contains([.toll, .restricted]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent the test harness from crashing when any of these things is nil, use optionals:

let firstStep = leg.steps.first // as opposed to step below
XCTAssertNotNil(firstStep)
let intersections = firstStep?.intersections
XCTAssertNotNil(intersections)
let intersection = intersections?.first
XCTAssertNotNil(intersection)
let roadClasses = intersection?.roadClasses
XCTAssertNotNil(roadClasses)
XCTAssertTrue(roadClasses?.contains([.toll, .restricted]) ?? false)

@bsudekum bsudekum mentioned this pull request Jul 20, 2017
1 task
@bsudekum bsudekum merged commit 08c9516 into master Jul 20, 2017
@bsudekum bsudekum deleted the class branch July 20, 2017 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants