Location 26.300.0: батчевый обратный геокодинг — до 20 координат за один вызов
Релиз от 17 июня 2026 с одной, но цельной темой: в модуль location завезли батчевый обратный геокодинг — метод findByCoordsList, который превращает список координат в список локаций за один вызов сервиса. Если вы строите интеграции с картами или доставкой и до сих пор дёргали findByCoords в цикле — это обновление для вас. Обратной несовместимости нет, миграций БД нет.
Новое: findByCoordsList сверху донизу
Добавлена целая цепочка — от публичного сервиса до реализаций в источниках:
Bitrix\Location\Repository\Location\Capability\IFindByCoordsList— новый интерфейс-capability с единственным методомfindByCoordsList(array $coordsList, int $zoom, string $languageId): array.LocationService::findByCoordsList(...)— публичная точка входа.LocationService::MAX_BATCH_SIZE = 20— публичный лимит размера батча.LocationRepository::findByCoordsList(...)и стратегияRepository\Location\Strategy\Find::findByCoordsList(...)— маршрутизация до первого репозитория, который реализует новый интерфейс и проходит поIScope.- Реализации для OSM (
Source\Osm\Repository) и Google (Source\Google\Repository). - В OSM API — новые методы
reverseBatch()иdetailsBatch(), работающие через actions шлюза Битриксаosmgateway.location.reverseBatchиosmgateway.location.detailsBatch.
Использование выглядит так:
<?php declare(strict_types=1);
use Bitrix\Main\Loader;
use Bitrix\Location\Service\LocationService;
Loader::requireModule('location');
$coordsList = [
['lat' => 55.7558, 'lng' => 37.6173], // pickup
['lat' => 59.9343, 'lng' => 30.3351], // delivery
];
$locations = LocationService::getInstance()->findByCoordsList(
$coordsList,
zoom: 18,
languageId: 'ru',
);
foreach ($locations as $key => $location) {
if ($location === null) {
// по этой точке ничего не нашлось — индекс сохранён
continue;
}
// работаем с найденной локацией
}
Главное в контракте — результат выровнен по индексам входного массива: «не найдено» — это null на своей позиции, а не дырка в массиве. Удобно, когда координаты привязаны к заказам или точкам маршрута. Phpdoc ядра описывает контракт как index-aligned list (array<int, Entity\Location|null>), так что надёжнее передавать обычный числовой список, а свои ключи маппить снаружи.
Проверьте лимиты и валидацию на входе
Валидация строгая: больше 20 координат (MAX_BATCH_SIZE) или элемент без числовых lat/lng — и вы получите ArgumentException. Если точек больше — режьте на куски сами:
foreach (array_chunk($coordsList, LocationService::MAX_BATCH_SIZE, true) as $chunk) {
$result += $locationService->findByCoordsList($chunk, 18, 'ru');
}
И ещё один нюанс контракта: при внутреннем RuntimeException сервис не бросает исключение наружу, а возвращает null по всем позициям (array_fill_keys). То есть «весь батч из null» может означать как «ничего не нашлось», так и «источник упал» — закладывайтесь на это в логике.
Мелочи и находки
- Батч работает только по внешним источникам.
findByCoordsListжёстко используетLOCATION_SEARCH_SCOPE_EXTERNAL— локальный репозиторий БД в батчевом поиске не участвует. - Google «батчует» фиктивно. Реализация для Google — это цикл по одиночным
findByCoords, то есть N HTTP-запросов; ошибки отдельных элементов уходят вErrorService, а в результат идётnull. У OSM батч настоящий: до двух HTTP-запросов (reverseBatch+detailsBatch, второй пропускается, если первый ничего не нашёл) на весь список. - Таймауты для OSM подняли. Для батч-запросов HTTP-таймаут вырос с 10 до 60 секунд (
HTTP_BATCH_TIMEOUT), появился приватныйmakeHttpClientWithTimeout(). - Фича зависит от шлюза. Новые методы OSM опираются на серверные actions
osmgateway.location.*— заработает только там, где шлюз Битрикса их уже поддерживает. - Breaking changes и deprecated отсутствуют: переформатирование
LocationService::findByExternalId()и выделение приватногоbuildLocationFromDetails()в OSM-репозитории — чистые рефакторинги без изменения публичного контракта.