Jetpack Compose - How do i draw Path(poly lines) between two locations On Google Maps

Published October 31, 2021

In this Jetpack compose Google Maps tutorial we will create a Google Maps and Draw Path between two Locations. To add Poly lines to the Google Maps we will use map.addPolyline() method. In the previous tutorial we cover how to add Markers to the Google Maps with Jetpack compose.

 

sample to code to add Ploy lines to maps

map.addPolyline(
    PolylineOptions().add(
        pickUp,
        LatLng(17.711845, 76.006210), //Root of Solapur
        LatLng(17.839834, 76.718450), //Root of Osmanabad
        destination
    )

 

Let's get started

Step 1: Create Jetpack Compose project with Andorid studio

Step 2: Add required dependencies in build.gradle file

Read previous example How to setup and Load Google Maps with Jetpack Compose

Step 3: Load Google Maps

AndroidView(
    {mapView}
) { mapView ->
    CoroutineScope(Dispatchers.Main).launch {


            mapView.getMapAsync {

}

}

 

Step 4: Create Polylines and add it to Google Maps

To Add poly lines between two location we need locations latlng, then add these lanlngs to PolylineOptions().

 

map.addPolyline(
    PolylineOptions().add(
        pickUp,
        LatLng(17.711845, 76.006210), //Root of Solapur
        LatLng(17.839834, 76.718450), //Root of Osmanabad
        destination
    )
)

 

To set the color for the Path between tow location by add color property to the PolylineOptions

map.addPolyline(
    PolylineOptions().add(
        pickUp,
        LatLng(17.711845, 76.006210), //Root of Solapur
        LatLng(17.839834, 76.718450), //Root of Osmanabad
        destination
    )
).color = R.color.red

 

Step 5: Run application, you can find the path between two given locations on the Maps.

Jetpack compose Draw path (route) between two location on Google Maps

 

 

Complete code for Draw poly lines on the maps between two location

package com.rrtutors.compose_maps


import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.google.android.libraries.maps.CameraUpdateFactory
import com.google.android.libraries.maps.MapView
import com.google.android.libraries.maps.model.LatLng
import com.google.android.libraries.maps.model.MarkerOptions
import com.google.android.libraries.maps.model.PolylineOptions
import com.google.maps.android.ktx.awaitMap
import com.rrtutors.compose_maps.ui.theme.ComposeMapsTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeMapsTheme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    GoogleMaps()
                }
            }
        }
    }
}
@Composable
fun GoogleMaps() {
    val mapView = rememberMapViewWithLifeCycle()

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        AndroidView(
            {mapView}
        ) { mapView ->
            CoroutineScope(Dispatchers.Main).launch {
                val map = mapView.awaitMap()
                map.uiSettings.isZoomControlsEnabled = true
                val pickUp = LatLng(17.385, 78.4867) //Hyderabad
                val destination = LatLng(18.5204, 73.8567) //Pune
                map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination, 8f))
                val markerOptions =  MarkerOptions()
                    .title("Hyderabad")
                    .position(pickUp)
                map.addMarker(markerOptions)
                val markerOptionsDestination = MarkerOptions()
                    .title("Pune")
                    .position(destination)
                map.addMarker(markerOptionsDestination)

                map.addPolyline(
                    PolylineOptions().add(
                        pickUp,
                        LatLng(17.711845, 76.006210), //Root of Solapur
                        LatLng(17.839834, 76.718450), //Root of Osmanabad
                        destination
                    )
                ).color = R.color.red //Polyline color
            }
        }
    }
}

@Composable
fun rememberMapViewWithLifeCycle(): MapView {
    val context = LocalContext.current
    val mapView = remember {
        MapView(context).apply {
            id = com.google.maps.android.ktx.R.id.map_frame
        }
    }
    val lifeCycleObserver = rememberMapLifecycleObserver(mapView)
    val lifeCycle = LocalLifecycleOwner.current.lifecycle
    DisposableEffect(lifeCycle) {
        lifeCycle.addObserver(lifeCycleObserver)
        onDispose {
            lifeCycle.removeObserver(lifeCycleObserver)
        }
    }

    return mapView
}

@Composable
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
    remember(mapView) {
        LifecycleEventObserver { _, event ->
            when(event) {
                Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
                Lifecycle.Event.ON_START -> mapView.onStart()
                Lifecycle.Event.ON_RESUME -> mapView.onResume()
                Lifecycle.Event.ON_PAUSE -> mapView.onPause()
                Lifecycle.Event.ON_STOP -> mapView.onStop()
                Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
                else -> throw IllegalStateException()
            }
        }
    }

 

Conclusion: We have done with draw route between two locations using Google Maps

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

1760 Views