Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,31 +256,32 @@ open class RouteController: NSObject {
}

let nearByCoordinates = routeProgress.currentLegProgress.nearbyCoordinates
guard let closest = closestCoordinate(on: nearByCoordinates, to: location.coordinate) else { return location }
let slicedLine = polyline(along: nearByCoordinates, from: closest.coordinate, to: nearByCoordinates.last)
let userDistanceBuffer = location.speed * RouteControllerDeadReckoningTimeInterval

// Get closest point infront of user
guard let pointOneSliced = coordinate(at: userDistanceBuffer, fromStartOf: slicedLine) else { return location }
guard let pointOneClosest = closestCoordinate(on: nearByCoordinates, to: pointOneSliced) else { return location }
guard let pointTwoSliced = coordinate(at: userDistanceBuffer * 2, fromStartOf: slicedLine) else { return location }
guard let pointTwoClosest = closestCoordinate(on: nearByCoordinates, to: pointTwoSliced) else { return location }
guard let closest = closestCoordinate(on: nearByCoordinates, to: location.coordinate) else { return nil }

let slicedLineBehind = polyline(along: nearByCoordinates.reversed(), from: closest.coordinate, to: nearByCoordinates.reversed().last)
let slicedLineInfront = polyline(along: nearByCoordinates, from: closest.coordinate, to: nearByCoordinates.last)
let userDistanceBuffer: CLLocationDistance = location.speed * RouteControllerDeadReckoningTimeInterval / 2

guard let pointBehind = coordinate(at: userDistanceBuffer, fromStartOf: slicedLineBehind) else { return nil }
guard let pointBehindClosest = closestCoordinate(on: nearByCoordinates, to: pointBehind) else { return nil }
guard let pointAhead = coordinate(at: userDistanceBuffer, fromStartOf: slicedLineInfront) else { return nil }
guard let pointAheadClosest = closestCoordinate(on: nearByCoordinates, to: pointAhead) else { return nil }

// Get direction of these points
let pointOneDirection = closest.coordinate.direction(to: pointOneClosest.coordinate)
let pointTwoDirection = closest.coordinate.direction(to: pointTwoClosest.coordinate)
let wrappedPointOne = wrap(pointOneDirection, min: -180, max: 180)
let wrappedPointTwo = wrap(pointTwoDirection, min: -180, max: 180)
let pointBehindDirection = pointBehindClosest.coordinate.direction(to: closest.coordinate)
let pointAheadDirection = closest.coordinate.direction(to: pointAheadClosest.coordinate)
let wrappedPointBehind = wrap(pointBehindDirection, min: -180, max: 180)
let wrappedPointAhead = wrap(pointAheadDirection, min: -180, max: 180)
let wrappedCourse = wrap(location.course, min: -180, max: 180)
let relativeAnglepointOne = wrap(wrappedPointOne - wrappedCourse, min: -180, max: 180)
let relativeAnglepointTwo = wrap(wrappedPointTwo - wrappedCourse, min: -180, max: 180)
let averageRelativeAngle = (relativeAnglepointOne + relativeAnglepointTwo) / 2
let relativeAnglepointBehind = wrap(wrappedPointBehind - wrappedCourse, min: -180, max: 180)
let relativeAnglepointAhead = wrap(wrappedPointAhead - wrappedCourse, min: -180, max: 180)
let averageRelativeAngle = (relativeAnglepointBehind + relativeAnglepointAhead) / 2
let absoluteDirection = wrap(wrappedCourse + averageRelativeAngle, min: 0 , max: 360)

// If the course is inaccurate and the user is on the route,
// calculate a rough estimate as to what the course should be at that point on the route.
if location.course <= 0 && snappedCoordinate.distance < RouteControllerUserLocationSnappingDistance {
let calculatedCourse = wrap((wrappedPointOne + wrappedPointTwo) / 2, min: 0 , max: 360)
let calculatedCourse = wrap((wrappedPointBehind + wrappedPointAhead) / 2, min: 0 , max: 360)
return CLLocation(coordinate: snappedCoordinate.coordinate, altitude: location.altitude, horizontalAccuracy: location.horizontalAccuracy, verticalAccuracy: location.verticalAccuracy, course: calculatedCourse, speed: location.speed, timestamp: location.timestamp)
}

Expand Down