получить город из результатов геокодера?

Возникли проблемы с получением содержимого различных массивов из результатов геокодера.

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...

любая помощь приветствуется!

Dc


person v3nt    schedule 15.06.2011    source источник


Ответы (12)


Получил эту работу в конце, используя:

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   
});
person v3nt    schedule 21.06.2011
comment
Работает хорошо, но было бы более элегантно и с меньшим количеством кода в качестве оператора «переключатель». - person Grant; 24.04.2014
comment
Не ожидайте, что это будет работать надежно, геокодирование Google имеет множество недостатков. населенный пункт не всегда доступен, иногда город действительно находится в поле состояния (уровень_1). Особенно, когда тип возвращаемого значения ROOFTOP, результаты Google Geocode плохие. В зарубежных странах они внезапно меняют формат. Вы можете доверять ПРИБЛИЗИТЕЛЬНЫМ результатам гораздо больше, чем ROOFTOP - person John; 24.12.2018
comment
Правильный. Не работает надежно. Google отмечает, что в компонентах, которые вы получаете в своем ответе, нет последовательности. А также то, что со временем это может измениться. developers.google.com/maps/documentation/places/web-service/ в разделе Результаты сведений о месте - person bjornl; 27.03.2021

попробовал пару разных запросов:

MK107BX

Кливленд-Парк-Кресент, Великобритания

как вы говорите, возвращаемый размер массива несовместим, но город для обоих результатов, по-видимому, находится в элементе address_component с типом ["местность", "политический"]. Может быть, вы могли бы использовать это как индикатор?

EDIT: получите объект местоположения с помощью jQuery, добавьте его в свою функцию 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
    });
person Иван Грозный    schedule 15.06.2011
comment
боюсь, что это не работает. Не знаете, как это будет, если нет переменных/массивов для «адресов»? - person v3nt; 15.06.2011
comment
извините, я был о другом запросе API карт Google. Отредактировано. - person Иван Грозный; 16.06.2011
comment
не беспокойся! любая идея, как я мог бы получить местность, хотя? Я просто получаю неопределенность в своих попытках ;-/ Если item.formatted_address работает, я ошибаюсь, думая, что это тоже должно быть - item.address_components.locality? - person v3nt; 16.06.2011
comment
нет, потому что formatted_address — это строка, а address_components — это массив. Я добавлю код о том, как просмотреть его. - person Иван Грозный; 16.06.2011
comment
первая строка может быть var arrAddress = item.address_components; в вашем случае. И ваш код не работает, потому что address_components — это массив. - person Иван Грозный; 16.06.2011
comment
Работает как шарм. Используя '.short_name', я, наконец, получаю название города без окончания ', Country'. Спасибо! - person kosemuckel; 08.12.2015

Мне пришлось создать программу, которая заполнила бы поля широты, долготы, города, округа и штата в пользовательской форме, когда пользователь щелкает место на карте. Эту страницу можно найти по адресу 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>
person Ed Kern    schedule 03.12.2012

Я предполагаю, что вы хотите получить город и штат/провинцию:

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();

person Jonathan Tonge    schedule 08.04.2013

Я создал эту функцию, чтобы получить основную информацию о результатах геокодера:

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',
}
person Jorge Luis Monroy    schedule 26.04.2020

Это сработало для меня:

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 или найдите другой способ сделать это.

person Eddy Vinck    schedule 22.07.2018

Я думаю, что это настоящая боль, что Google не предоставляет какой-либо функциональности для их получения. Во всяком случае, я думаю, что лучший способ найти правильный объект:

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);
   }            
}); 
person Andy Braham    schedule 12.01.2015

Возвращает местоположение, если оно существует. Если нет - возвращает 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;
});
person Eugene Chernyshov    schedule 21.11.2016

Вот некоторый код, который вы можете использовать с библиотекой 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;
            }

        });
person Jason Engage    schedule 04.05.2015

Я использовал функцию lodash под названием find, которая возвращает объект, для которого предикат возвращает true. Так просто!

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

Ну, это сработало для меня, если вы хотите получить город

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);
        }
    });
}
person Hicham Boummaaiz    schedule 03.06.2020

Вы можете получить город без итерации, как правило, город находится на втором ключе объекта address_components, поэтому второй означает 1:

results[0].address_components[1].long_name
person phpier    schedule 13.03.2021