我在 Filemaker 的 db 文件上使用 markerCLusterer V3,根据地址生成当前交付位置的(半实时)地图。从谷歌获取纬度/经度并填充这些字段是没有问题的。通过markerClusterer 生成地图是没有问题的。我什至在本地托管 JS,这样我就可以更改 maxZoom 变量以在最大缩放之上将集群分开,这样我就可以看到多个标记。但是,由于标记的纬度/经度完全相同,我只能看到最后一个输入的标记。我想将 OverlappingMarkerSpiderfier 集成到这个 JS 中,这样在我放大到 maxZoom 之后,标记会“蜘蛛”分开以查看标记(例如,多件设备被运送到同一个地址)。我在网上找不到有关如何执行此操作的任何信息。它' 要么就是这么简单,我错过了它,要么还没有完成。提前感谢您的帮助!
5 回答
我正在使用:MarkerClustererPlus-2.0.14 和 OverlappingMarkerSpiderfier-version-??
起初只有聚类有效,单击一个聚类会放大,但即使放大到最大,同一点上的 2 个或更多标记仍然保持聚类。不幸的是没有蜘蛛侠出现:-(。
但是注意到了markerClusterPlus 上的setMaxZoom() 方法。设置此选项时,您的适当缩放级别(对我来说是 15)spiderfier 会超出缩放级别。看起来markerClusters说从这里开始不再是我的事了,这取决于spiderfier :-)。
设置最大缩放将解决问题:
minClusterZoom = 14;
markerCluster.setMaxZoom(minClusterZoom);
但出于查看目的,您可能需要创建一个 clusterclick 侦听器,以防止它在同一位置的一组点上真正放大(单击一个集群设置地图的边界以覆盖集群中的点;如果所有点位于同一位置,它将一直放大,这往往看起来很糟糕):
google.maps.event.addListener(markerCluster, 'clusterclick', function(cluster) {
map.fitBounds(cluster.getBounds()); // Fit the bounds of the cluster clicked on
if( map.getZoom() > minClusterZoom+1 ) // If zoomed in past 15 (first level without clustering), zoom out to 15
map.setZoom(minClusterZoom+1);
});
将 Spiderfier JS 集成到 markerClusterer
为了使两者一起工作,您只需向 clusterMarker 对象添加一个 maxZoom
new MarkerClusterer(map, clusterMarker, {imagePath: 'images/m', maxZoom: 15});
(缩放级别 0 是完整的地球,而 20 非常接近地面)。这意味着如果您将地图进一步放大为 15 级缩放(例如,如果您单击一个集群),则不再显示这些集群。如果您现在单击位于完全相同位置(或彼此靠近)的标记,Spiderfier JS 将触发。
它现在遵循一个最小的工作示例。我在代码中做了一些注释,所以我认为它是不言自明的,但这里有一些事情要提一下:
- 将 YOUR_API_KEY 替换为您的 api 密钥
- 确保
oms.min.js
在加载 google maps api 后加载
例子:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://maps.googleapis.com/maps/apijs?key=YOUR_API_KEY">
</script>
<script src="oms.min.js"></script>
<script src="markerclusterer.js"></script>
<script>
window.onload = function() {
// cluster marker
var clusterMarker = [];
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng( 50, 3),
zoom: 6,
mapTypeId: 'terrain'
});
// Create infowindow
var infoWindow = new google.maps.InfoWindow();
// Create OverlappingMarkerSpiderfier instsance
var oms = new OverlappingMarkerSpiderfier(map,
{markersWontMove: true, markersWontHide: true});
// This is necessary to make the Spiderfy work
oms.addListener('click', function(marker) {
infoWindow.setContent(marker.desc);
infoWindow.open(map, marker);
});
// Some sample data
var sampleData = [{lat:50, lng:3}, {lat:50, lng:3}, {lat:50, lng:7}];
for (var i = 0; i < sampleData.length; i ++) {
var point = sampleData[i];
var location = new google.maps.LatLng(point.lat, point.lng);
// create marker at location
var marker = new google.maps.Marker({
position: location,
map: map
});
// text to appear in window
marker.desc = "Number "+i;
// needed to make Spiderfy work
oms.addMarker(marker);
// needed to cluster marker
clusterMarker.push(marker);
}
new MarkerClusterer(map, clusterMarker, {imagePath: 'images/m', maxZoom: 15});
}
</script>
</head>
<body><div id="map" style='width:400px;height:400px;'></div></body></html>
推荐
如果您是从头开始,我建议您使用 JS Libary Leaflet。因为这个库为您提供了LeafletMarkerCluster插件,它基本上是集成了 Spiderfier 的标记集群,以及许多其他很酷的东西。
优势:
- 集群看起来真不错
- 传单真的很容易使用,看起来很漂亮
- 您不需要自定义代码,因为 Spiderfier 和 markerCluster 已经集成
- 一些花哨的其他东西:比如在标记分布的区域悬停时显示边框。
- 您可以自由选择您的地图瓷砖供应商,不再局限于谷歌地图(可能的供应商在这里)
下站:
- 您可能需要投入 30 分钟来学习和使用 Leaflet API 而不是 Google API
- 如果你想使用 Google Map Tiles,那么你需要使用这个插件,因为你只有在使用 Google API 时才允许使用 Google Tiles。此插件是 Google API 的包装器。
这是一个示例代码:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
<link rel="stylesheet" href="leaflet/dist/MarkerCluster.css" />
<link rel="stylesheet" href="leaflet/dist/MarkerCluster.Default.css" />
<script src="leaflet/dist/leaflet.markercluster-src.js"></script>
<script>
$(document).ready(function(){
var tiles = L.tileLayer(***);//Depending on your tile provider
var map = new L.Map('map', {center: latlng, zoom: 1, layers: [tiles]});
var markers = new L.MarkerClusterGroup({
removeOutsideVisibleBounds: true,
spiderfyDistanceMultiplier: 2,
maxClusterRadius: 20
});
var markersList = [];
var sampleData = [{lat:50, lng:3}, {lat:50, lng:3}, {lat:50, lng:7}];
for (var i = 0; i < sampleData.length; i ++) {
var point = sampleData[i];
var location = new L.LatLng(point.lat, point.lng);
// create marker at location
var m = new L.Marker(location);
m.bindPopup("Number" +i); //Text to appear in window
markersList.push(m);
markers.addLayer(m);
}
var bounds = markers.getBounds();
map.fitBounds(bounds)
map.addLayer(markers);
}
</head>
<body><div id="map" style='width:400px;height:400px;'></div></body></html>
我遇到这篇文章是因为我正在寻找完全相同的东西,但对我来说幸运的是我成功了!
老实说,我没有做任何特别的事情,我遵循了 MarkerClusterer 的集成指南,然后遵循了 OverlappingMarkerSpiderfier 的集成指南,它们完美地协同工作。
当我单击/放大位于同一地址的一组属性时,最初它只显示“顶部”标记,但是当我单击它时,它们会像您想要的一样蜘蛛化!
当您尝试同时使用这两个脚本时,您会得到什么具体结果?
var markerClusterer = new MarkerClusterer(map, myMarkers, {
maxZoom: 15,
zoomOnClick: false
});
//zoom 0 corresponds to a map of the Earth fully zoomed out, 20 is closeup
//markerCluster goes away after zoom
//turn off zoom on click or spiderfy won't work