Блог API Яндекс.Карт

Определение местоположения с использованием Geolocation API

-----
Эта статья относится к API Яндекс.Карт 1.x. Рекомендуем посмотреть пример для API 2.0.
-----

В связи с ростом популярности мобильных устройств задача определения местоположения пользователя стала востребованной задачей. Владеть подобной информацией полезно для выполнения действий, адаптированных под конкретного пользователя. Например, можно установить центр карты в текущее географическое положение пользователя и отобразить необходимую для заданной области информацию.

На многих веб-сайтах задача определения координат пользователя решается с помощью преобразования IP адреса в координаты. Однако, такой способ дает малую точность, которая может не устроить пользователей вашего проекта. В данной статье будет рассмотрен другой способ получения информации о местоположении пользователя – Geolocation API, предложенный W3C.

На сегодняшний день, геолокация поддерживается лишь несколькими браузерами, наиболее популярные из них:

  • FireFox 3.1 и выше;
  • Opera 10.6 и выше;
  • Safari для iPhone (версия ОС 3.1. и выше);
  • Для браузеров Safari и Chrome - для поддержки GeolocationAPI требуется установить дополнительные модули.

Geolocation API предоставляет высокоуровневый интерфейс для получения координат местоположения устройства, предоставляющего доступ в интернет. API не зависит от средств получения информации о местоположении. Эта информация может быть получена при помощи GPS, сетевых параметров (IP адрес, RFID, WiFi адрес или ID ячейки GSM/CDMA), а также введена пользователем. Поэтому, информация полученная с помощью Geolocation API, является более точной, чем простое определение координат по IP адресу.

Интерфейс Geolocation API представляет два метода по определению местоположения пользователя: getCurrentPosition() и watchPosition(). Второй метод отличается от первого только тем, что после окончания вызова и возврата результата, продолжает отслеживать изменения местоположения устройства. Поэтому в случае, если необходимость в отслеживании местоположении отпала, то слушатель нужно удалить с помощью метода clearWatch(). В качестве параметра в метод clearWatch() передается идентификатор слушателя, возвращаемого методом watchPosition().

Получить доступ к интерфейсу Geolocation API можно через объект navigator.geolocation.

В методы getCurrentPosition() и watchPosition() передаются идентичные параметры (последние два из которых являются необязательными)

  • обработчик успешного получения координат;
  • обработчик неудачного получения координат;
  • объект с опциями.

Остановимся немного подробнее на последнем параметре. Он предоставляет возможность настройки запроса с помощью следующих опций:

  • enableHighAccuracy – отвечает за включение/выключения режима получения самых точных доступных данных. При включенном режиме запрос выполняется более длительный промежуток времени, однако точность будет выше. По умолчанию данный режим отключен;
  • timeout – максимальное время ожидания ответа в миллисекундах. По умолчанию Infinity (бесконечность);
  • maximumAge – время на которое кэшируются полученные данные. По умолчанию это значение равно 0, т. е. данные не кэшируются.

Например, вызывать метод getCurrentPosition() можно так:

navigator.geolocation.getCurrentPosition(
 
    // Обработчик успшеного получения координат
    function (position) {
        alert("Координаты: " + position.coords.longitude + ", " + position.coords.latitude);
    },
   
    // Оработчик неудачного завершения получения коордиант
    function (error) {
        alert("При определении координат произошла ошибка. Ее код: " + error.code);
    },
   
    // Параметры
    {
        enableHighAccuracy : false,     // Режим получения наиболее точных данных
        timeout : 10000,                // Максиальное время ожидания ответа (в миллисекундах)
        maximumAge : 1000               // Максимальное время жизни полученных данных
    }

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

Отнаследуемся от стандартной кнопки (класс YMaps.ToolBarButton) c помощью функции extend(

// Реализует наследование прототипа без исполнения конструктора родителя
// Подробнее о наследовании: http://javascript.ru/tutorial/object/inheritance
function extend (child, parent) {
    var c = function () {};
    c.prototype = parent.prototype;
    c.prototype.constructor = parent;
    return child.prototype = new c(
};

Класс кнопки будет выглядеть вот так:

// Кнопка "Геолокатор"
function GeolocatorButton (content, options) {
    // Переданный контент и параметры дополняем значениями по умолчанию
    this.content = YMaps.jQuery.extend({}, this.defaultContent, content);
    this.options = YMaps.jQuery.extend({}, this.defaultOptions, options);
 
    // Вызов родительского конструктора
    YMaps.ToolBarButton.call(this, this.content.normal);
}
 
// Наследование прототипа родителя
var ptp = extend(GeolocatorButton, YMaps.ToolBarButton);
 
//
// Определение различных констант и значений по умолчанию:
// defaultContent
// defaultOptions
// Errors
//
 
// Вызывается при добавлении кнопки на карту
ptp.onAddToToolBar = function (toolBar, parentContainer, group) {
    YMaps.ToolBarButton.prototype.onAddToToolBar.call(this, toolBar, parentContainer, group);
 
    // Указатель на карту
    this.map = toolBar.getMap(
 
    // Проверка поддерживает ли браузер Geolocation API
    if (navigator.geolocation) {
        this.geolocation = navigator.geolocation;
 
        this.listener = YMaps.Events.observe(this, this.Events.Click, this.getPosition, this);
    } else {
        this.hide(
    }
};
 
// Вызывается при удалении кнопки с карты
ptp.onRemoveFromToolBar = function () {
    YMaps.ToolBarButton.prototype.onRemoveFromToolBar.call(this);
 
    this.listener.cleanup(
 
    if (this.placemark) {
        this.map.removeOverlay(this.placemark()
        this.placemark = null;
    }
 
    this.listener = this.geolocation = this.content = this.options = this.map = null;
};
 
// Получает местоположение пользователя
ptp.getPosition = function () {
    //
    // Определение местоположения с использованием GeoLocation API
    //
};

Использовать данный класс совсем просто:

// Создание панели инструментов со стандартным набором кнопок
var toolBar = new YMaps.ToolBar(
 
// Добавление кнопки "Геолокатор"
toolBar.add(new GeolocatorButton()
 
// Добавление панели инструментов на карту
map.addControl(toolBar);

Посмотреть пример на отдельной странице

Geolocation API в настоящее время поддерживается далеко не всеми браузерами, однако, этот способ определения координат заслуживает внимания. В ближайшем будущем большая часть браузеров будет предоставлять рассмотренное API, позволяя разработчикам использовать этот удобный и достаточно точный способ определения местоположения пользователей.

12 комментариев
Также можно использовать функцию ymlib.setAutoBounds, предложенную в клубе. Эта функция для инициализации карты использует либо geolocation api, либо YMaps.location.
Если я установлю у себя такой сервис, и буду вести учет адресов. Насколько это законно?
Илья Житенев
28 января 2016, 06:26

У меня иногда выдаёт ошибку 3. Что это значит? Где можно посмотреть?

Дмитрий Сухоносов
28 января 2016, 06:26
console.log(error)

Коды ошибок:
PERMISSION_DENIED 1
POSITION_UNAVAILABLE 2
TIMEOUT    3

Задайте вопрос лучше в клубе разработчиков. Там много специалистов, Вам обязательно помогут. http://clubs.ya.ru/mapsapi/

Как это переписать под API 2.0?

Задайте вопрос лучше в клубе разработчиков. Там много специалистов, Вам обязательно помогут. http://clubs.ya.ru/mapsapi/

Удалённый пользователь
28 января 2016, 06:26

Как в новом апи делать кнопки с нужными картинками? Я пробовал button, у которого есть иконка для обычного и нажатого состояние, но нажатое не срабатывает. + ко всему как получить доступ к инстансу кнопки из события click ?

 

        ymaps.ready(init);        function init () {            // Создание экземпляра карты и его привязка к контейнеру с            // заданным id ("map")            var myMap = new ymaps.Map('YMapsID', {                    // При инициализации карты, обязательно нужно указать                    // ее центр и коэффициент масштабирования                    center: [37.64, 55.76], // Москва                    zoom: 5                });                            var b1 = new ymaps.control.Button({data: {                                               image: 'http://ymaps.narod2.ru/img/wifi_icon.png',                                               imageSelected: 'http://ymaps.narod2.ru/img/loader.gif'                                        },})b1.events.add('click', function (e) {//b1.deselect()                                // e.get(' ???? ')         // как получить b1 здесь?})                            myMap.controls.add(new ymaps.control.ToolBar([b1]));        }

 

Заранее спасибо!

Задайте вопрос лучше в клубе разработчиков. Там много специалистов, Вам обязательно помогут. http://clubs.ya.ru/mapsapi/

Пожалуйста ответьте на мой вопрос, немного не догоняю. У меня есть сайт. На нем перечень всех мед учреждений с адресами ( в базе). Могу ли я, используя только адреса, сделать функцияю "показать  на карте". Или надо сначала преобразовать  адреса в геогр. координаты? Дайти ссылочку, где читать и с чего начинать  Что-то я запуталась от обилия информации. Спасибо

Для отображения объектов на карте необходимо знать их координаты. Получить координаты из адресов можно, воспользовавшись Геокодером.

Спасибо за ответ. Т.е. я должна вручную воспользовавшись геокодером снять координаты, записать в базу, а потом уже выводить карты?