Search code examples
google-maps-api-3

Update clustered markers in Google Map with map filters


I just create a google map with markers and a select to filter those markers by category

    #map-canvas {
    width: 500px;
    height: 500px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=&v=3.0&sensor=true&language=ee&dummy=dummy.js"></script>
<div id="map-canvas"></div>
<select id="type" onchange="filterMarkers(this.value);">
    <option value="">Please select category</option>
    <option value="second">second</option>
    <option value="car">car</option>
    <option value="third">third</option>
</select>

and the js:

var gmarkers1 = [];
var markers1 = [];
var infowindow = new google.maps.InfoWindow({
    content: ''
});

// Our markers
markers1 = [
    ['0', 'Title 1', 52.4357808, 4.991315699999973, 'car'],
    ['1', 'Title 2', 52.4357808, 4.981315699999973, 'third'],
    ['2', 'Title 3', 52.4555687, 5.039231599999994, 'car'],
    ['3', 'Title 4', 52.4555687, 5.029231599999994, 'second']
];

/**
 * Function to init map
 */

function initialize() {
    var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
    var mapOptions = {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.TERRAIN
    };

    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    for (i = 0; i < markers1.length; i++) {
        addMarker(markers1[i]);
    }
}

/**
 * Function to add marker to map
 */

function addMarker(marker) {
    var category = marker[4];
    var title = marker[1];
    var pos = new google.maps.LatLng(marker[2], marker[3]);
    var content = marker[1];

    marker1 = new google.maps.Marker({
        title: title,
        position: pos,
        category: category,
        map: map
    });

    gmarkers1.push(marker1);

    // Marker click listener
    google.maps.event.addListener(marker1, 'click', (function (marker1, content) {
        return function () {
            console.log('Gmarker 1 gets pushed');
            infowindow.setContent(content);
            infowindow.open(map, marker1);
            map.panTo(this.getPosition());
            map.setZoom(15);
        }
    })(marker1, content));
}

/**
 * Function to filter markers by category
 */

filterMarkers = function (category) {
    for (i = 0; i < markers1.length; i++) {
        marker = gmarkers1[i];
        // If is same category or category not picked
        if (marker.category == category || category.length === 0) {
            marker.setVisible(true);
        }
        // Categories don't match 
        else {
            marker.setVisible(false);
        }
    }
}

// Init map
initialize();

I'm trying to cluster markers using the MarkerClusterer function. So I added as is shown here:

function initialize() {
    var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
    var mapOptions = {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.TERRAIN
    };

    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    for (i = 0; i < markers1.length; i++) {
        addMarker(markers1[i]);
    }
    var markerCluster = new MarkerClusterer(map, gmarkers1, {imagePath: 'MY_CUSTOM_DIR/images/m'});
}

Now this works greats. Markers are grouped, however, when I filter by category, the clusters are not updated. I have tried to read some tutorials about the repaint() function but I can solve it.


Solution

  • If you clear out the MarkerClusterer (MarkerCluster.clearMarkers()), then re-add the ones that you want visible, it works for me.

    filterMarkers = function(category) {
      var newmarkers = [];
      for (i = 0; i < markers1.length; i++) {
        marker = gmarkers1[i];
        // If is same category or category not picked
        if (marker.category == category || category.length === 0) {
          newmarkers.push(marker);
        }
      }
      markerCluster.clearMarkers();
      markerCluster.addMarkers(newmarkers);
    }
    

    proof of concept fiddle

    code snippet:

    /**
     * Function to init map
     */
    function initialize() {
      var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
      var mapOptions = {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      };
    
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      for (i = 0; i < markers1.length; i++) {
        addMarker(markers1[i]);
      }
      markerCluster = new MarkerClusterer(map, gmarkers1, {
        imagePath: 'https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m'
      });
    }
    
    /**
     * Function to add marker to map
     */
    function addMarker(marker) {
      var category = marker[4];
      var title = marker[1];
      var pos = new google.maps.LatLng(marker[2], marker[3]);
      var content = marker[1];
    
      marker1 = new google.maps.Marker({
        title: title,
        position: pos,
        category: category,
        map: map
      });
    
      gmarkers1.push(marker1);
    
      // Marker click listener
      google.maps.event.addListener(marker1, 'click', (function(marker1, content) {
        return function() {
          console.log('Gmarker 1 gets pushed');
          infowindow.setContent(content);
          infowindow.open(map, marker1);
          map.panTo(this.getPosition());
          map.setZoom(15);
        }
      })(marker1, content));
    }
    
    /**
     * Function to filter markers by category
     */
    filterMarkers = function(category) {
      var newmarkers = [];
      for (i = 0; i < markers1.length; i++) {
        marker = gmarkers1[i];
        // If is same category or category not picked
        if (marker.category == category || category.length === 0) {
          newmarkers.push(marker);
        }
      }
      markerCluster.clearMarkers();
      markerCluster.addMarkers(newmarkers);
    }
    google.maps.event.addDomListener(window, "load", initialize);
    
    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
      content: ''
    });
    var markerCluster;
    
    // Our markers
    markers1 = [
      ['0', 'Title 1', 52.4357808, 4.991315699999973, 'car'],
      ['1', 'Title 2', 52.4357808, 4.981315699999973, 'third'],
      ['2', 'Title 3', 52.4555687, 5.039231599999994, 'car'],
      ['3', 'Title 4', 52.4555687, 5.029231599999994, 'second']
    ];
    body,
    html {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    #map-canvas {
      width: 100%;
      height: 95%;
    }
    <script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map-canvas"></div>
    <select id="type" onchange="filterMarkers(this.value);">
      <option value="">Please select category</option>
      <option value="second">second</option>
      <option value="car">car</option>
      <option value="third">third</option>
    </select>