【问题标题】:Retrieving Postal Code with Google Maps Javascript API V3 Reverse Geocode使用 Google Maps Javascript API V3 反向地理编码检索邮政编码
【发布时间】:2011-07-17 11:53:45
【问题描述】:

每当 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' 搜索一个?有没有更好的方法来做到这一点?
  • @RomainM 是的,除非您想从结果中手动解析它,否则我会假设
  • 是的,您必须遍历数组并在其types 数组中查找具有“postal_code”的元素,该元素可能是最后一个或第一个或介于两者之间的任何位置。此外,哪个元素?您可能想从results[0].address_componentsresults 本身获取邮政编码:两者都试一下,看看哪个在您关心的地区最有效。一般来说,如果你关心有完整地址的地方,我建议results[0].address_components,如果你想在你得到的邮政编码中严格控制你的纬度,我会推荐results

标签: google-maps google-maps-api-3 geocoding reverse-geocoding postal-code


【解决方案1】:

只要在所有类型中搜索postal_code,找到就返回。

const address_components = [{"long_name": "2b","short_name": "2b","types": ["street_number"]}, { "long_name": "Louis Schuermanstraat","short_name": "Louis Schuermanstraat", "types": ["route"]},{"long_name": "Gent","short_name": "Gent","types": ["locality","political" ]},{"long_name": "Oost-Vlaanderen","short_name": "OV","types": ["administrative_area_level_2","political"]},{"long_name": "Vlaanderen","short_name": "Vlaanderen","types": ["administrative_area_level_1","political"]},{"long_name": "België","short_name": "BE","types": ["country","political"]},{"long_name": "9040","short_name": "9040","types": ["postal_code"]}];
    
// address_components = results[0]address_components

console.log({
  'object': getByGeoType(address_components),
  'short_name': getByGeoType(address_components).short_name,
  'long_name': getByGeoType(address_components).long_name,
  'route': getByGeoType(address_components, ['route']).long_name,
  'place': getByGeoType(address_components, ['locality', 'political']).long_name
});


