Ferrostar Navigation SDK
repository·main·Indexed 18 days ago
https://github.com/stadiamaps/ferrostarA Free and Open Source Software (FOSS) navigation SDK for modern mobile and web platforms. Ferrostar provides a navigation state machine, spatial algorithms, and core data models, offering platform-specific implementations for Android (including MapLibre Compose integration), iOS (via FerrostarCore Swift package), and React Native (@stadiamaps/ferrostar-core-react-native). It utilizes a core engine written in Rust with UniFFI bindings to manage navigation logic, routing backends, and location updates.
What's inside Ferrostar
- FerrostarCore is a Swift package designed to act as a high-level interface for the Ferrostar core. It manages interactions with the core and provides essential services, such as location updates, to the core engine. Its primary purpose is to abstract away the complexity of the Foreign Function Interface (FFI) bindings, ensuring that developers using the Navigation SDK do not need to interact with the low-level FFI layer directly.
What is Ferrostar Core?
mainFerrostar is a modern SDK designed for building turn-by-turn navigation applications. The core package provides the foundational logic required for navigation without being tied to a specific UI framework. It includes:
- The navigation state machine
- Common business logic
- Spatial algorithms
- Core data models
Use the core package if you are porting Ferrostar to a new platform or if you intend to build a custom user interface from scratch.
What is Ferrostar?
mainFerrostar is a modern, open-source SDK designed for building custom turn-by-turn navigation applications.
Key characteristics:
- Core Engine: Written in Rust for high performance and easy porting.
- Platform Native: Uses Swift for iOS and Kotlin for Android to leverage platform-specific features.
- Batteries Included: Provides bundled navigation UIs that are usable out of the box but are highly composable using SwiftUI, Jetpack Compose, and Web Components.
- Extensible: Allows developers to replace core logic, such as bringing their own offline routing or custom off-route detection logic.
- Vendor-Neutral: Does not upload telemetry to any specific vendor and supports multiple routing/map providers.
Note: Ferrostar is not a routing engine, basemap, or search solution. It is an SDK that integrates with these services.
Integrate Ferrostar Web Components into web applications
mainFerrostar is an SDK designed for building turn-by-turn navigation applications. The@stadiamaps/ferrostar-webcomponentspackage provides web components that allow you to integrate navigation capabilities directly into your web-based applications. For detailed tutorials and comprehensive setup instructions, refer to the official Ferrostar User Guide.What is `StaticLocationEngine`?
mainThe
StaticLocationEngineis an internal bridge used withinFerrostarMapLibreUImodules.MapLibre requires a
LocationEngineobject to function. To allow Ferrostar to support advanced features like location snapping and simulated routes while remaining compatible with MapLibre's generic requirements,StaticLocationEngineacts as a wrapper. It provides a simple interface to set locations, shieldingLocationProviderimplementors from the complexities of the MapLibre integration. This is generally transparent to most developers.What is Ferrostar Common?
mainFerrostar Common is the shared core of the Ferrostar project, containing the central navigation logic used across all platforms. To maintain platform independence, most navigation logic is kept internal, while a public interface is exposed to platform-specific code (such as Swift or Kotlin) through Foreign Function Interface (FFI) bindings. These bindings are automatically generated using UniFFI.How annotations work in Ferrostar
mainAnnotations are a way to include detailed routing information—such as speed limits, expected travel speed, and traffic—within a route response. Ferrostar follows the OSRM-style data structure, where annotations are a list of entries, each representing a line segment between consecutive coordinates along the route geometry.
FerrostarCoreprovides generic support for parsing arbitrary annotations. This allows you to define custom models for specialized parameters, while also providing built-in support for common Valhalla-based annotation models (used by Stadia Maps and Mapbox).How Route Providers work in Ferrostar
mainRoute providers are an abstraction layer that allows Ferrostar to communicate with different routing engines. This layer of indirection makes the system extensible, allowing you to use various backends (like Valhalla, OSRM, or custom local engines) by providing a standardized interface for requests and responses.
There are two primary types of providers:
RouteAdapter: Designed for request/response flows like HTTP or sockets. It splits the work into two halves: aRouteRequestGenerator(to build the request) and aRouteResponseParser(to parse the response).CustomRouteProvider: A single-method interface designed for use cases like local route generation where a rigid request/response model isn't required.
In most applications, you only interact with
FerrostarCore, which manages the lifecycle and execution of these providers.sequenceDiagram FerrostarCore->>+RouteAdapter: generateRequest RouteAdapter-->>+FerrostarCore: RouteRequest FerrostarCore-)Routing API: Network request Routing API--)FerrostarCore: Route response (bytes) FerrostarCore->>+RouteAdapter: parseResponse RouteAdapter->>FerrostarCore: [Route] or error FerrostarCore->>+Application Code: [Route] or errorCore components of the `ferrostar` crate
mainThe
ferrostarcrate is the primary engine of the library. It defines two fundamental architectural components required for navigation:- Navigation Controller: Manages the state and flow of navigation.
- Routing Backends: Handles the actual execution of routing logic.
For a detailed breakdown of how these components interact, refer to the Ferrostar Architecture Guide.
Choose a Location Provider
mainYou must configure a provider to receive location updates. Ferrostar provides several implementations:
NavigationLocationProvider: A wrapper that bundles a live provider (likeFusedNavigationLocationProvider) with aSimulatedLocationProvider. This is useful for supporting Google Play review requirements for Android Auto.FusedNavigationLocationProvider: Uses Google Play Services' Fused Location Client. It offers better positioning on supported devices. Requires thecom.stadiamaps.ferrostar:google-play-servicesdependency.AndroidLocationProvider: Uses the standard Android open-source location APIs. Use this if you need to support devices without Google Play Services or if you are distributing via F-Droid.SimulatedLocationProvider: Used for testing and development. It allows you to replay a route with awarpFactorto speed up playback.
// Example: Using NavigationLocationProvider to bundle live and simulated locations locationProvider = NavigationLocationProvider( liveProviding = FusedNavigationLocationProvider(appContext), simulatedProvider = SimulatedLocationProvider( warpFactor = 2u, initialLocation = initialSimulatedLocation.toAndroidLocation() ) ) // Example: Using SimulatedLocationProvider for testing private val locationProvider = SimulatedLocationProvider( warpFactor = 2u, initialLocation = initialSimulatedLocation ) locationProvider.setRoute(route)Core Components of Ferrostar
mainFerrostar is built around several key abstractions:
FerrostarCore: The primary class managing navigation logic, including route calculation, state management, location updates, and deviation handling.LocationProvider: Manages location updates via the React Native Geolocation API. You can implement custom behavior by implementing theLocationProviderInterface.RouteProvider: Handles interactions with the Valhalla routing service and manages route calculations.NavigationState: A data structure representing the current navigation session, including trip state, route geometry, and calculation status.
How Location Providers work in Ferrostar
mainFerrostar uses a common abstraction called the
LocationProviderprotocol (iOS) or interface (Android) to handle location data from various sources. This abstraction allows the core navigation logic to remain platform-agnostic while supporting different input types such as:- Platform Native Services: Real-world GPS data (e.g.,
CLLocationManageron iOS orFusedLocationProviderClienton Android). - Simulated Data: Pre-defined routes or manual coordinates for testing.
- Third-party SDKs: External location services like Naurt.
By using a
LocationProvider, you can swap between live GPS and simulated routes without changing your core navigation implementation.- Platform Native Services: Real-world GPS data (e.g.,