W dzisiejszym wpisie, tak jak obiecałem w ostatnio, przedstawię API geolokacyjne wprowadzone wraz z pojawieniem się HTML5. Poznamy więc metody określania pozycji użytkownika, a także sposoby na śledzenie jego przemieszczania się. Dowiemy się także, jakie błędy mogą wystąpić podczas pobierania pozycji i jak je obsłużyć. Pokażę również, jak można pokazać pobrane współrzędne jako punkt na mapie w google maps.

Aktualnie API geolokacyjne obsługiwane jest przez większość nowoczesnych przeglądarek. Co oczywiste jest ona też świetnie wspierana przez przeglądarki dostępne na urządzeniach mobilnych - na urządzeniach tych bardzo często dostępny jest moduł GPS, który znacznie poprawia wyniki określania pozycji (do określania współrzędnych używa się też WiFi a także geolokacji na podstawie adresu IP, które są oczywiście mniej dokładne).

Z racji tego, że udostępnienie współrzędnych użytkownika wiąże się z możliwością naruszenia jego prywatności, pobranie współrzędnych nie jest możliwe dopóki użytkownik na to nie pozwoli (podczas pierwszej próby wyświetlany jest przez przeglądarkę odpowiedni komunikat wraz z pytaniem o zgodę).

Dość tego przydługiego wstępu, przejdźmy do konkretów! ;)

Metody getCurrentPosition oraz watchPosition

Obie “bohaterki” tego paragrafu to właściwie podstawa całego API - pierwsza służy do określania aktualnej pozycji użytkownika jednorazowo, druga natomiast po pobraniu współrzędnych nie przestaje ich monitorować, dzięki czemu mamy możliwość śledzenia ruchu użytkownika (wywołanie tej metody zwraca ‘watchID’ - jest to identyfikator procesu obserwacji, dzięki któremu możemy się do niego później odwoływać).

Poniżej parametry przyjmowane przez obie metody (jedną i drugą wywołuje się z takimi samymi parametrami; w nawiasach kwadratowych parametry opcjonalne):

  • successCallback - jako pierwszy parametr podajemy nazwę funkcji, która wywołana zostanie gdy sprawdzanie współrzędnych zakończy się powodzeniem
  • [errorCallback] - na drugim miejscu możemy zarejestrować wywołanie zwrotne funkcji odpowiedzialnej za obsługę błędów
  • [options]- ostatni parametr to obiekt, w którym możemy ustawić trzy właściwości:
    • enableHighAccuracy - ustawiając tę właściwość na ‘true’ możemy określić, że pożądane jest określenie jak najdokładniejszych wyników - może to spowolnić uzyskanie wyników, a także spowodować większy pobór energii przez moduł GPS; domyślną wartością jest ‘false’
    • timeout - maksymalny czas oczekiwania na odpowiedź; domyślna wartość to 0 czyli wartość nieustalona
    • maximumAge - maksymalny czas życia (w milisekundach) zbuforowanej pozycji jaki jest możliwy do zaakceptowania; domyślnie 0 co oznacza, że pozycja ma zostać pobrana natychmiast

Poniżej prosty przykład użycia metody ‘getCurrentPosition()’:

function getCoordinates() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(alertPosition);
    } else {
        alert('twoja przeglądarka nie wspiera geolokacji...');
    }
}

function alertPosition(position)
{
    alert('szer. geogr.: ' + position.coords.latitude +
        ', długość geogr.: ' + position.coords.longitude);
}

Na początek przyjrzyjmy się drugiej linii powyższego kodu - w ten sposób możemy sprawdzić, czy przeglądarka wspiera w ogóle geolokację. Jeśli tak, wówczas wywoływana jest metoda ‘getCurrentPosition()’, która jako parametr przekazujemy nazwę metody “callback’a”.

Opcje koordynat

W linii dziewiątej widzimy definicję funkcji ‘alertPosition()’ - to ona właśnie wykona się po pobraniu pozycji użytkownika. Jak widać, jako parametr, pozyskuje ona obiekt ‘Position’, który z kolei zawiera obiekt ‘Coords’. To on posiada wszystkie pobrane informacje o geolokacji użytkownika (w przykładzie widzimy wykorzystanie informacji o długości i szerokości geograficznej). Poniżej opis wszystkich dostępnych informacji:

  • coords.latitude - współrzędna szerokości geograficznej (w postaci ułamka dziesiętnego)
  • coords.longitude - współrzędna długości geograficznej (również ułamek)
  • coords.altitude - wysokość nad poziomem morza (w metrach)
  • coords.accuracy - dokładność zwróconego wyniku w metrach
  • coords.altitudeAccuracy - dokładność zwróconej wysokości w metrach
  • coords.heading - kierunek podróży, w stosunku do północy
  • coords.speed - prędkość w metrach na sekundę
  • timestamp - znacznik czasu, mówiący o tym kiedy pozycja została uzyskana

