使用Google Maps Javascript API V3反向地理编码获取邮政编码

23

我正在尝试在googlemaps视口中心发生更改时,使用邮政编码向我的数据库提交查询。我知道可以使用类似以下内容的反向地理编码来完成此操作:

google.maps.event.addListener(map, 'center_changed', function(){
newCenter();
});
...
function newCenter(){
var newc = map.getCenter();
geocoder.geocode({'latLng': newc}, function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
  var newzip = results[0].address_components['postal_code'];
  }
});
};

当然,这段代码实际上是不起作用的。所以我想知道我需要如何更改它才能从结果数组中提取邮政编码。


看起来我别无选择,只能迭代地址组件并搜索一个带有types[0] == 'postal_code'的地址组件? 有更好的方法吗? - Romaine M.
@RomainM 是的,我会假设除非您想手动从结果中解析它。 - KJYe.Name
是的,您必须遍历数组并查找其types数组中具有“postal_code”的元素,该元素可能位于最后、最前或任何位置。此外,哪个元素?您可能希望从results[0].address_componentsresults本身获取邮政编码:尝试两者并查看在您关心的区域中哪个更好用。一般来说,如果您关心具有完整地址的地点,则建议使用results[0].address_components,如果您关心严格包含您的latlng的邮政编码,则使用results - miguev
23个回答

23

目前我意识到的是,在大多数情况下,邮政编码总是在每个返回地址的最后一个值中,因此,如果您想检索出第一个邮政编码(这是我的情况),可以使用以下方法:

var address = results[0].address_components;
var zipcode = address[address.length - 1].long_name;

1
我不得不使用 address.length - 2。不确定为什么你的不同? - Andy Lobel
2
我发布这个答案已经有很长时间了,但我记得在另一个项目中发现索引会根据结果而变化。换句话说,邮政编码有时不是最后一项。 - Tuco
2
@Tuco,索引确实会改变。有时它是最后一个元素,而其他时候则是倒数第二个元素。不过我不确定这是什么原因。 - jmiraglia
1
是的,您必须遍历数组并查找其“types”数组中具有“postal_code”的元素,该元素可能位于最后、最前或任何位置。 - miguev
2
对于那些想知道为什么邮政编码有时出现在倒数第二个位置的人,这是因为在某些情况下,最后一项是“postal_code_suffix”键。 - asprin
显示剩余4条评论

14

谢谢伙计,使用 underscore.js 的 find() 很漂亮的一行代码。 - jpincheira
下划线黑科技非常好。我目前的项目中没有使用下划线,也不想为此添加另一个库,但我会将这个答案加入书签 :D - guinetik
请查看此答案 https://dev59.com/Nm435IYBdhLWcg3wkA9e#62945561,其中使用了本地的 .find 方法。 - Rahil Wazir

12

好的,我明白了。解决方案有点丑陋,而且最后一个for循环可能不是必需的,但以下是代码,供其他需要从address_components[]中提取信息的人使用。这是在地理编码器回调函数内部。

// make sure to initialize i
for(i=0; i < results.length; i++){
            for(var j=0;j < results[i].address_components.length; j++){
                for(var k=0; k < results[i].address_components[j].types.length; k++){
                    if(results[i].address_components[j].types[k] == "postal_code"){
                        zipcode = results[i].address_components[j].short_name;
                    }
                }
            }
    }

这对我不起作用,我正在检查爱荷华城市的邮政编码,但它显示为未定义。 - Sam Cromer
这应该是批准的答案。对于没有邮政编码作为最后一个组件的地址有效。 - jmiraglia
2
嘿@SamCromer,我测试了上面的代码,答案也是未定义的。也许你在for循环之前也忘记了放置var i = 0。我添加了它,它运行得非常好! - guinetik
2
只要将'for(i; i < results.length; i++){'更改为'for(i=0; i < results.length; i++){', 这段代码就能完美运行。非常感谢这个解决方案。 - luke_mclachlan

12

使用 JQuery?

var searchAddressComponents = results[0].address_components,
    searchPostalCode="";

