Разработка store locator (карта магазинов/офисов) на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка store locator (карта магазинов/офисов) на 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка store locator (карта магазинов/офисов) на 1С-Битрикс

Пользователь вводит свой город или адрес и хочет увидеть ближайший магазин с маршрутом. Стандартными средствами Битрикс это не реализуется — нужна карта, геолокация, поиск по радиусу и фильтрация по типу точки. Всё это — кастомная разработка на базе инфоблока и картографического API.

Хранение данных о точках продаж

Каждая точка продаж — элемент инфоблока. Минимальный набор свойств:

  • ADDRESS — полный адрес (строка)
  • LAT / LNG — координаты (числовые свойства с точностью до 6 знаков)
  • PHONE — телефон (строка или множественное свойство)
  • WORKING_HOURS — режим работы (строка или JSON: {"mon-fri": "9:00-20:00", "sat": "10:00-18:00"})
  • POINT_TYPE — тип точки (список: «Магазин», «Пункт выдачи», «Сервисный центр»)
  • CITY_ID — привязка к справочнику городов (элемент инфоблока городов)
  • METRO — ближайшая станция метро
  • PHOTO — фото точки

Координаты (LAT/LNG) — ключевые. Их нужно получить при создании точки: либо вручную через Яндекс.Карты, либо через геокодирование по адресу через API Яндекс.Геокодера при сохранении элемента:

AddEventHandler('iblock', 'OnBeforeIBlockElementAdd', 'geocodeStoreAddress');

function geocodeStoreAddress(&$arFields) {
    if ($arFields['IBLOCK_ID'] !== IBLOCK_STORES_ID) return;
    $address = urlencode($arFields['PROPERTIES']['ADDRESS']['VALUE']);
    $http = new \Bitrix\Main\Web\HttpClient();
    $response = $http->get("https://geocode-maps.yandex.ru/1.x/?apikey=KEY&format=json&geocode=$address");
    $data = json_decode($response, true);
    $coords = $data['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos'];
    [$lng, $lat] = explode(' ', $coords);
    $arFields['PROPERTIES']['LAT']['VALUE'] = $lat;
    $arFields['PROPERTIES']['LNG']['VALUE'] = $lng;
}

Выбор картографического API

Яндекс.Карты API — приоритет для российской аудитории. Детальное покрытие РФ, пробки, геолокация пользователя, построение маршрутов. Тарифы: бесплатно до 1 000 запросов/сутки, далее коммерческий план.

2GIS API — хорошая альтернатива для городов РФ и СНГ, детальные карты офисных зданий (поэтажные планы).

OpenStreetMap + Leaflet.js — бесплатный вариант без лимитов на показы. Геокодирование через Nominatim (бесплатно, но с ограничениями по частоте запросов) или через платный Geocoding API.

Архитектура компонента

Компонент store locator состоит из двух частей:

PHP-бэкенд (component.php) — получает список точек из инфоблока, опционально фильтрует по городу или радиусу:

// Поиск в радиусе через формулу гаверсинуса (приближение)
// Для каталогов до 1000 точек — достаточно фильтрации на стороне JS
$res = CIBlockElement::GetList(
    [],
    ['IBLOCK_ID' => IBLOCK_STORES_ID, 'ACTIVE' => 'Y'],
    false, false,
    ['ID', 'NAME', 'PROPERTY_LAT', 'PROPERTY_LNG', 'PROPERTY_ADDRESS',
     'PROPERTY_PHONE', 'PROPERTY_WORKING_HOURS', 'PROPERTY_POINT_TYPE']
);
$points = [];
while ($el = $res->GetNext()) {
    $points[] = [
        'id'      => $el['ID'],
        'name'    => $el['NAME'],
        'lat'     => (float)$el['PROPERTY_LAT_VALUE'],
        'lng'     => (float)$el['PROPERTY_LNG_VALUE'],
        'address' => $el['PROPERTY_ADDRESS_VALUE'],
        'phone'   => $el['PROPERTY_PHONE_VALUE'],
        'hours'   => $el['PROPERTY_WORKING_HOURS_VALUE'],
        'type'    => $el['PROPERTY_POINT_TYPE_VALUE'],
    ];
}

