是否有一个服务或 API 我可以 ping 并传入纬度/经度作为参数,并返回纬度/经度对所在的邮政编码?这是仅限美国的,所以我不必担心国际代码等。
我觉得谷歌地图的反向地理编码对我来说太重了。如果可能的话,我更喜欢清淡一点的。这将在 javascript 中完成。
这称为反向地理编码(地址查找)。要获取 lat: 40.714224、lng: -73.961452 的地址,请使用参数
http://maps.googleapis.com/maps/api/geocode/json
(example) 查询
latlng=40.714224,-73.961452&sensor=true
,它返回 JSON 对象或使用 http://maps.googleapis.com/maps/api/geocode/xml
返回 XML 响应 (example)。它来自 Google,而且是免费的。
对于 Google API,您需要在 Google 地图中使用它,根据他们的网站:
注意:地理编码 API 只能与 Google 结合使用 地图;地理编码结果而不将其显示在地图上是 禁止。
请查看 http://geonames.org。有一个网络服务 findNearbyPostalCodes(国际)。
示例:findNearbyPostalCodesJSON?lat=47&lng=9&用户名=演示
缩短输出:
{
"postalCodes": [{
"adminCode3": "1631",
"distance": "2.2072",
"postalCode": "8775",
"countryCode": "CH",
"lng": 8.998679778165283,
"placeName": "Luchsingen",
"lat": 46.980169648620375
}]
}
模拟账户的限制为每小时 2000 次查询。
Google Maps API 可以获取与地理位置关联的邮政编码。但是,如果您位于丛林中的某个地方,那么此 API 将不会返回任何内容,因为邮政编码已映射到邮政地址。在这种情况下,您需要获取附近城市的邮政编码。
您可以使用此方法来做到这一点
//Reverse GeoCode position into Address and ZipCOde
function getZipCodeFromPosition(geocoder, map,latlng,userLocationInfoWindow) {
geocoder.geocode({'location': latlng}, function(result, status) {
if (status === 'OK') {
if (result[0]) {
console.log("GeoCode Results Found:"+JSON.stringify(result));
//Display Address
document.getElementById("address").textContent = "Address: " +result[0].formatted_address;
//Update Info Window on Server Map
userLocationInfoWindow.setPosition(latlng);
userLocationInfoWindow.setContent('<IMG BORDER="0" ALIGN="Left" SRC="https://media3.giphy.com/media/IkwH4WZWgdfpu/giphy.gif" style ="width:50px; height:50px"><h6 class ="pink-text">You Are Here</h4> <p class = "purple-text" style ="margin-left:30px;">'+result[0].formatted_address+'</p>');
userLocationInfoWindow.open(map);
map.setCenter(latlng);
//Try to Get Postal Code
var postal = null;
var city = null;
var state = null;
var country = null;
for(var i=0;i<result.length;++i){
if(result[i].types[0]=="postal_code"){
postal = result[i].long_name;
}
if(result[i].types[0]=="administrative_area_level_1"){
state = result[i].long_name;
}
if(result[i].types[0]=="locality"){
city = result[i].long_name;
}
if(result[i].types[0]=="country"){
country = result[i].long_name;
}
}
if (!postal) {
geocoder.geocode({ 'location': result[0].geometry.location }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//Postal Code Not found, Try to get Postal code for City
var result=results[0].address_components;
for(var i=0;i<result.length;++i){
if(result[i].types[0]=="postal_code"){
postal = result[i].long_name;
}
}
if (!postal) {
//Postal Code Not found
document.getElementById("postal").textContent = "No Postal Code Found for this location";
}else
{
//Postal Code found
document.getElementById("postal").textContent = "Zip Code: "+postal;
}
}
});
} else
{
//Postal Code found
document.getElementById("postal").textContent = "Zip Code: "+postal;
}
console.log("STATE: " + state);
console.log("CITY: " + city);
console.log("COUNTRY: " + country);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
</script>
工作示例
kubetz 的答案很好,但由于 我们必须使用 https 来获取地理定位工作(Geolocation API 从 Chrome 50 中的不安全来源中删除),因此调用 http://api.geonames.org失败,因为它不是通过 https。 从 geonames.org 获取的通过 https 调用的本地 php 脚本解决了这个问题。
//javascript function
function getZipFromLatLong() {
var url = "getzip.php";
var formData = new FormData();
formData.append("lat", current_lat);
formData.append("long", current_long);
var r = new XMLHttpRequest();
r.open("POST", url, true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) {
return;
} else {
data = r.responseText;
var jdata = JSON.parse(data);
document.getElementById("zip").value = jdata.postalCodes[0].postalCode;
}
}
r.send(formData);
}
//getzip.php script
<?php
$lat = $_POST["lat"];
$long = $_POST["long"];
$url = "http://api.geonames.org/findNearbyPostalCodesJSON?username=demo&lat=" . $lat . "&lng=" . $long;
$content = file_get_contents($url);
//the output is json, so just return it as-is
die($content);
?>
对于 Swift,请执行以下操作:
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
let locationManager = CLLocationManager()
let geoCoder = CLGeocoder()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("location map updated")
let longitude = manager.location?.coordinate.longitude
let latitude = manager.location?.coordinate.latitude
let currentLocation = CLLocation(latitude: latitude!, longitude: longitude!)
self.geoCoder.reverseGeocodeLocation(currentLocation, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark?
placeMark = placemarks?[0]
if let zipCodeFound = placeMark?.postalCode {
print(zipCodeFound)
})
}