Pregunta Actualizar / Volver a dibujar una capa en OpenLayers (KML) Network-Link Auto Refresh


TLDR Quiero actualizar una capa en un temporizador para trazar los nuevos datos de kml (como el enlace de actualización / enlace de red)


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

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

establecer el intervalo 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 Matemáticas al azar para que no cache:

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

Hubiera pensado que esto Actualizaría la capa. Como por configurarlo está cargado en falso lo descarga. ¿La visibilidad de True lo recarga y con Math al azar no debería permitir que cachee? Entonces, ¿alguien ha hecho esto antes o sabe cómo puedo hacer que esto funcione?


5
2018-06-08 06:40


origen


Respuestas:


ATENCIÓN: si bien 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 la capa expira y considera la capa cargada.

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

debajo de un cheque muy simple:

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 la actualización de la capa kml dinámica, a veces es posible que solo obtenga resultados parciales, por lo que TAMBIÉN desea verificar si el número de funciones cargadas es igual al número esperado de funciones.

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

ps: es posible que también desee hacer que la actualización de capa sea una tarea asíncrona utilizando:

setTimeout(UpdateKmlLayer(layerKMLStops),0);

el último estado del navegador en el código anterior: funciona bien en Chrome 20.01132.47, no en Firefox 13.0.1 si llama simultáneamente a varias funciones (para cargar varias capas de kml dinámicas [track, stops, poi's]) usando setTimeout.

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

  1. en lugar de tirar directamente del archivo php, 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 que el archivo php se analice como fuente para una capa kml, a menudo se agota. PERO, si llama al analizador php como una llamada ajax, se vuelve sincrónica y su código espera a que el analizador php complete su trabajo, antes de continuar con la actualización de la capa.

ya que el archivo kml ya se ha analizado y se guardó cuando actualicé, mi lector php simple no tiene tiempo de espera.

también, ya que no tiene que pasar por la capa tantas veces (normalmente la primera vez que tiene éxito), aunque el procesamiento lleva más tiempo, hace las cosas la primera vez (por lo general, todavía verifico si las funciones se cargaron ).

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

?>

2
2017-07-04 17:55



Pensé que ya que era lo suficientemente difícil para mí encontrar información sobre esto, agregaría esto:


1)

Crea 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)

Establezca la URL para 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)

Establezca el intervalo en el cual actualizar su capa:

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

4)

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

Espera que esto lo haga más fácil para otros.


10
2018-06-08 07:12