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, marker = marker,
mapView = mapView, mapView = mapView,
locationSearchProvider = context.config.root.global.betterLocation.locationSearchProvider.get(), locationSearchProvider = context.config.root.global.betterLocation.locationSearchProvider.get(),
googleMapsApiKey = context.config.root.global.betterLocation.googleMapsApiKey.get(),
saveCoordinates = { saveCoordinates = {
addSavedCoordinateDialog = true addSavedCoordinateDialog = true
} }

View File

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