Wprowadzenie do Geolokalizacji API
Polish (Polski) translation by Marta Szczypińska (you can also view the original English article)
Wprowadzenie
Od wielu lat papierowe mapy uważane są za zabytek. Zostały one zastąpione przez spełniające tę samą funkcję urządzenia GPS i aplikacje mobilne, które stały się praktycznie wszechobecne. Można je znaleźć w wyposażeniu aut, ale także, co ważniejsze, na tabletach i smartfonach.
Jedną z głównych cech charakterystycznych urządzeń nawigacyjnych jest wykrywanie i aktualizacja ich pozycji. Funkcja ta pomaga to użytkownikom w dotarciu z miejsca na miejsce poprzez wskazywanie kierunku jazdy.
Obecnie, mamy na tyle szczęścia, że geolokalizacja jest oryginalnie obsługiwana przez przeglądarki. W tym artykule skupimy się na Geolokalizacji API, pozwalającej aplikacjom na wykrywanie i śledzenie lokalizacji urządzeń.
Możliwość wykrycia aktualnej pozycji urządzenia ma szeroką gamę zastosowań. Przykładowo, w sieci firmy takie jak Google, Microsoft i Yahoo dostosowują stronę wyników wyszukiwania (ang. SERP) w zależności od aktualnego miejsca pobytu użytkownika. Lokalizacja jest kolejnym wspaniałym dodatkiem do geolokalizacji.
1. Geolokalizacja API- co to takiego?
Geolokalizacja API przypisuje interfejs wysokiego poziomu dla informacji o położeniu użytkownika (takich jak szerokość i długość geograficzna), powiązany z urządzeniem implementującym geolokalizację. Sam interfejs API nie jest powiązany ze źródłami informacji o lokalizacji.
Zwykle źródłami informacji o pozycji użytkownika są GPS, a także informacje zdobyte dzięki sygnałom sieci takim jak adres IP urządzenia, RFID (wykorzystywanie fal radiowych do przesyłu danych), Wi-Fi, Bluetooth, adres MAC, numer identyfikacyjny komórki w systemie GSM/CDMA, a także informacje wprowadzane przez użytkownika. Nie ma żadnej gwarancji, że API podaje aktualną lokalizację urządzenia.
Geolokalizacja API rekomendowana jest przez W3C, co oznacza, że jej specyfikacja jest stabilna. Można przyjąć, że ten stan nie ulegnie zmianie, chyba że będą trwały prace nad jej nową wersją. Warto zauważyć, iż w związku z tym, że Geolokalizacja API została opracowana niezależnie, oficjalnie nie jest ona częścią specyfikacji HTML5.
Teraz gdy już wiemy jakie potencjał posiada Geolokalizacja API, czas przekonać się jakie możliwości daje ona programistom.
Wdrażanie
Dokładność
Podczas wykrywania pozycji urządzenia API wykorzystuje wiele źródeł. Przykładowo, na laptopie lub komputerze stacjonarnym nieposiadających czipa z GPS, położenie urządzenia określane jest na podstawie adresu IP urządzenia, co oznacza, że lokalizacja podana przez API nie jest zbyt dokładna.
Jednakże na urządzeniach mobilnych, API może wykorzystać informacje z licznych, bardziej precyzyjnych źródeł, takich jak czip z GPS urządzenia, połączenie z siecią (Wi-Fi, 3G, HSPA+), system GSM/ transmisja CDMA telefonu.
Prywatność
Specyfikacja Geolokalizacji API opisuje także kwestie dotyczące prywatności i zezwoleń. Co więcej, wyraźnie wskazany jest wymóg uzyskania zgody użytkownika przed aktywacją API.
De facto oznacza to, że przeglądarka zobowiązana jest wyświetlić powiadomienie, w którym użytkownik proszony jest o wyrażenie zgody na włączenie API. Przykład takiego komunikatu dla użytkownika pokazany jest poniżej (Mapy Google).



