Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
web - tec / HTML5.pdf
Скачиваний:
45
Добавлен:
12.06.2015
Размер:
2.87 Mб
Скачать

Обработка ошибок

 

127

 

 

 

Свойство

Тип

Комментарий

coords..altitude

double или null

Метры над поверхностью условного

 

 

эллипсоида Земли

coords..accuracy

double

Метры

coords..altitudeAccuracy

double или null

Метры

coords..heading

double или null

Градусы по часовой стрелке от направле-

 

 

ния на север

coords..speed

double или null

Метры в секунду

timestamp

DOMTimeStamp

Как объект Date()

Гарантированно определены только три координатных свойства: coords.latitude, coords.longitude и coords.accuracy. Представление остальных (null, если не опреде-

лены) зависит от возможностей клиентского компьютера и сервера позиционирования, с которым тот связывается. Свойства heading и speed могут быть вычислены лишь тогда, когда известно предыдущее положение пользователя.

Обработка ошибок

Геолокация — это непростая система, в которой того и гляди что-нибудь не заладится. Уже говорилось о проблеме запроса согласия пользователя. Если страница запрашивает координаты пользователя, а пользователь не хочет их сообщать, вебмастер будет посрамлен, потому что пользователь всегда прав. Каким же образом реализовать в коде обработку ошибок? Для нее предназначен второй аргумент функции getCurrentPosition() — это тоже функция обратного вызова:

navigator.geolocation.getCurrentPosition(show_map, handle_error)

Если что-то не в порядке, функция обработки ошибок будет применена к объекту PositionError. Его свойства перечислены в табл. 6.3.

Таблица 6.3. Свойства объекта PositionError

Свойство

Тип

Комментарий

 

 

 

code

short

Код ошибки (порядковый номер)

 

 

 

message

DOMString

Не для конечных пользователей

 

 

 

Свойство code принимает одно из четырех значений:

PERMISSION_DENIED (1) — если пользователь нажмет кнопку Don't Share (Не сообщать) на панели геолокации или иным способом запретит доступ к данным о своем местонахождении;

POSITION_UNAVAILABLE (2) — если не работает сеть или невозможно связаться со спутником позиционирования;

TIMEOUT (3) — когда сеть работает, но на расчет координат уходит слишком много времени (что значит «слишком много», вы узнаете в следующем разделе);

UNKNOWN_ERROR (0) — если проблема в чем-то другом.

128 Глава 6.. Вот мы вас и нашли!

Пример:

function handle_error(err) { if (err.code == 1) {

// воля пользователя — закон для меня!

}

}

Разметка в вопросах и ответах

Вопрос: Будет ли API геолокации работать на Между­

ская система [WGS84] с двухмерными координатами.

народной космической станции, на Луне, на других пла-

Другие системы не поддерживаются». Поскольку МКС

нетах Солнечной системы?

облетает Землю по орбите, местоположение космо-

