【问题标题】:get city from geocoder results?从地理编码器结果中获取城市?
【发布时间】:2011-09-15 15:26:22
【问题描述】:

从地理编码器结果中获取不同数组内容时遇到问题。

item.formatted_address 有效,但 item.address_components.locality 无效?

geocoder.geocode( {'address': request.term }, function(results, status) {

        response($.map(results, function(item) {

        alert(item.formatted_address+" "+item.address_components.locality)
    }            
}); 

//返回的数组是;

 "results" : [
      {
         "address_components" : [
            {
               "long_name" : "London",
               "short_name" : "London",
               "types" : [ "locality", "political" ]
            } ],
          "formatted_address" : "Westminster, London, UK" // rest of array...

任何帮助表示赞赏!

直流

【问题讨论】:

    标签: google-maps geocoding street-address city


    【解决方案1】:

    最终使用:

    var arrAddress = item.address_components;
    var itemRoute='';
    var itemLocality='';
    var itemCountry='';
    var itemPc='';
    var itemSnumber='';
    
    // iterate through address_component array
    $.each(arrAddress, function (i, address_component) {
        console.log('address_component:'+i);
    
        if (address_component.types[0] == "route"){
            console.log(i+": route:"+address_component.long_name);
            itemRoute = address_component.long_name;
        }
    
        if (address_component.types[0] == "locality"){
            console.log("town:"+address_component.long_name);
            itemLocality = address_component.long_name;
        }
    
        if (address_component.types[0] == "country"){ 
            console.log("country:"+address_component.long_name); 
            itemCountry = address_component.long_name;
        }
    
        if (address_component.types[0] == "postal_code_prefix"){ 
            console.log("pc:"+address_component.long_name);  
            itemPc = address_component.long_name;
        }
    
        if (address_component.types[0] == "street_number"){ 
            console.log("street_number:"+address_component.long_name);  
            itemSnumber = address_component.long_name;
        }
        //return false; // break the loop   
    });
    

    【讨论】:

    • 效果很好,但作为“switch”语句会更优雅,代码更少。
    • 不要指望这会可靠,Google 的地理编码在很多方面都存在缺陷。 “locality”并不总是可用的,有时城市实际上在 state (level_1) 字段中。特别是当返回类型为 ROOFTOP 时,Google 地理编码结果很糟糕。在国外,他们突然转换格式。与“ROOFTOP”相比,您可以更信任“近似”结果
    • 正确。不能可靠地工作。谷歌指出,您在回复中获得的组件没有一致性。此外,它可能会随着时间而改变。 developers.google.com/maps/documentation/places/web-service/… 在“地点详情结果”下
    【解决方案2】:

    尝试了几个不同的请求:

    MK107BX

    Cleveland Park Crescent, UK

    如您所说,返回的数组大小不一致,但两个结果的 Town 似乎都位于类型为 [“locality”、“political”] 的 address_component 项中。也许您可以将其用作指标?

    EDIT:使用 jQuery 获取 locality 对象,将其添加到您的 response 函数中:

    var arrAddress = item.results[0].address_components;
    // iterate through address_component array
    $.each(arrAddress, function (i, address_component) {
        if (address_component.types[0] == "locality") // locality type
            console.log(address_component.long_name); // here's your town name
            return false; // break the loop
        });
    

    【讨论】:

    • 怕这行不通。不确定它会如何,因为“地址”没有变量/数组?
    • 对不起,我在处理不同的谷歌地图 api 请求。已编辑。
    • 别担心!知道我怎么能得到这个地方吗?我只是在尝试中不确定;-/ 如果 item.formatted_address 有效,我认为这也应该是错误的 - item.address_components.locality ?
    • 不,因为 formatted_address 是一个字符串,但 address_components 是一个数组。我将添加有关如何查看它的代码。
    • 在您的情况下,第一行可能是 var arrAddress = item.address_components;。而且您的代码不起作用,因为 address_components 是一个数组。
    【解决方案3】:

    我必须创建一个程序,当用户单击地图上的某个位置时,该程序将在用户表单中填写纬度、经度、城市、县和州字段。该页面可以在http://krcproject.groups.et.byu.net 找到,它是一个用户表单,允许公众为数据库做出贡献。我不自称是专家,但效果很好。

    <script type="text/javascript">
      function initialize() 
      {
        //set initial settings for the map here
        var mapOptions = 
        {
          //set center of map as center for the contiguous US
          center: new google.maps.LatLng(39.828, -98.5795),
          zoom: 4,
          mapTypeId: google.maps.MapTypeId.HYBRID
        };
    
        //load the map
        var map = new google.maps.Map(document.getElementById("map"), mapOptions);
    
        //This runs when the user clicks on the map
        google.maps.event.addListener(map, 'click', function(event)
        {
          //initialize geocoder
          var geocoder = new google.maps.Geocoder()
    
          //load coordinates into the user form
          main_form.latitude.value = event.latLng.lat();
          main_form.longitude.value = event.latLng.lng();
    
          //prepare latitude and longitude
          var latlng = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
    
          //get address info such as city and state from lat and long
          geocoder.geocode({'latLng': latlng}, function(results, status) 
          {
            if (status == google.maps.GeocoderStatus.OK) 
            {
              //break down the three dimensional array into simpler arrays
              for (i = 0 ; i < results.length ; ++i)
              {
                var super_var1 = results[i].address_components;
                for (j = 0 ; j < super_var1.length ; ++j)
                {
                  var super_var2 = super_var1[j].types;
                  for (k = 0 ; k < super_var2.length ; ++k)
                  {
                    //find city
                    if (super_var2[k] == "locality")
                    {
                      //put the city name in the form
                      main_form.city.value = super_var1[j].long_name;
                    }
                    //find county
                    if (super_var2[k] == "administrative_area_level_2")
                    {
                      //put the county name in the form
                      main_form.county.value = super_var1[j].long_name;
                    }
                    //find State
                    if (super_var2[k] == "administrative_area_level_1")
                    {
                      //put the state abbreviation in the form
                      main_form.state.value = super_var1[j].short_name;
                    }
                  }
                }
              }
            }
          });
        });
      }
    </script>
    

    【讨论】:

      【解决方案4】:

      我假设您想要获取城市和州/省:

      var map_center = map.getCenter();
      reverseGeocode(map_center);
      
      
      function reverseGeocode(latlng){
        geocoder.geocode({'latLng': latlng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                  var level_1;
                  var level_2;
                  for (var x = 0, length_1 = results.length; x < length_1; x++){
                    for (var y = 0, length_2 = results[x].address_components.length; y < length_2; y++){
                        var type = results[x].address_components[y].types[0];
                          if ( type === "administrative_area_level_1") {
                            level_1 = results[x].address_components[y].long_name;
                            if (level_2) break;
                          } else if (type === "locality"){
                            level_2 = results[x].address_components[y].long_name;
                            if (level_1) break;
                          }
                      }
                  }
                  updateAddress(level_2, level_1);
             } 
        });
      }
      
      function updateAddress(city, prov){
         // do what you want with the address here
      }
      

      不要尝试返回结果,因为您会发现它们是未定义的 - 异步服务的结果。你必须调用一个函数,比如updateAddress();

      【讨论】:

        【解决方案5】:

        我创建了这个函数来获取地理编码结果的主要信息:

        const getDataFromGeoCoderResult = (geoCoderResponse) => {
          const geoCoderResponseHead = geoCoderResponse[0];
          const geoCoderData = geoCoderResponseHead.address_components;
          const isEmptyData = !geoCoderResponseHead || !geoCoderData;
        
          if (isEmptyData) return {};
        
          return geoCoderData.reduce((acc, { types, long_name: value }) => {
            const type = types[0];
        
            switch (type) {
              case 'route':
                return { ...acc, route: value };
              case 'locality':
                return { ...acc, locality: value };
              case 'country':
                return { ...acc, country: value };
              case 'postal_code_prefix':
                return { ...acc, postalCodePrefix: value };
              case 'street_number':
                return { ...acc, streetNumber: value };
              default:
                return acc;
            }
          }, {});
        };
        

        所以,你可以这样使用它:

        const geoCoderResponse = await geocodeByAddress(value);
        const geoCoderData = getDataFromGeoCoderResult(geoCoderResponse);
        

        假设您要搜索Santiago Bernabéu Stadium,那么,结果将是:

        {
          country: 'Spain',
          locality: 'Madrid',
          route: 'Avenida de Concha Espina',
          streetNumber: '1',
        }
        

        【讨论】:

          【解决方案6】:

          这对我有用:

          const localityObject = body.results[0].address_components.filter((obj) => {
            return obj.types.includes('locality');
          })[0];
          const city = localityObject.long_name;
          

          或一口气:

          const city = body.results[0].address_components.filter((obj) => {
            return obj.types.includes('locality');
          )[0].long_name;
          

          我在 Node 中执行此操作,所以这没关系。如果您需要支持 IE,您需要为 Array.prototype.includes 使用 polyfill 或寻找其他方式。

          【讨论】:

            【解决方案7】:

            我认为谷歌不提供某种功能来获取这些是一个真正的痛苦。无论如何,我认为找到正确对象的最佳方法是:

            geocoder.geocode({'address': request.term }, function(results, status){
            
               response($.map(results, function(item){
            
                  var city = $.grep(item.address_components, function(x){
                     return $.inArray('locality', x.types) != -1;
                  })[0].short_name;
            
                  alert(city);
               }            
            }); 
            

            【讨论】:

              【解决方案8】:
              // Use Google Geocoder to get Lat/Lon for Address
              function codeAddress() {
                  // Function geocodes address1 in the Edit Panel and fills in lat and lon
                  address = document.getElementById("tbAddress").value;
                  geocoder.geocode({ 'address': address }, function (results, status) {
                      if (status == google.maps.GeocoderStatus.OK) {
                          loc[0] = results[0].geometry.location.lat();
                          loc[1] = results[0].geometry.location.lng();
                          document.getElementById("tbLat").value = loc[0];
                          document.getElementById("tbLon").value = loc[1];
                          var arrAddress = results[0].address_components;
                          for (ac = 0; ac < arrAddress.length; ac++) {
                              if (arrAddress[ac].types[0] == "street_number") { document.getElementById("tbUnit").value = arrAddress[ac].long_name }
                              if (arrAddress[ac].types[0] == "route") { document.getElementById("tbStreet").value = arrAddress[ac].short_name }
                              if (arrAddress[ac].types[0] == "locality") { document.getElementById("tbCity").value = arrAddress[ac].long_name }
                              if (arrAddress[ac].types[0] == "administrative_area_level_1") { document.getElementById("tbState").value = arrAddress[ac].short_name }
                              if (arrAddress[ac].types[0] == "postal_code") { document.getElementById("tbZip").value = arrAddress[ac].long_name }
                          }
                          document.getElementById("tbAddress").value = results[0].formatted_address;
                      }
                      document.getElementById("pResult").innerHTML = 'GeoCode Status:' + status;
                  })
              }
              

              【讨论】:

                【解决方案9】:

                如果存在则返回位置。如果不是 - 返回administrative_area_1

                city = results[0].address_components.filter(function(addr){
                   return (addr.types[0]=='locality')?1:(addr.types[0]=='administrative_area_level_1')?1:0;
                });
                

                【讨论】:

                  【解决方案10】:
                              //if (arrAddress[ac].types[0] == "street_number") { alert(arrAddress[ac].long_name) } // SOKAK NO
                              //if (arrAddress[ac].types[0] == "route") { alert(arrAddress[ac].short_name); } // CADDE
                              //if (arrAddress[ac].types[0] == "locality") { alert(arrAddress[ac].long_name) } // İL
                              //if (arrAddress[ac].types[0] == "administrative_area_level_1") { alert(arrAddress[ac].short_name) } // İL
                              //if (arrAddress[ac].types[0] == "postal_code") { alert(arrAddress[ac].long_name); } // POSTA KODU
                              //if (arrAddress[ac].types[0] == "neighborhood") { alert(arrAddress[ac].long_name); } // Mahalle
                              //if (arrAddress[ac].types[0] == "sublocality") { alert(arrAddress[ac].long_name); } // İlçe
                              //if (arrAddress[ac].types[0] == "country") { alert(arrAddress[ac].long_name); } // Ülke
                  

                  【讨论】:

                    【解决方案11】:

                    这里有一些代码可以与 lodash js 库一起使用:(只需将 $scope.x 替换为您自己的变量名即可存储值)

                        _.findKey(vObj.address_components, function(component) {
                    
                                if (component.types[0] == 'street_number') {
                                    $scope.eventDetail.location.address = component.short_name
                                }
                    
                                if (component.types[0] == 'route') {
                                    $scope.eventDetail.location.address = $scope.eventDetail.location.address + " " + component.short_name;
                                }
                    
                                if (component.types[0] == 'locality') {
                                    $scope.eventDetail.location.city = component.long_name;
                                }
                    
                                if (component.types[0] == 'neighborhood') {
                                    $scope.eventDetail.location.neighborhood = component.long_name;
                                }
                    
                            });
                    

                    【讨论】:

                      【解决方案12】:

                      我使用了一个名为 find 的 lodash 函数,它返回谓词返回 true 的对象。就这么简单!

                      let city = find(result, (address) => {
                        return typeof find(address.types, (a) => { return a === 'locality'; }) === 'string';
                      });
                      

                      【讨论】:

                        【解决方案13】:

                        如果你想获得这座城市,这对我有用

                        var city = "";
                        function getPositionByLatLang(lat, lng) {
                            geocoder = new google.maps.Geocoder();
                            var latlng = new google.maps.LatLng(lat, lng);
                            geocoder.geocode({ 'latLng': latlng }, function (results, status) {
                                if (status == google.maps.GeocoderStatus.OK) {
                                    if (results[1]) {
                                        //formatted address
                                        city = results[0].plus_code.compound_code;
                                        city = city.substr(0, city.indexOf(','));
                                        city = city.split(' ')[1];
                        
                                        console.log("the name of city is: "+ city);
                                    }
                                } else {
                                    // alert("Geocoder failed due to: " + status);
                                }
                            });
                        }
                        

                        【讨论】:

                          【解决方案14】:

                          不用迭代就可以得到城市,一般城市位于address_components对象的第二个键上,所以第二个表示1:

                          results[0].address_components[1].long_name
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2012-05-07
                            • 1970-01-01
                            • 2012-01-13
                            • 1970-01-01
                            • 2020-05-14
                            • 1970-01-01
                            相关资源
                            最近更新 更多