Get a list of markers in bounds of google map using markerclusterer v3

user1881482 picture user1881482 · Jan 31, 2014 · Viewed 30.7k times · Source

I currently have a google map populated with data from a database. I am using markerclusterer v3 to cluster the markers to make the map load faster. I have scoured the docs and cannot seem to find a way to get a listing of all markers that are in the map bounds. Essentially I am trying to create an external list of the markers addresses in an external div. Currently on page load it appends the whole list of addressees. What I would like to do is have only the markers, and the markers contained in clusters that appear on that map at that time to appear in the list. So at zoom 13 there is 6 clusters with 3 in each and one solo marker. At zoom 14 there is 3 clusters of 3 and 2 solo markers. At zoom 13 there would be 19 addresses in the list and at zoom 14 there would be 11 addresses in the list. Just a list of the markers in bounds of the map. I currently load all addresses once on initial map creation. I thought of creating an ajax post to the server on each zoom, but thought that was a little unnecessary to have a server call on each map movement. There has to be a way to get the list of markers in bounds controlled by markerclusterer.

.js

var markers = [];       
for (var i = 0; i < data.coords.length; i++) {
    var dataInd = data.coords[i];
    var latLng = new google.maps.LatLng(dataInd[1],dataInd[2]);
    var marker = new google.maps.Marker({position: latLng});
    markers.push(marker);

}
var map;
var myOptions = {
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};
function init() {
    map = new google.maps.Map(document.getElementById("map"), myOptions);
    var markerCluster = new MarkerClusterer(map, markers);
}
for (var i=0; i < markers.length; i++) {
    if (map.getBounds.contains(markers[i])) {
         console.log(markers);
    } else {
         console.log('failed');
    }
}

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

Answer

geocodezip picture geocodezip · Jan 31, 2014
  1. Make your markers array global.
  2. Make your map variable global (or at least in scope).
  3. Run this code:

    for (var i=0; i < markers.length; i++) 
    {
        if (map.getBounds().contains(markers[i].getPosition()))
        {
            // markers[i] in visible bounds
        } 
        else 
        {
            // markers[i] is not in visible bounds
        }
    }
    

Update: You may need to do this (if you are trying to add the loop to your init function). Other options (you haven't been real clear about why you want to do this):

  1. the marker test in your initial loop that adds the markers.
  2. to use addListenerOnce rather than addListener.
  3. you may want to re-render the "listOfItems" whenever the map is zoomed or panned (when the bounds changes again)

    var map = null;
    var markers = [];
    function init() 
    {
        var myOptions = 
        {
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("map"), myOptions);
        for (var i = 0; i < data.coords.length; i++) 
        {
            var dataInd = data.coords[i];
            var latLng = new google.maps.LatLng(dataInd[1],dataInd[2]);
            var marker = new google.maps.Marker({ position: latLng });        
            markers.push(marker);
            $('#listOfItems').append('<li>' + latlng + '</li>');
        }
    
        var markerCluster = new MarkerClusterer(map, markers);
    
        google.maps.event.addListener(map, 'bounds_changed', function() 
        {
            for (var i = 0; i < markers.length; i++) 
            {
                if (map.getBounds().contains(markers[i].getPosition())) 
                {
                    // markers[i] in visible bounds
                } 
                else 
                {
                    // markers[i] is not in visible bounds
                }
            }
        });
    }
    
    google.maps.event.addDomListener(window, 'load', init);