Данные прокидываются в JS через <script> с JSON или через AJAX-endpoint.

JS-фронтенд — инициализирует карту, добавляет маркеры, реализует поиск и фильтрацию:

// Яндекс.Карты API 3.0
import { load } from '@2gis/mapgl';
// или ymaps3.ready.then(() => { ... })

const map = new ymaps3.YMap(document.getElementById('map'), {
    location: { center: [37.617, 55.755], zoom: 10 }
});

// Кластеризация для большого числа точек
const clusterer = new ymaps3.YMapClusterer({ ... });

Кластеризация маркеров — обязательна при 50+ точках. Без неё карта перегружена маркерами и неиспользуема. Яндекс.Карты 3.0 и Leaflet.js (через плагин Leaflet.markercluster) поддерживают это из коробки.

Поиск по геолокации пользователя

// Получение геопозиции браузера
navigator.geolocation.getCurrentPosition((pos) => {
    const userLat = pos.coords.latitude;
    const userLng = pos.coords.longitude;
    // сортировка точек по расстоянию (формула гаверсинуса на JS)
    stores.sort((a, b) => distance(userLat, userLng, a.lat, a.lng) - distance(userLat, userLng, b.lat, b.lng));
    renderStoreList(stores.slice(0, 5)); // показываем 5 ближайших
});

При отказе пользователя от геолокации — фолбек: определение города по IP через Sypex Geo (PHP-библиотека, базы данных хранятся локально) или через API ip-api.com.

Боковая панель со списком точек

Карта без боковой панели — неудобный UX. Типичная компоновка: слева список точек с расстоянием от пользователя, справа карта. Клик по точке в списке центрирует карту и открывает балун. Клик по маркеру — подсвечивает карточку в списке.

Синхронизация реализуется через общий state (простой JS-объект или небольшая store на Vue/Alpine.js):

let selectedStore = null;

function selectStore(id) {
    selectedStore = id;
    // обновить подсветку в списке
    document.querySelectorAll('.store-card').forEach(el => el.classList.remove('active'));
    document.querySelector(`[data-store-id="${id}"]`).classList.add('active');
    // переместить карту
    map.setCenter([stores[id].lng, stores[id].lat], { duration: 300 });
}

Фильтрация по типу точки и городу

Выпадающий список с городами — это SELECT с onChange, который фильтрует массив stores на клиенте и перерисовывает маркеры. При 100+ городах список громоздкий; лучше — поле автодополнения с поиском по вводу.

Фильтр по типу точки (магазин / пункт выдачи / сервис) — чекбоксы, которые скрывают/показывают соответствующие маркеры через marker.setVisible(false).

Производительность при большом числе точек

При 500+ точках передача всего массива в JS при загрузке страницы нежелательна — большой JSON тормозит парсинг. Решение:

  • Пагинированный AJAX-запрос: при старте загружаем точки в границах видимой области карты, при перемещении карты — подгружаем новые
  • Серверный поиск по радиусу: запрос к PHP с параметрами lat, lng, radius, фильтрация в SQL через формулу гаверсинуса или через PostGIS (если PostgreSQL)
  • Кеширование: список точек редко меняется, агрессивный кеш на 1 час в таблице b_cache

Сроки

Масштаб Что входит Срок
До 50 точек Карта + список + фильтр по городу 1–2 недели
50–300 точек + кластеры, геолокация, поиск рядом 2–4 недели
300+ точек + серверный поиск по радиусу, PostGIS 4–6 недель

Store locator — точка контакта между онлайн и офлайн. Правильно реализованный, он снижает звонки в колл-центр с вопросом «а где вы находитесь» и повышает конверсию в посещение торговой точки.