Google Maps Api v3 - знайти найближчі маркери


89

Коли я натискаю на карту, який найкращий спосіб знайти найближчий маркер чи маркери? чи є в api деякі функції, які допоможуть мені це зробити?

це google map api v3.


1
Чи використовуєте ви якусь базу даних для зберігання координат маркерів?
Аргіропулос Ставрос

безумовно, позиції маркерів зберігаються в mysql datbase.
user198003

Відповіді:


112

Спочатку вам слід додати списку подій

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

Потім створіть функцію, яка переглядає масив маркерів і використовує формулу haversine для обчислення відстані кожного маркера від клацання.

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

Це відстежує найближчі маркери та попереджає його назву.

У мене є маркери як масив на моєму об’єкті карти


2
Не для того, щоб відкрити стару нитку, але я спробував це реалізувати, і, схоже, шукаю на схід, а не шукаю найближчий. Отже, якщо я шукаю місце, воно буде шукати на схід і знайти найближчий шлях, навіть якщо на заході є РЕАЛЬНИЙ. Чи має це сенс?
LeeR

@Lee - це має сенс, але я не можу дублювати проблему
Гален

1
Так, це у мене зовсім не спрацювало - посадіть мене в наше місце в Каліфорнії, і я перебуваю в Нью-Йорку. І там є маркер у моєму місці. Він все-таки знайшов маркер!
mheavers

@mheavers - У коді є помилка. змінити з (i = 1 на з (i = 0. Це не включало перший маркер.
Гален

1
@Magico, ви не можете перетворити javascript на php-код. Ви можете написати обгортку php, яка генерує код JavaScript, як у відповіді. Якщо ви не можете зробити це самостійно, взагалі не використовуйте php ...
Даніель В.


30

Я хотів би розширити пропозицію Леора для тих, хто заплутався, як обчислити найближче місце і насправді надати робоче рішення:

Я використовую маркери в markersмасиві, наприклад var markers = [];.

Тоді давайте матимемо свою позицію як щось подібне var location = new google.maps.LatLng(51.99, -0.74);

Тоді ми просто зменшуємо наші маркери до місця, яке ми маємо, приблизно так:

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

Вискакує ваш найближчий маркерний LatLngоб’єкт.


1
чудова відповідь!
Сезар Алонсо

Акуратна і чиста відповідь!
TheeBen

Чи можна це використовувати для сортування маркерів за відстанню, а не просто повернення одного?
Louis W

Звичайно @Louis, шукайте метод фільтрування. Ви можете використати це для їх сортування
Джонатан,

1
Я змусив це працювати, прибравши позицію на об’єкті розташування; приблизно так: computeDistanceBetween (location, prev.position) ... тому що location - це вже об’єкт LatLng.
holm50

9

Наведена вище формула для мене не спрацювала, але я використав її без жодних проблем. Передайте ваше поточне місцезнаходження функції та пройдіть через масив маркерів, щоб знайти найближчий:

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
Як ви заповнюєте markersмасив? Це шляхом створення маркера за допомогою var marker1 = new google.maps.Marker({ ... })?
посилення

1
@enchance Мені довелося це зробити: map.markers = map.markers || [];потім для кожного маркераmap.markers.push(marker);
травіс


4

Ось ще одна функція, яка чудово працює для мене, повертає відстань у кілометрах:

 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

Використовуйте метод computeDistanceBetween () Google map API, щоб розрахувати маркер поблизу вашого місцезнаходження та списку маркерів на карті Google.

Кроки: -

  1. Створити маркер на карті 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. На миші клацніть створити подію для отримання lat, long of your location і передайте її до 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());
        }
    

перейдіть за цим посиланням, дотримуючись інструкцій. Ви зможете наблизити маркер до свого місцезнаходження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.