Выбор! Я хочу выбирать!

Автор: Евгений Рыжков и Татьяна Головко Дата публикации: 25.03.2011

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

Второй метод использует GPS, чтобы «поговорить» со спутниками, которые находятся на орбите. Такой способ имеет погрешность всего несколько метров. Недостатком этого варианта является встроенный GPS, который потребляет слишком много энергии и поэтому его часто отключают. А это означает дополнительные задержки: после включения GPS требуется некоторое время на установление связи со спутниками. Если у тебя уже есть опыт использования Google Maps на iPhone или других смартфонах, то и с этими методами ты уже знаком. Сначала видишь большой круг, который постепенно приближает свою позицию (поиск ближайших вышек), затем круг меньший (найдены ближайшие вышки), а затем будет видна точка (позиция определилась с помощью GPS).

В зависимости от твоего веб-приложения, возможно и не потребуется высокая точность определения позиции. Например, ты ищешь афиши кинофильмов в близрасположенных кинотеатрах. Для такой задачи низкая точность будет вполне приемлема. Даже в большом городе, вокруг не так много кинотеатров. Тебе будет предоставлен просто их перечень. А вот, если приложение подсказывает путь, то тут нужна уже высокая точность, чтобы, например, приложение могло подсказать: «через 20 метров поверни налево».

Функция getCurrentPosition() может принимать третий необязательный аргумент — объект PositionOptions. У данного объекта доступны три свойства. Все они являются не обязательными.

Свойство Тип Значение по умолчанию Примечания
enableHighAccuracy boolean false true может быть медленнее
timeout long нет милисекунды
maximumAge long 0 милисекунды

Назначение свойства enableHighAccuracy следует из его названия. Если оно установлено в true (и устройство поддерживает данную фичу) — пользователь дает согласие на точное определение месторасположения. Телефоны iPhone и Android имеют свою шкалу определения точности. Поэтому свойство enableHighAccuracy для них может и не сработать, но и оставлять это свойство в false не следует.

Свойство timeout определяет, сколько миллисекунд приложение готово ждать для определения позиции. Этот отсчет не запускается, пока пользователь не даст разрешение на вычисление его положения. Т.е. это не таймер как долго думает пользователь, а таймер задержек сети.

Свойство maximumAge позволяет устройству дать ответ о положении из кеша. Например, вызываем фукцию getCurrentPosition() первый раз. Пользователь разрешил определить его положение и функция успешно вернула текущую позицию в 10:00. И предположим, что через минуту (в 10:01) мы снова вызываем функцию getCurrentPosition() со свойством maximumAge равным 75000:

navigator.geolocation.getCurrentPosition(success_callback, error_callback, {maximumAge: 75000});

Этим самым мы сообщаем, что нам не нужно знать текущее положение пользователя. Достаточно знать, где он находился 75 секунд назад. Поэтому в нашем примере новые координаты не будут вычисляться, а возьмутся прежние, т.к. прошло всего 60 секунд с прошлого определения позиции.

Прежде чем определять местоположение пользователя, следует подумать а какая точность нужна и установить в нужное значение enableHighAccuracy. Если местоположение пользователя нужно определять более одного раза, то нужно подумать, как можно использовать ранее полученные данные и использовать maximumAge. Если же нужно непрерывно вычислять положение пользователя, тогда функция getCurrentPosition() не для тебя. Тебе нужна watchPosition().

Функция watchPosition() имеет ту же структуру, что и getCurrentPosition(). Она так же принимает в параметрах две функции (одну для успешной обработки и одну для обработки ошибок) и тоже может принимать необязательный параметр PositionOptions. Разница лишь в том, что твои функции будут срабатывать каждый раз при изменении положения пользователя. Так пропадает постоянный опрос устройства: «изменилось ли положение?». Устройство само вызовет нужные функции, когда произойдет смена позиции. Это можно использовать для пометок на карте пройденного маршрута, указания, куда держать путь. Да вообще можно придумать массу примеров.

Функция watchPosition() возвращает число, которое можно куда-то сохранить. Если появится желание остановить отслеживание позиции, можно вызвать метод clearWatch() и передать ему сохраненное число. Это все работает примерно так же как функции setInterval() и clearInterval() в Javascript.

Куда дальше