Адрес в форме заказа или заявки — самое капризное поле. Люди пишут «ул. Ленина 5», «Ленина, 5 кв 12», «лен 5», забывают город, ставят запятые как попало. А доставке, диспетчеру и расчёту стоимости нужны не буквы, а координаты. Помогают два приёма: подсказки по мере ввода (человек выбирает готовый вариант вместо того, чтобы набирать всё) и геокодинг (превращение выбранного адреса в точку). В статье разбираем, как включить то и другое в Kartrout за минуту, как построить собственное поле на своей вёрстке и как не потратить квоту впустую.

Три способа получить адрес и координаты

Что нужноМетодЧто возвращает
Подсказки при вводеGET /v1/geocode/suggestДо 10 вариантов в формате GeoJSON: название, улица, номер дома, город, координаты
Поиск по нажатию EnterGET /v1/geocode/searchДо 20 результатов: display_name, lat, lon, разобранный адрес
Адрес по клику на картеGET /v1/geocode/reverseБлижайший адрес к координатам

Каждый запрос — одна единица квоты «Геокодинг». Исключение одно: повтор того же запроса подсказок в течение пяти минут бесплатный. Ключ публичный (pk_live_…) или секретный; для браузера нужен публичный с вашим доменом в списке разрешённых.

Быстрый путь: поиск и подсказки в виджете

Если на странице уже есть карта, строка поиска включается одним вызовом. В конструкторе встраивания личного кабинета это переключатели «Показать поиск» и «Автодополнение» (в блоке «Доп. функции»): конструктор сам допишет нужную строку кода.

Конструктор встраивания: включённый переключатель «Автодополнение» и строка кода attachSearch с параметром autocomplete
Рис. 1. Конструктор встраивания: (1) переключатель «Автодополнение» с пометкой, что каждая подсказка расходует квоту геокодинга, (2) строка кода, которую он добавляет.
map.attachSearch({
  placeholder: 'Введите адрес…',
  autocomplete: true,
  onResult: function (result) {
    // result.display_name, result.lat, result.lon
    document.getElementById('address').value = result.display_name;
    document.getElementById('lat').value = result.lat;
    document.getElementById('lon').value = result.lon;
  }
});

Что делает поле «из коробки»:

  • запрос уходит не на каждую букву, а после паузы в наборе (200 миллисекунд) и только начиная с двух символов;
  • под полем появляется список подсказок; выбор варианта мышью или стрелками и Enter переносит карту к точке и вызывает ваш onResult;
  • подсказки учитывают, где сейчас находится центр карты: «Тверская 7» на карте Москвы ищется прежде всего в Москве (смещение по центру карты появилось в версии виджета 1.7.0);
  • поле доступно для экранных читалок и клавиатуры (список реализован как ARIA-комбобокс);
  • без автодополнения поиск работает по нажатию Enter и показывает до пяти вариантов.
Поле поиска по адресу на карте Москвы с выпадающим списком подсказок при вводе «Новый Арб»
Рис. 2. Подсказки при вводе: (1) поле поиска, в которое набрано «Новый Арб», (2) список вариантов, который появляется после короткой паузы.

Своё поле ввода на вашей вёрстке

Карта в форме заказа нужна не всегда: часто достаточно обычного текстового поля с подсказками. Тогда обращайтесь к методу напрямую. Минимальный рабочий вариант на чистом JavaScript с паузой в наборе и отменой устаревших запросов:

<input id="addr" autocomplete="off" placeholder="Адрес доставки">
<ul id="hints"></ul>
<script>
  var KEY = 'pk_live_ВАШ_КЛЮЧ', timer, ctrl;
  var input = document.getElementById('addr'), list = document.getElementById('hints');

  input.addEventListener('input', function () {
    clearTimeout(timer);
    var q = input.value.trim();
    if (q.length < 3) { list.innerHTML = ''; return; }
    timer = setTimeout(function () {
      if (ctrl) ctrl.abort();                       // отменяем предыдущий запрос
      ctrl = new AbortController();
      var url = 'https://kartrout.ru/v1/geocode/suggest?limit=5&lat=55.7558&lon=37.6173'
              + '&q=' + encodeURIComponent(q) + '&key=' + KEY;
      fetch(url, { signal: ctrl.signal }).then(function (r) { return r.json(); }).then(function (fc) {
        list.innerHTML = '';
        fc.features.forEach(function (f) {
          var p = f.properties, li = document.createElement('li');
          li.textContent = [p.name, p.street, p.housenumber, p.city].filter(Boolean).join(', ');
          li.onclick = function () {                // выбранный вариант: сохраняем координаты
            input.value = li.textContent;
            document.getElementById('lon').value = f.geometry.coordinates[0];
            document.getElementById('lat').value = f.geometry.coordinates[1];
            list.innerHTML = '';
          };
          list.appendChild(li);
        });
      }).catch(function () {});
    }, 250);
  });
</script>

Параметры lat и lon в запросе подсказок необязательны, но заметно улучшают выдачу: они говорят, рядом с чем искать. Подставьте координаты центра вашего города или текущей области карты.

Ответ подсказок — стандартный GeoJSON FeatureCollection. В каждом объекте координаты лежат в geometry.coordinates в порядке «долгота, широта», а описание места — в properties:

{ "type": "Feature",
  "geometry": { "type": "Point", "coordinates": [37.6006237, 55.753003] },
  "properties": { "name": "улица Новый Арбат", "city": "Москва", "state": "Москва",
                  "country": "Россия", "postcode": "119019", "type": "street" } }

Точный адрес и «адрес по клику»

Подсказки работают по названиям и быстро реагируют на неполный ввод, но это поиск «на лету»: он находит улицы, организации и места, а совпадение именно с вашим номером дома не гарантирует. Для итогового, точного адреса используйте поиск по нажатию на кнопку или Enter:

GET https://kartrout.ru/v1/geocode/search?q=Новый Арбат 15, Москва&limit=1&addressdetails=1&accept-language=ru&key=pk_live_...

[{ "lat": "55.7521581", "lon": "37.5923984",
   "display_name": "Мумий Тролль, 15, улица Новый Арбат, 36, район Арбат, Москва, …, 127025, Россия",
   "address": { "house_number": "15", "road": "улица Новый Арбат", "city": "Москва", "postcode": "127025" } }]

Обратите внимание: на этот адрес найден ресторан, зарегистрированный в доме 15, и название организации стоит в начале строки. Это особенность открытых данных OpenStreetMap, на которых построен поиск: у дома может не быть отдельной записи, и тогда находится заведение с тем же номером. Для доставки это обычно не проблема (координата та же), но для печати в документе берите из ответа разобранные поля address.road и address.house_number, а не всю строку display_name.

Обратная задача — по точке на карте узнать адрес (например, клиент ткнул в карту, чтобы показать, куда привезти):

GET https://kartrout.ru/v1/geocode/reverse?lat=55.7525&lon=37.5922&accept-language=ru&key=pk_live_...

В ответе — один объект с полями display_name и address. Для крупных городов адрес обычно находится сразу, для сельских мест вернётся ближайшая улица или населённый пункт.

Сколько это стоит в квоте

Пока человек печатает, подсказки расходуют геокодинг: запрос уходит после каждой паузы в наборе. Сколько именно запросов приходится на один введённый адрес, зависит от скорости набора и привычек пользователя; мы не даём точной цифры, но ориентироваться стоит на несколько запросов на адрес. Лимиты за 30 дней: 1 500 геокодингов на «Базовом», 8 000 на «Старте», 40 000 на «Бизнесе», 150 000 на «Масштабе». Чтобы уложиться, сделайте следующее.

  • Не искать с одного-двух символов. В виджете порог два символа; в собственном поле поставьте три-четыре, как в примере выше.
  • Использовать паузу в 250–400 миллисекунд и отменять устаревшие запросы.
  • Не включать автодополнение там, где адрес вводят редко и хорошо знают (например, один раз в личном кабинете): поиск по Enter тратит ровно один запрос на адрес.
  • Рассчитывать на бесплатные повторы. Одинаковый запрос подсказок в течение пяти минут не списывается: если человек стёр символ и набрал снова, повторная выдача бесплатна.
  • Для списка адресов из таблицы подсказки не нужны. Тысячи готовых строк загружайте пакетно (массовый геокодинг из Excel и CSV): один адрес — одна единица без лишних промежуточных запросов.