$.each(searchAddressComponents, function(){
    if(this.types[0]=="postal_code"){
        searchPostalCode=this.short_name;
    }
});

使用short_name或long_name都可以
只有当从Google Maps API获取到邮政(邮编?)代码时,“searchPostalCode”变量才会包含该代码。

有时您的查询结果不会返回“postal_code”。


4

你也可以使用 JavaScript .find 方法,它与 underscore _.find 方法类似,但它是本地的并且不需要额外依赖。

const zip_code = results[0].address_components.find(addr => addr.types[0] === "postal_code").short_name;

你需要一个Polyfill来解决这个问题,因为IE不支持[https://caniuse.com/array-find]。 - MadMax

4
$.each(results[0].address_components,function(index,value){
    if(value.types[0] === "postal_code"){
        $('#postal_code').val(value.long_name);
    }
});

2

这只需两个循环。一旦我们找到第一个“类型”为“postal_code”,“结果”数组就会得到更新。

接着它使用新发现的数组集更新原始数组并再次循环。

            var i, j,
            result, types;

            // Loop through the Geocoder result set. Note that the results
            // array will change as this loop can self iterate.
            for (i = 0; i < results.length; i++) {

                result = results[i];

                types = result.types;

                for (j = 0; j < types.length; j++) {

                    if (types[j] === 'postal_code') {

                        // If we haven't found the "long_name" property,
                        // then we need to take this object and iterate through
                        // it again by setting it to our master loops array and 
                        // setting the index to -1
                        if (result.long_name === undefined) {
                            results = result.address_components;
                            i = -1;
                        }
                        // We've found it!
                        else {
                            postcode = result.long_name;
                        }

                        break;

                    }

                }

            }

2

您也可以使用此代码,此函数将帮助您在按钮单击、失去焦点、按键上或按下时获取zip。

只需将地址传递给此函数即可。

使用Google API和有效的密钥,并删除传感器选项,因为现在不需要它。

function callZipAPI(addSearchZip)
{    
    var geocoder = new google.maps.Geocoder();
    var zipCode = null;

    geocoder.geocode({ 'address': addSearchZip }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {

            //var latitude = results[0].geometry.location.lat();
            //var longitude = results[0].geometry.location.lng();

            var addressComponent = results[0].address_components;            
            for (var x = 0 ; x < addressComponent.length; x++) {
                var chk = addressComponent[x];
                if (chk.types[0] == 'postal_code') {
                    zipCode = chk.long_name;
                }
            }
            if (zipCode) {
                alert(zipCode);
            }
            else {
                alert('No result found!!');
            }
        } else {            
            alert('Enter proper address!!');
        }
    });
}

如果您想要纬度和经度,请取消这两行代码中的注释部分。 - Ashu Ashutosh

2
我将使用以下代码来获取“邮政编码”和“地点”,但您可以更改type的值以获取任何其他字段:

JAVASCRIPT

var address = results[0].address_components;
var zipcode = '';
var locality = '';

for (var i = 0; i < address.length; i++) {
     if (address[i].types.includes("postal_code")){ zipcode = address[i].short_name; }    
     if (address[i].types.includes("locality")){ locality = address[i].short_name; }
}

2

我认为与其依赖于索引,最好是在组件内部检查地址类型关键字。我通过使用switch case解决了这个问题。

      var address = '';
      var pin = '';
      var country = '';
      var state = '';
      var city = '';
      var streetNumber = '';
      var route ='';
      var place = autocomplete.getPlace(); 
      for (var i = 0; i < place.address_components.length; i++) {
        var component = place.address_components[i];
        var addressType = component.types[0];

        switch (addressType) {
            case 'street_number':
                streetNumber = component.long_name;
                break;
            case 'route':
                route = component.short_name;
                break;
            case 'locality':
                city = component.long_name;
                break;
            case 'administrative_area_level_1':
                state = component.long_name;
                break;
            case 'postal_code':
                pin = component.long_name;
                break;
            case 'country':
                country = component.long_name;
                break;
        }
       }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接