Is there a method to avoid this issue?
Using multiple Leaflet.markercluster groups as you currently have will not resolve the problem.
Consider this: how would the cluster icons' positions be calculated when one group lacks information about another group?
There are various potential solutions and alternate libraries that might better suit your requirements, eliminating the need to develop a new clustering algorithm from scratch.
One popular option for displaying different categories while clustering is the PruneCluster plugin:
PruneCluster is a high-speed real-time marker clustering library.
It serves as an alternative to Leaflet.markercluster with Leaflet integration.
https://i.sstatic.net/N3N1w.png
Extract taken from PruneCluster home page
Another workaround could involve combining all categories into a single Marker Cluster Group but customizing the cluster icon of the latter so it resembles the layout in the PruneCluster screenshot above, or even generating fake icons for each category:
https://i.sstatic.net/Wwk7D.png
function customClusterIcon(cluster) {
// Calculate number of markers from each category.
var markers = cluster.getAllChildMarkers();
var cat1count = 0;
var cat2count = 0;
for (var marker of markers) {
var category = marker.options.category;
if (category && category === 'cat2') {
cat2count += 1;
} else {
cat1count += 1;
}
}
// Determine the cluster icon based on presence of Markers from different categories.
if (cat2count === 0) {
return L.divIcon({
html: cat1count,
className: 'cat1cluster cluster',
iconSize: [20, 20]
});
} else if (cat1count === 0) {
return L.divIcon({
html: cat2count,
className: 'cat2cluster cluster',
iconSize: [20, 20]
});
} else {
return L.divIcon({
html: `
<div class="cat1cluster cluster">${cat1count}</div>
<div class="cat2cluster cluster">${cat2count}</div>
`,
className: '',
iconSize: [45, 20]
});
}
}
var paris = [48.86, 2.35];
var parisLeft = [48.86, 2.25];
var parisRight = [48.86, 2.45];
var map = L.map('map', {
maxZoom: 18
}).setView(paris, 11);
var mcg = L.markerClusterGroup({
iconCreateFunction: customClusterIcon
}).addTo(map);
var category1 = L.layerGroup();
var category2 = L.layerGroup();
var cat2style = {
color: 'red',
category: 'cat2'
};
var markerA = L.circleMarker(paris).addTo(category1);
var markerB = L.circleMarker(paris).addTo(category1);
var markerC = L.circleMarker(paris, cat2style).addTo(category2);
var markerD = L.circleMarker(paris, cat2style).addTo(category2);
var markerE = L.circleMarker(parisLeft).addTo(category1);
var markerF = L.circleMarker(parisLeft).addTo(category1);
var markerG = L.circleMarker(parisRight, cat2style).addTo(category2);
var markerH = L.circleMarker(parisRight, cat2style).addTo(category2);
mcg.addLayers([category1, category2]);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
height: 100%;
margin: 0;
}
.cat1cluster {
background-color: #3388ff;
}
.cat2cluster {
background-color: red;
}
.cluster {
width: 20px;
height: 20px;
display: inline-block;
text-align: center;
}
<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a1cdc4c0c7cdc4d5e1908f928f95">[email protected]</a>/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" />
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c4a8a1a5a2a8a1b084f5eaf7eaf0">[email protected]</a>/dist/leaflet-src.js" integrity="sha512-+ZaXMZ7sjFMiCigvm8WjllFy6g3aou3+GZngAtugLzrmPFKFK7yjSri0XnElvCTu/PrifAYQuxZTybAEkA8VOA==" crossorigin=""></script>
<!-- Leaflet.markercluster assets -->
<link rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="523e3733343e37267c3f3320393720313e272126372012637c667c63">[email protected]</a>/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b272e2a2d272e3f65262a39202e3928273e383f2e390b7a657f657a">[email protected]</a>/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f39f9692959f9687dd9e9281989681909f8680879681b3c2ddc7ddc2">[email protected]</a>/dist/leaflet.markercluster-src.js"></script>
<div id="map"></div>
You can then further modify the spiderification process to only display Markers from the clicked category cluster icon, and do similar adjustments for the hovering polygon if desired.