Google Maps API V3 — не удается геокодировать прогнозы AutocompleteService

Я использую google.maps.places.AutocompleteService для получения предложений по поиску мест, но не могу геокодировать некоторые из прогнозов.

Пример: когда я ищу «устье реки Стормс», я получаю в ответ один из прогнозов: «Лагерь для ротовой полости на реке Стормс, Южная Африка», но это адрес нельзя геокодировать для получения широты/долготы, например: http://maps.googleapis.com/maps/api/geocode/json?address=Storms%20River%20Mouth%20Rest%20Camp,%20South%20Africa&sensor=true

Есть ли способ получить значения широты/долготы для прогнозов автозаполнения?

Кроме того, я не понимаю, почему автозаполнение Google возвращает прогнозы, которые я не могу геокодировать.

Вот базовый пример логики и кода, с которым я работаю:

var geocoder = new google.maps.Geocoder();
var service = new google.maps.places.AutocompleteService(null, {
  types: ['geocode'] 
});

service.getQueryPredictions({ input: query }, function(predictions, status) {
  // Show the predictions in the UI
  showInAutoComplete(predictions);
};

// When the user selects an address from the autcomplete list
function onSelectAddress(address) {
  geocoder.geocode({ address: address }, function(results, status) {
   if (status !== google.maps.GeocoderStatus.OK) {
      // This shouldn't never happen, but it does
      window.alert('Location was not found.');
    }
    // Now I can get the location of the address from the results
    // eg: results[0].geometry.location
  });
}

[править] - Посмотрите рабочий пример здесь: http://demos.badsyntax.co/places-search-bootstrap/example.html


person badsyntax    schedule 19.01.2013    source источник


Ответы (6)


Используйте getPlacePredictions() вместо getQueryPredictions() . Это вернет reference для места, которое вы можете использовать для получения сведений с помощью placesService.getDetails() . Детали будут содержать геометрию места.

Примечание. placesService — это объект google.maps.places.PlacesService.

person Dr.Molle    schedule 19.01.2013
comment
service.getPlacePredictions() ничего не возвращает и принимает функцию обратного вызова. В этой функции обратного вызова я могу получить доступ к аргументам «predictions» и «status». - person badsyntax; 19.01.2013
comment
Вы хотите помочь или вы хотите быть умным aleck. Взгляните на элемент ссылки каждого прогноза или, при желании, в документы, и тогда вы увидите, где найти ссылку. - person Dr.Molle; 19.01.2013
comment
Я вовсе не пытаюсь быть умником. Ваши инструкции не имеют смысла. getPlacePredictions ничего не возвращает. Я не знаю, как еще это выразить. Возможно, я что-то упускаю? См. здесь: google-developers.appspot.com/maps/documentation /javascript/ - person badsyntax; 19.01.2013
comment
странно, я получаю отличные результаты от getPlacePredictions, когда следую своим бессмысленным инструкциям: jsfiddle.net/doktormolle/mFgdw - person Dr.Molle; 19.01.2013
comment
Спасибо! Я был совершенно незнаком с PlacesService. - person badsyntax; 19.01.2013
comment
@Dr.Molle - большое спасибо за пример кода - ты молодец, приятель! - person foxybagga; 06.08.2013
comment
Можете ли вы привести пример использования getDetails() в контексте использования getPlacePredictions()? - person zero_cool; 05.03.2019

Прогнозы, возвращаемые AutocompleteService, имеют свойство PlaceId. Вы можете передать геокодеру PlaceId вместо адреса в соответствии с документацией https://developers.google.com/maps/documentation/javascript/geocoding.

var service = new google.maps.places.AutocompleteService();
var request = { input: 'storms river mouth' };
service.getPlacePredictions(request, function (predictions, status) {
    if(status=='OK'){
        geocoder.geocode({ 
            'placeId': predictions[0].place_id
        }, 
        function(responses, status) {
            if (status == 'OK') {
                var lat = responses[0].geometry.location.lat();
                var lng = responses[0].geometry.location.lng();
                console.log(lat, lng);
            }
        });
    }
});
person Parmjeet Singh    schedule 19.07.2016

Попробуй это:

function onSelectAddress(address, callback) {
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            callback(results[0].geometry.location);
        } else {
            alert("Can't find address: " + status);
            callback(null);
        }
    });
}

