Google Maps Api v3 - encontre os marcadores mais próximos


89

Quando eu clico no mapa, qual é a melhor maneira de encontrar o marcador ou marcadores mais próximos? existe alguma função na api que vai me ajudar a fazer isso?

é google map api v3.


1
Você usa algum banco de dados para armazenar as coordenadas dos marcadores?
Argiropoulos Stavros

com certeza, as posições dos marcadores são armazenadas no banco de dados mysql.
user198003

Respostas:


112

Primeiro você tem que adicionar o ouvinte de eventos

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

Em seguida, crie uma função que percorra a matriz de marcadores e use a fórmula Haversine para calcular a distância de cada marcador a partir do clique.

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

Isso rastreia os marcadores mais próximos e alerta seu título.

Eu tenho meus marcadores como uma matriz no meu objeto de mapa


2
Sem querer abrir um tópico antigo, mas tentei implementar isso, e parece que busca o leste ao invés de encontrar o mais próximo. Portanto, se eu pesquisar por um local, ele pesquisará para o leste e encontrará o mais próximo dessa forma, mesmo que haja uma proximidade REAL no oeste. Isso faz sentido?
LeeR

@Lee - faz sentido, mas não posso repetir o problema
Galen

1
Sim, isso não funcionou para mim - coloque-me em nossa localização na Califórnia e eu estou em NY. E há um marcador na minha localização. Mas encontrou um marcador!
mheavers

@mheavers - há um erro no código. mudar de (i = 1 para de (i = 0. Não estava incluindo o primeiro marcador.
Galen

1
@Magico você não pode transformar javascript em código php. você pode escrever um wrapper php que gere código javascript como na resposta. Se você não pode fazer isso sozinho, não use php de jeito nenhum ...
Daniel W.


30

Eu gostaria de expandir a sugestão de Leor para qualquer pessoa confusa sobre como calcular o local mais próximo e realmente fornecer uma solução funcional:

Estou usando marcadores em uma markersmatriz, por exemplo var markers = [];.

Então vamos ter nossa posição como algo como var location = new google.maps.LatLng(51.99, -0.74);

Então, simplesmente reduzimos nossos marcadores em relação ao local que temos, assim:

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

O que sobressai é o seu LatLngobjeto marcador mais próximo .


1
resposta incrível!
Cesar Alonso

Resposta limpa e limpa!
TheeBen

Isso poderia ser usado para classificar os marcadores por distância, em vez de apenas retornar um?
Louis W

Claro, @Louis, procure o método de filtro. Você pode usar isso para classificá-los
Jonathan,

1
Eu fiz isso funcionar removendo a posição no objeto de localização; assim: computeDistanceBetween (location, prev.position) ... porque location já é um objeto LatLng.
holm50

9

A fórmula acima não funcionou para mim, mas usei-a sem problemas. Passe sua localização atual para a função e faça um loop por uma série de marcadores para encontrar o mais próximo:

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
Como você preenche a markersmatriz? É criando um marcador usando var marker1 = new google.maps.Marker({ ... })?
enchance

1
@enchance eu tive que fazer isso: map.markers = map.markers || [];então, para cada marcadormap.markers.push(marker);
travis


4

Aqui está outra função que funciona muito bem para mim, retorna a distância em quilô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;
    }

3

Use o método computeDistanceBetween () API do Google map para calcular próximo ao marcador entre a sua localização e a lista de marcadores no google map.

Passos:-

  1. Crie um marcador no mapa do 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. Com o mouse, clique em criar evento para obter lat, long de sua localização e passe para 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 link siga os passos. Você será capaz de chegar mais perto do marcador de sua localização.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.