And*_*huk 16 objective-c ios clgeocoder swift swift2
在我的一个应用程序中,我需要添加一个按名称查找城市的功能.我正在使用它CLGeocoder来实现这一点,我希望它具有与iOS天气应用程序相同的行为.
以下是我的代码:
CLGeocoder().geocodeAddressString(searchBar.text!, completionHandler:{ (placemarks, error) -> Void in
guard let nonNilMarks = placemarks else {return}
for placemark in nonNilMarks {
print("locality: \(placemark.locality)")
print("name: \(placemark.name)")
print("country: \(placemark.country)")
print("formatted address: \(placemark.addressDictionary)")
}
})
Run Code Online (Sandbox Code Playgroud)
它在大多数情况下都能很好地工作.但是,我最近注意到一些失败的情况.以下是一些示例的输出:
locality: Optional("Milan")
name: Optional("Milan")
country: Optional("Italy")
formatted address: Optional([SubAdministrativeArea: Milan, State: Lombardy, CountryCode: IT, Country: Italy, Name: Milan, FormattedAddressLines: (
Milan,
Italy
), City: Milan])
Run Code Online (Sandbox Code Playgroud)
这是正确的输出
德克萨斯州有一个叫意大利的小镇.如果我键入'Italy,TX',则输出为:
locality: Optional("Italy")
name: Optional("Italy")
country: Optional("United States")
formatted address: Optional([SubAdministrativeArea: Ellis, State: TX, CountryCode: US, Country: United States, Name: Italy, FormattedAddressLines: (
"Italy, TX",
"United States"
), City: Italy])
Run Code Online (Sandbox Code Playgroud)
当我输入"意大利"时,我只获得该国家的地方标记:
locality: nil
name: Optional("Italy")
country: Optional("Italy")
formatted address: Optional([CountryCode: IT, Name: Italy, FormattedAddressLines: (
Italy
), Country: Italy])
Run Code Online (Sandbox Code Playgroud)
这与'Italy,TX'的情况类似:
locality: Optional("Singapore")
name: Optional("Singapore")
country: Optional("Singapore")
formatted address: Optional([City: Singapore, CountryCode: SG, Name: Singapore, State: Singapore, FormattedAddressLines: (
Singapore,
Singapore
), Country: Singapore])
Run Code Online (Sandbox Code Playgroud)
再次,似乎与'意大利'的情况类似.它只找到一个国家:
locality: nil
name: Optional("Singapore")
country: Optional("Singapore")
formatted address: Optional([CountryCode: SG, Name: Singapore, FormattedAddressLines: (
Singapore
), Country: Singapore])
Run Code Online (Sandbox Code Playgroud)
在这个阶段我可能会geocodeAddressString:停止搜索它是否找到一个名称等于搜索参数的国家,所以我尝试将我的代码更改为:
let addrDict = [kABPersonAddressCityKey as NSString: searchBar.text!]
CLGeocoder().geocodeAddressDictionary(addrDict, completionHandler:{ (placemarks, error) -> Void in
print(placemarks)
})
Run Code Online (Sandbox Code Playgroud)
我认为通过将搜索词限制为城市名称,我会得到正确的结果.不幸的是,我得到完全相同的行为!
而THEN我意识到,我不仅案件的问题时,城市的名字等于国家名称.
locality: nil
name: Optional("Tokyo")
country: Optional("Japan")
formatted address: Optional([CountryCode: JP, Name: Tokyo, State: Tokyo, FormattedAddressLines: (
Tokyo,
Japan
), Country: Japan])
Run Code Online (Sandbox Code Playgroud)
不仅可以CLGeocoder省略结果(比如'意大利'),但它也可以告诉我一个地方没有locality时间,事实上它确实如此(我相信上次我查了一张地图东京还是一个城市! ).
有谁知道如何解决这些问题?
天气应用程序以某种方式做到了 - 搜索'新加坡'或'意大利'那里给出了正确的结果.我将不胜感激任何帮助!
PS虽然我正在使用Swift,但我将Objective-C添加为标签,因为我认为这个问题不是特定于Swift的.
使用你所展示的是完全正确的,我认为你无法做任何其他事情来改善结果.它仍然只是一些复杂的算法,试图根据规则集和一些假设对结果进行排序.
那很难过,我完全理解你的挫败感,因为我去过那里并做到了.问题在于地理编码数据库显然并不完整,而苹果并不是领导这一领域的公司 - 谷歌就是.在这里,您可以看到引入Geocoder时的技术说明,其中表示仍有国家不受支持或仅部分支持.
所以我的建议是,如果你想获得最好的结果(虽然仍然没有防止故障),请切换到Google Geolocation.对于相当多的请求它是免费的,之后它需要一些非常小的金额.根据我的经验,所有基本搜索的成功率约为99%,如果您提供更多信息,它的效果会更好.API选项也非常广泛.
以下是地理编码和反向地理编码的开发人员文档链接:https : //developers.google.com/maps/documentation/geocoding/intro https://developers.google.com/maps/documentation/javascript/examples/geocoding-相反
希望它至少有一点帮助.
编辑:在我写这篇文章之后,我做了一些研究,似乎我不是唯一提出这种说法的人(也包括相同的不受支持的链接).
| 归档时间: |
|
| 查看次数: |
3423 次 |
| 最近记录: |