Google Map Search Location

Welcome to this comprehensive tutorial on how to implement search location functionality in a Google Maps application using Kotlin! This feature is essential for any map-based app, allowing users to find locations easily and interact with the map. Understanding how to utilize the Geocoder class for geocoding and reverse geocoding will enhance your app's usability and experience.

Why Search Location Matters

In modern applications, users expect to find locations quickly and efficiently. Whether it's a restaurant, a park, or a friend's address, the ability to search for locations enhances user engagement. Developers use this capability to create intuitive and user-friendly applications that leverage location data effectively.

Understanding Geocoding and Reverse Geocoding

Before diving into the code, let's clarify some key concepts:

  • Geocoding: Converting a human-readable address (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (latitude and longitude). This is useful for placing markers on maps.
  • Reverse Geocoding: The opposite process, where geographic coordinates are converted back into a human-readable address. This can be useful for displaying the user's current location.
  • When to Use Geocoder

You would typically use the Geocoder class when:

  • You want to convert an address input by the user into coordinates for mapping.
  • You need to translate coordinates into a more understandable address format.
  • Key Methods of the Geocoder Class

The Geocoder class provides several methods:

  • getFromLocation(double latitude, double longitude, int maxResults): Returns a list of addresses for the specified latitude and longitude.
  • getFromLocationName(String location, int maxResults): Returns a list of addresses for a given location name.
  • isPresent: Checks if the Geocoder is available on the device.
  • Setting Up Your Project

Before we start coding, ensure you have a basic Android project set up with Google Maps API enabled. Your build.gradle file should include the following dependencies:

Example

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation 'com.google.android.gms:play-services-maps:18.0.2'
    implementation 'com.google.android.gms:play-services-location:18.0.0'
}

Don't forget to replace the version numbers with the latest available versions.

Creating the Layout

Create the layout file activity_maps.xml where users can input their search query. It will include an EditText for input and a Button to trigger the search.

Example

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/editTextLocation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Search Location" />

    <Button
        android:id="@+id/buttonSearch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Search" />
</LinearLayout>

Implementing the MapsActivity

Now, let's implement the MapsActivity.kt. This class will handle the interaction with the map and the geocoding functionality.

Example

package com.example.mapssearch

import android.location.Address
import android.location.Geocoder
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import java.io.IOException
import java.util.*

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
    private lateinit var googleMap: GoogleMap
    private lateinit var editTextLocation: EditText
    private lateinit var buttonSearch: Button

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

        editTextLocation = findViewById(R.id.editTextLocation)
        buttonSearch = findViewById(R.id.buttonSearch)

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

        buttonSearch.setOnClickListener { searchLocation() }
    }

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

    private fun searchLocation() {
        val locationName = editTextLocation.text.toString()
        if (locationName.isNotEmpty()) {
            val geocoder = Geocoder(this, Locale.getDefault())
            try {
                val addressList: List<Address> = geocoder.getFromLocationName(locationName, 1)
                if (addressList.isNotEmpty()) {
                    val address: Address = addressList[0]
                    val latLng = LatLng(address.latitude, address.longitude)
                    googleMap.addMarker(MarkerOptions().position(latLng).title(locationName))
                    googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10f))
                } else {
                    Toast.makeText(this, "Location not found", Toast.LENGTH_SHORT).show()
                }
            } catch (e: IOException) {
                Toast.makeText(this, "Geocoder service not available", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(this, "Please enter a location", Toast.LENGTH_SHORT).show()
        }
    }
}

Code Breakdown

  • Initialization: The MapsActivity initializes the map and sets up the search button click listener.
  • Geocoder Usage: When the user clicks the search button, we create a Geocoder instance and call getFromLocationName, which will return a list of possible addresses for the input name.
  • Marker Placement: If an address is found, we extract the latitude and longitude and place a marker on the map, zooming in on the location.
  • Example Outputs

Below are some expected outputs based on the searches you perform:

Example 1: Search for "Eiffel Tower"

Example

fun main() {
    // User inputs "Eiffel Tower"
}

Output:

Output

Marker placed at: Latitude: 48.8588443, Longitude: 2.2943506

Example 2: Search for "Statue of Liberty"

Example

fun main() {
    // User inputs "Statue of Liberty"
}

Output:

Output

Marker placed at: Latitude: 40.689247, Longitude: -74.044502

Example 3: Search for "Invalid Location"

Example

fun main() {
    // User inputs "This Place Does Not Exist"
}

Output:

Output

Toast Message: "Location not found"

Common Mistakes

  1. Not Checking for Empty Input: Forgetting to validate user input can lead to unnecessary API calls. Always check if the input is empty.
  2. Ignoring Permissions: Ensure that your app has the necessary permissions to access location services.
  3. Using Deprecated Libraries: Always use the latest version of libraries to avoid issues with deprecated methods.
  4. Best Practices

  • User Feedback: Always provide feedback to users, such as Toast messages when a location is not found.
  • Error Handling: Implement try-catch blocks around geocoding to handle potential exceptions gracefully.
  • Optimize API Calls: Limit the number of geocoding requests made to avoid hitting service limits.
  • Practice Exercises

Try implementing the following exercises to reinforce your understanding:

  1. Add Current Location: Modify the app to also show the user's current location on the map.
  2. Multiple Results: Enhance the app to display multiple possible locations for the input, allowing users to select from a list.
  3. Location History: Store a history of searched locations and allow users to quickly search them again.

With these exercises, you'll deepen your understanding of both Kotlin and Google Maps integration. Happy coding!

Input Required

This code uses input(). Please provide values below:

🤖 Coding Mentor
🤖

Hi! I'm your coding mentor

Ask me anything about programming:

• Python, Java, C++, JavaScript

• Algorithms & Data Structures

• Debugging & Code Help