Archiv:

Latest photoblog

photoblog

Blog » Geolocation

Geolib.js

I created a small JavaScript library to provide some basic geo functions like distance calculation, conversion of decimal coordinates to sexagesimal and vice versa, etc.

Usage:

To calculate distance between two geo coordinates
geolib.getDistance({"latitude": 51.511928, "longitude": 7.463536}, {"latitude": 51.510318, "longitude": 7.524133}, 10); // -> 4200 (Accuracy 10m)

Takes 2 or 3. First 2 arguments must be an object with a latitude and a longitude property (e.g. {latitude: 52.518611, longitude: 13.408056}). Coordinates can be in sexagesimal or decimal format. 3rd argument is accuracy (in meters). So a calculated distance of 1248 meters with an accuracy of 100 is returned as 1200.

Return value is always an integer and represents the distance in meters.

To convert it into miles use:
geolib.convertUnit('mi', value)

Convert sexagesimal to decimal
geolib.sexagesimal2decimal("51° 29' 46\" N"); // -> 51.49611111

Convert decimal to sexagesimal
geolib.decimal2sexagesimal(51.49611111); // -> 51° 29' 46.00

Download:
https://github.com/manuelbieh/geolib

Demo:
http://www.manuel-bieh.de/publikationen/scripts/geolib/demo.html

Geolocation jQuery-Plugin

I created a small jQuery plugin which acts as a simplification of the Geolocation API.

Instead of using navigator.geolocation.getCurrentPosition you can now just use the jQuery methods $.geolocation.get() or $.geolocation.watch().

