2010-06-08 39 views
5

TLDR Quiero actualizar una capa en un contador de tiempo por lo que representa los nuevos datos KML (como update-enlace/enlace de red)Actualizar/volver a dibujar una capa en OpenLayers (KML) Red-Link actualización automática


función de acción Hasta ahora he tratado de la siguiente manera:

   function RefreshKMLData(layer) { 
        layer.loaded = false; 
        layer.setVisibility(true); 
        layer.redraw({ force: true }); 
       } 

intervalo definido de la función:

   window.setInterval(RefreshKMLData, 5000, KMLLAYER); 

la propia capa:

  var KMLLAYER = new OpenLayers.Layer.Vector("MYKMLLAYER", { 
       projection: new OpenLayers.Projection("EPSG:4326"), 
       strategies: [new OpenLayers.Strategy.Fixed()], 
       protocol: new OpenLayers.Protocol.HTTP({ 
        url: MYKMLURL, 
        format: new OpenLayers.Format.KML({ 
         extractStyles: true, 
         extractAttributes: true 
        }) 
       }) 
      }); 

la url de KmlLayer con las matemáticas al azar por lo que doesnt caché:

var MYKMLURL = var currentanchorpositionurl = 'http://' + host + '/data?_salt=' + Math.random(); 

yo habría pensado que esto sería refrescar la capa . Como al configurar su carga a descarga falsa. ¿La visibilidad de True lo recarga y con Math al azar no debería permitir que cache? Entonces, ¿alguien ha hecho esto antes o sabe cómo puedo hacer que esto funcione?

Respuesta

2

ATENCIÓN: mientras que el método de @Lavabeams funciona perfectamente bien (lo he adaptado a mis necesidades sin ningún problema), la carga de la capa kml NO SIEMPRE SE COMPLETA correctamente.

aparentemente, dependiendo de cuánto tiempo lleva analizar el kml dinámico, el proceso de actualización de capa expira y considera la capa cargada.

por lo tanto, es aconsejable usar también un oyente de eventos de carga (antes de agregar capa al mapa) y verificar lo que se cargó efectivamente y si coincide con las expectativas.

por debajo de un muy simple comprobación:

var urlKMLStops = 'parseKMLStops12k.php';   
var layerKMLStops = new OpenLayers.Layer.Vector("Stops", { 
      strategies: [new OpenLayers.Strategy.Fixed({ preload: true })], 
      protocol: new OpenLayers.Protocol.HTTP({ 
       url: urlKMLStops, 
       format: new OpenLayers.Format.KML({ 
        extractStyles: true, 
        extractAttributes: true, 
        maxDepth: 2 
       }) 
      }) 
     }); 

layerKMLStops.events.register("loadend", layerKMLStops, function() { 
       var objFs = layerKMLStops.features; 
       if (objFs.length > 0) { 
        alert ('loaded '+objFs.length+' '+objFs[0]+' '+objFs[1]+' '+objFs[2]); 
       } else { 
        alert ('not loaded'); 
        UpdateKmlLayer(layerKMLStops); 
       } 
      }); 

con capa KML dinámico refrescante, a veces se puede obtener sólo resultados parciales, así que sería bueno también comprobar si el número de elementos cargados es igual al número esperado de características .

palabras de advertencia: dado que este oyente realiza un bucle, use un contador para limitar el número de intentos de recarga.

PS: También puede ser que desee para hacer la capa actualizar una tarea asíncrona mediante el uso de:

setTimeout(UpdateKmlLayer(layerKMLStops),0); 

