Предложения автозаполнения в Google Адресах с модулем No/Subpremise не поступают в массив ответов
Я использую API Google для автоматического заполнения адресов с помощью javascript
Когда я ввожу номер устройства и номер улицы в поле ввода, он отображает результаты в раскрывающемся списке предложений, но когда я выбираю адрес, слушатель для события "place_changed" не имеет адреса с адресом_компонент с type 'subpremise', даже свойство formatted_address не имеет в нем номера единицы. Хотя он содержит другие данные из "номера улицы", "города", "страны" и т.д.
Например: Если я набираю "1403/648 Bourke Street" с ограничениями в Австралии для Австралии. Он показывает мне 5 результатов в раскрывающемся списке с первым, как "1403/648 Bourke street, Melbourne, Australia", но когда я выбираю этот вариант, все, что я получаю в месте слушателя событий, является "648 Bourke street, Melbourne, Australia"
Эта проблема прерывистая, хотя она работает для некоторых адресов устройств, но не подходит для других. Любое предложение будет высоко оценено!
Ответы
Ответ 1
Мне кажется, что Google подтверждает, что адрес является реальным (хорошо по крайней мере реальный, когда он в последний раз обновлял базу данных своих мест - я думаю, с правительственными записями). Проблема заключается в том, что подразделения происходят все время, когда создаются новые "подрегрессивные" адреса, и поиск их по-видимому, происходит чаще. Странно, что они разрешают "недействительный" адрес в качестве предложения автозаполнения, но затем ограничивают результат.
Взгляд на адрес Сиднея, приведенный ниже, вернет "подремит" и "street_number"
"9/321 Питт-стрит, Сидней, Новый Южный Уэльс, Австралия"
Если адрес Мельбурна ниже, он становится таким же точным, как "маршрут"
"2/321 Питт-стрит, Брансуик, Виктория, Австралия"
Самая большая проблема заключается в том, что результат не возвращает номер единицы или улицы в ответе.
Я взломал следующий JS, чтобы сравнить введенный пользователем адрес с возвращенным результатом. Если "числа" отсутствуют, они добавляются. Вы можете настроить, как вам нужно, чтобы соответствовать вашему коду.
if (addressType == 'route') {
var regex = RegExp('^(.*)'+GPLACESSTREET.split(' ',1)[0]), // get all the user entered values before a match with the first word from the Google result
result = regex.exec(INPUTFEILD.value);
if ( Array.isArray(result) ) {
FULLSTREETADDRESS = result[1]+''+GPLACESSTREET; // add the street name to the user-entered unit & street number
}
}
Ответ 2
API автозаполнения Places не предназначен для поддержки результатов "subpremise". Об этом было сообщено и на него ответили некоторое время назад в трекере публичных проблем по адресу https://issuetracker.google.com/35830389
Австралийские адреса для результатов subpremise выглядят "достаточно близко" к адресам street_address/premise (они в основном начинаются с цифр). В настоящее время это приводит к тому, что Place Autocomplete возвращает результат, который может выглядеть как результат subpremise, однако обратите внимание, что тип по-прежнему "route":
http://maps.googleapis.com/maps/api/place/autocomplete/json?input=9/321%20Pitt%20Street,%20Sydney
description: "9/321 Pitt Street, Sydney NSW, Australia",
place_id: "Eig5LzMyMSBQaXR0IFN0cmVldCwgU3lkbmV5IE5TVywgQXVzdHJhbGlh",
types: ["route","geocode",],
Запросы сведений о месте (и геокодирование) с этим place_id фактически найдут правильный результат subpremise:
https://maps.googleapis.com/maps/api/place/details/json?placeid=Eig5LzMyMSBQaXR0IFN0cmVldCwgU3lkbmV5IE5TVywgQXVzdHJhbGlh
"result" : {
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"types" : [ "subpremise" ],
Однако это не гарантирует работу для всех запросов subpremise, или даже для этого конкретного в долгосрочной перспективе.
Более надежный подход - использовать API геокодирования для поиска "описания" прогноза:
https://maps.googleapis.com/maps/api/geocode/json?&address=9%2F321%20Pitt%20St%2C%20Sydney%20NSW%202000%2C%20Australia
"results" : [
{
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
],
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"place_id" : "Eik5LzMyMSBQaXR0IFN0LCBTeWRuZXkgTlNXIDIwMDAsIEF1c3RyYWxpYSIdGhsKFgoUChIJkyPU0z2uEmsR-pmiK6UvZUASATk",
"types" : [ "subpremise" ]
Ответ 3
Небольшая модификация кода @MountainAsh:
if (addressType == 'route') {
var regex = RegExp('^(.*?)'+GPLACESSTREET.split(' ',1)[0]), // get all the user entered values before a match with the first word from the Google result
result = regex.exec(INPUTFEILD.value);
if ( Array.isArray(result) ) {
FULLSTREETADDRESS = result[1]+''+GPLACESSTREET; // add the street name to the user-entered unit & street number
}
}
Обратите внимание на добавление ? в RegExp, что делает поиск неживым для случаев, когда имя улицы начинается с того же названия Suburb (например, 123 Clayton Rd, Clayton).
Ответ 4
Google не поддерживает это, но вы не можете остановить клиентов, делающих это!
Вот полная функция, вдохновленная кодом @MountainAsh и @Randell:
/* Add the unit number (+ fix the street number) if required.
*
* Idea from https://stackoverflow.com/questions/17936689/google-places-autocomplete-suggestions-with-unit-no-subpremise-is-not-coming-in
*
* Test cases:
* 9/321 Pitt Street, Sydney, New South Wales, Australia <-- Google throws away the unit number
* 2/321 Pitt Street, Brunswick, Victoria, Australia <-- Google says street number = 2
* 1b/123 Clayton Road, Clayton, Victoria, Australia <-- Google says street number = 1
*/
function autofillUnitNumber(txtAutocomplete, txtUnitNumber, txtStreetNumber, txtStreetName) {
var regex = RegExp("^(.*?)\/(.*?) " + txtStreetName.value); // get all the user entered values before a match with the street name; group #1 = unit number, group #2 = street number
var results = regex.exec(txtAutocomplete.value);
if (Array.isArray(results)) { // it was in unit number/street number format
var unitNumber = results[1]; // group #1
var streetNumber = results[2]; // group #2
txtUnitNumber.value = unitNumber;
txtStreetNumber.value = streetNumber;
}
}
Просто позвоните после того, как вы воспользовались автозаполнением Google для автозаполнения других полей формы, например:
autofillUnitNumber(
document.getElementById("txtAutocomplete"),
document.getElementById("txtUnitNumber"),
document.getElementById("txtStreetNumber"),
document.getElementById("txtStreetName"));
Ответ 5
Поскольку я просто хотел собрать номер объекта и добавить его к номеру улицы, мое решение:
const place = this.AutoComplete.getPlace();
if (isNullOrUndefined(place)) return;
const parts = place.address_components;
const getAddressPart = part => {
const found = parts.find(p => p.types.indexOf(part) > -1);
if (found) {
return found.long_name;
}
return null;
};
const address = this.Input.current.value; // input[text] value
let streetNumber = getAddressPart("street_number");
// Regex Match associated
if (streetNumber) {
const regex = RegExp('[^\\s,]*(${streetNumber})[^\\s,]*');
const foundStreetNumber = regex.exec(address);
streetNumber = foundStreetNumber[0];
}
const Address = {
FullAddress: address,
StreetNumber: streetNumber,
Street: getAddressPart("route"),
Suburb: getAddressPart("sublocality"),
City: getAddressPart("locality"),
Country: getAddressPart("country"),
PostCode: getAddressPart("postal_code")
};
Это улучшит данные номеров улиц из API Google Адресов, обслуживая такие адреса, как:
Mokoia Rd, 4/33, Биркенхед, Окленд 0626, Новая Зеландия
Пролетарская улица 3/25, Кидричево, Словения (адрес может не содержать номер улицы первым).
Он также не будет выполнять какую-либо работу, если номер улицы отсутствует, и значение будет таким же, если номер единицы отсутствует.