Nearby Search

Google Maps JavaScript API предоставляет механизм Nearby Search через сервис PlacesService, предназначенный для поиска объектов поблизости относительно заданной географической точки. Этот режим используется для получения списка мест в радиусе или в порядке удалённости от координат, с возможностью фильтрации по типам, ключевым словам и другим параметрам.

Nearby Search реализуется через метод nearbySearch объекта google.maps.places.PlacesService. Он работает асинхронно и возвращает результаты через callback-функцию.

Основная сигнатура:

service.nearbySearch(request, callback);

Где:

  • request — объект параметров поиска
  • callback — функция обработки результата

Callback имеет форму:

function(results, status, pagination) {}

Объект запроса определяет поведение поиска и включает следующие поля:

location

Обязательный параметр, задающий центр поиска:

location: new google.maps.LatLng(lat, lng)

Именно от этой точки строится радиус или вычисляется сортировка по расстоянию.

radius

Радиус поиска в метрах. Используется совместно с location:

radius: 1500

Ограничивает область поиска кругом вокруг точки.

keyword

Строка для текстового поиска по названиям и описаниям мест:

keyword: "coffee"

Используется для гибкого поиска без строгой привязки к типу.

type

Фильтрация по типу места:

type: "restaurant"

Поддерживаются стандартные категории Places API, такие как:

  • restaurant
  • cafe
  • hospital
  • bank
  • store

rankBy

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

  • google.maps.places.RankBy.PROMINENCE
  • google.maps.places.RankBy.DISTANCE

При использовании DISTANCE параметр radius не применяется, и обязательным становится отсутствие radius.

minPriceLevel и maxPriceLevel

Фильтрация по уровню цен (0–4):

minPriceLevel: 1,
maxPriceLevel: 3

Обработка результатов

Callback возвращает:

results

Массив объектов PlaceResult, содержащих информацию о найденных местах:

Основные поля:

  • name — название
  • geometry.location — координаты
  • vicinity — краткий адрес
  • rating — рейтинг
  • types — массив типов
  • place_id — уникальный идентификатор

status

Статус выполнения запроса:

  • OK — успешное выполнение
  • ZERO_RESULTS — ничего не найдено
  • OVER_QUERY_LIMIT — превышен лимит запросов
  • REQUEST_DENIED — отказ в доступе
  • INVALID_REQUEST — ошибка параметров

pagination

Объект для постраничной загрузки результатов.

Постраничная загрузка результатов

Nearby Search возвращает ограниченное количество объектов за один запрос. Для получения следующей страницы используется:

pagination.nextPage();

Однако вызов возможен только после небольшой задержки, так как API требует завершения текущего цикла обработки.

const service = new google.maps.places.PlacesService(map);

const request = {
  location: new google.maps.LatLng(49.806, 73.085),
  radius: 2000,
  type: "restaurant"
};

service.nearbySearch(request, (results, status, pagination) => {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    for (let i = 0; i < results.length; i++) {
      const place = results[i];
      console.log(place.name, place.geometry.location.toString());
    }

    if (pagination && pagination.hasNextPage) {
      setTimeout(() => {
        pagination.nextPage();
      }, 1000);
    }
  }
});

Сочетание keyword и type

При одновременном использовании keyword и type происходит пересечение фильтров, что может существенно сузить выборку:

const request = {
  location: new google.maps.LatLng(49.81, 73.09),
  radius: 3000,
  keyword: "pizza",
  type: "restaurant"
};

В таком режиме результаты будут включать только рестораны, содержащие текстовое совпадение с «pizza».

Особенности rankBy.DISTANCE

Режим сортировки по расстоянию изменяет структуру запроса:

const request = {
  location: new google.maps.LatLng(49.81, 73.09),
  rankBy: google.maps.places.RankBy.DISTANCE,
  type: "cafe"
};

В этом режиме:

  • радиус запрещён
  • возвращаются ближайшие объекты без учёта «значимости»
  • результат зависит исключительно от геометрической близости

Структура PlaceResult

Объект результата может содержать расширенные поля, зависящие от запроса:

{
  name: "Example Cafe",
  place_id: "abc123",
  vicinity: "Street 10",
  geometry: {
    location: LatLng
  },
  rating: 4.5,
  types: ["cafe", "food", "establishment"],
  opening_hours: {
    open_now: true
  }
}

Некоторые поля доступны только при определённых условиях или дополнительных запросах Place Details.

Фильтрация и уточнение выборки

Nearby Search поддерживает ограниченный набор фильтров, поэтому часто применяется комбинация:

  • type для жёсткой категории
  • keyword для семантического уточнения
  • radius для пространственного ограничения
  • rankBy для изменения логики сортировки

Сложные сценарии часто требуют дополнительного вызова Place Details по place_id.

Ограничения и квоты

Nearby Search в рамках Places Service имеет ряд ограничений:

  • лимит на количество результатов за один запрос
  • необходимость постраничной навигации
  • квоты API ключа
  • различие между legacy PlacesService и новым Places API

При интенсивной нагрузке предпочтительно минимизировать количество повторных запросов и кэшировать place_id.

Типичные паттерны использования

Поиск ближайших объектов инфраструктуры

Используется для отображения:

  • кафе рядом с пользователем
  • аптек в радиусе
  • банкоматов поблизости

Комбинированные интерфейсы карт

Nearby Search часто применяется вместе с:

  • маркерами (Marker)
  • кластерами (MarkerClusterer)
  • информационными окнами (InfoWindow)

Динамический поиск при перемещении карты

При событии bounds_changed или idle:

google.maps.event.addListener(map, "idle", () => {
  const center = map.getCenter();

  service.nearbySearch({
    location: center,
    radius: 1500,
    type: "store"
  }, callback);
});

Такой подход создаёт интерактивную карту с обновляемыми результатами.

Поведение при недостатке данных

При отсутствии результатов или некорректных параметрах API возвращает:

  • пустой массив results
  • статус ZERO_RESULTS или INVALID_REQUEST

При этом callback всё равно вызывается, что требует обязательной проверки status.

Совместимость с новым Places API

В современных версиях Google Maps JavaScript API часть функциональности Nearby Search постепенно мигрирует в Places API (New), где используется иной подход:

  • промисы вместо callback
  • более строгая типизация
  • расширенные поля данных
  • отдельные endpoints для поиска

Однако классический PlacesService.nearbySearch остаётся широко используемым в существующих проектах и поддерживается для обратной совместимости.