Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I've been working on my map which gets it's 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 thread, but cannot get it to work with my database. Using Drop Markers and MarkerClusterer together?

Would anyone please be able to help me figuring out how to add the drop animation to my code? My test map is here: http://mymap.mooo.com

Really appreciate any help or pointers.

 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() {}
share|improve this question
add comment

2 Answers 2

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: http://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.

share|improve this answer
    
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 Oct 15 '12 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 Oct 16 '12 at 14:19
    
Thanks Casey! Will have a ready on that. –  wibni Oct 17 '12 at 10:00
add comment

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.

share|improve this answer
    
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 Oct 13 '12 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 Oct 13 '12 at 14:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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