如何在已预聚类的数据上使用Leaflet MarkerCluster插件
你之前的方案不可行,因为L.MarkerCluster是MarkerCluster插件的内部类,设计上就不支持单独实例化使用,强依赖L.MarkerClusterGroup的事件管理、子节点调度、缩放匹配等内部逻辑,你手动构造的模拟group对象缺少大量必要属性和方法,才会出现点击无响应的问题。
下面是可直接运行的修改方案,完全适配你的预聚类树结构,保留MarkerCluster的所有默认交互效果:
<!DOCTYPE html> <html> <head> <title>预聚类MarkerCluster测试</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js"></script> <style> body { padding: 0; margin: 0; } html, body, #map { height: 100%; width: 100%; background: white; } </style> </head> <body> <div id='map'></div> <script> var map = L.map('map', { zoom: 0, center: [0,0], minZoom: -6, maxZoom: 30, crs: L.CRS.Simple, }); const dNode = { 3: [[], [-2, -1], 2], 4: [[], [-1, -2], 2], 5: [[], [2, 1], 2], 6: [[], [1, 2], 2], 1: [[3,4], [-1, -1], 1], 2: [[5,6], [1,1], 1], 0: [[1, 2], [0,0], 0], }; map.fitBounds([[-2, -2], [2, 2]]); // 初始化MarkerClusterGroup,适配预聚类结构 const mcg = L.markerClusterGroup({ iconCreateFunction: function () { return new L.divIcon({html: "AhA", iconSize: "auto", className: "custom-cluster"}); }, maxClusterRadius: 0, // 禁用插件自动合并点的逻辑 zoomToBoundsOnClick: true }); // 先初始化所有底层标记点 Object.values(dNode).forEach(node => { if(node[0].length === 0) { node[3] = L.marker(node[1]); mcg.addLayer(node[3]); } }); // 按层级从低到高绑定预聚类关系 Object.values(dNode).sort((a,b) => b[2] - a[2]).forEach(node => { if(node[0].length > 0) { const childNodes = node[0].map(childId => dNode[childId][3]); const cluster = mcg._getCluster(L.latLng(node[1]), node[2]); childNodes.forEach(child => { cluster.addChild(child); child.__parent = cluster; }); node[3] = cluster; } }); map.addLayer(mcg); </script> </body> </html>
运行上述代码后,点击显示AhA的聚类会自动缩放展开子节点,完全符合MarkerCluster的默认交互逻辑。
内容的提问来源于stack exchange,提问作者MrSiuol
相关产品推荐
相关产品推荐

