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

Autocomplete search for Android Demo App #295

Merged
merged 37 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8f584e5
Support arbitrary Valhalla options (formerly we only merged costing o…
ianthetechie Sep 25, 2024
4d7fda9
Fix argument
ianthetechie Sep 25, 2024
616b5e4
Improve docs of some convenience initializers
ianthetechie Sep 25, 2024
02dd283
Align Android with iOS costing options
ianthetechie Sep 25, 2024
306a121
swiftformat
ianthetechie Sep 25, 2024
02bb61b
Don't forget the web ;)
ianthetechie Sep 25, 2024
eb5a9e7
Add Android-specific README
ianthetechie Sep 25, 2024
5100feb
Set up Android to use API keys properly via local.properties
ianthetechie Sep 25, 2024
b97d5fa
Fix CI
ianthetechie Sep 25, 2024
8ff64b4
Fix subtle bug where Android location providers never updated lastLoc…
ianthetechie Sep 25, 2024
10f0c72
Rename U-Turn images to match how Kotlin stringifies the maneuvers
ianthetechie Sep 25, 2024
db4c02e
Allow the fused location provider to report an initial fix faster
ianthetechie Sep 25, 2024
afce8ff
First pass at an actually usable demo app
ianthetechie Sep 25, 2024
7a84dff
Merge branch 'main' into autocomplete-search
ianthetechie Sep 26, 2024
5fe9eff
Merge branch 'main' into autocomplete-search
ianthetechie Sep 27, 2024
924ea21
Merge branch 'main' into autocomplete-search
ianthetechie Oct 7, 2024
8f5bec4
Minor build script improvement
ianthetechie Oct 7, 2024
5f7abfb
Merge branch 'main' into autocomplete-search
ianthetechie Oct 8, 2024
37a4511
Checkpoint commit phase 1
ianthetechie Oct 10, 2024
f81cb8a
Checkpoint commit phase 2 highlighting some bad stuff to clean up
ianthetechie Oct 10, 2024
40d6470
Merge branch 'main' into autocomplete-search
ianthetechie Oct 10, 2024
9e887d6
Add docs on the StaticLocationEngine
ianthetechie Oct 10, 2024
784832a
Fix formatting + doc test
ianthetechie Oct 13, 2024
454309e
Fix typo in Android readme
ianthetechie Oct 14, 2024
821fd8a
Kotlin let closure idiom
ianthetechie Oct 14, 2024
ea883b1
ktfmtFormat + auto-commit
ianthetechie Oct 14, 2024
b8fc590
Remove extraneous env?
ianthetechie Oct 14, 2024
d5f5274
Try switching to a mix of Apple Silicon Ubuntu runners for Android
ianthetechie Oct 14, 2024
7501991
Fix runner permissions (I think)
ianthetechie Oct 14, 2024
ff295fc
Apply automatic changes
ianthetechie Oct 14, 2024
57e21d2
Merge branch 'main' into autocomplete-search
ianthetechie Oct 17, 2024
84745b0
Address open thread re: iOS uturn image name
ianthetechie Oct 19, 2024
71622fd
Add TODO docs
ianthetechie Oct 19, 2024
7510aa8
Fix the navigation camera (re-)application logic
ianthetechie Oct 19, 2024
56cb38f
Cleanup
ianthetechie Oct 22, 2024
b9211cb
Remove old comment
ianthetechie Oct 22, 2024
f80c494
Apply automatic changes
ianthetechie Oct 22, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/gradle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Install cargo-ndk
run: cargo install cargo-ndk

- name: Creat local.properties (required for cargo-ndk and the demo app)
- name: Create local.properties (required for cargo-ndk and the demo app)
run: echo 'stadiaApiKey=' > local.properties
working-directory: android

Expand Down
16 changes: 8 additions & 8 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/maplibre/maplibre-gl-native-distribution.git",
"state" : {
"revision" : "e409318144091c3ee9ad551b202e1c36695f8086",
"version" : "6.7.0"
"revision" : "f23db791d7b6f0329e3c6788d8e4152c24c52b6b",
"version" : "6.7.1"
}
},
{
"identity" : "maplibre-swift-macros",
"kind" : "remoteSourceControl",
"location" : "https://github.com/stadiamaps/maplibre-swift-macros.git",
"state" : {
"revision" : "236215c13bff962009e0f0257d6d8349be33442f",
"version" : "0.0.4"
"revision" : "9e27e62dff7fd727aebd0a7c8aa74e7635a5583e",
"version" : "0.0.5"
}
},
{
Expand All @@ -41,17 +41,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-syntax.git",
"state" : {
"revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
"version" : "509.1.1"
"revision" : "2bc86522d115234d1f588efe2bcb4ce4be8f8b82",
"version" : "510.0.3"
}
},
{
"identity" : "swiftui-dsl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/maplibre/swiftui-dsl",
"state" : {
"revision" : "5ba75ef1e4382fcc7ee71e274eb9c2a50906b14e",
"version" : "0.1.0"
"revision" : "c39688db3aac50b523ea062b286c584123022093",
"version" : "0.3.0"
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion android/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This directory tree contains the Gradle workspace for Ferrostar on Android.
* `composeui` - Jetpack Compose UI elements which are not tightly coupled to any particular map renderer.
* `core` - The core module is where all the "business logic", location management, and other core functionality lives.
* `demo-app` - A minimal demonstration app.
* `google-play-services` - Optional functionality that depends on Google Play Services (like a fused location client wrapper). This is a separate module so that apps are able to "de-Google" if necessary.
* `google-play-services` - Optional functionality that depends on Google Play Services (like the fused location client wrapper). This is a separate module so that apps are able to "de-Google" if necessary.
* `maplibreui` - Map-related user interface components built with MapLibre.

## Running the demo app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,22 @@ fun ManeuverImage(content: VisualInstructionContent, tint: Color = LocalContentC

@Preview
@Composable
fun ManeuverImagePreview() {
fun ManeuverImageLeftTurnPreview() {
ManeuverImage(
VisualInstructionContent(
text = "",
maneuverType = ManeuverType.TURN,
maneuverModifier = ManeuverModifier.LEFT,
roundaboutExitDegrees = null))
}

@Preview
@Composable
fun ManeuverImageContinueUturnPreview() {
ManeuverImage(
VisualInstructionContent(
text = "",
maneuverType = ManeuverType.CONTINUE,
maneuverModifier = ManeuverModifier.U_TURN,
roundaboutExitDegrees = null))
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,19 @@ class AndroidSystemLocationProvider(context: Context) : LocationProvider {
android.util.Log.d(TAG, "Already registered; skipping")
return
}
val androidListener = LocationListener { listener.onLocationUpdated(it.toUserLocation()) }
val androidListener = LocationListener {
val userLocation = it.toUserLocation()
lastLocation = userLocation
listener.onLocationUpdated(userLocation)
}
listeners[listener] = androidListener

val handler = Handler(Looper.getMainLooper())

executor.execute {
handler.post {
val last = locationManager.getLastKnownLocation(getBestProvider())
last?.let { androidListener.onLocationChanged(last) }
locationManager.requestLocationUpdates(getBestProvider(), 100L, 5.0f, androidListener)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ data class NavigationUiState(
*/
val heading: Float?,
/** The geometry of the full route. */
val routeGeometry: List<GeographicCoordinate>,
val routeGeometry: List<GeographicCoordinate>?,
/** Visual instructions which should be displayed based on the user's current progress. */
val visualInstruction: VisualInstruction?,
/**
Expand Down Expand Up @@ -76,6 +76,11 @@ interface NavigationViewModel {
fun toggleMute()

fun stopNavigation()

fun isNavigating(): Boolean = uiState.value.progress != null

// TODO: We think the camera may eventually need to be owned by the view model, but that's going
// to be a very big refactor (maybe even crossing into the MapLibre Compose project)
}

class DefaultNavigationViewModel(
Expand Down
11 changes: 8 additions & 3 deletions android/demo-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ android {
defaultConfig {
applicationId "com.stadiamaps.ferrostar.demo"
minSdk 26
targetSdk 34
targetSdk 35
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -64,11 +64,16 @@ dependencies {
implementation project(':core')
implementation project(':composeui')
implementation project(':maplibreui')
implementation project(':google-play-services')

implementation libs.maplibre.compose

implementation(platform(libs.okhttp.bom))
implementation(libs.okhttp.core)
implementation platform(libs.okhttp.bom)
implementation libs.okhttp.core

implementation libs.play.services.location

implementation libs.stadiamaps.autocomplete.search

testImplementation libs.junit
androidTestImplementation libs.androidx.test.junit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import com.stadiamaps.ferrostar.core.AlternativeRouteProcessor
import com.stadiamaps.ferrostar.core.AndroidTtsObserver
import com.stadiamaps.ferrostar.core.CorrectiveAction
import com.stadiamaps.ferrostar.core.FerrostarCore
import com.stadiamaps.ferrostar.core.LocationProvider
import com.stadiamaps.ferrostar.core.RouteDeviationHandler
import com.stadiamaps.ferrostar.core.SimulatedLocationProvider
import com.stadiamaps.ferrostar.core.service.FerrostarForegroundServiceManager
import com.stadiamaps.ferrostar.core.service.ForegroundServiceManager
import com.stadiamaps.ferrostar.googleplayservices.FusedLocationProvider
import java.net.URL
import java.time.Duration
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -56,7 +57,10 @@ object AppModule {
appContext = context
}

val locationProvider: SimulatedLocationProvider by lazy { SimulatedLocationProvider() }
val locationProvider: LocationProvider by lazy {
// TODO: Make this configurable?
FusedLocationProvider(appContext)
}
private val httpClient: OkHttpClient by lazy {
OkHttpClient.Builder().callTimeout(Duration.ofSeconds(15)).build()
}
Expand All @@ -69,7 +73,7 @@ object AppModule {
val core =
FerrostarCore(
valhallaEndpointURL = valhallaEndpointUrl,
profile = "bicycle",
profile = "auto",
httpClient = httpClient,
locationProvider = locationProvider,
foregroundServiceManager = foregroundServiceManager,
Expand All @@ -79,7 +83,20 @@ object AppModule {
minimumHorizontalAccuracy = 25U, automaticAdvanceDistance = 10U),
RouteDeviationTracking.StaticThreshold(15U, 25.0),
CourseFiltering.SNAP_TO_ROUTE),
options = mapOf("costingOptions" to mapOf("bicycle" to mapOf("use_roads" to 0.2))))
options =
mapOf(
"costingOptions" to
// Just an example... You can set multiple costing options for any profile
// in Valhalla.
// If your app uses multiple routing modes, you can have a master settings
// map, or construct a new one each time.
mapOf(
"low_speed_vehicle" to
mapOf(
"vehicle_type" to "golf_cart",
"top_speed" to 32 // 24kph ~= 15mph
)),
"units" to "miles"))

// Not all navigation apps will require this sort of extra configuration.
// In fact, we hope that most don't!
Expand All @@ -93,13 +110,7 @@ object AppModule {
Log.i(TAG, "Received alternate route(s): $routes")
if (routes.isNotEmpty()) {
// NB: Use `replaceRoute` for cases like this!
it.replaceRoute(
routes.first(),
NavigationControllerConfig(
StepAdvanceMode.RelativeLineStringDistance(
minimumHorizontalAccuracy = 25U, automaticAdvanceDistance = 10U),
RouteDeviationTracking.StaticThreshold(25U, 10.0),
CourseFiltering.SNAP_TO_ROUTE))
it.replaceRoute(routes.first())
}
}

Expand Down
Loading