Google Maps Api v3: encuentre los marcadores más cercanos

89

Cuando hago clic en el mapa, ¿cuál será la mejor manera de encontrar el marcador o marcadores más cercanos? ¿hay algunas funciones en api que me ayudarán a hacer eso?

es google map api v3.

user198003
fuente
1
¿Utiliza alguna base de datos para almacenar las coordenadas de los marcadores?
Argiropoulos Stavros
seguro, las posiciones de los marcadores se almacenan en la base de datos mysql.
user198003

Respuestas:

112

Primero tienes que agregar el eventlistener

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

Luego, cree una función que recorra la matriz de marcadores y utilice la fórmula haversine para calcular la distancia de cada marcador desde el 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);
}

Esto realiza un seguimiento de los marcadores más cercanos y alerta su título.

Tengo mis marcadores como una matriz en mi objeto de mapa

Galeno
fuente
2
No para abrir un hilo antiguo, pero he intentado implementar esto, y parece buscar hacia el este en lugar de encontrar el más cercano. Entonces, si busco una ubicación, buscará hacia el este y encontrará la más cercana de esa manera, incluso si hay un VERDADERO cerca en el oeste. ¿Tiene sentido?
LeeR
@Lee - tiene sentido, pero no puedo duplicar el problema
Galen
1
Sí, esto no funcionó en absoluto para mí, ponme en nuestra ubicación en California y estoy en Nueva York. Y hay un marcador en mi ubicación. ¡Sin embargo, encontró un marcador!
mheavers
@mheavers: hay un error en el código. cambiar de (i = 1 a de (i = 0. No incluía el primer marcador.
Galeno
1
@Magico no puedes convertir javascript en código php. puede escribir un contenedor php que genere código javascript como en la respuesta. Si no puede hacerlo por su cuenta, no use php en absoluto ...
Daniel W.
30

Me gustaría ampliar la sugerencia de Leor para cualquiera que esté confundido sobre cómo calcular la ubicación más cercana y realmente proporcionar una solución funcional:

Estoy usando marcadores en una markersmatriz, por ejemplo var markers = [];.

Entonces tengamos nuestra posición como algo como var location = new google.maps.LatLng(51.99, -0.74);

Entonces simplemente reducimos nuestros marcadores contra la ubicación que tenemos así:

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

Lo que aparece es el LatLngobjeto marcador más cercano .

Jonathan
fuente
1
respuesta impresionante!
Cesar Alonso
¡Respuesta ordenada y limpia!
TheeBen
¿Podría usarse esto para ordenar los marcadores por distancia, en lugar de simplemente devolver uno?
Louis W
Seguro @Louis, busca el método de filtro. Puedes usar eso para ordenarlos
Jonathan
1
Lo hice funcionar quitando la posición en el objeto de ubicación; así: computeDistanceBetween (ubicación, posición anterior) ... porque la ubicación ya es un objeto LatLng.
holm50
9

La fórmula anterior no funcionó para mí, pero la usé sin ningún problema. Pase su ubicación actual a la función y recorra una serie de marcadores para encontrar el más cercano:

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
fuente
1
¿Cómo se puebla la markersmatriz? ¿Es creando un marcador usando var marker1 = new google.maps.Marker({ ... })?
mejora el
1
@enchance tuve que hacer esto: map.markers = map.markers || [];luego para cada marcadormap.markers.push(marker);
travis
4

Aquí hay otra función que funciona muy bien para mí, devuelve la distancia en kilómetros:

 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
fuente
3

Utilice el método de API de mapas de Google computeDistanceBetween () para calcular el marcador cercano entre su ubicación y la lista de marcadores en el mapa de Google.

Pasos:-

  1. Crear marcador en el mapa de 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. En el mouse, haga clic en crear evento para obtener lat, long de su ubicación y páselo a 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());
        }
    

visite este enlace siga los pasos. Podrá acercarse al marcador de su ubicación.

Vikesh
fuente