Navigator: Geolocation und getCurrentPosition (in Arbeit)

Javascript Geolocation getCurrentPosition

Geolocation ist die Basis für die Positionsbestimmung in mobilen Apps und unterliegt besonderen Vorkehrungen zur Wahrung der Privatsphäre: Bevor der Browser die Daten herausgibt, wird der Benutzer um Erlaubnis gefragt. getCurrentPosition() gibt die Koordinaten zurück.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Geolocation: Erlaubnis gefragt

Der Browser muss beim Besucher rückfragen, bevor er die Daten – Longitude und Latitude – herausgeben darf. Wenn der Benutzer die Auskunft verweigert, kommt eine Fehlermeldung zurück.

Abfrage, ob Geolocation zugelassen

Seit Chrome 50 funktioniert Geolocation nur noch auf HTTPS-Seiten. Auf unverschlüsselten Seiten (HTTP) liefert Geolocation keine Daten.

Auf dem iPhone kann es vorkommen, dass Safari bei getCurrentPosition () gar nicht erst nach Zustimmung fragt, weil in den Systemeinstellungen unter »Zugriff auf Standort erlauben« NIE eingestellt ist.

getCurrentPosition () hat drei Argumente: success, error und options. success und error sind Callback-Funktionen, options ist ein Objekt.

function geoSuccess (position) {
   console.log (position);
}

function geoError (error) {
   console.log (`Fehler: ${error.code} – ${error.message}`);
}

const options = {};

navigator.geolocation.getCurrentPosition (geoSuccess, 
                                          geoError, // optional
                                          options); // optional

position als Argument der Callback-Funktion übermittelt die Ortsdaten.


GeolocationPosition
coords: GeolocationCoordinates {latitude: 51.450906716087964, 
                                longitude: 6.628457044934238, 
                                altitude: null, 
                                accuracy: 35, …}
timestamp: 717259652883

Die optionalen Optionen sind:

maximumAgeMaximale Zeit in Millisekunden, in der die Position aus dem Cache akzeptabel ist.
timeoutMaximale Zeit in Millisekunden, in der die Position geliefert werden muss.
enableHighAccuracyEin Boolscher Wert: Bei true soll das Gerät eine höhere Präzision nutzen falls möglich.

Latitude / Longitude

Bei Desktop-Rechnern im Cityumfeld kann das WiFi zur Positionsbestimmung herangezogen werden und liefert bis auf ~25 (?) Meter akkurate Daten. Ortsinformationen auf IP-Basis sind weniger exakt. Die Höhe (altitude) kann beim stationären Rechner naturgemäß nicht bestimmt werden.

Mobilgeräte gleichen die Signale von drei Satelliten im GPS zeitlich ab (Lateration / Trilateration) und können unter freiem Himmel bis auf 5 bis 10 Meter genaue Standortdaten liefern. Die Abfrage braucht auf allen Geräten ein paar Sekunden:

function showPosition (position) {
	const latitude = position.coords.latitude;
	const  longitude = position.coords.longitude;
	const altitude = (position.coords.altitude) ? position.coords.altitude :' Keine Höhenangaben vorhanden ';

	const showgeo = document.getElementById('showgeo');
	showgeo.innerHTML = `Latitude  ${latitude}  <br> 
	                    Longitude  ${longitude} <br> 
	                    Wie hoch über 0?  ${altitude}  <br>
	                    Mehr oder weniger auf ${position.coords.accuracy}  Meter`;
};
		
document.getElementById('showgeo').onclick = function() {
 	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition (showPosition);
	} else {
		document.getElementById('showgeoinfo').innerHTML = 
			'Dieser Browser unterstützt die Abfrage der Geolocation nicht.';
	}
 }

Wer jetzt den Standort nicht als Latitude und Longitude braucht, sondern z.B. als Köln, Venlo oder Le Buffet du Jardin in Antananarivo auf Madagaskar, braucht etwas wie Nominatim – Reverse Search

https://nominatim.openstreetmap.org/reverse.php?format=html&lat=-18.9100122&lon=47.52558&zoom=18

geolocation.getCurrentPosition

navigator.geolocation.getCurrentPosition gibt den Standort zurück, wenn der Benutzer den Zugriff ausdrücklich erlaubt:

coords.latitude
Latitude als Dezimalzahl
coords.longitude
Longitude als Dezimalzahl
coords.altitude
Altitude – Meter über Meeresspiegel
coords.accuracy
Genauigkeit der Angaben
coords.altitudeAccuracy
Genauigkeit der Webweichung
coords.heading
Grad Abweichung von Nord
coords.speed
Meter pro Sekunden
timestamp
ein Date-Objekt

geolocation.watchPosition() und clearWatch

watchPosition() registriert einen Event Handler, der automatisch Positionsänderungen meldet. Am Skript ändert sich gegenüber der einfachen Frage nur wenig.