function getByGeoType(components, type = ['postal_code']) {
  let result = null;
  $.each(components,
    function() {
      if (this.types.some(r => type.indexOf(r) >= 0)) {
        result = this;
        return false;
      }
    });
  return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【讨论】:

    【解决方案2】:

    我认为这是最准确的解决方案:

    zipCode: result.address_components.find(item => item.types[0] === 'postal_code').long_name;
    

    【讨论】:

      【解决方案3】:

      您也可以使用 JavaScript .find 方法,它类似于下划线 _.find 方法,但它是原生的,不需要额外的依赖。

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

      【讨论】:

      【解决方案4】:

      据我所知,zip 是最后一个或最后一个。 这就是为什么这是我的解决方案

      const getZip = function (arr) {
        return (arr[arr.length - 1].types[0] === 'postal_code') ? arr[arr.length - 1].long_name : arr[arr.length - 2].long_name;
      };
      const zip = getZip(place.address_components);
      

      【讨论】:

        【解决方案5】:

        好的,我明白了。该解决方案比我想要的要丑一些,而且我可能不需要最后一个 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;
                            }
                        }
                    }
            }
        

        【讨论】:

        • 这对我不起作用,我正在检查 Iowa City Iowa 的邮政编码,结果未定义。
        • 这应该是批准的答案。这适用于没有邮政编码作为最后一个组成部分的地址。
        • 嘿@SamCromer 我测试了上面的代码,答案也未定义。也许你也忘了把 var i= 0 放在 for 循环之前。我添加了,效果很好!
        • 这很好用,只要你将 'for(i; i
        【解决方案6】:

        我认为与其依赖索引,不如更好地检查组件内的地址类型键。我通过使用开关盒解决了这个问题。

              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;
                }
               }
        

        【讨论】:

          【解决方案7】:
          $.each(results[0].address_components,function(index,value){
              if(value.types[0] === "postal_code"){
                  $('#postal_code').val(value.long_name);
              }
          });
          

          【讨论】:

            【解决方案8】:

            我使用此代码来获取“邮政编码”和“位置”,但您可以使用它来获取任何其他字段,只需更改类型的值:

            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; }
            }
            

            【讨论】:

              【解决方案9】:

              Romaine M. — 谢谢!如果你只需要在谷歌返回的第一个结果中找到邮政编码,你可以只做2个循环:

              for(var j=0;j < results[0].address_components.length; j++){
                  for(var k=0; k < results[0].address_components[j].types.length; k++){
                      if(results[0].address_components[j].types[k] == "postal_code"){
                          zipcode = results[0].address_components[j].long_name;
                      }
                  }
              }
              

              【讨论】:

                【解决方案10】:

                现在看来还是从restful API中获取比较好,试试吧:

                https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR_KEY_HERE

                使用 AJAX GET 调用非常完美!

                类似:

                var your_api_key = "***";
                var f_center_lat = 40.714224;
                var f_center_lon = -73.961452;
                
                $.ajax({ url: "https://maps.googleapis.com/maps/api/geocode/json?latlng="+f_center_lat+","+f_center_lon+"&key="+your_api_key,
                            method: "GET"
                        })
                        .done(function( res ) { if (debug) console.log("Ajax result:"); console.log(res);
                            var zipCode = null;
                            var addressComponent = res.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);
                                $(current_map_form + " #postalcode").val(zipCode);
                            }
                            else {
                                //alert('No result found!!');
                                if (debug) console.log("Zip/postal code not found for this map location.")
                            }
                        })
                        .fail(function( jqXHR, textStatus ) {
                            console.log( "Request failed (get postal code via geocoder rest api). Msg: " + textStatus );
                        });
                

                【讨论】:

                  【解决方案11】:

                  在 PHP 中,我使用此代码。它几乎在所有条件下都有效。

                  $zip = $data["results"][3]["address_components"];
                  $zip = $index[0]["short_name"];
                  

                  【讨论】:

                    【解决方案12】:

                    您也可以使用此代码,此功能将有助于在按钮单击或 onblur 或 keyup 或 keydown 时获取 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!!');
                            }
                        });
                    }
                    

                    【讨论】:

                    • 如果你想要经纬度,只需从提到的两行中删除注释部分即可。
                    【解决方案13】:
                    //autocomplete is the text box where u will get the suggestions for an address.
                    
                    autocomplete.addListener('place_changed', function () {
                    //Place will get the selected place geocode and returns with the address              
                    //and marker information.
                            var place = autocomplete.getPlace();
                    //To select just the zip code of complete address from marker, below loop //will help to find. Instead of y.long_name you can also use y.short_name. 
                            var zipCode = null;
                            for (var x = 0 ; x < place.address_components.length; x++) {
                                var y = place.address_components[x];
                                if (y.types[0] == 'postal_code') {
                                    zipCode = y.long_name;
                                }
                            }
                        });
                    

                    【讨论】:

                    • 通过自动完成文本框,您可以获得所需的邮政地址,
                    • 请在您的回答中添加一些解释。它可能有助于 OP 了解您在此处发布的内容。
                    【解决方案14】:

                    使用JSONPath,只需一行代码即可轻松完成:

                    var zip = $.results[0].address_components[?(@.types=="postal_code")].long_name;
                    

                    【讨论】:

                      【解决方案15】:
                       return $http.get('//maps.googleapis.com/maps/api/geocode/json', {
                                  params: {
                                      address: val,
                                      sensor: false
                                  }
                              }).then(function (response) {
                                 var model= response.data.results.map(function (item) {
                                     // return item.address_components[0].short_name;
                                     var short_name;
                                   var st=  $.each(item.address_components, function (value, key) {
                                          if (key.types[0] == "postal_code") {
                                              short_name= key.short_name;
                                          }
                                      });
                                   return short_name;
                      
                                  });
                                      return model;
                              });
                      

                      【讨论】:

                        【解决方案16】:

                        使用 Jquery

                        • 您无法确定邮政编码存储在 address_components 数组中的哪个位置。有时在 address_components.length - 1 > pincode 中可能不存在。这在“经纬度地址”地理编码中是正确的。
                        • 您可以确定邮政编码将包含“postal_code”字符串。所以最好的方法是检查。
                           var postalObject = $.grep(results[0].address_components, function(n, i) {
                                                            if (n.types[0] == "postal_code") {
                                                                return n;
                                                            } else {
                                                                return null;
                                                            }
                                                        });
                        
                                                        $scope.query.Pincode = postalObject[0].long_name;
                        

                        【讨论】:

                          【解决方案17】:

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

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

                          【讨论】:

                          • 我不得不使用address.length - 2 不知道为什么你的不一样?
                          • 自从我发布这个答案以来已经有很长时间了,但我记得在另一个项目中我发现索引会根据结果而有所不同。换句话说,邮政编码有时可能不是最后一项。
                          • @Tuco,索引确实发生了变化。有时它是最后一个元素,有时它是倒数第二个。但不确定原因。
                          • 是的,您必须遍历数组并在其types 数组中查找具有“postal_code”的元素,该元素可能是最后一个或第一个或介于两者之间的任何位置。
                          • 对于那些想知道为什么邮政编码有时会排在倒数第二位的人,这是因为在某些情况下,最后一项是postal_code_suffix
                          【解决方案18】:

                          这个简单的代码对我有用

                          for (var i = 0; i < address.length; i++) {
                                  alert(address[i].types);
                                  if (address[i].types == "postal_code")
                                      $('#postalCode').val(address[i].long_name);
                                  if (address[i].types == "")
                                      $('#country').val(address[i].short_name);
                              }
                          

                          【讨论】:

                            【解决方案19】:

                            使用 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 将在上面工作
                            “searchPostalCode” 变量将包含邮政编码(邮编?) IF 并且仅当您从 Google Maps API 获得一个。

                            有时,您的查询不会得到“postal_code”。

                            【讨论】:

                              【解决方案20】:

                              您可以使用 underscore.js 库轻松完成此操作:http://documentcloud.github.com/underscore/#find

                              _.find(results[0].address_components, function (ac) { return ac.types[0] == 'postal_code' }).short_name
                              

                              【讨论】:

                              • 感谢哥们,使用 underscore.js 的 find() 非常不错的单行代码
                              • 下划线破解非常好。我没有在我当前的项目中使用下划线,我不想为它添加另一个库,但我正在为这个答案添加书签:D
                              • 使用本机.find 方法查看此答案stackoverflow.com/a/62945561/2264626
                              【解决方案21】:
                              places.getDetails( request_details, function(results_details, status){
                              
                                              // Check if the Service is OK
                                              if (status == google.maps.places.PlacesServiceStatus.OK) {                  
                              
                                                  places_postal           = results_details.address_components
                                                  places_phone            = results_details.formatted_phone_number
                                                  places_phone_int        = results_details.international_phone_number
                                                  places_format_address   = results_details.formatted_address
                                                  places_google_url       = results_details.url
                                                  places_website          = results_details.website
                                                  places_rating           = results_details.rating
                              
                                                  for (var i = 0; i < places_postal.length; i++ ) {
                                                      if (places_postal[i].types == "postal_code"){
                                                          console.log(places_postal[i].long_name)
                                                      }
                                                  }
                              
                                              }
                                          });
                              

                              这对我来说似乎工作得很好,这是使用新的 Google Maps API V3。如果这对任何人有帮助,请写下评论,我正在写我的剧本……所以它可能会改变。

                              【讨论】:

                                【解决方案22】:

                                这只需要两个 for 循环。一旦我们发现第一个“type”是“postal_code”,“results”数组就会更新。

                                然后它用新找到的数组集更新原始数组并再次循环。

                                            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;
                                
                                                    }
                                
                                                }
                                
                                            }
                                

                                【讨论】:

                                  【解决方案23】:

                                  总之,这是一个很大的努力。至少使用 v2 API,我可以检索这些详细信息:

                                  var place = response.Placemark[0];
                                  var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                                  
                                  myAddress = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName
                                  
                                  myCity = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName
                                  
                                  myState = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName
                                  
                                  myZipCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber
                                  

                                  必须有一种更优雅的方式来检索单个地址组件,而无需通过您刚刚经历的循环柔术。

                                  【讨论】:

                                  • 我希望你是对的,也许我只是不明白你应该如何与对象交互。如果您查看教程内容,很明显 address_components 是一个数组,并且由于 Javascript 没有关联数组,我能想到的唯一方法是使用循环 code.google.com/apis/maps/documentation/javascript/…
                                  猜你喜欢
                                  • 2020-06-05
                                  • 1970-01-01
                                  • 2012-06-08
                                  • 2013-05-30
                                  • 2011-09-27
                                  • 2013-10-05
                                  • 1970-01-01
                                  • 2013-04-25
                                  • 2013-04-05
                                  相关资源
                                  最近更新 更多