2016-10-05 3 views
0

У меня есть слой с маркерами в нем, markerLayer. У меня также есть один дополнительный маркер, user_marker. Я хочу, чтобы карта соответствовала отображению дополнительного маркера и следующих k-меток вокруг него.Масштабирование до k маркеров вокруг определенного

Я знаю, что есть leaflet-knn, но он берет GeoJSON, а не слои листов, и возвращает массив координат, который не совсем то, что требуется. Существует также leaflet.GeometryUtil, но у него есть возможность возвращать все слои в пределах определенного радиуса, а не ближайшего к k.

Есть ли встроенное решение в лифлете, которое я пропустил, или простое решение либо с помощью встроенных листовки, либо с внешней библиотекой для увеличения к ближайшим маркерам вокруг определенного маркера?

ответ

0

Вам необязательно нужны плагины для лифтов. Вы можете просто использовать метод distanceTo и отсортировать маркеры по расстоянию до user_marker. Затем вы вызываете метод fitBounds. Я создал working example here.

Ниже приведены важные шаги кода:

var testData = [{lat:37.7859,lon:-122.1362},{lat:37.6921,lon:-122.0312},{lat:37.823,lon:-122.6112},{lat:37.7478,lon:-122.1562},{lat:37.6759,lon:-122.0458},{lat:37.555,lon:-122.050}]; 

var marker_layer = new L.layerGroup(); 
var user_marker = L.marker(L.latLng(37.7829, -122.1312)).addTo(map); 

//k closest markers 
var k = 3; 
var dist_markers = []; 

$.each(testData, function(index, p) { 
    var latlng = L.latLng(p.lat, p.lon) 
    var marker = L.marker(latlng); 
    marker.addTo(marker_layer); 
    dist = L.latLng(37.7829, -122.1312).distanceTo(latlng); 
    dist_markers.push([dist,marker]); 
}); 

dist_markers.sort(Comparator); 
var close_markers = dist_markers.slice(0,k) 
close_markers = close_markers.map(function(d) {return d[1];}); 
var group = new L.featureGroup(close_markers); 

marker_layer.addTo(map); 
user_marker.addTo(map); 

map.on('click', function() { 
     map.fitBounds(group.getBounds()); 
}); 
+0

Это выглядит очень похоже на решение, которое я бы пошел за :) Я пошел eventuelly решения с 'leaflet.GeometryUtil', с некоторым хаком обходного путем;) –

0

Я знаю, что есть листовка-Knn, но он принимает в формате GeoJSON, не листовка слои

Так? Просто поместите свои маркеры вместе в L.LayerGroup и используйте его toGeoJSON() method.

С некоторыми обратными ссылками вы можете снова получить маркеры из поиска knn.

+0

я на самом деле сделал это и вернулся массив с широт и долгот. В этот момент я остановился, так как мне как-то понадобилось перевести их обратно в маркеры. Вместо этого я пошел на решение с L.GeometryUtil. В любом случае, вопрос состоял в том, было ли более простое решение или решение, которое не нуждалось в внешнем коде и некотором «обходном пути». Кажется, что нет ничего подобного или на StackOverflow, поэтому я спросил :) –

0

Это решение, в который я в конечном итоге пошел, используя L.GeometryUtil.

function fit_around_marker(user_marker, number) { 
    if (number >= markerLayer.getLayers().length) { 
     map.fitBounds(markerLayer.getBounds()); 
    } else { 
     var p = user_marker.getLatLng(); 
     var fit_layers = markerLayer.getLayers(); 
     var fit_array = []; 
     var r = 1; 
     while (fit_array.length < number) { 
      fit_array = L.GeometryUtil.layersWithin(map, fit_layers, p, r++); 
     } 
     var fit_markers = [user_marker]; 
     for (index = 0; index < fit_array.length; ++index) { 
      fit_markers.push(fit_array[index]["layer"]); 
     } 
     console.log(fit_markers); 
     var fit_layer = L.featureGroup(fit_markers); 
     map.fitBounds(fit_layer.getBounds()); 
    } 
} 
+0

GeometryUtil.layersWithin - хороший метод. Я думаю, что наиболее эффективное решение зависит от количества маркеров, которые у вас есть на вашем слое, расстояния между этими маркерами и значения «числа» в вашей функции. В самом деле, во многих случаях этого будет достаточно, чтобы вызвать слои с без аргумента радиуса, и поэтому вы сохраните цикл while. Если ваши маркеры очень далеки друг от друга, кажется сомнительным использовать цикл while с увеличением на один метр единицы r каждый раз. –

+0

Я согласен с увеличением, это было первое, что я проверил, и это было достаточно быстро, поэтому я все время его сохранял. Две заметки: увеличение в пикселях, а не в метрах. Я не знаю, как это переводится в метры. И внутренне, 'layersWithin' делает почти то же самое, что и ваш код :) Поэтому я бы предположил, что ваш пример используется. –

Смежные вопросы