Home > database >  Toggle groups of markers in Google Maps API
Toggle groups of markers in Google Maps API

Time:10-27

I have several groups ("state") of markers on a map which I want to be able to toggle their visibility without reloading the page.

I'm finding lots of variations of having markergroups but they all seem to be not working with this google api version.

Here is the HTML

<input type="checkbox" id="state" name="Backlog" checked> Backlog
<input type="checkbox" id="state" name="Breached" checked> Breached
<input type="checkbox" id="state" name="Active" checked> Active
<input type="checkbox" id="state" name="Scheduled" checked> Scheduled
<div id="map" style="height:800px;"></div>

Here is the javascript

<script>
function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
       zoom: 6,
        center: {lat: 54.3266311, lng: -2.7585563},
        mapTypeId: 'roadmap'
    });

    var infoWin = new google.maps.InfoWindow();

    var markers = locations.map(function(location, i) {
        var marker = new google.maps.Marker({
            position: location,
            icon: 'https://maps.google.com/mapfiles/kml/' location.type,
        });
        google.maps.event.addListener(marker, 'click', function(evt) {
            infoWin.setContent(location.info);
            infoWin.open(map, marker);
        })
        return marker;
    });

    var markerCluster = new MarkerClusterer(map, markers, {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
            minimumClusterSize: 2,
            maxZoom: 4,
            zoomOnClick: false
        }
    );
}

var locations = [{lat:53.750503,lng:-2.429168,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199925"},{lat:51.290162,lng:-0.833112,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 76669845"},{lat:51.301737,lng:0.051969,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199930"},{lat:50.525378,lng:-3.594341,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875603"},{lat:51.581895,lng:-0.724800,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78581052"},{lat:50.391133,lng:-4.072097,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78106941"},{lat:51.318527,lng:-1.021035,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78396115"},{lat:50.443925,lng:-3.561630,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875582"},{lat:53.625107,lng:-2.337432,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80444510"},{lat:52.432582,lng:-2.026563,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80423141"}]

Any help would be great :) I don't mind getting rid of the clusters, I just can't figure out how to!

CodePudding user response:

You can use the screenshot of resulting map with one checkbox unchecked

(if you want the clusters to reflect the currently visible icons, you will need to update the markers array passed in to it, rather than the visible property of the markers).

code snippet:

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 6,
    center: {
      lat: 54.3266311,
      lng: -2.7585563
    },
    mapTypeId: 'roadmap'
  });

  var infoWin = new google.maps.InfoWindow();

  var markers = locations.map(function(location, i) {
    var marker = new google.maps.Marker({
      position: location,
      icon: 'https://maps.google.com/mapfiles/kml/'   location.type,
    });
    google.maps.event.addListener(marker, 'click', function(evt) {
      infoWin.setContent(location.info);
      infoWin.open(map, marker);
    })
    return marker;
  });

  var markerCluster = new MarkerClusterer(map, markers, {
    imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
    minimumClusterSize: 2,
    maxZoom: 4,
    zoomOnClick: false
  });
  google.maps.event.addDomListener(document.getElementById('Backlog'), 'click', clickListener);
  google.maps.event.addDomListener(document.getElementById('Breached'), 'click', clickListener);
  google.maps.event.addDomListener(document.getElementById('Active'), 'click', clickListener);
  google.maps.event.addDomListener(document.getElementById('Scheduled'), 'click', clickListener);

  function clickListener() {
    var typeId = this.id;
    var type;
    for (var i = 0; i < iconMapping.length; i  ) {
      if (iconMapping[i].state == typeId)
        type = iconMapping[i].icon;
    }
    var markers = markerCluster.getMarkers();
    for (var i = 0; i < markers.length; i  ) {
      if (markers[i].getIcon().includes(type)) {
        markers[i].setVisible(this.checked);
      }
    }
  }
}
var iconMapping = [{
    icon: 'ylw-square-lv.png',
    state: 'Backlog'
  },
  {
    icon: 'blu-square-lv.png',
    state: 'Active'
  }
];
var locations = [{
  lat: 53.750503,
  lng: -2.429168,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 75199925"
}, {
  lat: 51.290162,
  lng: -0.833112,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 76669845"
}, {
  lat: 51.301737,
  lng: 0.051969,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 75199930"
}, {
  lat: 50.525378,
  lng: -3.594341,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 78875603"
}, {
  lat: 51.581895,
  lng: -0.724800,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 78581052"
}, {
  lat: 50.391133,
  lng: -4.072097,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 78106941"
}, {
  lat: 51.318527,
  lng: -1.021035,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 78396115"
}, {
  lat: 50.443925,
  lng: -3.561630,
  type: '/paddle/ylw-square-lv.png',
  state: 'Backlog',
  info: "<strong>Order ID:</strong> 78875582"
}, {
  lat: 53.625107,
  lng: -2.337432,
  type: '/paddle/blu-square-lv.png',
  state: 'Active',
  info: "<strong>Order ID:</strong> 80444510"
}, {
  lat: 52.432582,
  lng: -2.026563,
  type: '/paddle/blu-square-lv.png',
  state: 'Active',
  info: "<strong>Order ID:</strong> 80423141"
}]
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */

#map {
  height: 90%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>

<head>
  <title>Marker Clustering</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
  <script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>

  <!-- jsFiddle will insert css and js -->
</head>

<body>
  <input type="checkbox" name="state" id="Backlog" checked> Backlog
  <input type="checkbox" name="state" id="Breached" checked> Breached
  <input type="checkbox" name="state" id="Active" checked> Active
  <input type="checkbox" name="state" id="Scheduled" checked> Scheduled
  <div id="map"></div>

  <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async></script>
</body>

</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

If you want the clusters to reflect the number of visible markers, you need to change the code to update the markers array in the MarkerClusterer:

function clickListener() {
   var typeId = this.id;
   var type;
   var visibleMarkers = [];
   for (var i=0; i<iconMapping.length;i  ) {
     if (iconMapping[i].state==typeId)
       type = iconMapping[i].icon;
   }
   for (var i=0; i<markers.length; i  ) {
      if (markers[i].getIcon().includes(type)) {
         markers[i].setVisible(this.checked);
      }
      if (markers[i].getVisible())
        visibleMarkers.push(markers[i]);
   }
   markerCluster.clearMarkers();
   markerCluster.addMarkers(visibleMarkers);
}

screenshot of clusters showing only visible markers

code snippet:

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
       zoom: 6,
        center: {lat: 54.3266311, lng: -2.7585563},
        mapTypeId: 'roadmap'
    });

    var infoWin = new google.maps.InfoWindow();

    var markers = locations.map(function(location, i) {
        var marker = new google.maps.Marker({
            position: location,
            icon: 'https://maps.google.com/mapfiles/kml/' location.type,
        });
        google.maps.event.addListener(marker, 'click', function(evt) {
            infoWin.setContent(location.info);
            infoWin.open(map, marker);
        })
        return marker;
    });

    var markerCluster = new MarkerClusterer(map, markers, {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
            minimumClusterSize: 2,
            maxZoom: 4,
            zoomOnClick: false
        }
    );
    google.maps.event.addDomListener(document.getElementById('Backlog'), 'click', clickListener);
    google.maps.event.addDomListener(document.getElementById('Breached'), 'click', clickListener);
    google.maps.event.addDomListener(document.getElementById('Active'), 'click', clickListener);
    google.maps.event.addDomListener(document.getElementById('Scheduled'), 'click', clickListener);
    
    function clickListener() {
       var typeId = this.id;
       var type;
       var visibleMarkers = [];
       for (var i=0; i<iconMapping.length;i  ) {
         if (iconMapping[i].state==typeId)
           type = iconMapping[i].icon;
       }
       console.log("click type=" type)
       for (var i=0; i<markers.length; i  ) {
          console.log("markers[" i "] icon=" markers[i].getIcon() " map=" markers[i].getMap() "visible=" markers[i].getVisible());
          if (markers[i].getIcon().includes(type)) {
             markers[i].setVisible(this.checked);
          console.log("markers[" i "] map=" markers[i].getMap() " visible=" markers[i].getVisible())
          }
          if (markers[i].getVisible())
            visibleMarkers.push(markers[i]);
       }
       markerCluster.clearMarkers();
       console.log("after clear:" markerCluster.getMarkers().length)
       markerCluster.addMarkers(visibleMarkers);
       console.log("after add:" markerCluster.getMarkers().length)

    }
}
var iconMapping = [
{icon:'ylw-square-lv.png',state:'Backlog'},
{icon:'blu-square-lv.png',state:'Active'}
];
var locations = [{lat:53.750503,lng:-2.429168,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199925"},{lat:51.290162,lng:-0.833112,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 76669845"},{lat:51.301737,lng:0.051969,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199930"},{lat:50.525378,lng:-3.594341,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875603"},{lat:51.581895,lng:-0.724800,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78581052"},{lat:50.391133,lng:-4.072097,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78106941"},{lat:51.318527,lng:-1.021035,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78396115"},{lat:50.443925,lng:-3.561630,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875582"},{lat:53.625107,lng:-2.337432,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80444510"},{lat:52.432582,lng:-2.026563,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80423141"}]
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
#map {
  height: 90%;
}

/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Marker Clustering</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>

    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
<input type="checkbox" name="state" id="Backlog" checked> Backlog
<input type="checkbox" name="state" id="Breached" checked> Breached
<input type="checkbox" name="state" id="Active" checked> Active
<input type="checkbox" name="state" id="Scheduled" checked> Scheduled
    <div id="map"></div>

    <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly&channel=2"
      async
    ></script>
  </body>
</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related