Google Maps Api v3 - trouver les marqueurs les plus proches


89

Lorsque je clique sur la carte, quel sera le meilleur moyen de trouver le ou les marqueurs les plus proches? y a-t-il des fonctions dans l'API qui m'aideront à le faire?

c'est google map api v3.


1
Utilisez-vous une base de données pour stocker les coordonnées des marqueurs?
Argiropoulos Stavros

bien sûr, les positions des marqueurs sont stockées dans la base de données mysql.
user198003

Réponses:


112

Vous devez d'abord ajouter l'écouteur d'événements

google.maps.event.addListener(map, 'click', find_closest_marker);

Créez ensuite une fonction qui parcourt le tableau de marqueurs et utilise la formule haversine pour calculer la distance de chaque marqueur à partir du clic.

function rad(x) {return x*Math.PI/180;}
function find_closest_marker( event ) {
    var lat = event.latLng.lat();
    var lng = event.latLng.lng();
    var R = 6371; // radius of earth in km
    var distances = [];
    var closest = -1;
    for( i=0;i<map.markers.length; i++ ) {
        var mlat = map.markers[i].position.lat();
        var mlng = map.markers[i].position.lng();
        var dLat  = rad(mlat - lat);
        var dLong = rad(mlng - lng);
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c;
        distances[i] = d;
        if ( closest == -1 || d < distances[closest] ) {
            closest = i;
        }
    }

    alert(map.markers[closest].title);
}

Cela garde la trace des marqueurs les plus proches et alerte son titre.

J'ai mes marqueurs sous forme de tableau sur mon objet cartographique


2
Ne pas ouvrir un vieux fil, mais j'ai essayé de l'implémenter, et il semble chercher vers l'est plutôt que de trouver le plus proche. Donc, si je recherche un emplacement, il cherchera à l'est et trouvera le plus proche de cette façon, même s'il y a une VRAIE fermeture à l'ouest. Cela a-t-il du sens?
LeeR

@Lee - cela a du sens, mais je ne peux pas reproduire le problème
Galen

1
Ouais, ça n'a pas du tout fonctionné pour moi - mettez-moi dans notre bureau en Californie et je suis à New York. Et il y a un marqueur à mon emplacement. Il a cependant trouvé un marqueur!
mheavers

@mheavers - Il y a une erreur dans le code. changement de (i = 1 à de (i = 0. Il n'incluait pas le premier marqueur.
Galen

1
@Magico vous ne pouvez pas transformer javascript en code php. vous pouvez écrire un wrapper php qui génère du code javascript comme dans la réponse. Si vous ne pouvez pas le faire vous-même, n'utilisez pas du tout php ...
Daniel W.


30

J'aimerais développer la suggestion de Leor pour quiconque ne sait pas comment calculer l'emplacement le plus proche et fournir une solution fonctionnelle:

J'utilise des marqueurs dans un markerstableau, par exemplevar markers = []; .

Alors prenons notre position comme quelque chose comme var location = new google.maps.LatLng(51.99, -0.74);

Ensuite, nous réduisons simplement nos marqueurs par rapport à l'emplacement que nous avons comme ceci:

markers.reduce(function (prev, curr) {

    var cpos = google.maps.geometry.spherical.computeDistanceBetween(location.position, curr.position);
    var ppos = google.maps.geometry.spherical.computeDistanceBetween(location.position, prev.position);

    return cpos < ppos ? curr : prev;

}).position

Ce qui ressort est votre LatLngobjet marqueur le plus proche .


1
réponse géniale!
Cesar Alonso

Réponse soignée et propre!
TheeBen

Cela pourrait-il être utilisé pour trier les marqueurs par distance, plutôt que d'en renvoyer un?
Louis W

Bien sûr @Louis, recherchez la méthode de filtrage. Vous pouvez l'utiliser pour les trier
Jonathan

1
Je l'ai fait fonctionner en supprimant la position sur l'objet de localisation; comme ceci: computeDistanceBetween (location, prev.position) ... car location est déjà un objet LatLng.
holm50

9

La formule ci-dessus n'a pas fonctionné pour moi, mais je l'ai utilisée sans aucun problème. Passez votre position actuelle à la fonction et parcourez un tableau de marqueurs pour trouver le plus proche:

function find_closest_marker( lat1, lon1 ) {    
    var pi = Math.PI;
    var R = 6371; //equatorial radius
    var distances = [];
    var closest = -1;

    for( i=0;i<markers.length; i++ ) {  
        var lat2 = markers[i].position.lat();
        var lon2 = markers[i].position.lng();

        var chLat = lat2-lat1;
        var chLon = lon2-lon1;

        var dLat = chLat*(pi/180);
        var dLon = chLon*(pi/180);

        var rLat1 = lat1*(pi/180);
        var rLat2 = lat2*(pi/180);

        var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
                    Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(rLat1) * Math.cos(rLat2); 
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
        var d = R * c;

        distances[i] = d;
        if ( closest == -1 || d < distances[closest] ) {
            closest = i;
        }
    }

    // (debug) The closest marker is:
    console.log(markers[closest]);
}

1
Comment remplissez-vous le markerstableau? Est-ce en créant un marqueur en utilisant var marker1 = new google.maps.Marker({ ... })?
enchance le

1
@enchance que je devais faire ceci: map.markers = map.markers || [];puis pour chaque marqueurmap.markers.push(marker);
travis


4

Voici une autre fonction qui fonctionne très bien pour moi, renvoie la distance en kilomètres:

 function distance(lat1, lng1, lat2, lng2) {
        var radlat1 = Math.PI * lat1 / 180;
        var radlat2 = Math.PI * lat2 / 180;
        var radlon1 = Math.PI * lng1 / 180;
        var radlon2 = Math.PI * lng2 / 180;
        var theta = lng1 - lng2;
        var radtheta = Math.PI * theta / 180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist);
        dist = dist * 180 / Math.PI;
        dist = dist * 60 * 1.1515;

        //Get in in kilometers
        dist = dist * 1.609344;

        return dist;
    }

3

Utilisez la méthode API Google map computeDistanceBetween () pour calculer le marqueur proche entre votre position et la liste des marqueurs sur google map.

Pas:-

  1. Créez un marqueur sur la carte google.
    function addMarker(location) { var marker = new google.maps.Marker({ title: 'User added marker', icon: { path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW, scale: 5 }, position: location, map: map }); }

  2. Sur la souris, cliquez sur créer un événement pour obtenir lat, long de votre emplacement et passez-le à find_closest_marker ().

    function find_closest_marker(event) {
          var distances = [];
          var closest = -1;
          for (i = 0; i < markers.length; i++) {
            var d = google.maps.geometry.spherical.computeDistanceBetween(markers[i].position, event.latLng);
            distances[i] = d;
            if (closest == -1 || d < distances[closest]) {
              closest = i;
            }
          }
          alert('Closest marker is: ' + markers[closest].getTitle());
        }
    

visitez ce lien suivez les étapes. Vous pourrez vous rapprocher du marqueur de votre position.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.