2016-10-05 55 views
0

我有一个图层,其中有标记markerLayer。我也有一个额外的标记,user_marker。我希望地图适合显示额外的标记和其周围的下一个k标记。缩放到特定区域的k个标记

我知道有leaflet-knn,但它需要GeoJSON,而不是传单图层,并返回一个坐标数组,这不是我想要的。还有leaflet.GeometryUtil,但只能选择返回某个半径内的所有图层,而不是最接近的图层。

有没有内置解决方案的传单,我忽略了一个简单的解决方案或者与传单内置或与外部库放大到某个标记周围的K个最接近的标记?

回答

0

您不一定需要Leaflet插件。您可以简单地使用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'的解决方案,与一些hackish的解决办法;) –

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是一个不错的方法。我认为最有效的解决方案很大程度上取决于图层中的标记数量,这些标记之间的距离以及函数中“数字”的值。事实上,在很多情况下,只需要在不带radius参数的情况下调用layersWithin就足够了,因此您将保存一个while循环。如果你的标记距离很远,那么每次使用一个单位增加r的while循环似乎是值得怀疑的。 –

+0

我同意增加,这是我测试的第一件事,它是相当快,所以我暂时保留它。两个注意事项:增加以像素为单位,而不是以米为单位。我不知道这是如何转换为米。而在内部,'layersWithin'的功能与您的代码几乎相同:)所以我实际上会建议您的示例正在使用中。 –