API
API udostępnia trzy metody odnoszące się do obiektu window.navigator.geolocation
. Są to:
getCurrentPosition
watchPosition
clearWatch
Wykrywanie wsparcia przeglądarki
Podobnie jak w przypadku wielu innych interfejsów API bardzo łatwo sprawdzić, czy dana przeglądarka wspiera Geolokalizację API. Przyjrzyjmy się fragmentowi poniżej, w którym wykrywane jest wsparcie Geolokalizacji API.1 |
if (window.navigator && window.navigator.geolocation) { |
2 |
// I can watch you wherever you go...
|
3 |
} else { |
4 |
// Not supported
|
5 |
}
|
Lokalizowanie urządzenia
Aby wykryć lokalizację urządzenia, wywołujemy getCurrentPosition
lub watchPosition
, w zależności od potrzeb użytkownika. Obie metody służą do wykonania tego samego działania jedynie z kilkoma niewielkimi różnicami.
W celu uzyskania lokalizacji urządzenia getCurrentPosition
i watchPosition
zgłaszają asynchroniczne żądanie. Różnica między tymi metodami polega na tym, iż getCurrentPosition
dokonuje jednorazowej operacji, natomiast watchPosition
monitoruje lokalizację urządzenia pod kątem zmian i gdy to nastąpi, wysyła komunikat do aplikacji.
Geolokalizacja API jest na tyle inteligentna, by efektywnie wywoływać zwrotnie watchPosition
(gdy określono pozycję urządzenia), jeżeli zmieni się lokalizacja użytkownika.
Kolejną ważną różnicą pomiędzy getCurrentPosition
i watchPosition
jest zwracana wartość każdej metody. W przypadku pierwszej z nich (getCurrentPosition
), jest to wartość zerowa, podczas gdy watchPosition
zwraca identyfikator, który może zostać użyty do powstrzymania API przed monitorowaniem lokalizacji urządzenia poprzez funkcję clearWatch
.
Sygnatury getCurrentPosition
i watchPosition
wyglądają następująco:
1 |
// Get Current Position
|
2 |
getCurrentPosition(successCallback [, errorCallback [, options]]) |
3 |
|
4 |
// Watch Position
|
5 |
watchPosition(successCallback [, errorCallback [, options]]) |
Jak wskazują sygnatury, każda funkcja akceptuje trzy parametry. Jedynie pierwszy argument, funkcja successCallback, jest wymagany. Przyjrzyjmy się bliżej każdemu z argumentów.
-
successCallback
: ta funkcja wywołania zwrotnego uruchamiana jest po uzyskaniu lokalizacji użytkownika. Wywołanie zwrotne akceptuje obiektposition
, zawierający informacje o lokalizacji urządzenia. -
errorCallback
: funkcja ta jest uruchamiana w przypadku napotkania błędu. Wywoływany jest obiekterror
, zawierający informacje o rodzaju występującego błędu. -
options
: obiektoptions
daje programiście możliwość konfiguracji żądania asynchronicznego.
Aby zobaczyć, jak wykorzystać getCurrentPosition
i watchPosition
do uzyskania lokalizacji urządzenia spójrzmy na następujące fragmenty.
1 |
var geolocation = null; |
2 |
|
3 |
if (window.navigator && window.navigator.geolocation) { |
4 |
geolocation = window.navigator.geolocation; |
5 |
}
|
6 |
|
7 |
if (geolocation) { |
8 |
geolocation.getCurrentPosition(function(position) { |
9 |
console.log(position); |
10 |
});
|
11 |
|
12 |
var identifier = geolocation.watchPosition(function(position) { |
13 |
console.log(position); |
14 |
});
|
15 |
|
16 |
console.log(identifier); |
17 |
}
|
Zaprzestanie monitorowania lokalizacji
W poprzedniej sekcji wspomniałem o funkcji clearWatch
. Daje ona możliwość wstrzymania monitorowania lokalizacji urządzenia rozpoczętej przez wywołanie watchPosition
.
Funkcja clearWatch
akceptuje jeden wymagany argument, identyfikator zwracany do nas po wywołaniu watchPosition
.
Teraz gdy opisaliśmy już detale techniczne Geolokalizacji API, nadszedł czas na zgłębienie obiektów position
, error
i options
zwracanych przez Geolokalizację API.
Informacje o lokalizacji
Position
Metody zademonstrowane przez Geolokalizację API akceptują lub zwracają trzy rodzaje obiektów. Pierwszy obiekt, którym się zajmiemy to position
, zawierający interesujące nas informacje o lokalizacji. Spójrzmy na tabelę poniżej, aby zorientować się jakie informacje zawiera ten obiekt.
Obiekt position zwracany z efektywnego wywołania zwrotnego getCurrentPosition
i watchPosition
zawiera właściwości timestamp
i coords
. Coords
to obiekt zawierający dane lokalizacji takie jak: szerokość geograficzna, długość geograficzna, wysokość, dokładność, precyzyjność wysokości, kierunek i prędkość (latitude
, longitude
, altitude
, accuracy
, altitudeAccuracy
, heading
i speed
).
Większość przeglądarek nie zwraca wartości dla właściwości altitude
, altitudeAccuracy
, heading
i speed
. Jednakże, urządzenia mobilne takie jak smartfony i tablety dostarczają dokładniejsze informacje dzięki obecności czipa GPS lub innego sprzętu pomagającego w wykrywaniu lokalizacji urządzenia.
Właściwość timestamp
podaje czas wykrycia lokalizacji, co może być użyteczne, jeżeli potrzebna jest informacja, jak aktualne są zwrócone dane.
PositionError
Obiekt error
z wywołania zwrotnego błędu, drugi dodatkowy argument getCurrentPosition
i watchPosition
, ma właściwości code
i message
.
Właściwość message
krótko opisuje rodzaj błędu. Właściwość code
może mieć jedną z czterech wartości:
-
0
: Żądanie nie powiodło się z nieznanych przyczyn. -
1
: Żądanie nie powiodło się, ponieważ użytkownik nie wyraził zgody na użycie lokalizacji urządzenia. -
2
: Żądanie nie powiodło się ze względu na błąd sieci. -
3
: Żądanie nie powiodło się przez zbyt długi czas potrzebny na rozpoznanie pozycji urządzenia.
PositionOptions
Opcjonalny trzeci argument getCurrentPosition
i watchPosition
to obiekt PositionOptions
, umożliwiający programiście dostosowanie żądania asynchronicznego.
Obiekt PositionOptions aktualnie wspiera trzy opcje:
-
enableHighAccuracy
: jeżeli ustawiona wartość totrue
, strona internetowa lub aplikacja wskazuje, że chce uzyskać najlepszy możliwy (najdokładniejszy) rezultat. Może to skutkować wolniejszym czasem odpowiedzi lub zwiększonym zużyciem energii. Wartość domyślna tofalse
. -
timeout
: ta właściwość określa maksymalną ilość milisekund, po których upływie żądanie uważane jest za nieaktualne. Wartość domyślna toInfinity
. -
maximumAge
: gdy żądanie określenia lokalizacji powiodło się, przeglądarka zapisuje rezultaty w pamięci podręcznej do wykorzystania później. WłaściwośćmaximumAge
określa czas, po którego upływie pamięć podręczna musi zostać unieważniona. Wartość domyślna to0
co oznacza, że żądanie nie powinno być zapisywane w pamięci podręcznej.
Wsparcie przeglądarki
Wsparcie Geolokalizacji API jest na wysokim poziomie zarówno w przypadku przeglądarek na komputerze jak i na urządzeniach mobilnych. Spójrzmy na podsumowanie poniżej aby przekonać się które przeglądarki na PC wspierają Geolokalizację API:
- Firefox 3.5+
- Chrome 5.0+
- Safari 5.0+
- Opera 10.60+
- Internet Explorer 9.0+
Wsparcie dla przeglądarek mobilnych jest nawet lepsze, jak możecie zobaczyć w podsumowaniu:
- Android 2.0+
- iPhone 3.0+
- Opera Mobile 10.1+
- Symbian (S60 trzeciej i piątej generacji)
- Blackberry OS 6
Geolokalizacja API jest wspierana przez wiele przeglądarek. Być może zastanawiasz się co zrobić, jeżeli zetkniesz się z przeglądarką, która nie wspiera Geolokalizacji API. Możesz wierzyć lub nie, istnieje wiele łatek i podkładek, których zadaniem jest rozwiązanie tego problemu. Godne odnotowania są rozwiązania stworzone przez Manuela Bieha oraz niewielka podkładka autorstwa Paula Irisha.
Demonstracja
Teraz gdy poznaliśmy już Geolokalizację API na wylot, nadszedł czas, aby ujrzeć ją w akcji. Ta wersja demonstracyjna jest w pełni funkcjonalna i wykorzystuje wszystkie metody i obiekty opisane w artykule. Cel jest prosty, za każdym razem, gdy wykonane zostaje żądanie wykrycia lokalizacji urządzenia, dane o lokalizacji przedstawione są użytkownikowi w formacie listy.
Ta demonstracja zawiera trzy przyciski, pozwalające na wybór operacji która ma zostać wykonana. Demonstracja wykrywa także, czy przeglądarka wspiera Geolokalizację API. Jeżeli nie, wyświetlona zostanie wiadomość "API nieobsługiwane" i przyciski zostają wyłączone.
Kod źródłowy demonstracji pokazany jest poniżej, ale możesz także wypróbować wersję demo Geolokalizacji API.
1 |
<!DOCTYPE html>
|
2 |
<html>
|
3 |
<head>
|
4 |
<meta charset="UTF-8"> |
5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
6 |
<meta name="author" content="Aurelio De Rosa"> |
7 |
<title>Geolocation API Demo by Aurelio De Rosa</title> |
8 |
<style>
|
9 |
*
|
10 |
{
|
11 |
-webkit-box-sizing: border-box; |
12 |
-moz-box-sizing: border-box; |
13 |
box-sizing: border-box; |
14 |
}
|
15 |
|
16 |
body
|
17 |
{
|
18 |
max-width: 500px; |
19 |
margin: 2em auto; |
20 |
padding: 0 0.5em; |
21 |
font-size: 20px; |
22 |
}
|
23 |
|
24 |
h1
|
25 |
{
|
26 |
text-align: center; |
27 |
}
|
28 |
|
29 |
.hidden
|
30 |
{
|
31 |
display: none; |
32 |
}
|
33 |
|
34 |
.buttons-wrapper
|
35 |
{
|
36 |
text-align: center; |
37 |
}
|
38 |
|
39 |
.button-demo
|
40 |
{
|
41 |
padding: 0.5em; |
42 |
margin: 1em auto; |
43 |
}
|
44 |
|
45 |
.g-info
|
46 |
{
|
47 |
font-weight: bold; |
48 |
}
|
49 |
|
50 |
#log
|
51 |
{
|
52 |
height: 200px; |
53 |
width: 100%; |
54 |
overflow-y: scroll; |
55 |
border: 1px solid #333333; |
56 |
line-height: 1.3em; |
57 |
}
|
58 |
|
59 |
.author
|
60 |
{
|
61 |
display: block; |
62 |
margin-top: 1em; |
63 |
}
|
64 |
</style>
|
65 |
</head>
|
66 |
<body>
|
67 |
<h1>Geolocation API</h1> |
68 |
<div class="buttons-wrapper"> |
69 |
<button id="button-get-position" class="button-demo">Get current position</button> |
70 |
<button id="button-watch-position" class="button-demo">Watch position</button> |
71 |
<button id="button-stop-watching" class="button-demo">Stop watching position</button> |
72 |
</div>
|
73 |
|
74 |
<span id="g-unsupported" class="hidden">API not supported</span> |
75 |
|
76 |
<h2>Information</h2> |
77 |
<div id="g-information"> |
78 |
<ul>
|
79 |
<li>
|
80 |
Your position is <span id="latitude" class="g-info">unavailable</span>° latitude, |
81 |
<span id="longitude" class="g-info">unavailable</span>° longitude (with an accuracy of |
82 |
<span id="position-accuracy" class="g-info">unavailable</span> meters) |
83 |
</li>
|
84 |
<li>
|
85 |
Your altitude is <span id="altitude" class="g-info">unavailable</span> meters |
86 |
(with an accuracy of <span id="altitude-accuracy" class="g-info">unavailable</span> meters) |
87 |
</li>
|
88 |
<li>You're <span id="heading" class="g-info">unavailable</span>° from the True north</li> |
89 |
<li>You're moving at a speed of <span id="speed" class="g-info">unavailable</span>° meters/second</li> |
90 |
<li>Data updated at <span id="timestamp" class="g-info">unavailable</span></li> |
91 |
</ul>
|
92 |
</div>
|
93 |
|
94 |
<h3>Log</h3> |
95 |
<div id="log"></div> |
96 |
<button id="clear-log" class="button-demo">Clear log</button> |
97 |
|
98 |
<small class="author"> |
99 |
Demo created by <a href="http://www.audero.it">Aurelio De Rosa</a> |
100 |
(<a href="https://twitter.com/AurelioDeRosa">@AurelioDeRosa</a>) |
101 |
</small>
|
102 |
|
103 |
<script>
|
104 |
window.navigator = window.navigator || {}; |
105 |
window.navigator.geolocation = window.navigator.geolocation || |
106 |
undefined; |
107 |
if (navigator.geolocation === undefined) { |
108 |
document.getElementById('g-unsupported').classList.remove('hidden'); |
109 |
['button-get-position', 'button-watch-position', 'button-stop-watching'].forEach(function(elementId) { |
110 |
document.getElementById(elementId).setAttribute('disabled', 'disabled'); |
111 |
});
|
112 |
} else { |
113 |
var log = document.getElementById('log'); |
114 |
var watchId = null; |
115 |
var positionOptions = { |
116 |
enableHighAccuracy: true, |
117 |
timeout: 10 * 1000, // 10 seconds |
118 |
maximumAge: 30 * 1000 // 30 seconds |
119 |
};
|
120 |
|
121 |
function success(position) { |
122 |
document.getElementById('latitude').innerHTML = position.coords.latitude; |
123 |
document.getElementById('longitude').innerHTML = position.coords.longitude; |
124 |
document.getElementById('position-accuracy').innerHTML = position.coords.accuracy; |
125 |
|
126 |
document.getElementById('altitude').innerHTML = position.coords.altitude ? position.coords.altitude : |
127 |
'unavailable'; |
128 |
document.getElementById('altitude-accuracy').innerHTML = position.coords.altitudeAccuracy ? |
129 |
position.coords.altitudeAccuracy : |
130 |
'unavailable'; |
131 |
document.getElementById('heading').innerHTML = position.coords.heading ? position.coords.heading : |
132 |
'unavailable'; |
133 |
document.getElementById('speed').innerHTML = position.coords.speed ? position.coords.speed : |
134 |
'unavailable'; |
135 |
|
136 |
document.getElementById('timestamp').innerHTML = (new Date(position.timestamp)).toString(); |
137 |
|
138 |
log.innerHTML = 'Position succesfully retrieved<br />' + log.innerHTML; |
139 |
}
|
140 |
|
141 |
function error(positionError) { |
142 |
log.innerHTML = 'Error: ' + positionError.message + '<br />' + log.innerHTML; |
143 |
}
|
144 |
|
145 |
document.getElementById('button-get-position').addEventListener('click', function() { |
146 |
navigator.geolocation.getCurrentPosition(success, error, positionOptions); |
147 |
});
|
148 |
|
149 |
document.getElementById('button-watch-position').addEventListener('click', function() { |
150 |
watchId = navigator.geolocation.watchPosition(success, error, positionOptions); |
151 |
});
|
152 |
|
153 |
document.getElementById('button-stop-watching').addEventListener('click', function() { |
154 |
if (watchId !== null) { |
155 |
navigator.geolocation.clearWatch(watchId); |
156 |
log.innerHTML = 'Stopped watching position<br />' + log.innerHTML; |
157 |
}
|
158 |
});
|
159 |
|
160 |
document.getElementById('clear-log').addEventListener('click', function() { |
161 |
log.innerHTML = ''; |
162 |
});
|
163 |
}
|
164 |
</script>
|
165 |
</body>
|
166 |
</html>
|
167 |
Podsumowanie
W tym artykule, dowiedzieliśmy się, czym jest Geolokalizacja API, oraz jak i kiedy jej użyć.
Geolokalizacja API jest użytecznym narzędziem służącym do poprawy wrażeń użytkownika i może być użyta do różnych celów. Wsparcie przeglądarek nie stanowi na ogół problemu, warto jednak pamiętać, że starsze wersje Internet Explorera nie zapewniają wsparcia Geolokalizacji API.
Jak wspomnieliśmy w artykule, musicie zdawać sobie sprawę, że niektóre dane lokalizacji takie jak speed
, altitude
i heading
nie zawsze są dostępne. Pamiętajcie także, aby rozsądnie używać Geolokalizacji API, jako że wymaga ona sporo mocy akumulatora, zwłaszcza na urządzeniach mobilnych wyposażonych w czipa GPS.