const watchZiel = {
	latitude: 12.34567890,
	longitude: 5.678901234
}

function watchPosition (position) {
   if (watchZiel.latitude === coords.latitude && watchZiel.longitude === coords.longitude) {
      console.log ("Ziel erreicht");
   }
}

function watchError (error) {
   console.log (`Fehler: ${error.code} – ${error.message}`);
}

const watchOptions = {
   enableHighAccuracy: true, // GPS nutzen falls verfügbar
   timeout: 5000, // Wartezeit 
   maximumAge: 0 // Position nicht aus dem Cache
}

navigator.geolocation.getCurrentPosition (watchPosition, watchError, watchZiel);

Mit dem Desktop-Rechner jetzt noch eine Runde durch die Stadt drehen, um das Skript zu testen …

Der Aufruf von clearWatch cancelt einen vorangegangenen Aufruf von watchPosition.

Leaflet

Leaflet ist eine JavaScript Open-Source JavaScript-Library, die Einsetzen von Markern in Karten einfach macht. Die Library kann entweder über ein CDN (Content Delivery Network) geladen oder auf den eigenen Webspace kopiert werden.

Auf der Startseite https://leafletjs.com zeigt Leaflet ein Beispiel, dass für den ersten Test so übernommen werden kann. Das Beispiel braucht ein HTML-div-Element mit id="map". Etwas CSS zum Element (width und height), und schon zeigt die Testseite einen Ort in London.

const map = L.map("map").setView([51.505, -0.09], 13);

Das große L ist das Leaflet-Objekt, die Leaflet-Methode setView () setzt die Karte auf den Ort mit der Longitude und Latitude sowie einen Zoomfaktor.

L.tileLayer () holt die Kacheln einer Karte – hier von Openstreetmap. Karten wie Openstreetmap und auch Google Maps sind in Kacheln eingeteilt, um die Ladezeit in Grenzen zu halten.

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
   attribution: `© 
       <a href="https://www.openstreetmap.org/copyright">
          OpenStreetMap</a> contributors` 
}).addTo(myMap);

Am Ende setzt L.marker () den Marker auf den Ort.

L.marker([51.5, -0.09]).addTo(map)
    .bindPopup('A pretty CSS popup.<br> Easily customizable.')
    .openPopup();

Die eigene Position einsetzen

Jedes API hat seine eigene Struktur. Das Leaflet-API beschreibt seine Methoden wie setView () und addTo () in der Dokumentation.

Um die eigene Position bzw. die Position eines Nutzers in der Karte anzuzeigen, beginnt das Skript mit der gleichen Anweisung wie das Leaflet-Beispiel, nur mit setView([0, 0],0) (vor der Westküste Afrikas und einem Zoomfaktor von 0).

const myMap = L.map('myLeafletMap').setView([0, 0], 0);

L.tileLayer können wir ohne Änderung übernehmen.

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
   attribution: `© 
       <a href="https://www.openstreetmap.org/copyright">
          OpenStreetMap</a> contributors` 
}).addTo(myMap);

Mit dem Zoomfaktor 0 zeigt die Karte die ganze Welt in einem Streifen. myMarker deklariert den Marker und setzt ihn vorab auf die Position 0,0.

const myMarker = L.marker ([0,0]).addTo (myMap);

function location (position) {
	const lat = position.coords.latitude;
	const lng = position.coords.longitude;
	myMarker.setLatLng ([lat, lng]).update();
	myMap.setView([lat, lng], 10);
}
navigator.geolocation.getCurrentPosition (location);

getCurrentPosition () ruft die Funktion location () auf, die Latitude und Longitude aus der Eigenschaft coords liest. Das sind die Werte, die L.marker () mit der Leaflet-Methode update () überschreiben.

Am Ende setzt setView () die Position des Markers in die Mitte der Karte und den Zoomfaktor auf 10.

Karte und GDPR – Privatsphäre

Jedes Mal, wenn ein Besucher die Seite mit der Karte besucht, wird die Karte von einem Kartenserver geladen und die IP des Besuchers geloggt. Ohne einen Hinweis auf die Weitergabe der Daten an den Kartenserver ist das ein Verstoß gegen die GDPR (General Data Protection Regulation).

Die CSS-Datei und das Leaflet-Skript können wir auf den eigenen Webspace laden, die Kacheln der Karte allerdings nicht. Vor dem Einspielen der Karte brauchen wir einen Hinweis, und damit der Nutzer nicht bei jedem Besuch erneut zustimmen muss, brauchen wir Cookies.

Entfernung zwischen zwei Orten

Mit den Standortangaben Latitude und Longitude kann Javascript die Entfernung zwischen zwei Orten berechnen – allerdings natürlich nur Luftlinie.

Kurz und einfach: Calculate distance, bearing and more between Latitude/Longitude points