【问题标题】:List of links that "Look at" a KML placemark“查看”KML 地标的链接列表
【发布时间】:2013-07-12 21:48:02
【问题描述】:

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

KML 在游览中包含 FlyTo 和 LookAt 的列表以及文档中的 Placemarks :)。

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

【问题讨论】:

    标签: html kml google-earth-plugin


    【解决方案1】:

    您可以修改当前的 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());
    }
    

    【讨论】:

    • 嘿,非常感谢您的回复 :) 但我似乎仍然遇到问题,我确信在这方面我完全是个傻瓜。就像我说的我是新的 :(。但是当我创建指向 flyto 函数 TypeError 的链接时出现此错误:placemark is null [Break On This Error] var point = placemark.getGeometry();
    • 我非常感谢你帮助我解决这个问题。似乎它正在通过您给我的脚本添加所需的 URL,但似乎 url#placemark 实际上并没有从 KML 文件中提取地标数据。每个地标都返回 null .. 我添加了我的地标 KML 格式的示例以及更新的 HTML 以及您给我的更改。我明白你是否不想再帮忙了,谢谢你到目前为止帮助我:)
    • 我会说这是您在 url 上的缓存破坏 - Math.floor((Math.random()*100000)+1) - 删除它,它应该可以工作。原因是两个网址; kml 的加载位置和传递给 getElementByUrl 的参数必须完全匹配。该查询使 api 认为该调用正在引用另一个文档。
    • 另外,要输出链接,您可以简单地在您想要链接的 html 中创建并清空 div。即&lt;div id="links"&gt;&lt;/div&gt; 然后只需将console.log(links[index]); 行替换为document.getElementById('links').innerHTML += links[index];
    • 你太棒了!!!它工作得很好......非常感谢你耐心地引导我完成这个:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    相关资源
    最近更新 更多