This codelab introduces how to integrate and manipulate map and map data in an android application.

What you'll learn

Setup

  1. Create a new android app called MapLabDemo

Modify the Manifest

Edit the manifest and add a meta-data tag inside the Application tag. This loads our API key

<meta-data
   android:name="com.google.android.geo.API_KEY"
   android:value="GOOGLE_MAPS_API_KEY_HERE" />

Edit the Layout

Replace the content in the activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
    android:id="@+id/main"
   tools:context=".MainActivity">

   <fragment
       class="com.google.android.gms.maps.SupportMapFragment"
       android:id="@+id/map"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</FrameLayout>

Add the functionality to load the map

Create an instance variable in MainActivity that would store an instance of the GoogleMap

    private lateinit var mMap: GoogleMap

Let MainActivity implement the OnMapReadyCallback interface. Implement the necessary function

class MapActivity : AppCompatActivity(), OnMapReadyCallback {
    // Redacted for brevity
}

In the onCreate, load the map

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_map)

        //redacted

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

In the onMapReady callback, store the reference of the googleMap

  override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
    }

Create a class that will be responsible for holding the data for that point.

class CustomMarkerPoints(val id:Int, val point:LatLng)

Create an instance variable of MainActivity.kt that would hold a list of our newly created class

val pointsList = mutableListOf()

Modify the onMapReady function and add a listener to the map

    mMap.setOnMapClickListener { latLng ->
        addMarkerAtLocation(latLng)
    }

Implement the ‘addMarkerAtLocation' function

    private fun addMarkerAtLocation(latLng: LatLng) {
        val newCustomPoint = CustomMarkerPoints(pointsList.length + 1, latLng)

        pointsList.add(newCustomPoint)

        mMap.addMarker(
            MarkerOptions()
                .position(latLng)
                .title("Marker ${newCustomPoint.id}")
        )

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10f))
    }

Implement a function to draw the polyline

    private fun drawPolyline() {
        
        val latLngPoints = pointsList.map { it.point } 

        val polylineOptions = PolylineOptions()
            .addAll(latLngPoints)
            .color(Color.BLUE)
            .width(5f)
            .geodesic(true)

        mMap.addPolyline(polylineOptions)

        val bounds = LatLngBounds.builder()
        latLngPoints.forEach { bounds.include(it) }
        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 100))
    }

Given the code for the lab, modify it so that the redraw of the polylines and markers do not add unnecessary layers to the map

Hint

mMap.clear() // remove the old points and lines from the map

Everytime the location's updated, clear the map layer and redraw the points.

Google Maps Key: AIzaSyC-WIjYI-GvrM9J1n82i8Xoljtfs-p_WsQ