Ответ: Спецификация (http://www.w3.org/TR/geolo­

навтов на станции (http://twitter.com/Astro_TJ) описы-

вается широтой, долготой и высотой. Но, будучи ори-

cation-API/#coordinates_interface) гласит: «Эталонная

ентированной на координатную сеть Земли, Мировая

система географических координат, используемая­

геодезическая система неприменима к Луне и другим

в атрибутах этого интерфейса, — Мировая геодезиче-

планетам.

 

 

Требую выбора!

Такие популярные мобильные устройства, как iPhone и Android, поддерживают два способа определения координат. Первый способ — триангуляция, основанная на оценке расстояний до нескольких башен-ретрансляторов вашего сотового оператора. Это быстрая процедура, для которой не нужно никакого специального GPS-оборудования, но ее точность оставляет желать лучшего. В зависимости от того, сколько ретрансляторов находится поблизости, ваше местонахождение может быть установлено с точностью до квартала (если их много) или до одного-двух километров (если их мало).

Другой способ состоит в том, что GPS-модуль вашего мобильного устройства связывается с находящимися на околоземной орбите спутниками GPS-позицио­ нирования. Как правило, GPS позволяет определить местонахождение с точностью до нескольких метров. Обратная сторона медали — чрезвычайно высокое энергопотребление GPS-чипов. На мобильном устройстве общего назначения такой модуль, как правило, по умолчанию выключен и включается лишь при необходимости. Вот почему инициализация связи с GPS-спутником требует некоторого времени.

Если вам когда-либо приходилось открывать Карты Google на iPhone или другом смартфоне, то оба способа вам уже знакомы. Сначала на карте появляется большой круг (окрестность ближайшей башни-ретранслятора), затем он уменьшается (триангуляция по другим башням) и наконец стягивается в точку (координаты, полученные с GPS-спутника).

Я рассказываю об этом потому, что не каждое веб-приложение нуждается в высокой точности координат. Так, например, если пользователь ищет, какой бы ему фильм посмотреть в одном из окрестных кинотеатров, хватит «приблизительных» координат, ведь даже в больших городах кинотеатров не так много и так или иначе

Требую выбора!

129

система должна будет вывести афиши всего нескольких из них. С другой стороны, для пошагового инструктирования в реальном времени нужна самая высокая точность. Иначе невозможно будет сказать пользователю: «Пройдя 20 метров, сверните направо» и т. п.

У функции getCurrentPosition() есть необязательный третий аргумент — объект PositionOptions. В нем можно устанавливать значения трех свойств (табл. 6.4). Свойства объекта PositionOptions тоже необязательны.

Таблица 6.4. Свойства объекта PositionOptions

Свойство

Тип

По умолчанию

Комментарий

enableHighAccuracy

boolean

false

Установка true может

 

 

 

замедлить работу

timeout

long

(не установлено)

В миллисекундах

maximumAge

long

0

В миллисекундах

Еслифункциональностьустройствапозволяетрассчитыватьточныекоординаты, а пользователь согласен делиться ими, то их пересылку на сервер можно включить, установив для свойства enableHighAccuracy значение true. На смартфонах iPhone иAndroidдоступк«низкоточному»и«высокоточному»позиционированиюразделен,

поэтомувозможно,чтовызовgetCurrentPosition() приenableHighAccuracy:true выдаст ошибку, а при enableHighAccuracy:false пройдет успешно.

Свойство timeout определяет длительность промежутка (в миллисекундах), в течение которого ваше веб-приложение будет ждать присылки координат. Отсчет времени начинается с того момента, когда пользователь разрешает браузеру передать сведения о своем местонахождении. Таким образом, мы ограничиваем во времени не пользователя, а сеть.

Свойство maximumAge позволяет устройству сразу отсылать кэшированные данныеокоординатах.Так,например,пустьвашастраницавызвалаgetCurrentPosition() в первый раз, пользователь согласился и ваша первая (на случай успеха) функция обратного вызова применяется к координатам, вычисленным ровно в 10:00 утра. Допустим,черезминутупослеэтого,в10:01,высновавызываетеgetCurrentPosition(), на этот раз с присвоенным атрибуту maximumAge значением 75000:

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

Написав так, вы заявляете, что собственно нынешнее местонахождение пользователя вам знать не обязательно; достаточно узнать, где он находился 75 секунд (75 000 миллисекунд) назад. В данном случае устройство помнит, где пользователь был 60 секунд (60 000 миллисекунд) назад: координаты вычислялись при первом вызове getCurrentPosition(). Поскольку эти сведения не старше оговоренного срока давности, система не выполняет повторный расчет координат, а возвращает те же самые данные, что и в первый раз: широту, долготу, точность, метку времени

(10:00 утра).

Итак, прежде чем запрашивать пользователя о его местонахождении, задумайтесь о том, какая вам нужна точность данных, и, если это необходимо, включите enableHighAccuracy. Если местонахождение пользователя надо будет определять

130

Глава 6.. Вот мы вас и нашли!

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

нить watchPosition().

У watchPosition() та же структура, что и у getCurrentPosition(). В качестве аргументов она принимает две функции обратного вызова: одну обязательную (на случай успешного вызова) и одну необязательную (на случай ошибки), а необязательный третий аргумент — объект PositionOptions, со свойствами которого вы познакомились ранее. Разница в том, что ваша функция обратного вызова будет выполняться каждый раз, когда местонахождение пользователя изменит-

ся. Активным­ образом «опрашивать» аппарат пользователя нет необходимости: он сам определит удобный интервал «опроса» и будет запускать первую из двух функций обратного вызова каждый раз после того, как координаты пользователя изменятся. Можно применять watchPosition() для отображения движущегося маркера на карте, построения маршрута в реальном времени и т. д. по вашему усмотрению.

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

вJavaScript, знайте, что здесь механизм точно такой же.

Ачто в IE?

API геолокации, стандартизованный W3C (см. раздел «API геолокации» этой главы), не поддерживается в Internet Explorer. Но не спешите отчаиваться! Gears (http://tools..google..com/gears/) — разработанное Google браузерное расширение с открытым исходным кодом, функционирующее на платформах Windows, Mac OS X, Linux, Windows Mobile и Android. Оно эмулирует в старых браузерах некоторые из новых функций, в частности API геолокации. Этот интерфейс отличается от стандартизованного W3C, но служит тем же целям.

Раз уж мы заговорили о наследуемой функциональности платформ, отмечу, что мобильные аппараты, построенные на платформах BlackBerry, Nokia, Palm и OMTP BONDI, имеют собственные API геолокации. Разумеется, все эти прикладные интерфейсы отличаются от интерфейса Gears, который, в свою очередь, отличается от W3C API геолокации. Как же быть?..

На помощь спешит geo.js

Сценарий geo.js (http://code..google..com/p/geo-location-javascript/) — это JavaScript-

библиотека, распространяемая под лицензией MIT с открытым исходным кодом. Она позволяет сглаживать различия между W3C API геолокации, API приложения Gears и разнообразными API мобильных платформ. Чтобы воспользоваться geo.js,

На помощь спешит geo..js

131

надо поместить в нижнюю часть страницы два сценария (строго говоря, их можно поместить в любую часть страницы, но если внедрить их в контейнер <head>, страница будет загружаться медленнее, так что не делайте этого).

Первый из этих сценариев — gears_init.js (http://code..google..com/apis/gears/ gears_init..js),инициализирующийGears,еслиэторасширениеустановлено.Второй — geo.js (http://geo-location-javascript..googlecode..com/svn/trunk/js/geo..js). Код страницы должен выглядеть приблизительно так:

<!DOCTYPE html> <html>

<head>

<meta charset="utf-8">

<title>Название моей страницы</title>

</head>

<body>

...

<script src=”gears_init.js”></script> <script src=”geo.js”></script>

</body>

</html>

Теперь вы готовы к использованию любого из доступных API геолокации:

if (geo_position_js.init()) { geo_position_js.getCurrentPosition(geo_success, geo_error);

}

Разберем этот код по порядку. Сначала надо явным образом вызвать функцию init(). Если поддерживается и доступен хотя бы один API геолокации, функция возвратит true:

if (geo_position_js.init()) {

Вызвав функцию init(), мы не устанавливаем местонахождение пользователя, а только удостоверяемся, что это возможно сделать. Чтобы перейти кделу, вызовем функцию getCurrentPosition():

geo_position_js.getCurrentPosition(geo_success, geo_error);

При вызове getCurrentPosition() браузер спросит пользователя, можно ли рассчитать и передать на сайт его координаты. В частности, при геолокации с помощью Gears появится окно с вопросом, разрешает ли пользователь сайту прибегнуть к функциональности Gears. При встроенной поддержке API геолокации в браузере окно будет выглядеть иначе (например, в Firefox 3.5, как вы уже видели, появляется информационная панель в верхней части страницы).

Функция getCurrentPosition() принимает в качестве аргументов две функции обратного вызова. Если с помощью getCurrentPosition() местонахождение пользователя было успешно найдено (то есть пользователь согласился на передачу данных и API геолокации благополучно исполнил запрос), то выполняется первая из переданных функций. В данном примере она называется geo_success:

geo_position_js.getCurrentPosition(geo_success, geo_error);

Соседние файлы в папке web - tec