Store locator, то есть поиск магазинов на карте, это та самая небольшая функция, которая рано или поздно нужна любому бизнесу с несколькими точками: поле «найдите ближайший магазин», превращающее почтовый индекс в короткий ранжированный список магазинов на карте. Снаружи это выглядит тривиально, и счастливый путь действительно прост, но хороший локатор незаметно делает три вещи хорошо: понимает неаккуратный ввод геопозиции, ранжирует точки по реальной близости и рендерит результат на карте, с которой человек может что-то сделать.
Это руководство разбирает, как store locator работает на самом деле, четыре шага сборки через maps API и те детали, которые отличают демо от того, что можно выкатывать в продакшен. Каждая карта в статье отрендерена самим MapAtlas API.
Что store locator делает на самом деле
Уберите оформление, и store locator превращается в конвейер из трёх стадий:
- Геокодинг ввода посетителя. «1012 Amsterdam», «SW1A 1AA» или переданная GPS-позиция, всё это должно стать одной парой широты и долготы.
- Ранжирование ближайших магазинов. Имея эту координату и список ваших точек, найдите ближайшие в разумном радиусе.
- Рендер результатов. Разместите ранжированные магазины на карте маркерами, каждый с адресом, часами работы и ссылкой на маршрут.
Карта ниже, это ровно третья стадия, отрендеренная на тайлах MapAtlas: шесть точек в центре Амстердама, расставленных по расстоянию от посетителя. Здесь это супермаркеты, но карта выглядит одинаково независимо от того, приходят маркеры из POI-датасета или из вашего собственного списка магазинов.

