Ограничение результатов по региону

Работа с географическими ограничениями в Google Maps JavaScript API строится вокруг двух ключевых подходов: смещение (biasing) и жёсткое ограничение (restricting) результатов. Эти механизмы определяют, какие объекты, адреса и места возвращаются при поиске, автодополнении и геокодировании, а также какие области карты доступны для взаимодействия.

Географическая фильтрация в Google Maps API не является единым переключателем. Она распределена по нескольким уровням:

  • уровень карты (Map)
  • уровень сервисов Places
  • уровень Geocoding API
  • уровень UI-компонентов (Autocomplete)

Каждый из них использует собственные параметры, но логика едина:

  • bias — повышает релевантность результатов в заданной области, но не исключает остальные
  • restriction — полностью исключает результаты вне заданной области

Разница между ними критична: bias улучшает UX, restriction обеспечивает строгую географическую изоляцию.

Ограничение области отображения карты

На уровне карты используется параметр restriction, который задаёт допустимые границы перемещения.

const map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: 48.0, lng: 66.9 },
  zoom: 6,
  restriction: {
    latLngBounds: {
      north: 55.0,
      south: 40.0,
      east: 80.0,
      west: 50.0,
    },
    strictBounds: true
  }
});

latLngBounds

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

strictBounds

  • true — жёсткое ограничение, карта «отталкивается» от границ
  • false — допускается временный выход за пределы при инерции или программных изменениях

Смещение и ограничение в Autocomplete

Компонент автодополнения — один из основных источников географических данных, и он поддерживает несколько уровней фильтрации.

Ограничение по стране

const autocomplete = new google.maps.places.Autocomplete(input, {
  componentRestrictions: { country: "kz" }
});

Параметр componentRestrictions полностью исключает результаты вне указанной страны.

Смещение по области

const autocomplete = new google.maps.places.Autocomplete(input);

autocomplete.setBounds(
  new google.maps.LatLngBounds(
    { lat: 42.0, lng: 46.0 },
    { lat: 55.0, lng: 87.0 }
  )
);

Этот вариант не блокирует результаты, но повышает их релевантность внутри указанного прямоугольника.

strictBounds для Autocomplete

autocomplete.setOptions({
  strictBounds: true
});

При включении:

  • возвращаются только результаты внутри bounds
  • внешние результаты полностью исключаются

Геокодирование с региональной фильтрацией

Geocoding API поддерживает параметр region, который влияет на приоритет результатов.

const geocoder = new google.maps.Geocoder();

geocoder.geocode({
  address: "Abay Street",
  region: "kz"
}, (results, status) => {
  console.log(results);
});

Особенности region

  • не ограничивает результаты строго
  • влияет на сортировку и приоритет
  • полезен для неоднозначных запросов

Дополнительно можно использовать bounds:

geocoder.geocode({
  address: "Abay Street",
  bounds: {
    north: 55,
    south: 40,
    east: 80,
    west: 50
  }
});

Places API и фильтрация поиска

При работе с Places Service используется комбинация viewport bias и радиуса поиска.

Поиск по кругу (radius)

const request = {
  location: { lat: 48.0, lng: 66.9 },
  radius: 5000,
  type: "restaurant"
};

service.nearbySearch(request, callback);

Здесь радиус задаёт строгую географическую границу.

Поиск с bias по viewport

const request = {
  query: "coffee",
  bounds: map.getBounds()
};

service.textSearch(request, callback);

Viewport влияет на ранжирование, но не полностью исключает внешние результаты.

Работа с viewport как основным механизмом ограничения

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

google.maps.event.addListener(map, "bounds_changed", () => {
  const bounds = map.getBounds();

  const request = {
    bounds: bounds,
    query: "hotel"
  };

  placesService.textSearch(request, callback);
});

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

Различие между bias и restriction на практике

Bias (смещение)

  • улучшает релевантность
  • не ограничивает результат
  • используется в поиске и геокодировании

Restriction (ограничение)

  • полностью фильтрует результаты
  • используется в UI и Autocomplete
  • применяется для контроля доступа к регионам

Использование bounding box как универсального фильтра

Bounding box — основной инструмент географической фильтрации:

const bounds = {
  north: 50.5,
  south: 49.0,
  east: 76.0,
  west: 73.0
};

Он применяется:

  • в Autocomplete
  • в Geocoding
  • в Places API
  • в ограничении карты

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

Часто границы формируются из текущего состояния карты:

const bounds = map.getBounds();

autocomplete.setBounds(bounds);

или:

const request = {
  bounds: map.getBounds(),
  type: "atm"
};

Это создаёт контекстно-зависимую систему поиска.

Географическая логика комбинирования параметров

На практике одновременно используются несколько уровней:

  • componentRestrictions — страна
  • bounds — регион или город
  • strictBounds — жёсткое ограничение
  • region — языково-географический приоритет

Комбинация выглядит так:

const autocomplete = new google.maps.places.Autocomplete(input, {
  componentRestrictions: { country: "kz" }
});

autocomplete.setBounds(cityBounds);

autocomplete.setOptions({
  strictBounds: true
});

Частые архитектурные паттерны

Привязка поиска к карте

  • пользователь двигает карту
  • bounds обновляются
  • запросы выполняются заново

Ограничение в рамках страны

  • фиксированный componentRestrictions
  • динамический viewport внутри страны

Гибридный режим

  • страна ограничена строго
  • город задаётся через bounds
  • поиск остаётся свободным внутри региона

Важные особенности поведения API

  • bias всегда слабее restriction
  • bounds могут игнорироваться при отсутствии strict режима
  • Autocomplete может возвращать POI вне viewport при bias
  • Geocoding может возвращать глобальные результаты без region

Эти особенности требуют явного контроля логики на уровне приложения, а не только API параметров