How to get city name from latitude and longitude coordinates in Google Maps?

Viewed 215555

How might I obtain the city name in Google Maps if I have latitude and longitude coordinates of a town or area?

I tried using the latitude, longitude and I got country but I don't know how to get city name.

15 Answers

From a Geocoder object, you can call the getFromLocation(double, double, int) method. It will return a list of Address objects that have a method getLocality().

Geocoder gcd = new Geocoder(context, Locale.getDefault());
List<Address> addresses = gcd.getFromLocation(lat, lng, 1);
if (addresses.size() > 0) {
    System.out.println(addresses.get(0).getLocality());
}
else {
   // do your stuff
}
import org.json.JSONObject

fun parseLocation(response: String): GeoLocation? {

val geoCodes by lazy { doubleArrayOf(0.0, 0.0) }

val jObj = JSONObject(response)
if (jObj.has(KEY_RESULTS)) {

    val jArrResults = jObj.getJSONArray(KEY_RESULTS)
    for (i in 0 until jArrResults.length()) {
        val jObjResult = jArrResults.getJSONObject(i)
        //getting latitude and longitude
        if (jObjResult.has(KEY_GEOMETRY)) {
            val jObjGeometry = jObjResult.getJSONObject(KEY_GEOMETRY)

            if (jObjGeometry.has(KEY_LOCATION)) {
                val jObjLocation = jObjGeometry.getJSONObject(KEY_LOCATION)
                if (jObjLocation.has(KEY_LAT)) {
                    geoCodes[0] = jObjLocation.getDouble(KEY_LAT)
                }

                if (jObjLocation.has(KEY_LNG)) {
                    geoCodes[1] = jObjLocation.getDouble(KEY_LNG)
                }
            }
        }

        var administrativeAreaLevel1: String? = null

        //getting city
        if (jObjResult.has(KEY_ADDRESS_COMPONENTS)) {

            val jArrAddressComponents = jObjResult.getJSONArray(KEY_ADDRESS_COMPONENTS)
            for (i in 0 until jArrAddressComponents.length()) {

                val jObjAddressComponents = jArrAddressComponents.getJSONObject(i)
                if (jObjAddressComponents.has(KEY_TYPES)) {

                    val jArrTypes = jObjAddressComponents.getJSONArray(KEY_TYPES)
                    for (j in 0 until jArrTypes.length()) {

                        when (jArrTypes.getString(j)) {

                            VALUE_LOCALITY, VALUE_POSTAL_TOWN -> {
                                return GeoLocation(jObjAddressComponents.getString(KEY_LONG_NAME), *geoCodes)
                            }

                            ADMINISTRATIVE_AREA_LEVEL_1 -> {
                                administrativeAreaLevel1 = jObjAddressComponents.getString(KEY_LONG_NAME)
                            }

                            else -> {
                            }
                        }
                    }
                }
            }

            for (i in 0 until jArrAddressComponents.length()) {

                val jObjAddressComponents = jArrAddressComponents.getJSONObject(i)
                if (jObjAddressComponents.has(KEY_TYPES)) {

                    val jArrTypes = jObjAddressComponents.getJSONArray(KEY_TYPES)

                    val typeList = ArrayList<String>()
                    for (j in 0 until jArrTypes.length()) {
                        typeList.add(jArrTypes.getString(j))
                    }

                    if (typeList.contains(VALUE_SUBLOCALITY)) {
                        var hasSubLocalityLevel = false
                        typeList.forEach { type ->
                            if (type.contains(VALUE_SUBLOCALITY_LEVEL)) {
                                hasSubLocalityLevel = true

                                if (type == VALUE_SUBLOCALITY_LEVEL_1) {
                                    return GeoLocation(jObjAddressComponents.getString(KEY_LONG_NAME), *geoCodes)
                                }
                            }
                        }
                        if (!hasSubLocalityLevel) {
                            return GeoLocation(jObjAddressComponents.getString(KEY_LONG_NAME), *geoCodes)
                        }
                    }
                }
            }
        }

        if (geoCodes.isNotEmpty()) return GeoLocation(administrativeAreaLevel1, geoCodes = *geoCodes)
     }
   }
return null
}

data class GeoLocation(val latitude: Double = 0.0, val longitude: Double = 0.0, val city: String? = null) : Parcelable {

constructor(city: String? = null, vararg geoCodes: Double) : this(geoCodes[0], geoCodes[1], city)

constructor(source: Parcel) : this(source.readDouble(), source.readDouble(), source.readString())

companion object {
    @JvmField
    val CREATOR = object : Parcelable.Creator<GeoLocation> {

        override fun createFromParcel(source: Parcel) = GeoLocation(source)

        override fun newArray(size: Int): Array<GeoLocation?> = arrayOfNulls(size)
    }
}

override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeDouble(latitude)
    dest.writeDouble(longitude)
    dest.writeString(city)
}

override fun describeContents() = 0
}

I´m in Brazil. Because of the regional details sometimes the city cames in differents ways. I think its the same in India and other countries. So, to prevent errors I make this verification:

private fun getAddress(latLng: LatLng): String {
    // 1
    val geocoder = Geocoder(this)
    val addresses: List<Address>?
    var city = "no"

    try {

        addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1)

        if (null != addresses && !addresses.isEmpty()) { //prevent from error
             //sometimes the city comes in locality, sometimes in subAdminArea.
            if (addresses[0].locality == null) {

                city = addresses[0].subAdminArea
            } else {
                city = addresses[0].locality
            }

            }
    } catch (e: IOException) {
        Log.e("MapsActivity", e.localizedMessage)
    }

    return city
    }

You can also check if city returns "no". If so, wasn´t possible to get the user location. Hope it helps.

Related