Skip to content

Commit

Permalink
Merge pull request #219 from stadiamaps/feat/common/snapped-course
Browse files Browse the repository at this point in the history
feat: starting point for course snapping
  • Loading branch information
ianthetechie authored Sep 17, 2024
2 parents 73c0eac + 5889af5 commit fd5b8b1
Show file tree
Hide file tree
Showing 22 changed files with 422 additions and 68 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if useLocalFramework {
path: "./common/target/ios/libferrostar-rs.xcframework"
)
} else {
let releaseTag = "0.10.1"
let releaseTag = "0.11.0"
let releaseChecksum = "cc959191f3d066f628264c103e5ea0c3544664ffd0e61907e082d7f1a4d8c5d2"
binaryTarget = .binaryTarget(
name: "FerrostarCoreRS",
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ plugins {

allprojects {
group = "com.stadiamaps.ferrostar"
version = "0.10.1"
version = "0.11.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.Test
import uniffi.ferrostar.BoundingBox
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.ManeuverModifier
import uniffi.ferrostar.ManeuverType
Expand Down Expand Up @@ -132,7 +133,8 @@ class FerrostarCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

try {
// Tests that the core generates a request and attempts to process it, but throws due to the
Expand Down Expand Up @@ -179,7 +181,8 @@ class FerrostarCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))
val routes =
core.getRoutes(
initialLocation =
Expand Down Expand Up @@ -229,7 +232,8 @@ class FerrostarCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))
val routes =
core.getRoutes(
initialLocation =
Expand Down Expand Up @@ -299,7 +303,8 @@ class FerrostarCoreTest {
locationProvider = locationProvider,
foregroundServiceManager = foregroundServiceManager,
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

val deviationHandler = DeviationHandler()
core.deviationHandler = deviationHandler
Expand Down Expand Up @@ -348,7 +353,8 @@ class FerrostarCoreTest {
): RouteDeviation {
return RouteDeviation.OffRoute(42.0)
}
})))
}),
CourseFiltering.RAW))

assert(foregroundServiceManager.startCalled)
assert(deviationHandler.called)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import okhttp3.mock.rule
import okhttp3.mock.url
import org.junit.Assert.assertEquals
import org.junit.Test
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.NavigationControllerConfig
import uniffi.ferrostar.RouteDeviationTracking
Expand Down Expand Up @@ -252,7 +253,8 @@ class ValhallaCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

return runTest {
val routes =
Expand Down Expand Up @@ -299,7 +301,8 @@ class ValhallaCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None),
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW),
costingOptions = mapOf("auto" to mapOf("useTolls" to 0)))

return runTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.stadiamaps.ferrostar.core.service.ForegroundServiceManager
import java.net.URL
import java.time.Duration
import okhttp3.OkHttpClient
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.NavigationControllerConfig
import uniffi.ferrostar.RouteDeviationTracking
import uniffi.ferrostar.StepAdvanceMode
Expand Down Expand Up @@ -58,7 +59,8 @@ object AppModule {
NavigationControllerConfig(
StepAdvanceMode.RelativeLineStringDistance(
minimumHorizontalAccuracy = 25U, automaticAdvanceDistance = 10U),
RouteDeviationTracking.StaticThreshold(25U, 10.0)),
RouteDeviationTracking.StaticThreshold(25U, 10.0),
CourseFiltering.SNAP_TO_ROUTE),
costingOptions = mapOf("bicycle" to mapOf("use_roads" to 0.2)))

// Not all navigation apps will require this sort of extra configuration.
Expand All @@ -78,7 +80,8 @@ object AppModule {
NavigationControllerConfig(
StepAdvanceMode.RelativeLineStringDistance(
minimumHorizontalAccuracy = 25U, automaticAdvanceDistance = 10U),
RouteDeviationTracking.StaticThreshold(25U, 10.0)))
RouteDeviationTracking.StaticThreshold(25U, 10.0),
CourseFiltering.SNAP_TO_ROUTE))
}
}

