Geolocation Api

Geolocation Api to jedno z tych API, które nie mają nic wspólnego ze specyfikacją html5. Został opracowany przez organizację W3C, a nie WHATWG. Api pozwala dowiedzieć się o aktualnej pozycji użytkownika (za jego zgodą) oraz śledzić jego pozycję. Za jego pomocą można z łatwością usprawnić dowolne aplikacje wykorzystujące dane geograficzne. Funkcjonalność ta może być używana np. aby prowadzić kogoś do punktu docelowego. Może to być również wykorzystywane do tzw. geotagowania np. aby oznaczyć gdzie zostało zrobione zdjęcie. Całe api dotyczy obiektu geolocation, który znajduje się wewnątrz obiektu navigator. W celu sprawdzenia czy przeglądarka obsługuje geolokalizację można użyć poniższego kodu.

if (navigator.geolocation) {
  //geolokalizacja obsługiwana
}
else {
  //geolokalizacja nie jest obsługiwana
}
Ponadto na witrynie caniuse można sprawdzić jakie przeglądarki obsługują to api.
Geolocation Api oferuje metody pozwalające na uzyskiwanie informacji geograficznych od użytkownika:
  • getCurrentPosition - pozwala pobrać bieżącą pozycję użytkownika,
  • watchPosition - śledzi pozycję użytkownika. W celu sprawdzenia, czy nie uległa zmianie, sprawdza ją w regularnych odstępach czasu.
Jeśli użytkownik odwiedza serwis po raz pierwszy przeglądarka wyświetla okno dialogowe z pytaniem o zezwolenie na śledzenie jego lokalizacji. Obydwie z powyższych metod pobierają takie same parametry: funkcję obsługi sukcesu, funkcję obsługi błędów, opcje geolokalizacji. Poniżej najprostsze użycie api.
navigator.geolocation.getCurrentPosition(function (position) {
	// Sukces! tutaj jakieś działania na lokalizacji
});
Do funkcji obsługi sukcesu przekazywany jest obiekt position posiadający dwie właściwości: coords (współrzędne czyli to co nas najbardziej interesuje) oraz timestamp. Informacje zapisane w obiekcie coords to latitude, longitude i accuracy. Atrybut accuracy to miara dokładności pomiaru długości i szerokości geograficznej wyrażona w metrach. Informację tę możemy wykorzystać na przykład do pokazania promienia dokładności w przypadku prezentowania pozycji użytkownika na mapie. Dobrze zatem odczytajmy współrzędne położenia użytkownika.
navigator.geolocation.getCurrentPosition(function (position) {
	var coords = position.coords;
	alert('Twoje położenie to: '+coords.latitude+', '+coords.longitude);
});
Niestety nie wszystkie sprawdzenia lokalizacji są udane. Być może GPS nie może być zlokalizowany lub użytkownik nie zezwolił na określenie lokalizacji. Przeglądarka pyta się zawsze czy zezwolić na użycie pozycji użytkownika. Okienko pytające o udostępnienie danych o aktualnej pozycji Dobrą praktyką jest więc zaimplementowanie funkcji obsługi błędów. Funkcja obsługi błędów otrzymuje jeden argument z obiektem opisującym błąd pozycji. Obiekt ten ma dwie właściwości: code - kod błędu (0 - nieznany błąd, 1 - brak uprawnień, 2 - nie można znaleźć pozycji, 3 - timeout) oraz message. Dodajmy zatem funkcję obsługi błędu.
navigator.geolocation.getCurrentPosition(function (position) {
	var coords = position.coords;
	alert('Twoje położenie to: '+coords.latitude+', '+coords.longitude);
}, function(error) {
	alert('Wystąpił błąd '+error.code);
});
Trzecim argumentem metod getCurrentPosition i watchPosition są opcje geolokalizacji. Opcja enableHighAccuracy nakazuje urządzeniu podjęcie próby uzyskania dokładniejszego odczytu długości i szerokości geograficznej. W przypadku urządzeń przenośnych może to oznaczać wykorzystanie GPS. Domyślnie ten atrybut ma ustawioną wartość false. Atrybut timeout informuje procedurę geolokalizacyjną o tym, jak długo powinien czekać na pozycję, zanim wywoła procedurę obsługi błędu (odliczanie nie rozpoczyna się jednak, jeśli aplikacja czeka na potwierdzenie żądania przez użytkownika). W przypadku upływu limitu czasu kod błędu jest ustawiany na wartość 3. Domyślną wartością parametru timeout jest 0 co oznacza oczekiwanie w nieskończoność. Opcję maximumAge można wykorzystać do poinformowania przeglądarki o tym, czy mają być używane dane o pozycji, które zostały wcześniej zbuforowane. Jeśli żądanie nastąpi w czasie odległym o nie więcej niż maximumAge (w milisekundach), to zostanie zwrócona informacja z bufora i nie będzie wysłane nowe żądanie o ustalenie pozycji. Domyslną wartością parametru jest 0 (przeglądarka ustala pozycję przy każdym żądaniu).
Metoda watchPosition śledzi pozycję użytkownika. Podczas pracy z watchPosition przydatna może być też metoda clearWatch. Metoda watchPosition zwraca unikatowy identyfikator, który jest przekazywany do metody clearWatch w celu usunięcia określonej obserwacji. Można na przykład obliczyć dystans pomiędzy punktem startowym a końcowym wycieczki.
var start;
navigator.geolocation.getCurrentPosition(function (position) {
	start = position;
}, function(error) {
	alert('Wystąpił błąd '+error.code);
});
navigator.geolocation.watchPosition(function(position) {
	distanceHaversine(start.coords.latitude, start.coords.longitude,
	position.coords.latitude, position.coords.longitude);
});
Przykładowa funkcja obliczająca odległość między dwoma punktami.
function rad(x)
{
	return x*Math.PI/180;
}

function distanceHaversine(p1, p2) 
{
	var R = 6371;//km
	var dLat  = rad(p2.lat() - p1.lat());
	var dLong = rad(p2.lng() - p1.lng());
	var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
	Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
	var d = R * c;
	return d.toFixed(3);//km
}
Przydatne linki:
Html5 Rocks
Developer Mozilla
Dive into html5