feat(location): implement Google Maps geocoding search

Add support for Google Maps Geocoding API in location search dialog.
- Update ChooseLocationDialog signature to accept API key.
- Switch search provider logic based on configuration.
- Use Google Maps Geocoding API when provider is 'google_maps'.
- Maintain OpenStreetMap Nominatim support as fallback/default.
- Pass configured API key from BetterLocationRoot UI.
This commit is contained in:
daplugg23
2026-02-05 17:20:24 -06:00
parent d485718245
commit 46e9b7e7f5
2 changed files with 48 additions and 18 deletions

View File

@@ -357,6 +357,7 @@ class BetterLocationRoot : Routes.Route() {
marker = marker,
mapView = mapView,
locationSearchProvider = context.config.root.global.betterLocation.locationSearchProvider.get(),
googleMapsApiKey = context.config.root.global.betterLocation.googleMapsApiKey.get(),
saveCoordinates = {
addSavedCoordinateDialog = true
}

View File

@@ -595,6 +595,7 @@ class AlertDialogs(
marker: MutableState<Marker?> = remember { mutableStateOf(null) },
mapView: MutableState<MapView?> = remember { mutableStateOf(null) },
locationSearchProvider: String = "osm",
googleMapsApiKey: String = "",
saveCoordinates: (() -> Unit)? = null,
dismiss: () -> Unit = {}
) {
@@ -702,28 +703,56 @@ class AlertDialogs(
val resultsScrollState = rememberScrollState()
suspend fun search() {
okHttpClient.newCall(Request.Builder()
.url("https://nominatim.openstreetmap.org/search".toUri().buildUpon().appendQueryParameter("q", locationName).appendQueryParameter("format", "jsonv2").build().toString())
.header("User-Agent", Constants.OSM_USER_AGENT)
.build()
).await().use { response ->
if (!response.isSuccessful) {
return@use
if (locationSearchProvider == "google_maps") {
// Google Maps Search
okHttpClient.newCall(Request.Builder()
.url("https://maps.googleapis.com/maps/api/geocode/json".toUri().buildUpon()
.appendQueryParameter("address", locationName)
.appendQueryParameter("key", googleMapsApiKey)
.build().toString())
.build()
).await().use { response ->
if (!response.isSuccessful) return@use
runCatching {
val jsonResponse = JsonParser.parseString(response.body?.string() ?: "{}").asJsonObject
if (jsonResponse.has("results")) {
val results = jsonResponse.getAsJsonArray("results")
addressResults = results.take(5).map { jsonElement ->
val result = jsonElement.asJsonObject
val geometry = result.getAsJsonObject("geometry").getAsJsonObject("location")
Triple(
result.get("formatted_address").asString,
geometry.get("lat").asString,
geometry.get("lng").asString
)
}
}
}
}
runCatching {
val body = JsonParser.parseString(response.body?.string() ?: "[]").asJsonArray
addressResults = body.take(5).map { jsonElement ->
val jsonObject = jsonElement.asJsonObject
Triple(
jsonObject.get("display_name").asString,
jsonObject.get("lat").asString,
jsonObject.get("lon").asString
)
} else {
// OSM Nominatim Search (Existing Logic)
okHttpClient.newCall(Request.Builder()
.url("https://nominatim.openstreetmap.org/search".toUri().buildUpon()
.appendQueryParameter("q", locationName)
.appendQueryParameter("format", "jsonv2")
.build().toString())
.header("User-Agent", Constants.OSM_USER_AGENT)
.build()
).await().use { response ->
if (!response.isSuccessful) return@use
runCatching {
val body = JsonParser.parseString(response.body?.string() ?: "[]").asJsonArray
addressResults = body.take(5).map { jsonElement ->
val jsonObject = jsonElement.asJsonObject
Triple(
jsonObject.get("display_name").asString,
jsonObject.get("lat").asString,
jsonObject.get("lon").asString
)
}
}
}
}
searchJob = null
}