В основе определения местоположения в мобильных браузерах лежит Geolocation API, предоставляемый средой выполнения JavaScript. Доступ к координатам возможен только при соблюдении ряда условий безопасности: использование HTTPS, явное разрешение пользователя и поддержка устройства.
Основной метод получения позиции:
navigator.geolocation.getCurrentPosition(success, error, options);
Для непрерывного отслеживания:
navigator.geolocation.watchPosition(success, error, options);
Параметры options определяют точность, таймаут и
поведение кэширования:
const options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
enableHighAccuracy активирует GPS вместо
приблизительных данных Wi-Fi/сетиtimeout ограничивает время ожидания ответаmaximumAge управляет использованием кэшированных
координатLeaflet предоставляет встроенный механизм геолокации через метод
map.locate().
Базовая инициализация карты:
const map = L.map('map').setView([0, 0], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
Запуск определения местоположения:
map.locate({ setView: true, maxZoom: 16 });
Параметры:
setView — автоматически центрирует карту на найденной
позицииmaxZoom — устанавливает масштаб после определения
координатwatch — включает непрерывное отслеживание
положенияLeaflet генерирует событие locationfound:
map.on('locationfound', function (e) {
const radius = e.accuracy;
L.marker(e.latlng).addTo(map)
.bindPopup('Текущая позиция').openPopup();
L.circle(e.latlng, radius).addTo(map);
});
Объект события содержит ключевые данные:
latlng — координаты пользователяaccuracy — радиус точности в метрахaltitude — высота (если доступна)speed — скорость (на мобильных устройствах с GPS)Круг точности визуализирует погрешность определения координат, что особенно важно при использовании сетевых методов позиционирования.
При отказе или сбое вызывается событие
locationerror:
map.on('locationerror', function (e) {
console.log(e.message);
});
Типичные причины ошибок:
Для мобильных сценариев навигации используется режим
watch: true:
map.locate({
watch: true,
enableHighAccuracy: true
});
В этом режиме карта обновляется при каждом изменении координат.
Обновление маркера:
let userMarker;
let accuracyCircle;
map.on('locationfound', function (e) {
if (userMarker) {
map.removeLayer(userMarker);
map.removeLayer(accuracyCircle);
}
userMarker = L.marker(e.latlng).addTo(map);
accuracyCircle = L.circle(e.latlng, e.accuracy).addTo(map);
});
Leaflet не предоставляет отдельного метода остановки watch напрямую, поэтому используется API браузера:
const watchId = navigator.geolocation.watchPosition(success, error);
// остановка
navigator.geolocation.clearWatch(watchId);
При этом необходимо хранить watchId вне обработчиков
событий.
На мобильных устройствах поведение геолокации отличается от десктопа:
При первом получении координат часто требуется автоматическое позиционирование:
map.on('locationfound', function (e) {
map.setView(e.latlng, 16);
});
Для предотвращения постоянного “скачка” карты применяется флаг:
let firstFix = true;
map.on('locationfound', function (e) {
if (firstFix) {
map.setView(e.latlng, 16);
firstFix = false;
}
});
Геолокация часто привязывается к UI-кнопке:
const locateBtn = L.control({ position: 'topleft' });
locateBtn.on Add = function () {
const btn = L.DomUtil.create('button', 'locate-btn');
btn.innerHTML = '?';
btn.oncl ick = function () {
map.locate({ setView: true, maxZoom: 16 });
};
return btn;
};
locateBtn.addTo(map);
Для мобильной навигации используется комбинация настроек:
map.locate({
enableHighAccuracy: true,
maximumAge: 0,
timeout: 15000,
watch: true
});
Повышенная точность достигается за счёт GPS, но увеличивает энергопотребление и время получения координат.
В мобильных условиях координаты могут поступать из разных источников:
Leaflet не управляет источниками напрямую, но корректно отображает
accuracy, позволяя визуально оценивать качество данных.
При наличии данных heading можно визуализировать
направление:
map.on('locationfound', function (e) {
if (e.heading !== undefined) {
console.log('Направление:', e.heading);
}
});
На практике направление часто нестабильно на низких скоростях и в помещениях.
При слабом GPS сигнале координаты могут “прыгать”. Для сглаживания используется простая фильтрация:
let lastLatLng;
map.on('locationfound', function (e) {
if (!lastLatLng) {
lastLatLng = e.latlng;
return;
}
const distance = map.distance(lastLatLng, e.latlng);
if (distance < 50) {
lastLatLng = e.latlng;
userMarker.setLatLng(e.latlng);
}
});
Такой подход снижает визуальные скачки маркера.
После получения координат пользовательской позиции они передаются в системы маршрутизации:
function onLocationFound(e) {
const start = e.latlng;
const destination = L.latLng(48.8566, 2.3522);
}
Дальнейшая логика обычно строится поверх внешних сервисов маршрутов, а Leaflet используется как слой визуализации.
На мобильных браузерах:
Поэтому стабильное отслеживание требует активного экрана и взаимодействия с картой.
При отказе в доступе API возвращает код ошибки:
map.on('locationerror', function (e) {
if (e.code === 1) {
console.log('Доступ запрещён');
}
});
Коды:
1 — отказ в разрешении2 — позиция недоступна3 — таймаутГеолокация часто комбинируется с пользовательскими слоями:
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
L.control.scale().addTo(map);
После получения координат добавляются динамические объекты: маркеры, зоны, маршруты, области интересов.
Типичные проблемы:
Leaflet-события позволяют локализовать проблему:
locationfound не вызывается → проблема APIlocationerror с кодом → ошибка доступа или сетиПервый вызов геолокации часто задерживается из-за запроса разрешения. В этот момент карта уже должна быть инициализирована, иначе события могут не привязаться.
const map = L.map('map').setView([0, 0], 2);
map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);
map.locate();