Обработка успешной геолокации

В библиотеке Leaflet обработка геолокации строится вокруг встроенного механизма браузерного Geolocation API и событийной модели карты. Успешное определение координат фиксируется событием locationfound, которое возникает после вызова map.locate() при корректном получении данных от устройства пользователя.

Геолокация в Leaflet реализуется асинхронно: карта инициирует запрос, браузер получает разрешение, после чего формируется объект события с координатами, точностью и дополнительными метаданными.

Инициация запроса геолокации

Запуск определения местоположения выполняется через метод карты:

map.locate({
  setView: true,
  maxZoom: 16,
  enableHighAccuracy: true
});

Параметры влияют на поведение обработки результата:

  • setView — автоматическое перемещение карты к найденной точке
  • maxZoom — уровень масштабирования после центрирования
  • enableHighAccuracy — использование GPS вместо сетевых данных при возможности

После выполнения запроса карта начинает ожидать событие locationfound.

Событие locationfound

Успешное получение координат приводит к генерации события:

map.on('locationfound', function (e) {
  console.log(e.latlng);
});

Объект события содержит ключевые поля:

  • latlng — координаты в формате { lat, lng }
  • accuracy — радиус погрешности в метрах
  • timestamp — время получения данных (в зависимости от браузера)
  • bounds — предполагаемая область, если доступна

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

Отображение маркера текущей позиции

Наиболее распространённый сценарий — отображение маркера в точке определения координат:

let userMarker;

map.on('locationfound', function (e) {
  if (userMarker) {
    map.removeLayer(userMarker);
  }

  userMarker = L.marker(e.latlng).addTo(map)
    .bindPopup('Текущее местоположение')
    .openPopup();
});

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

Визуализация точности определения

Погрешность геолокации играет критическую роль в пользовательском опыте. Leaflet позволяет отобразить радиус точности в виде окружности:

let accuracyCircle;

map.on('locationfound', function (e) {
  if (accuracyCircle) {
    map.removeLayer(accuracyCircle);
  }

  accuracyCircle = L.circle(e.latlng, {
    radius: e.accuracy,
    color: '#136aec',
    fillColor: '#136aec',
    fillOpacity: 0.15,
    weight: 1
  }).addTo(map);
});

Значение e.accuracy возвращается в метрах и описывает радиус, внутри которого с высокой вероятностью находится пользователь.

Совместное использование маркера и окружности формирует стандартную модель отображения геопозиции.

Автоматическое центрирование карты

При успешном определении координат часто применяется центрирование карты на полученной позиции:

map.on('locationfound', function (e) {
  map.setView(e.latlng, 15);
});

Альтернативный вариант — использование границ:

map.on('locationfound', function (e) {
  const bounds = e.bounds;

  if (bounds) {
    map.fitBounds(bounds);
  } else {
    map.setView(e.latlng, 15);
  }
});

Метод fitBounds обеспечивает более гибкую адаптацию масштаба, особенно при наличии рассчитанной области.

Обновление позиции в реальном времени

При включённом режиме слежения браузер может периодически обновлять координаты. В Leaflet это реализуется через повторные вызовы locationfound.

map.locate({
  watch: true,
  enableHighAccuracy: true
});

Обработчик события остаётся тем же, но данные поступают непрерывно:

map.on('locationfound', function (e) {
  userMarker.setLatLng(e.latlng);
  accuracyCircle.setLatLng(e.latlng);
  accuracyCircle.setRadius(e.accuracy);
});

Такой подход используется в задачах навигации и трекинга перемещения.

Управление состоянием слоя геолокации

Для предотвращения накопления слоёв применяется централизованное управление объектами:

const locationLayer = L.layerGroup().addTo(map);

map.on('locationfound', function (e) {
  locationLayer.clearLayers();

  L.marker(e.latlng).addTo(locationLayer);
  L.circle(e.latlng, { radius: e.accuracy }).addTo(locationLayer);
});

Использование layerGroup упрощает очистку и обновление отображения без ручного удаления каждого объекта.

Преобразование координат и работа с объектом LatLng

Объект e.latlng является экземпляром LatLng, предоставляемым Leaflet и поддерживает операции преобразования:

map.on('locationfound', function (e) {
  const lat = e.latlng.lat;
  const lng = e.latlng.lng;

  const point = map.latLngToContainerPoint(e.latlng);
});

Преобразования используются при интеграции с пользовательскими оверлеями и DOM-элементами.

Комбинация с пользовательскими интерфейсными слоями

Геолокация часто интегрируется с кастомными элементами управления:

map.on('locationfound', function (e) {
  const info = {
    latitude: e.latlng.lat,
    longitude: e.latlng.lng,
    accuracy: Math.round(e.accuracy)
  };

  updateSidebar(info);
});

Передача данных вне карты позволяет синхронизировать состояние интерфейса с картографическим слоем.

Поведение при повторных событиях

При активном watch-режиме событие locationfound может вызываться многократно. Это требует устойчивой логики обновления:

  • обновление координат без создания новых слоёв
  • пересчёт радиуса точности
  • сохранение ссылки на существующие объекты
let state = {
  marker: null,
  circle: null
};

map.on('locationfound', function (e) {
  if (!state.marker) {
    state.marker = L.marker(e.latlng).addTo(map);
  } else {
    state.marker.setLatLng(e.latlng);
  }

  if (!state.circle) {
    state.circle = L.circle(e.latlng, { radius: e.accuracy }).addTo(map);
  } else {
    state.circle.setLatLng(e.latlng);
    state.circle.setRadius(e.accuracy);
  }
});

Связь с визуальными слоями карты

Результаты геолокации часто используются как основа для последующего построения маршрутов, фильтрации объектов и динамической загрузки данных. Координаты из locationfound становятся точкой входа для геопространственных операций, выполняемых поверх карты Leaflet.