Prosty licznik podróży korzystający z interfejsu Geolocation API

Michael Mahemoff
Michael Mahemoff

Wstęp

Interfejs Geolocation API umożliwia sprawdzanie, gdzie znajduje się użytkownik, i monitorowanie go, gdy się porusza, zawsze za jego zgodą. Tę funkcję można wykorzystać w zapytaniach użytkowników, np. do nakierowania użytkownika do punktu docelowego. Można go również wykorzystać do „geotagowania” niektórych treści utworzonych przez użytkownika, na przykład w celu oznaczenia miejsca zrobienia zdjęcia. Interfejs API jest niezależna od urządzenia – nie ma znaczenia, jak przeglądarka określa lokalizację – o ile klienci mogą prosić o dane o lokalizacji i otrzymywać je w standardowy sposób. Mechanizm może wykorzystywać GPS lub Wi-Fi albo po prostu poprosić użytkownika o ręczne wpisanie lokalizacji. Ponieważ każde z tych wyszukiwań zajmie trochę czasu, interfejs API jest asynchroniczny. Za każdym razem, gdy prosisz o dostęp do lokalizacji, przekazujesz ją metodę wywołania zwrotnego.

Przykładem jest licznik podróży pokazujący początkową lokalizację i wyświetlający odległość, jaką pokonali od wczytania strony.

Krok 1. Sprawdź zgodność

Obsługa przeglądarek

  • 5
  • 12
  • 3,5
  • 5

Źródło

Zgodność możesz łatwo sprawdzić, testując obecność obiektu geolokalizacji:

// check for Geolocation support
if (navigator.geolocation) {
  console.log('Geolocation is supported!');
}
else {
  console.log('Geolocation is not supported for this Browser/OS version yet.');
}

Krok 2. Deklarowanie kodu HTML licznika podróży

W tym przykładzie tworzysz miernik podróży, więc zadeklaruj ten kod HTML:

<div id="tripmeter">
<p>
Starting Location (lat, lon):<br/>
<span id="startLat">???</span>°, <span id="startLon">???</span>°
</p>
<p>
Current Location (lat, lon):<br/>
<span id="currentLat">???</span>°, <span id="currentLon">???</span>°
</p>
<p>
Distance from starting location:<br/>
<span id="distance">0</span> km
</p>
</div>

W kilku następnych krokach do wypełnienia wszystkich pustych spanów użyjemy interfejsu Geolocation API.

Krok 3. Określanie bieżącej lokalizacji użytkownika

getCurrentPosition() będzie asynchronicznie raportować dane o bieżącej lokalizacji użytkownika. Wywołuj je natychmiast po wczytaniu strony, aby zapewnić prawidłowe wypełnienie pozycji początkowej i zapisanie na później:

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
});
};

Jeśli po raz pierwszy aplikacja w tej domenie prosi o uprawnienia, przeglądarka zwykle sprawdza zgodę użytkownika. W zależności od przeglądarki mogą być też dostępne ustawienia pozwalające na sprawdzanie uprawnień zawsze lub nie. W takim przypadku proces potwierdzania jest pomijany.

Po uruchomieniu tego kodu powinno być już widać pozycję początkową. W zależności od lokalizacji, z której korzysta przeglądarka, obiekt pozycji może zawierać znacznie więcej informacji niż tylko szerokość i długość geograficzną – np. wysokość lub kierunek. Możesz dokładniej zbadać ten problem, rejestrując zmienną pozycji w konsoli.

Krok 4. Obsługa błędów

Nie wszystkie wyszukiwania lokalizacji zakończyły się powodzeniem. Możliwe, że nie udało się zlokalizować odbiornika GPS lub nagle wyłączono wyszukiwanie lokalizacji. W przypadku błędu będzie wywoływany drugi, opcjonalny argument funkcji getCurrentPosition(), dzięki czemu możesz powiadomić użytkownika o tym w wywołaniu zwrotnym:

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
// same as above
}, function(error) {
alert('Error occurred. Error code: ' + error.code);
// error.code can be:
//   0: unknown error
//   1: permission denied
//   2: position unavailable (error response from locaton provider)
//   3: timed out
});
};

Krok 5. Monitorowanie lokalizacji użytkownika

Poprzednie wywołanie funkcji getCurrentPosition() zostało wykonane tylko raz podczas wczytywania strony. Aby śledzić zmiany, użyj narzędzia watchPosition(). Funkcja wywołania zwrotnego automatycznie powiadamia o każdym ruchu użytkownika:

navigator.geolocation.watchPosition(function(position) {
document.getElementById('currentLat').innerHTML = position.coords.latitude;
document.getElementById('currentLon').innerHTML = position.coords.longitude;
});

Krok 6. Pokaż przebyty dystans

Ten krok nie jest bezpośrednio związany z interfejsem Geolocation API, ale stanowi zakończenie prezentacji i pokazuje, w jaki sposób można wykorzystać dane o lokalizacji. Dodaj dodatkową linię do modułu obsługi watchPosition(), aby uzupełnić przebytą odległość:

navigator.geolocation.watchPosition(function(position) {
// same as above
document.getElementById('distance').innerHTML =
    calculateDistance(startPos.coords.latitude, startPos.coords.longitude,
                    position.coords.latitude, position.coords.longitude);
});

Funkcja calculateDistance() wykonuje algorytm geometryczny, aby określić odległość między 2 współrzędnymi. Implementacja JavaScriptu opiera się na skrypcie udostępnionym przez firmę Moveable Type na licencji Creative Commons:

function calculateDistance(lat1, lon1, lat2, lon2) {
var R = 6371; // km
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}