使用L.GeoJSON加载数据时Leaflet MarkerCluster聚合标记全部相同如何解决
问题原因
- 你在
onEachFeature回调中错误地固定读取了整个GeoJSON集合的第一个要素属性:所有点位的弹窗、提示文本都硬编码取geoJSONFeature.features[0].properties,而非当前遍历到的feature.properties,所以所有标记的交互内容完全一致。 - 你创建的
markerClusterGroup实例clusters没有实际承载点位:点位直接被添加到了普通layerGroup中,MarkerCluster的聚合能力根本没有生效。 - OMS点击事件存在多处错误:回调中引用的
geojsonFeature是$.getJSON回调的局部变量,全局监听器无法正常读取;也没有给标记提前绑定desc属性,同时坐标赋值没有转换GeoJSON的[经度,纬度]格式为Leaflet要求的[纬度,经度]。 - 弹窗绑定逻辑冗余:你已经在
onEachFeature中给每个标记单独绑定了弹窗,不需要额外在OMS的全局点击事件中再手动打开弹窗,两者会产生冲突。
修正后的代码
var oms = new OverlappingMarkerSpiderfier(timemap); // 移除冗余的全局oms点击监听,直接使用每个标记自带的绑定弹窗即可 function getMapInfo(thisLayer, startyear, endyear) { layerGroups["layerGroup" + thisLayer] = L.layerGroup(); var clusters = L.markerClusterGroup({ spiderfyOnMaxZoom: true, showCoverageOnHover: false, zoomToBoundsOnClick: false, maxClusterRadius: 0 }); // 先把聚合组添加到图层组中 clusters.addTo(layerGroups["layerGroup" + thisLayer]); $.getJSON("geojson.php?layer="+thisLayer+"&startyear="+startyear+"&endyear="+endyear, function (geoJSONFeature) { iconGroup["icon"+thisLayer]= new L.Icon({ iconUrl: "css/images/"+geoJSONFeature.features[0].properties.icon, shadowUrl: "css/images/shadow.png", iconSize: [32, 37], shadowSize: [51, 37], shadowAnchor: [10, 37], iconAnchor: [10, 40], popupAnchor: [5, -20] }); var location = new L.geoJSON(geoJSONFeature, { pointToLayer: function (feature, latlng) { return L.marker(latlng, {icon: iconGroup["icon"+thisLayer]}); }, onEachFeature: function (feature, layer) { // 改为读取当前遍历到的feature的属性,而非固定取第一个要素的属性 layer.bindPopup('<h1>'+feature.properties.item+'</h1><p>'+feature.properties.shortdesc+'</p>'); layer.bindTooltip(feature.properties.item); oms.addMarker(layer); } // 点位添加到聚合组,而非直接加到图层组 }).addTo(clusters); timemap.addLayer(layerGroups["layerGroup" + thisLayer]); }); }
补充说明:如果同一图层下不同点位需要使用不同图标,将
iconUrl赋值逻辑中的geoJSONFeature.features[0]改为当前feature即可。
内容的提问来源于stack exchange,提问作者LeeJS
相关产品推荐
相关产品推荐

