Question

My javascript is very weak. Is it possible to modify the same code below to do the following:

Any advice to offer?

Sample Code:

var ge;

// store the object loaded for the given file... initially none of the objects
// are loaded, so initialize these to null
var currentKmlObjects = {
  'red': null,
  'yellow': null,
  'green': null
};

google.load("earth", "1");

function init() {
  // Create checkboxes
  var content = document.getElementById('content');
  var inputHTML = 'Placemarks:<br/>';
  inputHTML += '<input type="checkbox" id="kml-red-check" onclick="toggleKml(\'red\');"/>' +
               '<label for="kml-red-check">Red</label>' +
               '<input type="checkbox" id="kml-yellow-check" onclick="toggleKml(\'yellow\');"/>' +
               '<label for="kml-yellow-check">Yellow</label>' +
               '<input type="checkbox" id="kml-green-check" onclick="toggleKml(\'green\');"/>' +
               '<label for="kml-green-check">Green</label>';
  content.innerHTML = inputHTML;

  google.earth.createInstance('content', initCB, failureCB);
}

function initCB(instance) {
  ge = instance;
  ge.getWindow().setVisibility(true);


  // add a navigation control
  ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);

  // add some layers
  ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
  ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

  // fly to Santa Cruz
  var la = ge.createLookAt('');
  la.set(37, -122,
          0, // altitude
          ge.ALTITUDE_RELATIVE_TO_GROUND,
          0, // heading
          0, // straight-down tilt
          5000 // range (inverse of zoom)
  );
  ge.getView().setAbstractView(la);

  // if the page loaded with checkboxes checked, load the appropriate
  // KML files
  if (document.getElementById('kml-red-check').checked)
    loadKml('red');

  if (document.getElementById('kml-yellow-check').checked)
    loadKml('yellow');

  if (document.getElementById('kml-green-check').checked)
    loadKml('green');

  document.getElementById('installed-plugin-version').innerHTML =
      ge.getPluginVersion().toString();
}

function failureCB(errorCode) {
}

function toggleKml(file) {
  // remove the old KML object if it exists
  if (currentKmlObjects[file]) {
    ge.getFeatures().removeChild(currentKmlObjects[file]);
    currentKmlObject = null;
  }

  // if the checkbox is checked, fetch the KML and show it on Earth
  var kmlCheckbox = document.getElementById('kml-' + file + '-check');
  if (kmlCheckbox.checked)
    loadKml(file);
}

function loadKml(file) {
  var kmlUrl = 'http://earth-api-samples.googlecode.com/svn/trunk/' +
               'examples/static/' + file + '.kml';

  // fetch the KML
  google.earth.fetchKml(ge, kmlUrl, function(kmlObject) {
    // NOTE: we still have access to the 'file' variable (via JS closures)

    if (kmlObject) {
      // show it on Earth
      currentKmlObjects[file] = kmlObject;
      ge.getFeatures().appendChild(kmlObject);
    } else {
      // bad KML
      currentKmlObjects[file] = null;
      alert('Bad KML');

      // uncheck the box
      document.getElementById('kml-' + file + '-check').checked = '';
    }
  });
}

google.setOnLoadCallback(init);

For bonus points, can I get the kml to be reloaded afterwards?

Was it helpful?

Solution

To make the objects draggable you need to set up some event listeners and handle the movement in the callback function. I presume the objects you wish to drag are place-marks (KmlPlacemark) if so you need something like this...(NB: This is untested and written here so there could be some typos.)

var dragging = false; // the object being dragged

var url = "http://.../moveTo?"; // path to your cgi script

function init() {

// Rest of your method body...

google.earth.addEventListener(ge.getGlobe(), "mousedown", function(e) 
  { 
    // if it is a place mark
    if(e.getTarget().getType() == 'KmlPlacemark') 
    { 
      // set it as the dragging target
      dragging = e.getTarget(); 
     } 
  }); 


google.earth.addEventListener(ge.getGlobe(), "mouseup", function(e)
  {
     // drop on mouse up (if we have a target)
     if(dragging) {
       // build the query string
       // ...you could use getName or getSnippet rather than getId
       var query = "lat=" + dragging.getGeometry().getLatitude() +
       "&long=" + dragging.getGeometry().getLongitude() + 
       "&id=" + dragging.getId(); 
       // send the query to the url
       httpPost(url, query); 
       // clear the dragging target
       dragging = false; 
     }
  }); 


google.earth.addEventListener(ge.getGlobe(), "mousemove", function(e) 
  { 
    // when the mouse moves (if we have a dragging target)
    if(dragging) { 
      // stop any balloon opening
      e.preventDefault(); 
      // drag the object
      // i.e. set the placemark location to cursor the location
      dragging.getGeometry().setLatLng(e.getLatitude(), e.getLongitude());
    } 
  }); 

}

// send a HTTP POST request
// could use jQuery, etc....
function httpPost(url, query) {
    var httpReq = false;
    var self = this;
    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.httpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject) {
        self.httpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.httpReq .open('POST', url, true);
    self.httpReq .setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    self.httpReq .onreadystatechange = function() {
        if (self.httpReq .readyState == 4) {
            // do something...
            alert(self.httpReq.responseText); 
        }
    }
    self.httpReq.send(query);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top