Contrary to the standard API the only parameter the functions expect is a JSON object with three properties in no particular order: success, error, options. For success and error you can also use their alias properties „win“ and „fail“:
$.geolocation.get({win: function() {}, fail: function() {}, options);

You can also use $.geolocation.getCurrentPosition(success, error, options) to get native API feeling if this makes you happier. In conjunction with my Geolocation API polyfill script this also works with some non-standard Geolocation APIs like Google Gears or Blackberry Location.

Usage

$.geolocation.clearWatch(watchID)
Stops tracking of the user for the according watchID.
watchID (Integer)
$.geolocation.get(options)
Get the current position of the user
options (Object)

  • error
    Function to call if geolocation request failed
  • fail
    Alias for error
  • options
    Options for the geolocation request

    • enableHighAccuracy
    • maximumAge
    • timeout
  • success
    Function to call if geolocation request was successful
  • win
    Alias for success
$.geolocation.getCurrentPosition(success, error, options)
Get the current position of the user (API standard behavior)
success Function to call if geolocation request was successful
error Function to call if geolocation request failed
options Options for the geolocation request

  • enableHighAccuracy
  • maximumAge
  • timeout
$.geolocation.stop(watchID)
Stops tracking of the user for the according watchID.
watchID (Integer)
$.geolocation.stopAll()
Stops all watchPosition callbacks.
$.geolocation.watch(options)
Track the movement of the user
Returns: watchID (Integer)
options (Object)

  • error
    Function to call if geolocation request failed
  • fail
    Alias for error
  • options
    Options for the geolocation request

    • enableHighAccuracy
    • maximumAge
    • timeout
  • success
    Function to call if geolocation request was successful
  • win
    Alias for success
$.geolocation.watchPosition(success, error, options)
Track the movement of the user (API standard behavior)
Returns: watchID (Integer)
success Function to call if geolocation request was successful
error Function to call if geolocation request failed
options Options for the geolocation request

  • enableHighAccuracy
  • maximumAge
  • timeout

Examples

function alertMyPosition(position) {
	alert("Your position is " + position.coords.latitude + ", " + position.coords.longitude);
}
 
function noLocation(error) {
	alert("No location info available. Error code: " + error.code);
}
 
$('#getPositionButton').bind('click', function() {
	$.geolocation.get({win: alertMyPosition, fail: noLocation});
});
 
$('#watchPositionButton').bind('click', function() {
	// alertMyPosition is called each time the user's position changes
	myPosition = $.geolocation.watch({win: alertMyPosition}); 
});
 
$('#stopButton').bind('click', function() {
	$.geolocation.stop(myPosition);
});

Demo

http://manuel-bieh.de/publikationen/scripts/jquery/geolocation/

Download

https://github.com/manuelbieh/jQuery-Geolocation

Geolocation: und dein Browser weiß, wo du bist

Viele Web-Entwickler haben lange darauf gewartet, mit aktuellen Smartphones und auch neueren Browsern am Desktop ist es nun endlich möglich: die zielgenaue Ortung des Besuchers einer Website. Die W3C Geolocation API hilft dabei.

Damit wird es einem Seitenbetreiber nun ermöglicht – vorheriges Einverständnis des Besuchers vorausgesetzt – dessen aktuelle Position (Längengrad, Breitengrad, Höhenlage), die Reisegeschwindigkeit, sowie die Himmelsrichtung zu ermitteln und daran angelehnt entsprechend geolokalisierte Inhalte auszuliefern. Für einen Tankstellenbetreiber wäre es damit z.B. möglich, einen Tankstellenfinder zu realisieren, der dem Besucher die umliegenden Tankstellen inklusive Entfernung oder sogar eine genaue Wegbeschreibung auf dem Handy präsentiert. Auch eine Tracking-Anwendung, die bspw. die zurückgelegte Wegstrecke beim Joggen für die spätere Analyse am PC aufzeichnet, könnte so – ohne eine App zu installieren – mit dem Browser realisiert werden.

Anders als bei bisherigen Methoden wird dabei nicht ausschließlich auf die IP des anfragenden Clients geachtet, sondern es werden darüber hinaus Parameter wie umliegende öffentliche W-LAN SSIDs (inkl. Stärke des Empfangs) oder ein möglicherweise vorhandenes GPS-Modul abgefragt. Um datenschutzrechtliche Bedenken aus der Welt zu schaffen, wird der Benutzer beim Versuch einer Ortung jedoch vorab um Erlaubnis gefragt. Sollte dieser die Anfrage verneinen, ist der Zugriff auf den Standort über die API nicht möglich.

Wie bei den meisten Technologien, die sich gerade in den Kinderschuhen befinden, gibt es aber auch bei der Implementierung der Geolocation API leider noch einige Tücken. So unterstützen nicht alle Browser mit grundsätzlicher Unterstützung der Geolocation API auch alle Funktionen, die in der Spezifikation vorgesehen sind, und auch die Methoden, mit der die Daten abgefragt werden können, unterscheiden sich teilweise erheblich. Darüber hinaus nagt häufiges Orten bei mobilen Geräten, also Geräten ohne permanenten Strom-Anschluss, stark am jeweiligen Akku. Die Lokalisierung sollte also nicht unnötig oft oder mit einem übertrieben kurzen Intervall durchgeführt werden.

Zumindest um das Problem mit dem nicht einheitlichen Interface zu umgehen, gibt es einige frei nutzbare Open Source JavaScript Libraries, die ein vereinheitlichtes Interface zur Verfügung stellen, wie beispielsweise Geo-location-javascript oder Better Geolocation API.

Eine generelle Unterstützung des Standards, ob vollständig oder nicht, gibt es im Wesentlichen bisher in den folgenden Browsern bzw. Geräten:

  • Android Webkit und Dolphin HD
  • Apple iPhone/iPod Safari iOS 3.0+
  • Blackberry OS 4.1+
  • Firefox 3.5+ (< 3.5 mit installiertem Geode Addon)
  • Google Chrome
  • Opera 10.6+
  • Alle Browser mit installiertem Google Gears

Um eine Ortung in einem Browser durchzuführen, der den Standard korrekt implementiert, kann der folgende exemplarische Code verwendet werden:

var successCallback = function(position) {
    alert('Ihre Position: ' + position.coords.latitude + ', ' + position.coords.longitude);
}
 
var errorCallback = function(error) {
alert('Es konnte keine Ortung durchgeführt werden. Fehlercode: ' + error.code);
}
 
if(typeof (navigator.geolocation) != 'undefined') {
    navigator.geolocation.getCurrentPosition(
        successCallback,
        errorCallback,
        {
            enableHighAccuracy: true,
            maximumAge: 10000
        }
    );
}


Zur Erklärung: Mittels typeof(navigator.geolocation) != 'undefined' wird abgefragt, ob der Browser des Benutzers die Geolokalisierung unterstützt. Daraufhin wird die Methode getCurrentPosition() aufgerufen, welche versucht, die aktuelle Position des Benutzers zu ermitteln. Gelingt dies, wird die als successCallback angegebene Funktion aufgerufen und ein Objekt position übergeben. Dieses erhält dann in position.coords.longitude bspw. den ermittelten Längengrad in Dezimalform (z.B. 7.45333164).

Schlägt eine Ortung hingegen fehl, wird die als errorCallback angegebene Callback-Funktion aufgerufen. Als Übergabe gibt es hier das PositionError-Objekt, das gemäß Spezifikation die Zahlenwerte 0 (Unbekannter Fehler), 1 (Ortung nicht erlaubt), 2 (Position konnte nicht ermittelt werden) oder 3 (Timeout) enthalten kann.

Als dritter, zusätzlicher und zugleich optionaler Parameter kann noch ein Objekt in JSON-Notation angegeben werden, um die Eigenschaften der Abfrage genauer zu spezifizieren. Gültige Eigenschaften des Objekts sind:

  • enableHighAccuracy
  • maximumAge
  • timeout

Die Eigenschaft enableHighAccuracy soll sicherstellen, dass ein besonders genaues Ortungsergebnis erzielt wird. Dies geht allerdings, wie eingangs angesprochen, einerseits auf Kosten des Akkus, andererseits verzögert es die Ortung unter Umständen massiv. Im Gegenzug wird dafür die Fehleranfälligkeit sowie die Möglichkeit der Fehlortun verringert.

Über die Eigenschaft maximumAge kann festgelegt werden, wie alt das Ergebnis der letzten Ortung maximal sein darf (in Millisekunden), bevor eine erneute Ortung durchgeführt wird. Setzt man den Wert sehr hoch, ist das Ergebnis, sollte man sich in der Zeit seit der letzten Ortung bereits weit vom Ursprungsort weg bewegt haben, sehr ungenau. Setzt man es hingegen sehr niedrig an, geht das auch hier zu Lasten des Akkus. Einen empfehlenswerten Erfahrungswert gibt es hier nicht, da kommt es sehr auf den jeweiligen Anwendungsfall und etwas Fingerspitzengefühl an.
Mittels der dritten Eigenschaft, timeout, kann angegeben werden wie lange das Gerät bzw. der Browser probiert, die Position herauszufinden, bevor die errorCallback-Funktion mit dem Vermerk Timeout aufgerufen wird.

Neben der getCurrentPosition()-Methode, gibt es auch noch eine zweite Methode watchPosition(). Mit dieser Methode, die die gleichen Parameter erwartet wie auch getCurrentPosition(), ist es möglich, die Bewegung eines Benutzers zu verfolgen und die als successCallback definierte Funktion bei jeder Positionsänderung erneut aufzurufen. Um dieses Verhalten zu stoppen, muss die dritte und letzte Methode der API, clearWatch(), mit der Rückgabe-ID des watchPosition() Aufrufs aufgerufen werden.

Am konkreten Beispiel:

if(typeof (navigator.geolocation) != 'undefined') {
    var watchExample = navigator.geolocation.watchPosition(
        successCallback,
        errorCallback,
        {
            enableHighAccuracy: true, maximumAge: 10000
        }
    );
 
    // watchPosition wieder anhalten:
    navigator.geolocation.clearWatch(watchExample);
 
}

Die Geolocation API bietet eine sehr interessante Möglichkeit für Seitenbetreiber, die ihre Seite mit standortspezifischen Daten anreichern möchten. Man kann davon ausgehen, dass in Zukunft mehr mobile Geräte und mehr Browser den Standard korrekt unterstützen werden. Wenn die Hürden der Vereinheitlichung des Interfaces erst einmal genommen sind oder man sich mit den genannten Möglichkeiten weiterhilft, entstehen so viele neue Möglichkeiten, um das Web mit sinnvollen zusätzlichen Funktionen anreichern zu können. Der Kreativität des Web-Entwicklers sind dabei (fast) keine Grenzen gesetzt.

Dieser Artikel entstand im Rahmen des Webkrauts Adventskalenders und wurde dort am 3. Dezember 2010 erstveröffentlicht.

W3C Geolocation API Polyfill

Ich habe meine freie Zeit gerade etwas genutzt um ein Javascript zu erstellen, mit dem man aus dem Browser heraus auf eine einheitliche Geolocation API zugreifen kann. Aktuell unterstützt das Script offiziell die folgenden Browser:

  • Android Webkit
  • Android Dolphin HD
  • Apple iPhone/iPod Safari iOS 3.0+
  • Blackberry OS 4.1+
  • Firefox 3.5+
  • Firefox < 3.5 mit Geode Addon
  • Google Chrome
  • Opera 10.6+
  • Alle Browsers mit installiertem Google Gears

Andere Browser bieten zur Zeit keine Unterstützung für Geolocation (korrigiert mich bitte wenn ich einem Browser Unrecht tue).

Wie wird das Script verwendet?

Das Script muss einfach vor dem ersten Geolocation Request eines Dokuments mittels <script src="geolocation.js"></script> eingebunden werden. Danach kann einheitlich durch navigator.geolocation.* auf die Methoden aus dem W3C Standard zugegriffen werden. Namentlich sind das getCurrentPosition(), watchPosition() und clearWatch().

Das Script mappt dann die proprietären Abfragemethoden (Blackberry Location, Google Gears) auf das navigator.geolocation Objekt und stellt eine einheitliche API zur Abfrage bereit.

Demo

http://www.manuel-bieh.de/publikationen/scripts/geolocation/demo.html

Download

Das Script gibt es bei Github und auf Google Code. Zieht es euch dort, wo es euch lieber ist. Ich halte für gewöhnlich beide Versionen auf dem aktuellen Stand
Google Code: http://code.google.com/p/better-geolocation-api/
Github: https://github.com/manuelbieh/Geolocation-API-Polyfill

Es tut sich was, bei der Geolokalisierung

… wenn vielleicht auch nur langsam: bei insFX ist ein Artikel erschienen in dem schön beschrieben wird, was ich hier ja bereits öfters bemängelt hatte; nämlich die native Unterstützung der Standortermittlung im Browser.

Hier gehts es zum Artikel: Der iPhone-App Killer: Mobile Webbrowser bekommen endlich Zugriff auf die Geolocation! Und hier noch eine etwas ältere Ausführung von mir, von Anfang des Jahres, mit einigen Fragen und Wünschen: Einige Dinge die ich mich gelegentlich frage.

Dann dürfte es ja jetzt nur noch ein paar Jahre dauern, bis sowas vielleicht flächendeckend funktioniert, schön!