Google Maps Api v3 - Finden Sie die nächsten Markierungen

89

Wenn ich auf die Karte klicke, welcher Weg ist der beste, um den nächsten Marker oder die nächsten Marker zu finden? Gibt es einige Funktionen in API, die mir dabei helfen?

Es ist Google Map API v3.

user198003
quelle
1
Verwenden Sie eine Datenbank, um die Koordinaten der Marker zu speichern?
Argiropoulos Stavros
Sicher, Markierungspositionen werden in der MySQL-Datenbank gespeichert.
user198003

Antworten:

112

Zuerst müssen Sie den Ereignislistener hinzufügen

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

Erstellen Sie dann eine Funktion, die das Array von Markern durchläuft und mithilfe der Haversine-Formel den Abstand jedes Markers vom Klick berechnet.

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);
}

Dadurch werden die nächstgelegenen Markierungen verfolgt und der Titel angezeigt.

Ich habe meine Markierungen als Array auf meinem Kartenobjekt

Galen
quelle
2
Nicht um einen alten Thread zu öffnen, aber ich habe versucht, dies zu implementieren, und es scheint eher nach Osten zu suchen, als den nächsten zu finden. Wenn ich also nach einem Ort suche, wird er nach Osten suchen und auf diese Weise den nächstgelegenen finden, selbst wenn es im Westen eine ECHTE Nähe gibt. Ist das sinnvoll?
LeeR
@ Lee - es macht Sinn, aber ich kann das Problem nicht duplizieren
Galen
1
Ja, das hat bei mir überhaupt nicht funktioniert - bringen Sie mich an unseren Standort in Kalifornien und ich bin in NY. Und an meinem Standort befindet sich eine Markierung. Es hat allerdings einen Marker gefunden!
mheavers
@mheavers - Der Code enthält einen Fehler. Wechsel von (i = 1 zu von (i = 0. Es war nicht der erste Marker enthalten.
Galen
1
@Magico Sie können Javascript nicht in PHP-Code verwandeln. Sie können einen PHP-Wrapper schreiben, der Javascript-Code wie in der Antwort generiert. Wenn Sie es nicht alleine schaffen, verwenden Sie PHP überhaupt nicht ...
Daniel W.
29

Ich möchte Leors Vorschlag für alle erweitern, die sich nicht sicher sind, wie sie den nächstgelegenen Standort berechnen und tatsächlich eine funktionierende Lösung anbieten sollen:

Ich verwende Marker in einem markersArray, z var markers = [];.

Dann lassen Sie uns unsere Position als so etwas haben var location = new google.maps.LatLng(51.99, -0.74);

Dann reduzieren wir einfach unsere Markierungen gegen den Ort, den wir so mögen:

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

Was herausspringt, ist Ihr nächstgelegenes Markierungsobjekt LatLng.

Jonathan
quelle
1
tolle Antwort!
Cesar Alonso
Ordentliche und saubere Antwort!
TheeBen
Könnte dies verwendet werden, um die Markierungen nach Entfernung zu sortieren, anstatt nur eine zurückzugeben?
Louis W
Sicher @Louis, schauen Sie sich die Filtermethode an. Sie können das verwenden, um sie zu sortieren
Jonathan
1
Ich habe es zum Laufen gebracht, indem ich die Position auf dem Standortobjekt entfernt habe. wie folgt: computeDistanceBetween (location, prev.position) ... weil location bereits ein LatLng-Objekt ist.
holm50
9

Die obige Formel hat bei mir nicht funktioniert, aber ich habe sie ohne Probleme verwendet. Übergeben Sie Ihren aktuellen Standort an die Funktion und durchlaufen Sie eine Reihe von Markierungen, um die nächstgelegene zu finden:

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]);
}
mheavers
quelle
1
Wie füllt man das markersArray? Ist es durch Erstellen eines Markers mit var marker1 = new google.maps.Marker({ ... })?
Enchance
1
@enchance Ich musste dies tun: map.markers = map.markers || [];dann für jeden Markermap.markers.push(marker);
Travis
4

Hier ist eine weitere Funktion, die für mich hervorragend funktioniert und die Entfernung in Kilometern zurückgibt:

 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;
    }
Chris Panayotoff
quelle
3

Verwenden Sie die Google Map-API computeDistanceBetween () Methode zwischen Ihrem Standort und der Markierungsliste auf zu berechnen.

Schritte:-

  1. Erstellen Sie eine Markierung auf Google Map.
    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. Klicken Sie bei der Maus auf Ereignis erstellen, um lat, long von Ihrem Standort abzurufen, und übergeben Sie dieses an 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());
        }
    

Besuchen Sie diesen Link und folgen Sie den Schritten. Sie können näher an Ihren Standort gelangen.

Vikesh
quelle