2012-08-02 21 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