2

I've been working on my map which gets its details from a MySQL database. I use MarkerCluster Plus to cluster my markers but would like to add the drop animation to it.

I found this Q&A, but cannot get it to work with my database. Using Drop Markers and MarkerClusterer together?

How do I add the drop animation to my code?

My test map is here: http://mymap.mooo.com

 var customIcons = {
  BOO: {
    icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png'        
  },
  CIE: {
    icon: 'http://labs.google.com/ridefinder/images/mm_20_green.png' 
  } 
};

var cluster =[];     
var min = .999;
var max = 1.001;

 
function load() {
  var map = new google.maps.Map(document.getElementById("map"), {
    center: new google.maps.LatLng(0,28.287167),
    zoom: 3,
    mapTypeId: 'roadmap'
  });
       
  var infoWindow = new google.maps.InfoWindow;    
  var mcOptions = {gridSize: 20, maxZoom: 19};    
  // this variable will collect the html which will eventually be placed in the side_bar 
  var side_bar_html = ""; 
              
  // Change this depending on the name of your PHP file
  downloadUrl("phpsqlajax_genxml2.php", function(data) {
    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
      var name = markers[i].getAttribute("assetno");
      var address = markers[i].getAttribute("address");
      var type = markers[i].getAttribute("type");
      var assetdesc = markers[i].getAttribute("assetdesc");
      var location = markers[i].getAttribute("location");
      var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat"))* (Math.random() * (max - min) + min) ,
          parseFloat(markers[i].getAttribute("lng"))* (Math.random() * (max - min) + min));
      var html = "<div style='font-family: Arial; font-size: 12px;'><b>" + name + "</b> <br/>" + assetdesc + "<br/>" + location + "</div>";
      var icon = customIcons[type] || {};
      
      setTimeout(function() {
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,            
            animation: google.maps.Animation.DROP   
        });         
        return marker;
        
        setTimeout(function () {                
            bindInfoWindow(marker, map, infoWindow, html);       
            cluster.push(marker);   
            // save the info we need to use later for the side_bar
            // add a line to the side_bar html
            side_bar_html += '<a href="javascript:myclick(' + (cluster.length-1) + ')">' + name + ' - ' + assetdesc +'<\/a><br>';   
        }, 1500);
      }, i * 50);
      
    }                     
    var markerCluster = new MarkerClusterer(map, cluster, mcOptions);   
    // put the assembled side_bar_html contents into the side_bar div
    document.getElementById("side_bar").innerHTML = side_bar_html;        
  });     
}

// This function picks up the click and opens the corresponding info window
function myclick(i) {
    google.maps.event.trigger(cluster[i], "click");
}   

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
      new ActiveXObject('Microsoft.XMLHTTP') :
      new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    }
  };

  request.open('GET', url, true);
  request.send(null);
}

function doNothing() {}
0

2 Answers 2

1

I think I found the problem with your code. I've highlighted the line below:

setTimeout(function() {
    ...

        icon: icon.icon,            
        animation: google.maps.Animation.DROP   
    });         

    return marker; // <---!!!!!!! This line !!!!!!!!!

    setTimeout(function () {                
        bindInfoWindow(marker, map, infoWindow, html);       
    ...

}, i * 50);

Calling return marker; here exits the downloadUrl function. Anything after the return statement isn't executed, so the second setTimeout is never reached and the marker is never added to the cluster.

Because your code is all in one function, the second setTimeout has access to the marker variable. Removing return marker; will allow the code contained in the second setTimeout to execute. Note that I can't test that this will fix the issue because I don't have access to your data script and link that you provided doesn't match the example code in the question. But I think it should do the trick.

Update (10/15/2012): Reply to Comment

Ok. I see two problems with your demo code.

First, remove the random number generation. I used that in my example to generate random coordinates. You seem to have lat/lng for all of your points, and multiplying them by a random number is not what you want do.

This:

var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat"))* (Math.random() * (max - min) + min) ,
parseFloat(markers[i].getAttribute("lng"))* (Math.random() * (max - min) + min));

Should be:

var point = new google.maps.LatLng(
    parseFloat(markers[i].getAttribute("lat")),
    parseFloat(markers[i].getAttribute("lng"))
);

Secondly, you need to add the markers to an instance of markerCluster. Right now, they are just being added to the array cluster. Either make cluster a markerClusterer instance, or instantiate another variable to use as your markerClusterer instance. For example: var mc = new MarkerClusterer(map);. Then use mc.addMarker(marker); to add a marker to the cluster in the second setTimeout.

Update (10/16/2012): Reply to 2nd Comment

Sorry--there's still one issue with your code. Because of the way JavaScript works (asynchronously) and the way your code is structured, when the first setTimeout is called, all the variables used to construct the marker (point, type, etc) are actually referencing the last item in your data. You have to break your code into smaller functions (generally a good practice to follow anyway), and use what's called a closure. More on that here: https://stackoverflow.com/questions/111102/how-do-javascript-closures-work. Here is a simplified example how this technique can be used to implement marker animation + markerClusterer: http://jsfiddle.net/WASLk/2/.

Note that I didn't need to do this in my original example because all the data used to build the markers (the random coordinates) was contained within the addMarker function.

2
  • Thanks for your reply Casey. Sadly that won't work either. Updated my code with your suggestion here: mymap.mooo.com/index2.html It's not only that the cluster won't work, but my marker locations are wrong as well. They should be all over Africa, but are all placed into Zambia. So it looks like it's still not entering the 2nd timeout function for some reason.
    – wibni
    Commented Oct 15, 2012 at 3:29
  • Thanks a lot for that Casey! I'm getting a lot closer. Got the cluster and the animation working together now. Only issue is that it does not add my individual markers. It adds my last marker as many times as I have markers. As you can also see in the side bar it's all the same item. The XML is correct. Regarding the random numbers, that is actually intentionally. The location details are not detailed enough, i.e. I might just only have an address as New York, USA. So therefore I'm adding an offset to seperate the markers on the map.
    – wibni
    Commented Oct 16, 2012 at 14:19
0

A blog post from the Author that answered the question you linked to seems to have it figured out.

Looks like you need to add a setTimeout function and return the marker and add it to the cluster.

You may notice that to get the marker animations to work, the map attribute of the marker must be set. If not, the marker won't be added to the map, and therefore, there will be no animation. However, if you set the map and animation for the marker, when you add the marker to the cluster, the cluster takes control of the marker being added to the map and the animation is lost. To integrate marker animation and clustering, you first have to add the marker to the map, then, after the animation plays out, add the marker to the cluster. This is accomplished by returning the marker object from the addMarker function and then adding the marker to the cluster.

2
  • Thanks for your help Roy. I understand what your saying and it makes sense. I reckon I just don't have to skills to translate it into my code. I've updated my code above. I've now added the time out functions. With the first timeout function I should add the marker to the map. The 2nd timeout function, adds the marker into the cluster. At least that is what I'm intending to do with my code. I now have my animation, but all markers are added in the same location, my clusters are gone and so is my sidebar. ;(
    – wibni
    Commented Oct 13, 2012 at 10:32
  • It looks like you incorporated the code he used to generate random markers too. I've got minimal experience writing javascript, I suspect you'll have more luck on StackOverflow for code specifics.
    – Roy
    Commented Oct 13, 2012 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.