estado más reciente del navegador de código anterior: Funciona bien en cromo 20.01132.47, no en Firefox 13.0.1 si invocar simultáneamente varias funciones (para cargar múltiples capas kilométricas [track, stops, poi's]) usando setTimeout.

EDITAR: meses después, no estoy totalmente satisfecho con esta solución. así creé 2 pasos intermedios que garantizan que cargue todos mis datos:

  1. en lugar de tirar el archivo php directamente, hago que el analizador php kml guarde un archivo kml. Luego uso un simple lector php para leer este archivo.

por qué esto funciona mejor:

esperando el archivo php para analizar como origen de una capa KML, a menudo el tiempo de espera. PERO, si llamas al analizador php como una llamada ajax, se convierte en sincrónico y tu código espera a que el analizador php complete su trabajo, antes de proceder a actualizar la capa.

ya que el archivo kml ya se ha analizado y guardado cuando actualizo, mi lector php simple no agota el tiempo de espera.

también, ya que no tiene que pasar por la capa tantas veces (por lo general tiene éxito la primera vez), aunque el procesamiento lleva más tiempo, hace las cosas la primera vez (por lo general, sigo controlando si las características fueron cargadas).

<?php 
session_start(); 

$buffer2 =""; 
// this is for /var/www/ztest 
// for production, use '../kmlStore 
$kmlFile = "fileVault/".session_id()."/parsedKML.kml"; 
//echo $kmlFile; 
$handle = @fopen($kmlFile, "r"); 
if ($handle) { 
    while (($buffer = fgets($handle, 4096)) !== false) { 
    $buffer2 .= $buffer; 
    } 
    echo $buffer2; 
    if (!feof($handle)) { 
    echo "Error: unexpected fgets() fail\n"; 
    } 
    fclose($handle); 
} 

?> 
+1

Mi respuesta fue mucho más antigua, pero ahora es mejor. Actualizado. – Sphvn

10

Robusto visto ya que era bastante difícil para mí encontrar información sobre este yo añadiría esto:


1)

crear la capa KML:

  //Defiine your KML layer// 
      var MyKmlLayer= new OpenLayers.Layer.Vector("This Is My KML Layer", { 
       //Set your projection and strategies// 
       projection: new OpenLayers.Projection("EPSG:4326"), 
       strategies: [new OpenLayers.Strategy.Fixed()], 
       //set the protocol with a url// 
       protocol: new OpenLayers.Protocol.HTTP({ 
        //set the url to your variable// 
        url: mykmlurl, 
        //format this layer as KML// 
        format: new OpenLayers.Format.KML({ 
         //maxDepth is how deep it will follow network links// 
         maxDepth: 1, 
         //extract styles from the KML Layer// 
         extractStyles: true, 
         //extract attributes from the KML Layer// 
         extractAttributes: true 
        }) 
       }) 
      }); 

2)

Establecer la dirección URL de la capa KML:

//note that I have host equal to location// //Math.Random will stop caching// 
var mykmlurl = 'http://' + host + '/KML?key=' + Math.random(); 

3)

Ajuste el intervalo en el que se actualiza la capa de:

  //function called// //timer// //layer to refresh// 
window.setInterval(UpdateKmlLayer, 5000, MyKmlLayer); 

4)

El función para actualizar la capa:

  function UpdateKmlLayer(layer) { 
       //setting loaded to false unloads the layer// 
       layer.loaded = false; 
       //setting visibility to true forces a reload of the layer// 
       layer.setVisibility(true); 
       //the refresh will force it to get the new KML data// 
       layer.refresh({ force: true, params: { 'key': Math.random()} }); 
      } 

esperanzas Esto hace que sea más fácil para algunos otros por ahí.

+2

Sería bueno saber por qué esto tiene -1. Hice una pregunta y encontré la solución 4 días después y la actualicé. Por favor explique por qué ayudar a la comunidad de SO vale la pena un voto a la baja? – Sphvn

+2

¿Por qué no usa OpenLayers.Strategy.Refresh (http://dev.openlayers.org/apidocs/files/OpenLayers/Strategy/Refresh-js.html) en lugar de la estrategia fija? Fue diseñado exactamente para su propósito. – fbuchinger

+1

Estoy usando actualización ... El resto es para detener los problemas de almacenamiento en caché a través de broswers IE/FF/Chrome/Safari/Opera ... y la razón para tenerlo en una función es que puedo llamarlo varias veces para varias capas. El uso de visibilidad para FORCES verdadero lo vuelve a cargar incluso si decide guardarlo en caché normalmente en IE7- – Sphvn

Cuestiones relacionadas