La géolocalisation avec Javascript - sans JQuery et Cie

Par Alan Pilloud
Publié le 5 février 2017

Les navigateurs embarquent une API de geolocalisation qui permet de récupérer votre position avec précision.

Dans ce court article, nous allons voir comment récupérer les informations de géolocalisation du navigateur et les comparer à d’autres points.

En premier, vous pouvez tester ce code pour voir un exemple de ce qu’il est possible de faire.

Le support sur les différents navigateurs est excellent ( voir sur caniuse.com ), mais on peut désactiver la fonctionnalité dans l’éventualité où l’API n’est pas disponible.

Tester si la géolocalisation est disponible est très simple :

if (navigator.geolocation) {
    // do stuff here... add a button, for instance
}

On récupère la position du navigateur

Il suffit d’une fonction pour récupérer la position du navigateur. navigator.geolocation.getCurrentPosition reçoit deux fonctions et un objet d’options en paramètre.

La première fonction reçoit la position et est exécutée en cas de succès.

La seconde fonction gère les erreurs, par exemple si l’utilisateur a désactivé la géolocalisation ou si pour une raison technique, la position ne peut être obtenue.

L’objet d’options permet de paramétrer trois options :

  • enableHighAccuracy: défaut à false. Si true, le navigateur essaie d’avoir la meilleure précision possible. Cela peut entraîner un temps de réponse plus lent.
  • timeout: défaut à Infinity. On peut spécifier un temps d’attente maximum en millisecondes. Il est très important de définir une valeur limite à ce paramètre. De cette sorte, on est sûr de recevoir une erreur si l’obtention de la position prend trop de temps.
  • maximumAge: défaut à 0. La réponse peut être mise en cache pour un temps indiqué en millisecondes.

Voici une fonction qui trouve les coordonnées du navigateur après avoir obtenu l’autorisation de l’utilisateur :

var myPosition = null;

function getLocation() {
    navigator.geolocation.getCurrentPosition((position) => {
        // return the coordinates
        myPosition = position.coords;
    }, (error) => {
        // check if the user denied geolocation, or if there was any other problem
        if (error.code == error.PERMISSION_DENIED) {
            alert('Geolocation has been disabled on this page, please review your browser\'s parameters');
        } else {
            alert('Unable to find your position, try again later.');
        }
    }, {
        timeout: 10000
    });
}

Comparer des points géolocalisés

Voici comment on compare le point récupéré à une liste d’autres points.

Cela permet par exemple de fournir une fonctionnalité du type “10 restaurants se trouvent autour de vous”.

const points = [
    { name: 'Lausanne', lat: 46.534271, lng: 6.620206 },
    { name: 'Zürich', lat: 47.381583, lng: 8.531827 },
    { name: 'Le Mans', lat: 48.001837, lng: 0.194578 },
    { name: 'Montpellier', lat: 43.624121, lng: 3.871447 },
    { name: 'Münich', lat: 48.140408, lng: 11.586595 },
    { name: 'Mexico', lat: 19.427701, lng: -99.266023 },
    { name: 'Buenos Aires', lat: -34.422808, lng: -58.572664 },
    { name: 'Brasilia', lat: -15.792772, lng: -47.883031 },
    { name: 'Yaoundé', lat: 3.875265, lng: 11.487751 },
    { name: 'Oklahoma City', lat: 35.509992, lng: -97.539860 },
    { name: 'Québec', lat: 45.502601, lng: -73.589665 }
];

/**
 * Filter the list in the given radius in km
 */
function filterPoints(radius) {
    // don't do anything else until we have a position
    if (myPosition == null) {
        return false;
    }

    // return only the points in the area
    return points.filter((point) => calculateDistance(myPosition.latitude, myPosition.longitude, point.lat, point.lng) <= radius );
}

Et finalement, le coeur de cette comparaison, c’est la fonction calculateDistance que voici :

function calculateDistance(lat1, long1, lat2, long2) {
    var p = 0.017453292519943295;    // Math.PI / 180
    var c = Math.cos;
    var a = 0.5 - c((lat2 - lat1) * p)/2 +
        c(lat1 * p) * c(lat2 * p) *
        (1 - c((long2 - long1) * p))/2;

    return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

On fournit les paramètres requis, soit les coordonnées des deux points à comparer et on obtient une distance en kilomètres.

Conclusion, la geolocalisation en frontend, c’est la classe =)

Filtrer des points en frontend est un joli plus pour une expérience utilisateur la plus immédiate possible.

Bien sûr, je vous ai mis un exemple fonctionnel ici : Filtrer des points selon votre localisation

Si vous avez aimé cet article, je serais heureux que vous le partagiez et je vous en remercie par avance. De plus, si vous avez des questions, n’hésitez pas à me contacter sur Twitter.

Envie d'en parler ?

Ecrivez un email ou DM sur twitter