html - "Look at"KML 地标的链接列表

标签 html kml google-earth-plugin

我正在尝试在 GE 旁边添加一个列,其中包含所有地标的列表,作为链接或按钮,当您单击这些链接时,它将退出游览并跳转到(或飞到)该地标的位置和弹出气球。

KML 有一个游览内部的 FlyTo 和 LookAt 列表以及文档中的地标 :)。

这是我的 KML 地标示例:

<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>

这是我的 JavaScript 和 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>

最佳答案

您可以修改当前的 walkKmlDom 实现,因为它已经在遍历 kml dom 并检查地标。即

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

只需使用它来构建指向地标的链接列表。您可以在地标对象上使用 getUrl 来执行此操作。参见 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]);
}

然后您需要实现 flyto 辅助函数以实际飞到这些位置并在单击链接时打开气球。像下面这样的东西应该可以工作。

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());
}

关于html - "Look at"KML 地标的链接列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17624540/

相关文章:

html - CSS:悬停时减小元素大小,但保持原始 "hover area"

javascript - jQuery 基于 anchor 生成列表

file - 在浏览器中显示的Google Map上覆盖多个KML文件

javascript - 在 Google Earth 插件的照片叠加层中获取点击的像素坐标

javascript - 自动计算多个下拉选择

django - Django 中的范围 slider

java - Java 中 KML 颜色的十六进制到 BGR 十六进制转换

KML + 谷歌地球 : Make a Polygon or GroundOverlay clickable?

c# - 尝试在 Google 地球插件中创建组选择框