سؤال

I am trying to add a column next to GE that has a list of all the Placemarks, as links or buttons, and when you click on those links it will exit the tour and jump to (or flyto) that placemark's location and pop-up the balloon.

the KML has a list of FlyTo's and LookAt's inside of a tour as well as Placemarks inside a document :).

Here is an Example of my KML placemark:

<Placemark id="Mussorie">
 <name>Karen Snyder</name>
  <description>
  Karen Snyder is an Arts Specialist learning language and culture through the arts in     Mussorie, India
    </description>
    <styleUrl>#Icon</styleUrl>
    <Point>
     <coordinates>79.134521,30.040566,0</coordinates>
    </Point>
   </Placemark>

Here is my JavaScript and HTML:

<html>
    <head>
      <title>Shepherd Global Outreach Partners</title>
      <script src="https://www.google.com/jsapi"> </script>
      <script src="http://earth-api-samples.googlecode.com/svn/trunk/lib/kmldomwalk.js" type="text/javascript"> </script>
      <script type="text/javascript">
        var ge;
        var tour;
        var curr_pm;
        var obj_pm;
        var linksit='';
        var linksitcount=1;
        var links = [];
        google.load("earth", "1");

        function init() {
          var urlquery = location.href.split("?");
          if(urlquery[1]) {
            var urlterms = urlquery[1].split(",");
            curr_pm = urlterms[0];
          }

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

        function initCB(instance) {
          ge = instance;
          ge.getWindow().setVisibility(true);
          ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);

          var href = 'http://www.shepnet.org/GO.kml?ID='+Math.floor((Math.random()*100000)+1) ;
          google.earth.fetchKml(ge, href, fetchCallback);

          function fetchCallback(fetchedKml) {
             // Alert if no KML was found at the specified URL.
             if (!fetchedKml) {
                setTimeout(function() {
                    alert('Bad or null KML');
                 }, 0);
                 return;
             }

             // Add the fetched KML into this Earth instance.
             ge.getFeatures().appendChild(fetchedKml);

             // Walk through the KML to find the tour object; assign to variable 'tour.'
             walkKmlDom(fetchedKml, function() {
                if (this.getType() == 'KmlTour') {
                   tour = this;
                   return false;
                 }
             });

            if (tour) {
              ge.getTourPlayer().setTour(tour);
              ge.getTourPlayer().play();
              ge.getTourPlayer().setLoop(true) 
            }

            if (!fetchedKml) {
              // wrap alerts in API callbacks and event handlers
              // in a setTimeout to prevent deadlock in some browsers
              setTimeout(function() {
                alert('Bad or null KML');
              }, 0);
              return;
            }

            // Show the entire KML file in the plugin.
            currentKmlObject = fetchedKml;
            ge.getFeatures().appendChild(currentKmlObject);

            //Walk the DOM looking for a KmlLineString - the Race Path
            var links = [];
            walkKmlDom(fetchedKml, function() {
            if (this.getType() == 'KmlPlacemark') {
              // create a link to the placemark
              links.push('<a href="javascript:void(0);" onclick="flyto(\'' + this.getUrl() + '\')"> ' + this.getName() + ' </a><br>');
            }});

            for (index = 0; index < links.length; ++index) {
              console.log(links[index]);
            }

          }
        }

        var flyto = function(url) {
          // close any currently open balloon.
          ge.setBalloon(null); 

          // find the placemark from the url parameter
          var placemark = ge.getElementByUrl(url);
          if(placemark == null) {
            console.log("Placemark is null: " + url);
            return;
          }

          // create a lookat based on that feature's geometry 
          var lookAt = ge.createLookAt('');
          lookAt.setLatitude(placemark.getGeometry().getLatitude());
          lookAt.setLongitude(placemark.getGeometry().getLatitude())

          // Update the view in Google Earth using the lookat
          ge.getView().setAbstractView(lookAt);

          // open the feature's balloon
          ge.setBalloon(placemark.getBalloon());
        }

        function failureCB(errorCode) {
        }

        function UCLA() {
          ge.getTourPlayer().reset();
          var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
          camera.setLatitude(34.0688272174651);
          camera.setLongitude(-118.445067424559);
          camera.setAltitude(10000);
          ge.getView().setAbstractView(camera);   
        }

        function pauseTour() {
          window.open(href = 'http://www.shepnet.org/GO.kml#UCLA');  
        }

        function resetTour() {
          ge.getTourPlayer().reset();
        }
        function exitTour() {
          ge.getTourPlayer().setTour(null);
        }

        google.setOnLoadCallback(init);

      </script>
    </head>
      <body>
      <div id="map3d" style="height: 768px; width: 1280px;"></div>
      <div id ="controls">
        <input type="button" onClick="flyto('http://www.shepnet.org/GO.kml#UCLA')" value="UCLA"/>
        <input type="button" onClick="resetTour()" value="Stop/Reset Tour"/>
        <input type="button" onClick="exitTour()" value="Exit Tour"/>
        <a href="javascript:void(0);" onClick="flyto('http://www.shepnet.org/GO.kml#Mussorie')"> 'Mussorie' </a>
      </div>
      </body>
  </html>
هل كانت مفيدة؟

المحلول

You can modify your current walkKmlDom implementation as that is already walking the kml dom and checking for Placemarks. i.e.

walkKmlDom(fetchedKml, function() {
            if (this.getType() == 'KmlPlacemark' && this.getID().toLowerCase() == curr_pm.toLowerCase()) {
                obj_pm = this;
                    return false; // stop the DOM walk here.
            } 

Simply use that to build a list of links to the placemarks. You can use getUrl on the placemark object to do this. See https://developers.google.com/earth/documentation/accessors

var links = [];
walkKmlDom(fetchedKml, function() {
  if (this.getType() == 'KmlPlacemark') {
    // create a link to the placemark
    links.push('<a href="javascript:void(0);" onclick="flyto(' + this.getUrl() + ')"> ' + this.getName() + ' </a>');
    // rest of your current conditional logic here
    // if(this.getID().toLowerCase()) etc..
  } 
}

// do something with links...
for (index = 0; index < links.length; ++index) {
  console.log(links[index]);
}

Then you need to implement the flyto helper function to actually fly to the locations and open the balloons when the links are clicked. Something like the following should work.

var flyto = function(url) {
  // close any currently open balloon.
  ge.setBalloon(null); 

  // find the placemark from the url parameter
  var placemark = ge.getElementByUrl(url); 
  if(placemark == null) {
    console.log("Placemark is null: " + url);
    return;
  }

  // create a lookat based on that feature's geometry 
  var lookAt = ge.createLookAt('');
  lookAt.setLatitude(placemark.getGeometry().getLatitude());
  lookAt.setLongitude(placemark.getGeometry().getLatitude())

  // Update the view in Google Earth using the lookat
  ge.getView().setAbstractView(lookAt);

  // open the feature's balloon
  ge.setBalloon(placemark.getBalloon());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top