Порядок цветов, это и есть ранжирование. Посетитель искал из центра карты, а маркеры показывают ближайшие точки по порядку, начиная с самой близкой.
Шаг 1: геокодируем ввод посетителя
Посетитель вводит индекс, город или полный адрес, а вам нужна координата. Это прямое геокодирование.
// Turn what the visitor types into a coordinate (autocomplete geocoding)
const res = await fetch(
`https://gateway.mapmetrics-atlas.net/autocomplete/` +
`?token=${API_TOKEN}&text=${encodeURIComponent(query)}` +
`&focus.point.lat=52.37&focus.point.lon=4.89` // bias toward your service area
);
const { features } = await res.json();
const [lon, lat] = features[0].geometry.coordinates; // [lon, lat]
const label = features[0].properties.label; // "Damrak, Amsterdam, North Holland, Netherlands"
Здесь важны две детали. Передавайте focus.point рядом с зоной вашего присутствия, чтобы «Cambridge» разрешался в нужный город, и обрабатывайте случай, когда посетитель делится GPS устройства вместо ввода текста: тогда координата у вас уже есть и этот шаг пропускается целиком.
Шаг 2: ранжируем магазины по расстоянию
Координата посетителя получена. Сами магазины, это ваши собственные данные: список точек, у каждой широта и долгота, который живёт в вашей базе. Их ранжирование, это расчёт расстояния по прямой (формула гаверсинуса), без единого вызова API:
// Your branches, each with a lat/lon. Rank by distance from the visitor.
const ranked = stores
.map(s => ({ ...s, distance_m: haversine(lat, lon, s.lat, s.lon) }))
.sort((a, b) => a.distance_m - b.distance_m)
.slice(0, 6);
Базовому локатору больше ничего и не нужно. Для крупной сети сначала стоит отфильтровать точки по bounding box вокруг посетителя, чтобы не мерить расстояние до каждой точки на каждом запросе, и только потом сортировать оставшиеся. На выходе получается короткий список ближайших точек, у каждой есть distance_m.
Шаг 3: сортируем по расстоянию, затем уточняем по времени в пути
Расстояние по прямой, это правильное значение по умолчанию. Оно быстрое, не требует дополнительного вызова и для плотной сети обычно корректно. Но ближайший по прямой магазин не всегда быстрее всего достижим: точка в 400 метрах через реку легко превращается в десятиминутный крюк до ближайшего моста.
Если в вашем локаторе «ближайший» действительно означает «быстрее всего добраться», переранжируйте нескольких первых кандидатов по реальному времени в пути вызовом directions или matrix:
// Re-rank the closest stores by real drive time (MapAtlas Matrix API)
const res = await fetch(`https://gateway.mapmetrics-atlas.net/matrix/?token=${API_TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sources: [{ lat, lon }],
targets: top3.map(s => ({ lat: s.lat, lon: s.lon })),
costing: 'auto', // 'auto' | 'bicycle' | 'pedestrian'
}),
});
const { sources_to_targets } = await res.json();
const row = sources_to_targets[0]; // one entry per target, each with .time (seconds)
const byTime = top3
.map((s, i) => ({ ...s, time: row[i].time }))
.sort((a, b) => a.time - b.time);
Это делается только для горстки ближайших кандидатов, поэтому остаётся одним дешёвым вызовом, а не одним на каждый магазин.
Шаг 4: рендерим магазины на карте
Финальный шаг, это сама карта. Поставьте маркер для каждого ранжированного магазина, добавьте попап с адресом и часами работы и подберите рамку вида так, чтобы все результаты были видны. С maps API, который отдаёт тайлы, геокодинг и поиск от одного провайдера, весь локатор держится на одном вендоре и одной системе координат от начала до конца, и именно на этом построена карта выше в статье.
Дайте каждому маркеру попап с тем минимумом, который нужен посетителю для действия: название, адрес, расстояние, часы работы и ссылка «Маршрут», передающая координату в маршрутизатор.
Детали, отличающие демо от продакшена
Пустые результаты. Кто-то ищет из региона, где у вас нет точек. Решите заранее, расширять ли радиус автоматически, показывать ли единственный ближайший магазин, каким бы далёким он ни был, или честно сказать «магазинов в радиусе 50 км нет».
Часы работы. Локатор, показывающий закрытый магазин как ближайший вариант, раздражает. Фильтруйте или помечайте точки по часам работы, чтобы «открыто сейчас» было полноценной опцией.
Неоднозначный ввод. «Cambridge» есть в Англии и в Массачусетсе; «Springfield» встречается десятки раз. Привязка к стране на шаге геокодинга убирает большую часть проблемы, а автодополнение по мере ввода убирает остальное.
Мобильный GPS и согласие. На мобильных самый сильный сценарий, это кнопка «использовать мою геопозицию», но чтение GPS устройства, это данные о местоположении, и оно требует согласия. Спрашивайте сначала и откатывайтесь на текстовый ввод, если посетитель отказал.
Приватность. Геопозиция посетителя становится персональными данными в тот момент, когда она привязана к нему. Геокодируйте по запросу, не храните сырую координату и используйте API с инфраструктурой в ЕС, чтобы геопозиция не покидала ЕЭЗ. Полную картину смотрите в нашем руководстве по GDPR-совместимым картам.
Собираем store locator на MapAtlas
MapAtlas даёт весь конвейер из одного API и одной системы координат. Geocoding API превращает индексы и города в координаты с привязкой к стране; вы ранжируете собственный список точек относительно этой координаты; API Directions и Matrix переранжируют первых кандидатов по реальному времени в пути; а тайлы Dynamic Maps рендерят результат ровно так, как показано в этой статье. Поскольку всё по умолчанию работает внутри ЕС, геопозиция посетителя остаётся в ЕЭЗ, и локатор остаётся GDPR-совместимым без дополнительной работы.
Полные форматы запросов и ответов по каждому эндпоинту есть в документации MapAtlas API. На Search API тоже стоит взглянуть, если вы хотите, чтобы локатор находил точки интереса вокруг посетителя, а не только ваши собственные магазины.
Store locator, это небольшая функция с изрядным количеством тихих решений внутри: понять размытый ввод, отранжировать по настоящей близости и учесть тот факт, что геопозиция, это персональные данные. Сделайте эти три вещи правильно, и поле «найдите ближайший магазин» перестанет быть второстепенной деталью и станет одним из самых используемых элементов вашего сайта.
Часто задаваемые вопросы
Что такое store locator?
Store locator, или поиск магазинов на карте, это функция «найти магазин рядом с вами» на сайте розничной сети или сервисной компании. Посетитель вводит почтовый индекс, город или делится геопозицией, а локатор возвращает ближайшие точки, отсортированные по расстоянию, каждая с булавкой на карте, адресом, часами работы и ссылкой на маршрут. Под капотом это три шага: геокодировать ввод в координату, выполнить поиск ближайших по вашему списку точек и отрендерить результаты на карте.
Как сделать store locator?
Store locator собирается в четыре шага. Первый: геокодировать ввод посетителя (индекс или город) в широту и долготу через geocoding API. Второй: выполнить запрос по радиусу или поиск ближайших соседей по координатам ваших магазинов, чтобы получить ближайшие точки. Третий: отсортировать результаты по расстоянию и, при желании, по времени в пути. Четвёртый: отрендерить ранжированные магазины маркерами на карте с попапами. Maps API, который отдаёт геокодинг, поиск рядом и тайлы карты от одного провайдера, позволяет пройти все четыре шага без сшивания разных сервисов.
Нужен ли мне store locator API?
Вам нужны геокодинг, тайлы карты и обычно ранжирование по времени в пути; сам список магазинов, это ваши собственные данные. Короткий список точек можно захардкодить и посчитать расстояние по прямой самостоятельно, но как только понадобятся поиск по индексу, сортировка по времени в дороге и отрендеренная карта, API, объединяющий геокодинг, matrix и рендеринг карты у одного провайдера, избавит вас от связывания трёх вендоров и согласования их форматов координат.
Как store locator ранжирует ближайшие магазины?
Простейшее ранжирование, это расстояние по прямой (great-circle) от координаты посетителя до каждого магазина по возрастанию. Такой подход быстрый и вполне годится для плотной городской сети. Для лучшего опыта стоит переранжировать первых кандидатов по реальному времени в пути через directions или matrix API, потому что ближайший по прямой магазин не всегда быстрее всего достижим, когда в дело вступают реки, шоссе и односторонние улицы.
Соответствует ли store locator требованиям GDPR?
Может соответствовать, а если посетитель находится в ЕС, то обязан. Store locator обрабатывает геопозицию, а она становится персональными данными, как только привязана к пользователю. Для соответствия геокодируйте по запросу вместо хранения координаты посетителя, используйте maps API с инфраструктурой в ЕС, чтобы геопозиция не покидала ЕЭЗ, и запрашивайте согласие перед чтением GPS устройства. MapAtlas обрабатывает запросы геопозиции внутри ЕС по умолчанию.