Tylko trzy pierwsze z wymienionych właściwości jest gwarantowana (pozostałe mogą mieć wartość ‘null’, dlatego lepiej jest sprawdzić to przed ich użyciem).

Metoda clearWatch

Funkcja ta ma zastosowanie, jeli wcześniej użyta została metoda ‘watchPosiotion()’ - zachowuje ona informacje o lokalizacji i dokonuje stałych ich aktualizacji jeśli użytkownik się przemieszcza. Czasem jednak, chcielibyśmy zatrzymać śledzenie użytkownika - tutaj właśnie z pomocą przychodzi nam funkcja ‘clearWatch()’. Przyjmuje ona jako parametr wejściowy wartość ‘watchID’, którą uzyskano wcześniej wywołując metodę ‘watchPosition()’.

Obsługa błędów

Tak jak wspomniałem wcześniej, drugi parametr metody ‘getCurrentPosition’ (oraz ‘watchPosition’) definiuje funkcję odpowiedzialną za obsługę błędów. Poniżej przykład takiej funkcji:

function alertError(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED:
            alert("Użytkownik nie zgodził się na geolokację");
            break;
        case error.POSITION_UNAVAILABLE:
            alert("Informacje o współrzędnych są niedostępne");
            break;
        case error.TIMEOUT:
            alert("Przekroczenie czasu oczekiwania na współrzędne");
            break;
        case error.UNKNOWN_ERROR:
            alert("Wystąpił nieznany błąd");
            break;
    }
}

Oczywiście, poszczególne błędy trzeba by obsłużyć w bardziej elegancki sposób… Widać jednak, że poszczególne kody błędów dostępne są w obiekcie ‘Error’ przekazanym jako parametr funkcji, poprzez jego właściwość ‘code’.

Zaznaczanie pozycji na mapie

Na koniec jeszcze obiecany przykład tego, w jaki sposób możemy zaznaczyć uzyskane dzięki API geolokacji wyniki na mapie (w tym przypadku będzie to mapa google ale inne systemy map, również dostarczają swoje API, które możemy wykorzystać).

Aby pokazać jak dokonać zaznaczenia na mapie, zmodyfikujmy metodę ‘alertPostion()’ z pierwszego przykładu:

function alertPosition(position) {
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;

    var coords = new google.maps.LatLng(latitude, longitude);

    var mapOptions = {
        zoom: 10,
        center: coords,
        mapTypeControl: true,
        navigationControlOptions: {
            style: google.maps.NavigationControlStyle.SMALL
        },
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(
        document.getElementById('container'), mapOptions
    );

    var marker = new google.maps.Marker({
                      position: coords,
                      map: map,
                      title: 'Your current location!';
    });
}

Na początku pobieramy współrzędne z obiektu ‘Posiotion’. Następnie tworzymy, za pomocą API google’a, obiekt ‘Coords’. Kolejna rzecz to zdefiniowanie opcji mapy - ustawiamy początkowe przybliżenie, koordynaty miejsca na które ma być wycentrowana mapa (czyli współrzędne użytkownika), decydujemy czy umożliwić zmianę typu mapy (zwykła mapa czy widok satelitarny), definiujemy styl kontrolek sterowania mapy oraz typ mapy. Kiedy mamy już zdefiniowane opcje, możemy utworzyć samą mapę - linie od siedemnastej do dziewiętnastej - jak widać, korzystamy z API google’a, podając element kontenera (na przykład <div>), oraz zdefiniowane wcześniej opcje mapy. Na koniec definiujemy znaczek na mapie wskazujący pozycję użytkownika.

Podsumowanie

Tym postem dobrnęliśmy do końca kolejnego celu egzaminacyjnego jakim była implementacja API dostępnych w HTML5. W kolejnym wpisie, rozpoczniemy zapoznawanie się z zagadnieniami zasięgu (ang. scope) zmiennych i obiektów.

Jak zwykle zapraszam!