The clustering functionality on Google Maps markers is ineffective

Encountering an issue with the marker clustering feature on this website (the map is located at the bottom).

After including the markerclusterer.js file, I initiated the clustering with the following code:

var mc = new MarkerClusterer(map);

If you need the uncompressed JS file, it can be accessed here: here

Could it be possible that the issue lies in the way I'm initializing the clustering? Any suggestions would be greatly appreciated. Thank you.

Answer №1

https://i.sstatic.net/uJiKZ.png After testing the code below on your platform, I confirm that it is functioning as expected. Feel free to replace your current app.js code with the provided code snippet.

var map;
var markers = [];

/* MAP FILTER */

// Capture click on the input
jQuery(function () {
    jQuery('input[name=filter]').change(function () {
      var filterClickId = jQuery(this).attr('id');
      MarkersFilter(filterClickId);
  });
});

// Show or hide marker based on input state
function MarkersFilter(category){
   if (document.getElementById(category).checked === false) { // Hide the marker
      for (var i=0;i<markers.length;i++) {
         if (markers[i].properties == category)  {
            markers[i].setVisible(false);
         }
      }
   } else { // Show the marker
      for (var i=0;i<markers.length;i++) {
         if (markers[i].properties == category)  {
            markers[i].setVisible(true);
         }
      }
   }
}

/* END OF MAP FILTER */

/* ICONS FOR DIFFERENT TYPES */