Затем вызов и обратный вызов:

onSelectAddress('your address here', function(location){
//Do something with location
if (location)
     alert(location);
});

Извините за мой английский. У меня к вам вопрос: можете ли вы показать мне метод showInAutoComplete() ??? Я показываю прогнозы в списке href, но не знаю, как сохранить значение адреса, на которое нажали.

person mrk    schedule 07.02.2013
comment
Большое спасибо, что указали мне на API-интерфейсы геокодирования, моя проблема была немного другой, но это помогло мне ее решить! - person Romko; 21.10.2015

Вот код, который я написал, вдохновленный @Dr.Molle

    function initializePlaces(q) {
        googleAutocompleteService = new google.maps.places.AutocompleteService();            
        if(q){
            googleAutocompleteService.getPlacePredictions({
                input: q
            }, callbackPlaces);
        }else { //no value entered loop }
    }

    function callbackPlaces(predictions, status) {
        if (status != google.maps.places.PlacesServiceStatus.OK) {
            alert(status);
            return;
        }

        for (var i = 0; i < predictions.length; i++) {
            googlePlacesService = new google.maps.places.PlacesService(document.getElementById("q"));
            googlePlacesService.getDetails({
                reference: predictions[i].reference
            }, function(details, status){
                if(details){
                    console.log(details.geometry.location.toString());
                }
            });
            console.log(predictions[i].description);
        }
    };

    google.maps.event.addDomListener(window, 'load', initializePlaces);

    $(document).on('keyup', 'input#q', function(e){
        initializePlaces($(this).val());
    });

Проблема, которую я вижу, - это новый объект PlacesService при каждом нажатии клавиши, что может быть излишним - хотя я не знаю, как это обойти.

Выкладываю сюда на случай, если кто-то ищет.

person foxybagga    schedule 06.08.2013
comment
почему вы использовали document.get(q) в цикле for? - person vipulsodha; 05.10.2014
comment
Также интересует, как использовать getDetails(). Я думаю, вы можете просто инициализировать службу в одном месте вне цикла. - person zero_cool; 05.03.2019

Если вам нужно вернуть все результаты сразу в правильном порядке, используйте это:

var service = new google.maps.places.AutocompleteService();
service.getPlacePredictions({
    input: '*** YOUR QUERY ***'
}, function(predictions, status) {
    var data = [];

    if (status != google.maps.places.PlacesServiceStatus.OK) {
        console.error(status);
        processResults(data);
        return;
    }

    var s = new google.maps.places.PlacesService(document.createElement('span'));
    var l = predictions.length;
    for (var i = 0, prediction; prediction = predictions[i]; i++) {
        (function(i) {
            s.getDetails(
                {
                    reference: prediction.reference
                },
                function (details, status) {
                    if (status == google.maps.places.PlacesServiceStatus.OK) {
                        data[i] = details;
                    } else {
                        data[i] = null;
                    }
                    if (data.length == l) {
                        processResults(data);
                    }
                }
            );
        })(i);
    } });

function processResults(data) {
    console.log(data);
}
person gondo    schedule 19.07.2015

Может быть, это могло бы помочь вам.

 var autocomplete = new google.maps.places.Autocomplete(this.input);
 //this.input is the node the AutocompleteService bindTo
 autocomplete.bindTo('bounds', this.map);
 //this.map is the map which has been instantiated

 google.maps.event.addListener(autocomplete, 'place_changed', function() {
     var place = autocomplete.getPlace();
     //then get lattude and longitude
     console.log(place.geometry.location.lat());
     console.log(place.geometry.location.lng());
 }
person Li Dian    schedule 19.01.2013
comment
Я не хочу использовать виджет пользовательского интерфейса google.maps.places.Autocomplete, я хочу использовать службу google.maps.places.AutocompleteService с собственным автозаполнением. - person badsyntax; 19.01.2013
comment
Вы можете переписать css .pac-container и .pac-item. - person Li Dian; 19.01.2013
comment
Он не ищет использование Autocomplete UI. Есть и другие вопросы/ответы, которые охватывают это. - person Raha; 25.02.2018