
Enables seamless integration of Google Maps functionalities in applications with a unified API, reducing platform-specific code. Offers map rendering, marker management, camera control, and Google Places suggestions.
KGoogleMap is available on mavenCentral().
implementation("io.github.the-best-is-best:kgoogle-map:1.1.1")Add the following line in your Package.swift file:
dependencies: [
.package(url: "https://github.com/the-best-is-best/KGoogleMap.git", from: "1.1.0")
]fun MainViewController(): UIViewController
{
IOSKLocationServices().requestPermission()
IOSKGoogleMap.init("YOUR GOOGLE MAP KEY")
return ComposeUIViewController { App() }
}AndroidKGoogleMap.initialization(this, "YOUR GOOGLE MAP KEY")
setContent {
// add this
KLocationService().ListenerToPermission()
App()
}@Composable
internal fun App() = AppTheme {
val mapController = remember {
KMapController(
initPosition = LatLng(30.01306, 31.20885),
zoom = 15f
)
}
val viewModel by remember { mutableStateOf(GoogleMapViewModel()) }
val scope = rememberCoroutineScope()
if (viewModel.requestPermission) {
KLocationService().EnableLocation()
viewModel.requestPermission = false
}
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(modifier = Modifier.fillMaxSize()) {
TypeAhead(
itemsProvider = { query -> viewModel.onQueryChanged(query) },
itemToString = { it.fullText },
onItemSelected = {
scope.launch {
viewModel.getPlaceDetails(it.placeId, 1)
}
}
)
Spacer(Modifier.height(10.dp))
TypeAhead(
itemsProvider = { query -> viewModel.onQueryChanged(query) },
itemToString = { it.fullText },
onItemSelected = {
scope.launch {
viewModel.getPlaceDetails(it.placeId, 2)
}
}
)
Spacer(Modifier.height(10.dp))
ElevatedButton(onClick = { viewModel.getRoad() }) {
Text("Fetch Road")
}
Box(modifier = Modifier.fillMaxSize()) {
KGoogleMapView(
controller = mapController,
onMapLoaded ={
println("map loaded")
},
onMapClick = {
println("click loc :${it}")
},
onMapLongClick = {
println("long click loc :${it}")
}
)
}
}
}
}
class GoogleMapViewModel : ViewModel() {
private val googlePlaces = KPlacesHelper()
var selectedAddress1: PlaceDetails? = null
private set
var selectedAddress2: PlaceDetails? = null
private set
var directions: DirectionsResponse? = null
private set
private val locationService = KLocationService()
var isGPSEnabled by mutableStateOf(true)
private set
var requestPermission by mutableStateOf(false)
init {
viewModelScope.launch {
locationService.gpsStateFlow().collect { gps ->
isGPSEnabled = gps
}
}
}
suspend fun onQueryChanged(query: String): List<AutocompleteSuggestion> {
return if (query.isNotEmpty()) {
delay(500)
fetchSuggestions(query)
} else {
emptyList()
}
}
fun enableGPSAndLocation() {
requestPermission = true
}
private suspend fun fetchSuggestions(query: String): List<AutocompleteSuggestion> {
return withContext(Dispatchers.IO) {
try {
suspendCancellableCoroutine { continuation ->
googlePlaces.fetchSuggestions(query) { suggestions ->
continuation.resume(suggestions)
}
}
} catch (e: Exception) {
emptyList()
}
}
}
suspend fun getPlaceDetails(placeId: String, searchId: Int) {
withContext(Dispatchers.IO) {
googlePlaces.fetchPlaceDetails(placeId, {
if (searchId == 1) {
selectedAddress1 = it
} else {
selectedAddress2 = it
}
})
}
}
fun getRoad() {
viewModelScope.launch {
if (selectedAddress1 != null && selectedAddress2 != null) {
val ktorServices = KtorServices()
directions = ktorServices.getRoadPoints(
selectedAddress1!!.address!!,
selectedAddress2!!.address!!,
)
}
}
}
}KGoogleMap is available on mavenCentral().
implementation("io.github.the-best-is-best:kgoogle-map:1.1.1")Add the following line in your Package.swift file:
dependencies: [
.package(url: "https://github.com/the-best-is-best/KGoogleMap.git", from: "1.1.0")
]fun MainViewController(): UIViewController
{
IOSKLocationServices().requestPermission()
IOSKGoogleMap.init("YOUR GOOGLE MAP KEY")
return ComposeUIViewController { App() }
}AndroidKGoogleMap.initialization(this, "YOUR GOOGLE MAP KEY")
setContent {
// add this
KLocationService().ListenerToPermission()
App()
}@Composable
internal fun App() = AppTheme {
val mapController = remember {
KMapController(
initPosition = LatLng(30.01306, 31.20885),
zoom = 15f
)
}
val viewModel by remember { mutableStateOf(GoogleMapViewModel()) }
val scope = rememberCoroutineScope()
if (viewModel.requestPermission) {
KLocationService().EnableLocation()
viewModel.requestPermission = false
}
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(modifier = Modifier.fillMaxSize()) {
TypeAhead(
itemsProvider = { query -> viewModel.onQueryChanged(query) },
itemToString = { it.fullText },
onItemSelected = {
scope.launch {
viewModel.getPlaceDetails(it.placeId, 1)
}
}
)
Spacer(Modifier.height(10.dp))
TypeAhead(
itemsProvider = { query -> viewModel.onQueryChanged(query) },
itemToString = { it.fullText },
onItemSelected = {
scope.launch {
viewModel.getPlaceDetails(it.placeId, 2)
}
}
)
Spacer(Modifier.height(10.dp))
ElevatedButton(onClick = { viewModel.getRoad() }) {
Text("Fetch Road")
}
Box(modifier = Modifier.fillMaxSize()) {
KGoogleMapView(
controller = mapController,
onMapLoaded ={
println("map loaded")
},
onMapClick = {
println("click loc :${it}")
},
onMapLongClick = {
println("long click loc :${it}")
}
)
}
}
}
}
class GoogleMapViewModel : ViewModel() {
private val googlePlaces = KPlacesHelper()
var selectedAddress1: PlaceDetails? = null
private set
var selectedAddress2: PlaceDetails? = null
private set
var directions: DirectionsResponse? = null
private set
private val locationService = KLocationService()
var isGPSEnabled by mutableStateOf(true)
private set
var requestPermission by mutableStateOf(false)
init {
viewModelScope.launch {
locationService.gpsStateFlow().collect { gps ->
isGPSEnabled = gps
}
}
}
suspend fun onQueryChanged(query: String): List<AutocompleteSuggestion> {
return if (query.isNotEmpty()) {
delay(500)
fetchSuggestions(query)
} else {
emptyList()
}
}
fun enableGPSAndLocation() {
requestPermission = true
}
private suspend fun fetchSuggestions(query: String): List<AutocompleteSuggestion> {
return withContext(Dispatchers.IO) {
try {
suspendCancellableCoroutine { continuation ->
googlePlaces.fetchSuggestions(query) { suggestions ->
continuation.resume(suggestions)
}
}
} catch (e: Exception) {
emptyList()
}
}
}
suspend fun getPlaceDetails(placeId: String, searchId: Int) {
withContext(Dispatchers.IO) {
googlePlaces.fetchPlaceDetails(placeId, {
if (searchId == 1) {
selectedAddress1 = it
} else {
selectedAddress2 = it
}
})
}
}
fun getRoad() {
viewModelScope.launch {
if (selectedAddress1 != null && selectedAddress2 != null) {
val ktorServices = KtorServices()
directions = ktorServices.getRoadPoints(
selectedAddress1!!.address!!,
selectedAddress2!!.address!!,
)
}
}
}
}