var iconBase = '/mapshapes/';
        var icons = {
          schools: {
            icon :{
              url: iconBase + 'schools_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          commerce: {
            icon: {
              url: iconBase + 'commerce_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          culture: {
            icon:{
              url: iconBase + 'culture_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          health: {
            icon:{
              url : iconBase + 'health_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          sports: {
            icon:{
              url: iconBase + 'sports_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          safety: {
            icon:{
              url: iconBase + 'safety_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          hospitality: {
            icon:{
              url: iconBase + 'hospitality_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          publictransport: {
            icon:{
              url: iconBase + 'publictransport_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          libris: {
            icon:{
              url: iconBase + 'libris.png',
              scaledSize: new google.maps.Size(70, 70),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          }
        };

function loadMarkers(map) {

  var infoWindow = new google.maps.InfoWindow();
  geojson_url = '/project.geojson';

  jQuery.getJSON(geojson_url, function(result) {
      data = result['locations'];
      jQuery.each(data, function(key, val) {
        var point = new google.maps.LatLng(parseFloat(val['geometry']['coordinates'][0]), parseFloat(val['geometry']['coordinates'][1]));
        var titleText = val['properties']['name'];    
        var address = val['geometry']['address'];
        var marker = new google.maps.Marker({
           position: point,
           title: titleText,
           icon: icons[val['type']].icon,
           map: map,
           properties: val['type']
        });
        var markerInfo = "<div><h3>" + titleText + "</h3> " + address + "</div>";
        marker.addListener('click', function() {
          infoWindow.close();
          infoWindow.setContent(markerInfo);
          infoWindow.open(map, marker);
        });
        markers.push(marker);
      });
      var Marker = new MarkerClusterer(map, markers, {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
      Marker.addMarkers(markers);

  });
}

/* CREATE MAP */
function initMap() {
    map_options = {
      zoom: 16,
      center: {lat: 50.808757, lng: 4.314472},
      styles: [
    {
        "featureType": "administrative",
        "elementType": "labels.text.fill",
        "stylers": [
            {
                "color": "#444444"
            }
        ]
    },
    {
        "featureType": "landscape",
        "elementType": "all",
        "stylers": [
            {
                "color": "#f2f2f2"
            }
        ]
    },
    {
        "featureType": "poi",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "road",
        "elementType": "all",
        "stylers": [
            {
                "saturation": -100
            },
            {
                "lightness": 45
            }
        ]
    },
    {
        "featureType": "road.highway",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "simplified"
            }
        ]
    },
    {
        "featureType": "road.arterial",
        "elementType": "labels.icon",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "transit",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "water",
        "elementType": "all",
        "stylers": [
            {
                "color": "#46bcec"
            },
            {
                "visibility": "on"
            }
        ]
    }
]
    }


    map_document = document.getElementById('projectmap');
    map = new google.maps.Map(map_document,map_options);
    loadMarkers(map);
}

google.maps.event.addDomListener(window, 'load', initMap);

https://i.sstatic.net/LmOd7.png

Answer №2

Once you have pushed all the markers within the array using the loadMarkers method, ensure that you call the MarkerCluster api. Remember to include MasterCluster.addMarkers(markers) after the jquery.each loop.

Furthermore, make sure to save the reference of the MasterCluster instance on line 99 in app.js and pass it to the loadMarker method. This will allow you to call the addMarkers api on it.

Answer №3

For optimal performance, it is recommended to declare and initialize the markerCluster after loading the markers

var markerCluster = new MarkerClusterer(map, markers,{
  imagePath: 'https://example.com/markerclusterer/m',
  zoomOnClick: true
});

Answer №4

Once the initialization process is completed at line 100, save the MarkerCluster instance in a variable like so:

var cluster = new MarkerCluster(map);

When invoking loadMarkers() in the next line, pass this variable as shown below:

loadMarkers(cluster);

Receive the argument in the loadMarkers function as demonstrated below:

function loadMarkers(markerCluster) { // markerCluster will be utilized in the final line of this function as depicted below.

Within the loadMarkers function, following the jQuery foreach loop, insert the following line:

markerCluster.addMarkers(markers);

Answer №5

Your code is in need of some adjustments. The recommendations I provided were not followed. If you haven't made any other changes, simply replace your entire app.js file with the code below. I have made the necessary modifications and included the complete file.

var map;
var markers = [];

/* MAP FILTER */

// Capture click on the input
jQuery(function () {
    jQuery('input[name=filter]').change(function () {
      var filterClickId = jQuery(this).attr('id');
      MarkersFilter(filterClickId);
  });
});

// Show or hide marker based on the input state
function MarkersFilter(category){
   if (document.getElementById(category).checked===false) { // Hide the marker
      for (var i=0;i<markers.length;i++) {
         if (markers[i].properties==category)  {
            markers[i].setVisible(false);
         }
      }
   } else { // Show the marker
      for (var i=0;i<markers.length;i++) {
         if (markers[i].properties==category)  {
            markers[i].setVisible(true);
         }
      }
   }
}

/* END MAP FILTER */

/* ICONS FOR DIFFERENT TYPES */

var iconBase = '/mapshapes/';
        var icons = {
          schools: {
            icon :{
              url: iconBase + 'schools_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          trade: {
            icon: {
              url: iconBase + 'trade_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          culture: {
            icon:{
              url: iconBase + 'culture_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          health: {
            icon:{
              url : iconBase + 'health_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          sports: {
            icon:{
              url: iconBase + 'sports_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          safety: {
            icon:{
              url: iconBase + 'safety_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          catering: {
            icon:{
              url: iconBase + 'catering_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          publictransport: {
            icon:{
              url: iconBase + 'publictransport_maps.svg',
              scaledSize: new google.maps.Size(35, 35),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          },
          libris: {
            icon:{
              url: iconBase + 'libris.png',
              scaledSize: new google.maps.Size(70, 70),
              origin: new google.maps.Point(0,0),
              anchor: new google.maps.Point(0, 0)
            }
          }
        };

function loadMarkers(map) {

  var infoWindow = new google.maps.InfoWindow();
  geojson_url = '/project.geojson';

  jQuery.getJSON(geojson_url, function(result) {
      data = result['locations'];
      jQuery.each(data, function(key, val) {
        var point = new google.maps.LatLng(parseFloat(val['geometry']['coordinates'][0]), parseFloat(val['geometry']['coordinates'][1]));
        var titleText = val['properties']['name'];    
        var address = val['geometry']['address'];
        var marker = new google.maps.Marker({
           position: point,
           title: titleText,
           icon: icons[val['type']].icon,
           map: map,
           properties: val['type']
        });
        mc.addMarkers(markers);
        var markerInfo = "<div><h3>" + titleText + "</h3> " + address + "</div>";
        marker.addListener('click', function() {
          infoWindow.close();
          infoWindow.setContent(markerInfo);
          infoWindow.open(map, marker);
        });
        markers.push(marker);
      });
      var Marker = new MarkerCluster(map, markers, {imagePath: 'http://localhost/libris/mapshapes/'});
  });
}

/* CREATE MAP */
function initMap() {
    map_options = {
      zoom: 16,
      center: {lat: 50.808757, lng: 4.314472},
      styles: [
    {
        "featureType": "administrative",
        "elementType": "labels.text.fill",
        "stylers": [
            {
                "color": "#444444"
            }
        ]
    },
    {
        "featureType": "landscape",
        "elementType": "all",
        "stylers": [
            {
                "color": "#f2f2f2"
            }
        ]
    },
    {
        "featureType": "poi",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "road",
        "elementType": "all",
        "stylers": [
            {
                "saturation": -100
            },
            {
                "lightness": 45
            }
        ]
    },
    {
        "featureType": "road.highway",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "simplified"
            }
        ]
    },
    {
        "featureType": "road.arterial",
        "elementType": "labels.icon",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "transit",
        "elementType": "all",
        "stylers": [
            {
                "visibility": "off"
            }
        ]
    },
    {
        "featureType": "water",
        "elementType": "all",
        "stylers": [
            {
                "color": "#46bcec"
            },
            {
                "visibility": "on"
            }
        ]
    }
]
    }


    map_document = document.getElementById('projectmap');
    map = new google.maps.Map(map_document,map_options);
    loadMarkers(map);
}

google.maps.event.addDomListener(window, 'load', initMap);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Continuously spinning loading icon appears when submission button is triggered

We are currently experiencing some issues with our mobile forms. Our users utilize a mobile form to submit contact requests, but the problem arises when they hit 'submit' - the loading icon continues to spin even after the form has been successf ...

Exporting variables in node.js allows you to share data between different

Hi, I'm currently working with a file that looks like this: module.exports = { some variables that are being exported here, execute(message) { } } I want to export the message parameter to another file. I've attempted using var msg ...

Add a static line of names to a JavaScript file

Looking for a way to generate data with the following javascript snippet: for (var l = 0; l < table.length; l +=1) { fs.appendFile('results/Test'+ username +'.csv', var1+i, var2 , function(err) { if(err) { return c ...

Next.js version 13 is causing the page to refresh each time the router is pushed

I am currently developing a search application using NextJs 13, and I have encountered an issue where the page refreshes every time I click the search button. Strangely, this only happens when the application is deployed on Vercel. When running the app l ...

What are the methods for incorporating reflection into three.js?

While working on a WebGL project using Three.js, I am aiming to incorporate a reflective cube surface that mimics the appearance of a mobile phone display. The surface should be able to reflect light while maintaining a black color scheme. ...

AngularJS: Utilizing bold text to enhance the separation of concerns between controllers and templates

In my AngularJS version 1 application with Ecmascript 6, I have a requirement to display a string where one part is in normal weight and the other part is bold. For instance, consider the following scenarios: Will start now Will start in 6 minutes Will ...

Explore the wonders of Jest and Playwright by heading over to youtube.com and discovering an exciting video!

As part of my job responsibilities, I have been tasked with automating tests for a web application that our team developed. Using Playwright and Jest, I am required to write automation scripts from scratch. To practice utilizing Playwright, I decided to cr ...

Guide on incorporating a library into your Ionic application without the need to upload it to npm

Recently, I successfully created an Angular application, an Ionic application, and a custom library in my workspace. I am able to import the library files into my Angular application but facing challenges when trying to import them into my Ionic applicat ...

The Impact of Spaces in Inline Scripting within Asp.NET

As I was coding in JavaScript on an Asp.NET page today, I encountered a small issue. Here's what happened: <script type="type/javascript"> var elementID = document.getElementById("<%=txtMyServerControl.ClientID %>") </script> T ...

Using MeanJS to assign a Mongoose object reference to an array in Angular

Having an issue with MeanJS and using the $update function of the $resource service in Angular provided by MeanJS. Here is a basic outline of my problem: Mongoose schema: var mongoose = require('mongoose'), Schema = mongoose.Schema; var Lotion ...

Display all saved bookmarks by utilizing JavaScript

How can I utilize Javascript to display a complete list of my bookmarks? Any advice on achieving this would be greatly appreciated. Thank you in advance. ...

The function grunt.task.run() is malfunctioning

Currently, I am experimenting with integrating Grunt into my Express application. Here is a snippet of the code I have: var grunt = require('grunt'); require(process.cwd() + '/gruntfile.js')(grunt); grunt.task.run('development&ap ...

What is the best way to pass the index value of a v-for loop as an argument to a computed property function in Vue?

I'm looking to pass the index value from a v-for loop (inside a path tag) as a parameter to a function stateData(index) defined in a computed property in Vue. I attempted to achieve this using v-model="stateData[index]", but an error is being displaye ...

What is the optimal event to trigger a function when there is any modification in a text area using Javascript?

I need a function to trigger every time there is any modification in my textarea, such as characters being typed, deleted, cut, pasted, etc. Currently, I am using: onkeyup || onmousemove = function(); It appears that only onmousemove is being triggered. ...

How can a loading bar be shown while a PHP page is loading?

I currently have an HTML form that directs to a PHP file upon submission. The PHP file takes some time to load due to background processes running, so I am interested in implementing a progress bar or alert to indicate when the file is fully loaded. Does ...

Tips for launching a node.js application using pm2 in cluster mode

Our team is currently attempting to launch our application using pm2 0.12.8 on an Ubuntu 14.04 system with an octa-core processor. We followed the instructions provided in the GitHub readme file, which includes a straightforward command for running the Nod ...

Manipulate and transform elements within an array using both Filter and Map functionalities in React

Below is the component I am working with: function Params(props) { const { Parameters } = useFetchParams(); return ( <div className='Params'> { Parameters && Parameters.map(parameter =&g ...

Enhance your cloud functions by updating data

Recently, I encountered an issue with a function I wrote that interacts with the Real Time Database. Every time I attempted to write data to a specific node, it would add the complete dataset and then promptly delete everything except one entry. https://i ...

Difficulty accessing `evt.target.value` with `RaisedButton` in ReactJS Material UI

My goal is to update a state by submitting a value through a button click. Everything works perfectly when using the HTML input element. However, when I switch to the Material UI RaisedButton, the value isn't passed at all. Can someone help me identif ...

Is there a way to find out the ultimate destination of a shortened URL without actually opening the webpage?

I am trying to implement a feature where I can click on links within email messages and have the full link displayed in a separate pane using jQuery. However, I am facing some challenges with this implementation. My plan is to use AJAX to call a PHP scrip ...