javaScript: Flying around and asynchronicity in google Earth
This relates to Data Driven Mapping applications and the Javascript HowTo section
Flying around a marker and the complications of asynchronicity
Walkthrough
mcpherSpot.prototype.initFlyAround = function() { var spot = this; // been asked to rotate around the spot if (!spot.flying) { var vm = spot.parent; var ve = vm.ve; var ge = ve.ge; spot.flying = true; ge.setBalloon(null); spot.lookAt.setRange(parseFloat(vm.control.flyrange)); ge.getOptions().setFlyToSpeed(parseFloat(vm.control.flyspeed)); spot.initialLookAtHeading = spot.lookAt.getHeading(); google.earth.addEventListener(ge, 'frameend', function () { mcpherFly(spot); }); vm.statusUpdate('..flying around '+spot.title,true); mcpherFly(spot); } }
spot.fly needs to adjust the heading (the compass direction we are looking at the spot from). This will cause the view to rotate (asynchronously), and the handler for frameend we set up previously will kick us back here when done.
function mcpherFly(spot){ // whats the point of this? // seems that i can't addevent listener of spot.fly directly... spot.fly(); } mcpherSpot.prototype.fly = function() { // changing the heading and re- do var spot = this; if (spot.flying){ var vm = spot.parent; var ve=vm.ve; var ge = ve.ge; var newHeading = spot.lookAt.getHeading() + parseFloat(vm.control.flyincrement); if (newHeading > 360) { newHeading -= 360; } spot.lookAt.setHeading(newHeading); ve.showLookAt(spot); } return (spot.flying); }
We already have an event handler set up to deal with clicking on the marker.
google.earth.addEventListener(spot.placemark, 'click', function(e) { mcpherClicks(e,spot,false); } );
We are going to also handle stopping flying around in that same handler. If there is some flying going on, we need to stop it, and then set up another handler to work on the clicks after everything caused by the flying has settled down. Dealing with click versus double click is explained in Click events in Google Earth. Note the use of preventDefault to stop Earth reacting to a click with its own default behavior.
function mcpherClicks(e,spot,plot){ if(e.preventDefault)e.preventDefault(); if(e.stopPropagation)e.stopPropagation(); if (spot.flying){ var ge = spot.parent.ve.ge; spot.stopFlyAround(); google.earth.addEventListener(ge.getView(), 'viewchangeend', mcpherFlyingClicks(spot,plot)); } else { spot.dealWithClicks(plot); } }
According to the Google Earth API documentation, the ‘viewchangeend’ event is not a reliable indicator that everything is absolutely over, so it recommends waiting a bit till there are no more of these events fired. When the timeout eventually executes below, we know that the flying has subsided, so we can move to deal with the clicks.
function mcpherFlyingClicks(spot,plot){ var vm = spot.parent; var ge = vm.ve.ge; if(spot.timer) clearTimeout(spot.timer); spot.timer = setTimeout( function(){ spot.dealWithClicks(plot); }, 100); }
There is a similar problem to deal with when handling the plotting of balloons. This is explained in Creating a tabbed Google Mapping InfoWindow