2012-08-02 12 views
5

Tengo muchos conjuntos de datos KML grandes, que se sirven utilizando una jerarquía de enlaces de red basados ​​en regiones; como se describe en la KML reference:Enlaces de red basados ​​en regiones en API de Google Earth

Uso de Regiones en conjunción con enlaces de red, puede crear una jerarquía de punteros, cada uno de los cuales apunta a una sub-región específica. El <viewRefreshMode>, como se muestra en el siguiente archivo KML, tiene una opción onRegion, que especifica cargar los datos de Región solo cuando la Región está activa. Si proporciona regiones anidadas con múltiples niveles de detalle, se cargan cantidades de datos mayores solo cuando el punto de vista del usuario activa la siguiente carga.

Esto funciona bien cuando se carga en Google Earth.

Ahora deseo cargar esto en una aplicación usando el Google Earth plug-in. Y necesito acceder al contenido cargado a través de la API de Google Earth; (es decir, adjuntar eventos de clic, alterar estilos) para integrar el contenido en la aplicación.

El problema es que no he encontrado ninguna referencia a un evento 'en carga' para los enlaces de red. En mi mente, la forma en que esto funcionaría es:

  • de carga de alto nivel de enlace de red a través de la API, adjuntando una función de devolución de llamada que se invoca cuando se carga la red de vínculos.
  • En la función de devolución de llamada, analice el KML devuelto por el enlace de red. Para niveles intermedios en la jerarquía de regionalización, este KML contendrá solo enlaces de red al siguiente nivel de regionalización. Cargue estos en el complemento a través de la API, especificando nuevamente la misma función de devolución de llamada, que se invocará cuando se carguen (es decir, cuando su región se vuelva visible).
  • Eventualmente, el KML devuelto contendrá el 'contenido' real. En esta etapa, cargamos el contenido real (es decir, marcas de posición) en el complemento, después de realizar las modificaciones deseadas (por ejemplo, adjuntar eventos-oyentes, estilos de configuración, etc.).

Estoy pensando que el javascript sería algo como el siguiente.
Tenga en cuenta: este es solo un boceto para ayudar a comprender mi pregunta. Estoy NO preguntando por qué este código no funciona.

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

¿Esto es posible?
¿He tomado un giro equivocado en mi forma de pensar? Creo que he seguido las prácticas recomendadas para administrar grandes conjuntos de datos KML, pero no estoy seguro de cómo usarlos a través de la API.

Adición:

Como un ejemplo del tipo de problema que estoy tratando de resolver: Imagínese que usted está construyendo una aplicación web mediante el complemento de Google Earth, y desea mostrar una marca de posición para cada conjunto de semáforos en el mundo. Las marcas de posición solo deben mostrarse en un nivel de detalle apropiado (por ejemplo, cuando la cámara se encuentra a 5 km de altitud). Cuando un usuario hace clic en una marca de posición, queremos que la aplicación web cargue estadísticas para ese conjunto de semáforos y que los muestre en una barra lateral.

¿Cómo diseñarías esto?

Respuesta

1

No necesita acceder directamente a los datos del objeto para proporcionar la funcionalidad que necesita. Manejaría la carga de datos exactamente como lo hizo, usando una jerarquía de enlaces de red basados ​​en regiones. Luego, si su escenario de uso es como el que estableció en su apéndice, entonces simplemente usaría los datos de destino del evento click para cargar sus datos estadísticos en función de las marcas de posición, según sea necesario.

Por ejemplo, podría simplemente configurar un controlador genérico de eventos de mousedown en el objeto de la ventana y luego probar para ver si el objetivo es una marca de posición. Puede agregar este oyente genérico antes de cargar cualquier información y aún se disparará cuando haga clic en las marcas de posición cargadas dinámicamente. No es necesario adjuntar detectores de eventos individuales a las marcas de posición.

p. Ej.

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

Tienes razón. Al configurar controladores de eventos de nivel "global", puedo filtrar en la ID de destino para determinar cómo manejar el evento. ¡Gracias! –

+0

Sin preocupaciones, me alegro de haber ayudado. – Fraser

0

No estoy seguro si esto es exactamente lo que quiere, pero no es una API kmltree que:

  1. construir el árbol KML para usted basado en el KML especificado
  2. permitirá tener una 'kmlloaded 'controlador de eventos

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

sí requiere puedes traer otra aplicación js, pero funciona bastante bien y te da una buena funcionalidad incorporada.

Hasta el momento no he encontrado nada solo desde el plug-in que desencadenar un evento cuando se carga el kml ...

es posible que pueda intentar usar fetchKml() especialmente si están codificando esa url para el enlace allí?

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

Gracias por la respuesta Matt. He visto el proyecto KmlTree; pero no creo que aborde el problema. Parece tratarse de analizar KML en un menú de árbol. No creo que maneje enlaces de red basados ​​en la región. He agregado un apéndice a mi pregunta, con un ejemplo del tipo de problema que intento resolver. –

Cuestiones relacionadas