2012-08-02 80 views
5

我有许多大型的KML数据集,它们使用基于区域的网络链接层次结构进行服务;如KML reference描述:谷歌地球API中基于地区的网络链接

使用区域与NetworkLink一起配合,您可以创建指针层次结构,每个指向一个特定子区域。如以下KML文件所示,<viewRefreshMode>具有onRegion选项,该选项指定仅在区域处于活动状态时加载区域数据。如果您提供具有多个细节级别的嵌套区域,则只有当用户的视点触发下一个加载时才加载更大量的数据。

这在加载到Google地球中时效果很好。

我现在希望在使用Google Earth plug-in的应用程序中加载这些文件。 我需要通过Google Earth API访问加载的内容; (即附加点击事件,改变样式)以将内容集成到应用程序中。

问题是,我没有找到任何有关网络链接的“有载”事件的参考。在我看来,这将工作的方式是:

  • 通过API加载顶级网络链接,附加一个回调函数,该函数将在网络链接加载时调用。
  • 在回调函数中,解析网络链接返回的KML。对于区域层级中的中间层级,此KML将只包含到下一个区域级别的网络链接。通过API将它们加载到插件中,再次指定相同的回调函数,当这些函数被加载时(即,当它们的区域变得可见时)将被调用。
  • 最终,返回的KML将包含实际的“内容”。在此阶段,我们会在执行任何所需的修改(例如附加事件监听器,设置样式等)后,将实际内容(即地标)加载到插件中。

我在想这个javascript看起来像下面这样。
请注意:这只是一个粗略的草图,可能有助于理解我的问题。我是不是问为什么这段代码不起作用。

//create network link 
var networkLink = ge.createNetworkLink(""); 
networkLink.setName("Regionated hierarchy root"); 

// create a Link object 
//the network-links contained in the kml that will be returned in this file 
//are region-based; they will only be loaded when the user zooms into the relevant 
//region. 
var link = ge.createLink(""); 
link.setHref("http://foo.com/regionatedRoot.kml"); 

// attach the Link to the NetworkLink 
networkLink.setLink(link); 

//specify the callback function to be invoked when the network link is loaded 
//this is is the part that doesn't actually exist; pure fiction... 
networkLink.onLoad = networkLinkLoaded; 

// add the NetworkLink feature to Earth 
ge.getFeatures().appendChild(networkLink); 

// function which will be invoked when a network-link is loaded 
// i.e. when its region becomes active 
function networkLinkLoaded(kml) { 

    //parse the kml returned for child network links, 
    //this will create the network link KmlObject, with a 
    //region specified on it. 
    for (childNetworkLink in parseNetworkLinks(kml)) { 
     //and append them, again hooking up the call-back 
     childNetworkLink.onLoad = networkLinkLoaded; 
     ge.getFeatures().appendChild(childNetworkLink); 
    } 

    //if the user has zoomed in far enough, then the kml returned will 
    //contain the actual content (i.e. placemarks). 
    //parse the kml returned for content (in this case placemarks) 
    for (placemark in parsePlacemarks(kml)) { 
     //here we would attach event-listeners to the placemark 
     ge.getFeatures().appendChild(placemark); 
    } 
} 

这可能吗?
我在思考中转弯了吗?我相信我遵循了管理大型KML数据集的推荐做法,但我不确定如何通过API使用这些数据集。

附录

由于问题我试图解决这个类型的例子: 想象一下你正在建设使用谷歌地球插件的Web应用程序,并且你要显示每一组地标世界上的交通灯。地标应该只显示在适当的详细程度上(例如,当相机在5公里高度时)。当用户点击地标时,我们希望网络应用程序为该组交通灯加载统计信息,并将其显示在侧栏中。

你会如何设计这个?

回答

1

您不需要直接访问对象数据以提供所需的功能。您可以像使用基于区域的网络链接层次结构一样处理数据加载。 然后,如果您的使用场景与您在附录中列出的使用场景相似,那么您只需使用click事件中的目标数据根据需要加载基于地标的统计数据即可。

例如,您可以简单地在窗口对象上设置一个通用的mousedown事件处理程序,然后测试以查看目标是否为地标。您可以在加载任何数据之前添加此通用侦听器,并且在点击动态加载的地标时它仍会被触发。根本不需要将单个事件侦听器附加到地标上。

例如

window.google.earth.addEventListener(ge.getWindow(), 'mousedown', onWindowMouseDown); 

var onWindowMouseDown = function(event) { 
    if (event.getTarget().getType() == 'KmlPlacemark') { 
    // get the placemark that was clicked 
    var placemark = event.getTarget(); 

    // do something with it, or one of its relative objects... 
    var document = placemark.getOwnerDocument(); 
    var parent = placemark.getParentNode(); 

    // etc... 
    } 
} 
+0

你说得对。通过设置'全局'级别的事件处理程序,我可以过滤目标ID以确定如何处理事件。谢谢! – 2012-08-27 07:01:24

+0

不用担心,很高兴有帮助。 – Fraser 2012-08-28 16:31:45

0

不知道这是否是你所需的东西,但有一个kmltree API,这个API:你根据给定的

  • 让你有一个“kmlloaded的KML

    1. 打造出来的KML树“事件处理程序

    http://code.google.com/p/kmltree/

    function initCB(instance){ 
        ge = instance; 
        ge.getWindow().setVisibility(true); 
    
        var gex = gex = new GEarthExtensions(ge); 
    
        var tree = kmltree({ 
         url: 'http://foo.com/regionatedRoot.kml', 
         gex: gex, 
         mapElement: $('#map3d'), 
         element: $('#tree'), 
        }); 
    
        $(tree).bind('kmlLoaded', function(event, kmlObject){ //do something here }); 
    
        tree.load(); 
    } 
    

    它确实需要你带来另一个js API,但它工作得很好,并给你一些很好的内置功能。

    到目前为止,我没有发现任何东西只是从插件加载KML时将触发一个事件...

    你也许可以)来尝试使用fetchKml(特别是如果你硬编码那里的链接的网址?

    google.earth.fetchKml(ge, 'http://foo.com/regionatedRoot.kml', function(kmlObject){ 
        //do logic here 
    }); 
    
  • +0

    感谢您的回答。我已经看过KmlTree项目;但我不相信它解决了这个问题。它似乎是将KML解析为树形菜单。我不相信它处理基于地区的网络链接? 我已经在我的问题中添加了一个附录,并带有一个我尝试解决的问题类型的示例。 – 2012-08-09 00:04:26