Предложения автозаполнения в 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, Кидричево, Словения (адрес может не содержать номер улицы первым).

Он также не будет выполнять какую-либо работу, если номер улицы отсутствует, и значение будет таким же, если номер единицы отсутствует.