Expand Down
3 changes: 2 additions & 1 deletion apple/DemoApp/Demo/DemoNavigationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ struct DemoNavigationView: View {
// You have a lot of flexibility here based on your use case.
let config = SwiftNavigationControllerConfig(
stepAdvance: .relativeLineStringDistance(minimumHorizontalAccuracy: 32, automaticAdvanceDistance: 10),
routeDeviationTracking: .staticThreshold(minimumHorizontalAccuracy: 25, maxAcceptableDeviation: 20)
routeDeviationTracking: .staticThreshold(minimumHorizontalAccuracy: 25, maxAcceptableDeviation: 20),
snappedLocationCourseFiltering: .snapToRoute
)

ferrostarCore = try! FerrostarCore(
Expand Down
3 changes: 2 additions & 1 deletion apple/DemoApp/Demo/Navigation Delegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class NavigationDelegate: FerrostarCoreDelegate {
let config = SwiftNavigationControllerConfig(
stepAdvance: .relativeLineStringDistance(minimumHorizontalAccuracy: 32,
automaticAdvanceDistance: 10),
routeDeviationTracking: .staticThreshold(minimumHorizontalAccuracy: 25, maxAcceptableDeviation: 20)
routeDeviationTracking: .staticThreshold(minimumHorizontalAccuracy: 25, maxAcceptableDeviation: 20),
snappedLocationCourseFiltering: .snapToRoute
)
try core.startNavigation(
route: route,
Expand Down
8 changes: 6 additions & 2 deletions apple/Sources/FerrostarCore/Models/ModelWrappers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ public enum SwiftRouteDeviationTracking {

/// A Swift wrapper around `UniFFI.NavigationControllerConfig`.
public struct SwiftNavigationControllerConfig {
public init(stepAdvance: StepAdvanceMode, routeDeviationTracking: SwiftRouteDeviationTracking) {
public init(stepAdvance: StepAdvanceMode,
routeDeviationTracking: SwiftRouteDeviationTracking,
snappedLocationCourseFiltering: CourseFiltering)
{
ffiValue = FerrostarCoreFFI.NavigationControllerConfig(
stepAdvance: stepAdvance,
routeDeviationTracking: routeDeviationTracking.ffiValue
routeDeviationTracking: routeDeviationTracking.ffiValue,
snappedLocationCourseFiltering: snappedLocationCourseFiltering
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@
}
}
}
},
"Start Navigation" : {

}
},
"version" : "1.0"
Expand Down
94 changes: 91 additions & 3 deletions apple/Sources/UniFFI/ferrostar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ public protocol NavigationControllerProtocol: AnyObject {
* Depending on the advancement strategy, this may be automatic.
* For other cases, it is desirable to advance to the next step manually (ex: walking in an
* urban tunnel). We leave this decision to the app developer and provide this as a convenience.
*
* This method is takes the intermediate state (e.g. from `update_user_location`) and advances if necessary.
* As a result, you do not to re-calculate things like deviation or the snapped user location (search this file for usage of this function).
*/
func advanceToNextStep(state: TripState) -> TripState

Expand Down Expand Up @@ -622,6 +625,9 @@ open class NavigationController:
* Depending on the advancement strategy, this may be automatic.
* For other cases, it is desirable to advance to the next step manually (ex: walking in an
* urban tunnel). We leave this decision to the app developer and provide this as a convenience.
*
* This method is takes the intermediate state (e.g. from `update_user_location`) and advances if necessary.
* As a result, you do not to re-calculate things like deviation or the snapped user location (search this file for usage of this function).
*/
open func advanceToNextStep(state: TripState) -> TripState {
try! FfiConverterTypeTripState.lift(try! rustCall {
Expand Down Expand Up @@ -1742,28 +1748,57 @@ public func FfiConverterTypeLocationSimulationState_lower(_ value: LocationSimul
}

public struct NavigationControllerConfig {
/**
* Configures when navigation advances to the next step in the route.
*/
public var stepAdvance: StepAdvanceMode
/**
* Configures when the user is deemed to be off course.
*
* NOTE: This is distinct from the action that is taken.
* It is only the determination that the user has deviated from the expected route.
*/
public var routeDeviationTracking: RouteDeviationTracking
/**
* Configures how the heading component of the snapped location is reported in [`TripState`].
*/
public var snappedLocationCourseFiltering: CourseFiltering

// Default memberwise initializers are never public by default, so we
// declare one manually.
public init(stepAdvance: StepAdvanceMode, routeDeviationTracking: RouteDeviationTracking) {
public init(
/**
* Configures when navigation advances to the next step in the route.
*/ stepAdvance: StepAdvanceMode,
/**
* Configures when the user is deemed to be off course.
*
* NOTE: This is distinct from the action that is taken.
* It is only the determination that the user has deviated from the expected route.
*/ routeDeviationTracking: RouteDeviationTracking,
/**
* Configures how the heading component of the snapped location is reported in [`TripState`].
*/ snappedLocationCourseFiltering: CourseFiltering
) {
self.stepAdvance = stepAdvance
self.routeDeviationTracking = routeDeviationTracking
self.snappedLocationCourseFiltering = snappedLocationCourseFiltering
}
}

public struct FfiConverterTypeNavigationControllerConfig: FfiConverterRustBuffer {
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NavigationControllerConfig {
try NavigationControllerConfig(
stepAdvance: FfiConverterTypeStepAdvanceMode.read(from: &buf),
routeDeviationTracking: FfiConverterTypeRouteDeviationTracking.read(from: &buf)
routeDeviationTracking: FfiConverterTypeRouteDeviationTracking.read(from: &buf),
snappedLocationCourseFiltering: FfiConverterTypeCourseFiltering.read(from: &buf)
)
}

public static func write(_ value: NavigationControllerConfig, into buf: inout [UInt8]) {
FfiConverterTypeStepAdvanceMode.write(value.stepAdvance, into: &buf)
FfiConverterTypeRouteDeviationTracking.write(value.routeDeviationTracking, into: &buf)
FfiConverterTypeCourseFiltering.write(value.snappedLocationCourseFiltering, into: &buf)
}
}

Expand Down Expand Up @@ -2619,6 +2654,59 @@ public func FfiConverterTypeWaypoint_lower(_ value: Waypoint) -> RustBuffer {
FfiConverterTypeWaypoint.lower(value)
}

// Note that we don't yet support `indirect` for enums.
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
/**
* Controls filtering/post-processing of user course by the [`NavigationController`].
*/

public enum CourseFiltering {
/**
* Snap the user's course to the current step's linestring using the next index in the step's geometry.
*/
case snapToRoute
/**
* Use the raw course as reported by the location provider with no processing.
*/
case raw
}

public struct FfiConverterTypeCourseFiltering: FfiConverterRustBuffer {
typealias SwiftType = CourseFiltering

public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CourseFiltering {
let variant: Int32 = try readInt(&buf)
switch variant {
case 1: return .snapToRoute

case 2: return .raw

default: throw UniffiInternalError.unexpectedEnumCase
}
}

public static func write(_ value: CourseFiltering, into buf: inout [UInt8]) {
switch value {
case .snapToRoute:
writeInt(&buf, Int32(1))

case .raw:
writeInt(&buf, Int32(2))
}
}
}

public func FfiConverterTypeCourseFiltering_lift(_ buf: RustBuffer) throws -> CourseFiltering {
try FfiConverterTypeCourseFiltering.lift(buf)
}

public func FfiConverterTypeCourseFiltering_lower(_ value: CourseFiltering) -> RustBuffer {
FfiConverterTypeCourseFiltering.lower(value)
}

extension CourseFiltering: Equatable, Hashable {}

public enum InstantiationError {
case JsonError
}
Expand Down Expand Up @@ -4079,7 +4167,7 @@ private var initializationResult: InitializationResult = {
if uniffi_ferrostar_checksum_func_location_simulation_from_route() != 47899 {
return InitializationResult.apiChecksumMismatch
}
if uniffi_ferrostar_checksum_method_navigationcontroller_advance_to_next_step() != 60524 {
if uniffi_ferrostar_checksum_method_navigationcontroller_advance_to_next_step() != 3820 {
return InitializationResult.apiChecksumMismatch
}
if uniffi_ferrostar_checksum_method_navigationcontroller_get_initial_state() != 63862 {
Expand Down
Loading

0 comments on commit fd5b8b1

Please sign in to comment.