首页 > 解决方案 > 如何从 Geocoder 获取城市名称?

问题描述

在 Android 中(Java 或 Kotlin 都可以)我如何从经度和纬度中获取城市名称?

下面我写了一个函数来显示地址数据。我想对其进行修改,使其返回城市名称:

private fun getCity(context: Context, latitude: Float, longitude: Float) {
    val gcd = Geocoder(context, Locale.getDefault())
    val addresses = gcd.getFromLocation(latitude.toDouble(), longitude.toDouble(), 1)
    Log.d("-----", "-----")
    Log.d("latitude", latitude.toString())
    Log.d("longitude", longitude.toString())
    if (addresses.size > 0) {
        val locality = addresses[0].locality
        if (locality != null) {
            Log.d("locality", locality.toString())
        }
        val adminArea = addresses[0].adminArea
        if (adminArea != null) {
            Log.d("adminArea", adminArea.toString())
        }
        val subAdminArea = addresses[0].subAdminArea
        if (subAdminArea != null) {
            Log.d("subAdminArea", subAdminArea.toString())
        }
        val subLocality = addresses[0].subLocality
        if (subLocality != null) {
            Log.d("subLocality", subLocality.toString())
        }
        val thoroughfare = addresses[0].thoroughfare
        if (thoroughfare != null) {
            Log.d("thoroughfare", thoroughfare.toString())
        }
        val subThoroughfare = addresses[0].subThoroughfare
        if (subThoroughfare != null) {
            Log.d("subThoroughfare", subThoroughfare.toString())
        }
        val extras = addresses[0].extras
        if (extras != null) {
            Log.d("extras", extras.toString())
        }
        val premises = addresses[0].premises
        if (premises != null) {
            Log.d("premises", premises.toString())
        }
        val postalCode = addresses[0].postalCode
        if (postalCode != null) {
            Log.d("postalCode", postalCode.toString())
        }
        val featureName = addresses[0].featureName
        if (featureName != null) {
            Log.d("featureName", featureName.toString())
        }
        val getAddressLine0 = addresses[0].getAddressLine(0)
        if (getAddressLine0 != null)
            Log.d("getAddressLine0", getAddressLine0.toString())
        for (i in 0 until addresses[0].maxAddressLineIndex) {
            Log.d("getAddressLine($i)", addresses[0].getAddressLine(i).toString())
        }
    }
}

如果我运行getCity(context, 53.7f, -1.506f)featureName则包含正确的城市名称 Wakefield。

如果我运行getCity(context, 53.801f, -1.549f)featureName现在包含街道名称 Portland Place。getAddressLine(0)返回 Portland Place, 5 Calverley St, Leeds LS1 3DA, UK,其中包含正确的城市 Leeds。我可以从 getAddressLine(0) 中删除街道名称、邮政编码和门牌号码,以留在城市中。不幸的是,在某些极端情况下这是行不通的,因为有时街道名称包含 ingetAddressLine(0)而不是 in 的缩写thoroughfare

这个问题如何在android中通过纬度和经度获取城市名称?有完全不同的答案,因为不同国家的地址以不同的方式存储。

似乎有很多变体和边缘情况我需要编码只是为了获得英国 2 个相邻城市的城市名称。如何从世界范围内的任何纬度或经度中获取正确的城市名称?世界上有太多的城市可以测试我的代码并为其编写代码,并且可能存在许多我不知道甚至存在的边缘案例和变体。

编辑

下面的函数正确地获取了英国的城市。不幸的是,它在美国和印度以及任何有州的国家都失败了。

private fun getCity(context: Context, latitude: Float, longitude: Float): String {
    val gcd = Geocoder(context, Locale.getDefault())
    val addresses = gcd.getFromLocation(latitude.toDouble(), longitude.toDouble(), 1)
    if (addresses.size > 0) {
        val locality = addresses[0].locality
        val getAddressLine0 = addresses[0].getAddressLine(0)
        if (getAddressLine0 != null) {
            val strs = getAddressLine0.split(",").toTypedArray()
            if (strs.count() == 1) {
                if (locality != null && locality != "") {
                    return "$locality, ${strs[0]}"
                }
                return strs[0]
            }
            for (str in strs) {
                var tempStr = str.replace(postalCode, "")
                if (tempStr != str) {
                    tempStr = tempStr.trim()
                    if (locality != null && locality != "" && locality != tempStr) {
                        return "$locality, $tempStr"
                    }
                    return tempStr
                }
            }
        }
        if (locality != null) {
            return locality
        }
    }
    return ""
}

标签: javaandroidkotlingeolocationlatitude-longitude

解决方案


Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List addresses = geocoder.getFromLocation(MyLat, MyLong, 1); 
String cityName = addresses.get(0).getAddressLine(0); 
String stateName = addresses.get(0).getAddressLine(1); 
String countryName = addresses.get(0).getAddressLine(2);

推荐阅读