Клуб API Карт

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

Пост в архиве.

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

На многих веб-сайтах задача определения координат пользователя решается с помощью преобразования 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, позволяя разработчикам использовать этот удобный и достаточно точный способ определения местоположения пользователей.

Определение местоположения с использованием 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, позволяя разработчикам использовать этот удобный и достаточно точный способ определения местоположения пользователей.