Skip to content

Commit

Permalink
Merge pull request #2275 from mapbox/jerrad/delenda-duet
Browse files Browse the repository at this point in the history
Upgrade to post-Objective-C MapboxDirections.swift
  • Loading branch information
1ec5 authored Dec 26, 2019
2 parents f634a37 + a5942cb commit 298985d
Show file tree
Hide file tree
Showing 72 changed files with 1,422 additions and 734 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

### Other changes
* Since pure Swift protocols cannot have optional methods, various delegate protocols now provide default no-op implementations for all their methods and conform to the `UnimplementedLogging` protocol, which can inform you at runtime when a delegate method is called but has not been implemented. Messages are sent through Apple Unified Logging and can be disabled globally through [Unifed Logging](https://developer.apple.com/documentation/os/logging#2878594), or by overriding the delegate function with a no-op implementation. ([#2230](https://github.com/mapbox/mapbox-navigation-ios/pull/2230))
* Renamed `RouteProgress.nearbyCoordinates` to `RouteProgress.nearbyShape`. ([#2275](https://github.com/mapbox/mapbox-navigation-ios/pull/2275))
* Removed `RouteLegProgress.nearbyCoordinates`. ([#2275](https://github.com/mapbox/mapbox-navigation-ios/pull/2275))

## v0.38.1

Expand Down
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 5.2
binary "https://www.mapbox.com/ios-sdk/MapboxNavigationNative.json" ~> 6.2.1
github "mapbox/MapboxDirections.swift" ~> 0.30.0
github "mapbox/MapboxDirections.swift" "jerrad/delenda-duet-dependencies" #~> 0.30.0
github "mapbox/turf-swift" ~> 0.3
github "mapbox/mapbox-events-ios" ~> 0.9.5
github "ceeK/Solar" ~> 2.1.0
Expand Down
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ github "CedarBDD/Cedar" "v1.0"
github "Quick/Nimble" "v8.0.4"
github "Quick/Quick" "v2.2.0"
github "ceeK/Solar" "2.1.0"
github "mapbox/MapboxDirections.swift" "v0.30.0"
github "mapbox/MapboxDirections.swift" "472cbced199ef2d9c5c2fa49a21e8f6b249e9bf8"
github "mapbox/MapboxGeocoder.swift" "v0.10.2"
github "mapbox/mapbox-events-ios" "v0.9.5"
github "mapbox/mapbox-speech-swift" "v0.1.1"
Expand Down
4 changes: 2 additions & 2 deletions Example/AppDelegate+CarPlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ extension AppDelegate: CarPlayManagerDelegate {
}
}

func carPlayManager(_ carPlayManager: CarPlayManager, didFailToFetchRouteBetween waypoints: [Waypoint]?, options: RouteOptions, error: NSError) -> CPNavigationAlert? {
func carPlayManager(_ carPlayManager: CarPlayManager, didFailToFetchRouteBetween waypoints: [Waypoint]?, options: RouteOptions, error: DirectionsError) -> CPNavigationAlert? {
let okTitle = NSLocalizedString("CARPLAY_OK", bundle: .main, value: "OK", comment: "CPAlertTemplate OK button title")
let action = CPAlertAction(title: okTitle, style: .default, handler: {_ in })
let alert = CPNavigationAlert(titleVariants: [error.localizedDescription],
subtitleVariants: [error.localizedFailureReason ?? ""],
subtitleVariants: [error.failureReason ?? ""],
imageSet: nil,
primaryAction: action,
secondaryAction: nil,
Expand Down
18 changes: 8 additions & 10 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import UserNotifications
import AVKit

private typealias RouteRequestSuccess = (([Route]) -> Void)
private typealias RouteRequestFailure = ((NSError) -> Void)
private typealias RouteRequestFailure = ((Error) -> Void)

class ViewController: UIViewController {
// MARK: - IBOutlets
Expand Down Expand Up @@ -205,15 +205,13 @@ class ViewController: UIViewController {
}

fileprivate func requestRoute(with options: RouteOptions, success: @escaping RouteRequestSuccess, failure: RouteRequestFailure?) {
let handler: Directions.RouteCompletionHandler = { (waypoints, routes, error) in
// Calculate route offline if an offline version is selected
let shouldUseOfflineRouting = Settings.selectedOfflineVersion != nil
Settings.directions.calculate(options, offline: shouldUseOfflineRouting) { (waypoints, routes, error) in
if let error = error { failure?(error) }
guard let routes = routes else { return }
return success(routes)
}

// Calculate route offline if an offline version is selected
let shouldUseOfflineRouting = Settings.selectedOfflineVersion != nil
Settings.directions.calculate(options, offline: shouldUseOfflineRouting, completionHandler: handler)
}

// MARK: Basic Navigation
Expand Down Expand Up @@ -267,7 +265,7 @@ class ViewController: UIViewController {
customViewController.userRoute = route

let destination = MGLPointAnnotation()
destination.coordinate = route.coordinates!.last!
destination.coordinate = route.shape!.coordinates.last!
customViewController.destination = destination
customViewController.simulateLocation = simulationButton.isSelected

Expand Down Expand Up @@ -363,8 +361,8 @@ extension ViewController: MGLMapViewDelegate {

self.mapView?.localizeLabels()

if let routes = routes, let currentRoute = routes.first, let coords = currentRoute.coordinates {
mapView.setVisibleCoordinateBounds(MGLPolygon(coordinates: coords, count: currentRoute.coordinateCount).overlayBounds, animated: false)
if let routes = routes, let currentRoute = routes.first, let coords = currentRoute.shape?.coordinates {
mapView.setVisibleCoordinateBounds(MGLPolygon(coordinates: coords, count: UInt(coords.count)).overlayBounds, animated: false)
self.mapView?.show(routes)
self.mapView?.showWaypoints(on: currentRoute)
}
Expand All @@ -384,7 +382,7 @@ extension ViewController: NavigationMapViewDelegate {

func navigationMapView(_ mapView: NavigationMapView, didSelect route: Route) {
guard let routes = routes else { return }
guard let index = routes.firstIndex(where: { $0 == route }) else { return }
guard let index = routes.firstIndex(where: { $0 === route }) else { return }
self.routes!.remove(at: index)
self.routes!.insert(route, at: 0)
}
Expand Down
39 changes: 19 additions & 20 deletions MapboxCoreNavigation/CLLocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension CLLocation {
Returns a Boolean value indicating whether the receiver is within a given distance of a route step.
*/
func isWithin(_ maximumDistance: CLLocationDistance, of routeStep: RouteStep) -> Bool {
guard let closestCoordinate = Polyline(routeStep.coordinates!).closestCoordinate(to: coordinate) else {
guard let shape = routeStep.shape, let closestCoordinate = shape.closestCoordinate(to: coordinate) else {
return false
}
return closestCoordinate.distance < maximumDistance
Expand All @@ -50,14 +50,14 @@ extension CLLocation {

func snapped(to routeProgress: RouteProgress) -> CLLocation? {
let legProgress = routeProgress.currentLegProgress
let coords = coordinates(for: routeProgress)
let polyline = snappingPolyline(for: routeProgress)

guard let closest = Polyline(coords).closestCoordinate(to: coordinate) else { return nil }
guard let calculatedCourseForLocationOnStep = interpolatedCourse(along: coords) else { return nil }
guard let closest = polyline.closestCoordinate(to: coordinate) else { return nil }
guard let calculatedCourseForLocationOnStep = interpolatedCourse(along: polyline) else { return nil }

let userCourse = calculatedCourseForLocationOnStep
let userCoordinate = closest.coordinate
guard let firstCoordinate = legProgress.leg.steps.first?.coordinates?.first else { return nil }
guard let firstCoordinate = legProgress.leg.steps.first?.shape?.coordinates.first else { return nil }

guard shouldSnap(toRouteWith: calculatedCourseForLocationOnStep, distanceToFirstCoordinateOnLeg: self.coordinate.distance(to: firstCoordinate)) else { return nil }

Expand All @@ -67,10 +67,10 @@ extension CLLocation {
/**
Calculates the proper coordinates to use when calculating a snapped location.
*/
func coordinates(for routeProgress: RouteProgress) -> [CLLocationCoordinate2D] {
func snappingPolyline(for routeProgress: RouteProgress) -> Polyline {
let legProgress = routeProgress.currentLegProgress
let nearbyCoordinates = routeProgress.nearbyCoordinates
let stepCoordinates = legProgress.currentStep.coordinates!
let nearbyPolyline = routeProgress.nearbyShape
let stepPolyline = legProgress.currentStep.shape!

// If the upcoming maneuver a sharp turn, only look at the current step for snapping.
// Otherwise, we may get false positives from nearby step coordinates
Expand All @@ -79,37 +79,36 @@ extension CLLocation {
let finalHeading = upcomingStep.finalHeading {
// The max here is 180. The closer it is to 180, the sharper the turn.
if initialHeading.clockwiseDifference(from: finalHeading) > 180 - RouteSnappingMaxManipulatedCourseAngle {
return stepCoordinates
return stepPolyline
}

if finalHeading.difference(from: course) > RouteControllerMaximumAllowedDegreeOffsetForTurnCompletion {
return stepCoordinates
return stepPolyline
}
}

if speed <= RouteControllerMaximumSpeedForUsingCurrentStep {
return stepCoordinates
return stepPolyline
}

return nearbyCoordinates
return nearbyPolyline
}

/**
Given a location and a series of coordinates, compute what the course should be for a the location.
*/
func interpolatedCourse(along coordinates: [CLLocationCoordinate2D]) -> CLLocationDirection? {
let nearByPolyline = Polyline(coordinates)
func interpolatedCourse(along polyline: Polyline) -> CLLocationDirection? {
guard let closest = polyline.closestCoordinate(to: coordinate) else { return nil }

guard let closest = nearByPolyline.closestCoordinate(to: coordinate) else { return nil }

let slicedLineBehind = Polyline(coordinates.reversed()).sliced(from: closest.coordinate, to: coordinates.reversed().last)
let slicedLineInFront = nearByPolyline.sliced(from: closest.coordinate, to: coordinates.last)
let reversedPolyline = Polyline(polyline.coordinates.reversed())
let slicedLineBehind = reversedPolyline.sliced(from: closest.coordinate, to: reversedPolyline.coordinates.last)
let slicedLineInFront = polyline.sliced(from: closest.coordinate, to: polyline.coordinates.last)
let userDistanceBuffer: CLLocationDistance = max(speed * RouteControllerDeadReckoningTimeInterval / 2, RouteControllerUserLocationSnappingDistance / 2)

guard let pointBehind = slicedLineBehind.coordinateFromStart(distance: userDistanceBuffer) else { return nil }
guard let pointBehindClosest = nearByPolyline.closestCoordinate(to: pointBehind) else { return nil }
guard let pointBehindClosest = polyline.closestCoordinate(to: pointBehind) else { return nil }
guard let pointAhead = slicedLineInFront.coordinateFromStart(distance: userDistanceBuffer) else { return nil }
guard let pointAheadClosest = nearByPolyline.closestCoordinate(to: pointAhead) else { return nil }
guard let pointAheadClosest = polyline.closestCoordinate(to: pointAhead) else { return nil }

// Get direction of these points
let pointBehindDirection = pointBehindClosest.coordinate.direction(to: closest.coordinate)
Expand Down
2 changes: 1 addition & 1 deletion MapboxCoreNavigation/CoreFeedbackEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FeedbackEvent: CoreFeedbackEvent {

class RerouteEvent: CoreFeedbackEvent {
func update(newRoute: Route) {
if let geometry = newRoute.coordinates {
if let geometry = newRoute.shape?.coordinates {
eventDictionary["newGeometry"] = Polyline(coordinates: geometry).encodedPolyline
eventDictionary["newDistanceRemaining"] = round(newRoute.distance)
eventDictionary["newDurationRemaining"] = round(newRoute.expectedTravelTime)
Expand Down
18 changes: 9 additions & 9 deletions MapboxCoreNavigation/EventDetails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ struct NavigationEventDetails: EventDetails {
requestIdentifier = dataSource.routeProgress.route.routeIdentifier

if let location = dataSource.router.rawLocation,
let coordinates = dataSource.routeProgress.route.coordinates,
let coordinates = dataSource.routeProgress.route.shape?.coordinates,
let lastCoord = coordinates.last {
userAbsoluteDistanceToDestination = location.distance(from: CLLocation(latitude: lastCoord.latitude, longitude: lastCoord.longitude))
} else {
userAbsoluteDistanceToDestination = nil
}

if let geometry = session.originalRoute.coordinates {
originalGeometry = Polyline(coordinates: geometry)
if let shape = session.originalRoute.shape {
originalGeometry = Polyline(coordinates: shape.coordinates)
originalDistance = round(session.originalRoute.distance)
originalEstimatedDuration = round(session.originalRoute.expectedTravelTime)
originalStepCount = session.originalRoute.legs.map({$0.steps.count}).reduce(0, +)
Expand All @@ -139,8 +139,8 @@ struct NavigationEventDetails: EventDetails {
originalStepCount = nil
}

if let geometry = session.currentRoute.coordinates {
self.geometry = Polyline(coordinates: geometry)
if let shape = session.currentRoute.shape {
self.geometry = Polyline(coordinates: shape.coordinates)
distance = round(session.currentRoute.distance)
estimatedDuration = round(session.currentRoute.expectedTravelTime)
} else {
Expand Down Expand Up @@ -314,12 +314,12 @@ extension RouteLegProgress: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(upcomingStep?.instructions, forKey: .upcomingInstruction)
try container.encodeIfPresent(upcomingStep?.maneuverType.description, forKey: .upcomingType)
try container.encodeIfPresent(upcomingStep?.maneuverDirection.description, forKey: .upcomingModifier)
try container.encodeIfPresent(upcomingStep?.maneuverType, forKey: .upcomingType)
try container.encodeIfPresent(upcomingStep?.maneuverDirection, forKey: .upcomingModifier)
try container.encodeIfPresent(upcomingStep?.names?.joined(separator: ";"), forKey: .upcomingName)
try container.encodeIfPresent(currentStep.instructions, forKey: .previousInstruction)
try container.encode(currentStep.maneuverType.description, forKey: .previousType)
try container.encode(currentStep.maneuverDirection.description, forKey: .previousModifier)
try container.encode(currentStep.maneuverType, forKey: .previousType)
try container.encode(currentStep.maneuverDirection, forKey: .previousModifier)
try container.encode(currentStep.names?.joined(separator: ";"), forKey: .previousName)
try container.encode(Int(currentStep.distance), forKey: .distance)
try container.encode(Int(currentStep.expectedTravelTime), forKey: .duration)
Expand Down
Loading

0 comments on commit 298985d

Please sign in to comment.