I initialize map and via ajax function (filters) I want to change numbers of markers (clusters) and star markers loads on map. I tried dynamically initialize markerClusterer in async function because I use advanced Markers (AdvancedMarkerElelement) to load access to this class from “marker” library, but I got not built clusters in t.MarkerClusterer object (clusters returns null). I am using @googlemaps/markerclusterer the unpkg version.
var map;
var markers_field = [];
var markerCluster;
function initialize() {
var mapOptions = {
zoom: 3,
center: {lat: parseFloat('52.373920'), lng: parseFloat('9.735603') },
mapTypeId: google.maps.MapTypeId.SATELLITE,
keyboardShortcuts: false,
mapTypeControl: true,
gestureHandling: "greedy",
streetViewControl: false,
heading: 0,
tilt: 0,
mapId: "55f47556969d555c",
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
setPolygon(map,coord_c,69);
readFilters();
}
async function loadMarkerLibrary() {
try {
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
// Use AdvancedMarkerElement or perform other operations here
console.log("Marker library loaded successfully");
return AdvancedMarkerElement; // Return if needed
} catch (error) {
console.error("Error loading marker library:", error);
// Handle error appropriately
}
}
async function setMarkers(map, includes, c) {
const markerElement = await loadMarkerLibrary();
markers_field.forEach(marker => marker.setMap(null));
markers_field = [];
var i_color= 'red';
let j_counter = 1;
for (let i = 0; i < points.length; i++) {
const point = points[i];
if(c=='cat')
i_color = colors_c[point['cat_id']];
if(c=='item')
i_color = colors_i[point['item_id']];
if(c=='dtls')
i_color = colors_d[point['dtls_id']];
if(c=='sub_dtls')
i_color = colors_sd[point['sub_dtls_id']];
if(c=='subcat')
i_color = colors_sc[point['subcat']];
if(c=='subcat2')
i_color = colors_sc2[point['subcat2']];
if (inArray(point['id'], includes) && point['i_x']!==''&&point['i_y']!=='' ) {
var div = document.createElement('div');
div.className = 'custom-marker';
div.innerHTML = point['contentStringImage']+'<div class="marker-point"></div><div class="marker-text text-white">'+point['contentStringTitle']+'</div>';
icon_image = div;
let shouldDisplayMarker = true;
// Display marker if it should be shown
if(shouldDisplayMarker) {
markers_field[j_counter] = new markerElement({
position: {lat: parseFloat(point['i_x'] - delta), lng: parseFloat(point['i_y'])},
//map,
content: icon_image,
//icon: icon2,
zIndex: (j_counter + 1),
//gmpDraggable: true
});
infowindow[j_counter] = new google.maps.InfoWindow({
content: point['contentString'],
ariaLabel: "",
});
markers_field[j_counter].customData = j_counter;
google.maps.event.addListener(markers_field[j_counter], 'click', function (evt) {
var j_counter_tmp = this.customData;
if (currentInfoWin !== null) {
currentInfoWin.close(map, this);
}
infowindow[j_counter_tmp].open({
anchor: markers_field[j_counter_tmp],
map,
shouldFocus: false,
});
currentInfoWin = infowindow[j_counter_tmp];
});
j_counter++;
}
}
}
if(markerCluster)
{
// Clear previous markers from the MarkerClusterer
markerCluster.clearMarkers();
}
// Initialize and configure MarkerClusterer with custom algorithm
const customAlgorithm = {
calculate: ({ markers, map }) => {
if (!markers || markers.length === 0) {
console.warn('No markers provided to customAlgorithm.calculate');
return [];
}
var clusters = [];
markers.forEach(marker => {
if (marker && marker.position ) {
let addedToCluster = false;
for (let cluster of clusters) {
const distance = google.maps.geometry.spherical.computeDistanceBetween(marker.position, cluster.center);
if (distance < 20) { // Example distance threshold for clustering
cluster.markers.push(marker);
addedToCluster = true;
break;
}
}
if (!addedToCluster) {
clusters.push({center: marker.position, markers: [marker]});
}
}
});
console.log(clusters);
const result = clusters.map(cluster => ({
position: cluster.center,
markers: cluster.markers,
count: cluster.markers.length,
}));
console.log('Custom Algorithm Result:', result);
return result;
}
};
const filteredMarkers = markers_field.filter(marker => marker !== undefined);
console.log('Filtered Markers:', filteredMarkers);
// Initialize MarkerClusterer with custom algorithm and small gridSize
markerCluster = new markerClusterer.MarkerClusterer({
map: map,
markers: filteredMarkers,
gridSize: 30, // Small grid size for fine clustering
algorithm: customAlgorithm, // Use custom clustering algorithm
maxZoom: 20, // Max zoom level for clustering
minimumClusterSize: 2 // Minimum cluster size for clustering
});
console.log(markerCluster);
markerCluster.addMarkers(filteredMarkers);
var currentZoom = map.getZoom();
handleZoomChange(currentZoom);
// Listen for zoom changes
map.addListener('zoom_changed', () => {
var currentZoom = map.getZoom();
handleZoomChange(currentZoom);
});
}
function handleZoomChange(zoomLevel) {
if (zoomLevel > 15) {
markerCluster.setMap(null); // Disable clustering
showIndividualMarkers();
} else {
markerCluster.setMap(map); // Enable clustering
hideIndividualMarkers();
}
}
function showIndividualMarkers() {
markers_field.forEach(marker => {
marker.map = map;
});
}
function hideIndividualMarkers() {
markers_field.forEach(marker => {
marker.map = null;
});
}
function readFilters()
{
cat_id = jQuery('#cat_id').val();
item_id = jQuery('#item_id').val();
dtls_id = jQuery('#dtls_id').val();
sub_dtls_id = jQuery('#sub_dtls_id').val();
subcat = jQuery('#subcat_id').val();
subcat2 = jQuery('#subcat2_id').val();
year_from = jQuery('#year_from').val();
year_to = jQuery('#year_to').val();
var show_to_archeologist = 0;
area_id = jQuery('#area_id').val();
area_id_all = jQuery("#area_id_all").val();
area_id_all = area_id_all.split(",");
for(let i=0;i<area_id_all.length;i++)
hidePolygon(area_id_all[i]);
for(let i=0;i<area_id.length;i++)
setPolygon(map,coord_c,area_id[i]);
$.ajax({
url: "/m/gmap_cluster.php",
method: "POST",
data: {"cat_id": cat_id, "task":"filters", "id":69, "area_id":jQuery("#area_id").val(), "item_id":item_id, "dtls_id":dtls_id, "sub_dtls_id":sub_dtls_id, "subcat":subcat, "subcat2":subcat2, "year_from":year_from, "year_to":year_to, "show_to_archeologist":show_to_archeologist},
dataType: "html",
success: function (result) {
if(result!='' && jQuery("#inlineCheckbox01").is(":checked") )
{
includes = result.split(",");
c = 'all';
if(!isEmpty(cat_id) && isNotNullArray(cat_id) )
c = 'cat';
if(!isEmpty(item_id) && isNotNullArray(item_id))
c = 'item';
if(!isEmpty(dtls_id) && isNotNullArray(dtls_id) )
c = 'dtls';
if(!isEmpty(sub_dtls_id) && isNotNullArray(sub_dtls_id))
c = 'sub_dtls';
if(!isEmpty(subcat) && isNotNullArray(subcat))
c = 'subcat';
if(!isEmpty(subcat2) && isNotNullArray(subcat2))
c = 'subcat2';
setMarkers(map, includes, c);
}
else {
for(let i=0;i<markers_field.length;i++) {
if(isSet(markers_field[i])) {
markers_field[i].setMap(null);
}
}
}
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
markerCluster console result: t.MarkerClusterer {markers: Array(19), clusters: Array(0), algorithm: {…}, renderer: B, onClusterClick: ƒ, …}...
Custom Algorithm Result: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {position: _.zr, markers: Array(3), count: 3}
1: {position: _.zr, markers: Array(5), count: 5}
2: {position: _.zr, markers: Array(4), count: 4}
3: {position: _.zr, markers: Array(3), count: 3}
4: {position: _.zr, markers: Array(1), count: 1}
5: {position: _.zr, markers: Array(1), count: 1}
6: {position: _.zr, markers: Array(1), count: 1}
7: {position: _.zr, markers: Array(1), count: 1}
...
error in chrome console:
Uncaught TypeError: r is not iterable
at t.MarkerClusterer.render (markerclusterer.ts:187:31)
at t.MarkerClusterer.onAdd (markerclusterer.ts:233:10)
at Hqa.draw (overlay.js:4:860)
at Iqa.vi (overlay.js:4:1116)
at Apa (map.js:54:428)
at map.js:54:1