Что делать с координатами после выбора

  1. Сохраните не только строку, но и координаты (lat, lon) и разобранные поля: улицу, дом, город. Строка нужна человеку, координаты — расчётам.
  2. Проверьте, попадает ли адрес в зону доставки: стройте зону (зоны доступности) и проверяйте точку на сервере проверкой «точка внутри многоугольника».
  3. Посчитайте расстояние и время до склада или точки выдачи методом маршрута и от этого рассчитайте стоимость доставки.
  4. Покажите клиенту его точку на карте и дайте возможность подвинуть метку, если найденная координата неточна.

Ограничения, о которых нужно знать честно

  • Это открытые данные. Полнота адресов в OpenStreetMap высокая в городах и заметно ниже в малых посёлках: новая улица или дом могут отсутствовать.
  • Подсказки нечёткие. Они прощают опечатки и пропуски, но по той же причине могут предложить похожую улицу в другом районе. Поэтому смещение по центру карты важно, а итоговый выбор должен подтверждать человек.
  • Точность не равна единице. Если дом не найден, поиск может вернуть улицу целиком или населённый пункт. Проверяйте тип результата перед тем, как считать маршрут от «середины улицы».
  • Публичный ключ виден в коде страницы. Привяжите его к вашему домену, иначе чужой сайт сможет расходовать вашу квоту (как привязать ключ к домену).
  • Персональные данные. Адреса клиентов — данные, которые вы собираете и храните у себя. Не отправляйте их в публичные места без необходимости и следуйте правилам обработки персональных данных вашей организации.

Практический порядок работы

  1. Решите, нужна ли в форме карта или достаточно поля: для карты включите автодополнение в конструкторе, для поля используйте пример выше.
  2. Привяжите публичный ключ к домену и создайте отдельный ключ для формы.
  3. Добавьте центр города в запросы подсказок, поставьте порог по длине и паузу в наборе.
  4. Сохраняйте координаты и разобранный адрес вместе с заказом.
  5. Проверьте форму на живых адресах: «с опечаткой», «без города», «с номером квартиры», «в посёлке». Если в вашем регионе часть адресов не находится, оставьте клиенту возможность поставить метку вручную.

Частые вопросы

Как включить автодополнение адреса на карте?

Вызовите map.attachSearch({ autocomplete: true }) или включите переключатель «Автодополнение» в конструкторе встраивания личного кабинета. Запрос уходит после паузы в наборе (200 мс) и начиная с двух символов.

Сколько стоят подсказки?

Каждый запрос подсказок — одна единица квоты «Геокодинг»; повтор того же запроса в течение пяти минут бесплатный. Лимиты за 30 дней: 1 500 на «Базовом», 8 000 на «Старте», 40 000 на «Бизнесе», 150 000 на «Масштабе». Если адрес вводят редко, обычный поиск по Enter тратит ровно один запрос на адрес.

Почему подсказка не содержит нужный номер дома?

Подсказки работают по названиям и прощают неполный ввод, но номер дома не гарантируют. Для итогового адреса используйте поиск (/v1/geocode/search) и берите разобранные поля address.road и address.house_number.

Как найти адрес по точке на карте?

Запросом GET /v1/geocode/reverse?lat=…&lon=…: в ответе объект с полями display_name и address. Один запрос — одна единица квоты геокодинга.

Какой ключ нужен для подсказок в браузере?

Публичный (pk_live_…) с вашим доменом в списке разрешённых. Секретный ключ в код страницы помещать нельзя.

Можно ли сделать подсказки без карты, только в текстовом поле?

Да. Обращайтесь напрямую к /v1/geocode/suggest: в ответе GeoJSON с названием, улицей, номером дома, городом и координатами. В статье есть готовый пример на JavaScript с паузой в наборе и отменой устаревших запросов.