2010-06-08 19 views
5

TLDR Je veux rafraîchir une couche sur une minuterie de sorte qu'il trace les nouvelles données de kml (comme update-link/lien réseau)Actualiser/Redessiner une couche dans OpenLayers (KML) Réseau-Link Auto Refresh


jusqu'à présent, j'ai fonction d'action essayé comme suit:

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

intervalle défini de la fonction:

   window.setInterval(RefreshKMLData, 5000, KMLLAYER); 

la couche elle-même:

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

l'url pour KmlLayer avec Math aléatoire de sorte qu'il ne marche pas cache:

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

J'aurais pensé que cela Actualisez la couche . Comme en définissant son chargé à faux le décharge. Visibilité à true le recharge et avec le Math random ne devrait pas lui permettre de mettre en cache? Alors, est-ce que quelqu'un a déjà fait cela ou sait comment je peux faire fonctionner ça?

Répondre

2

ATTENTION: bien que la méthode de @Lavabeams fonctionne parfaitement (je l'ai adaptée à mes besoins sans aucun problème), le chargement de la couche kml NE FONCTIONNE TOUJOURS PAS correctement. Apparemment, en fonction de la durée d'analyse de votre kml dynamique, le processus d'actualisation de la couche expire et considère que la couche est chargée.

par conséquent, il est sage d'utiliser également un écouteur d'événement de chargement (avant d'ajouter une couche à la carte) et de vérifier ce qui a été effectivement chargé et s'il correspond aux attentes.

ci-dessous un très simple vérification:

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

avec la couche kml dynamique rafraîchissante, vous pouvez parfois obtenir que des résultats partiels, vous pouvez également vérifier si le nombre de fonctions chargées est égal au nombre attendu de caractéristiques . Mots de prudence: puisque cet écouteur boucle, utilisez un compteur pour limiter le nombre de tentatives de rechargement.

ps: vous pouvez également faire couche rafraîchir une tâche asynchrone en utilisant:

setTimeout(UpdateKmlLayer(layerKMLStops),0); 

dernier état du navigateur sur le code ci-dessus: fonctionne bien sur le chrome 20.01132.47, pas sur Firefox 13.0.1 si vous appeler simultanément diverses fonctions (pour charger plusieurs couches kml dynamiques [piste, arrêts, poi]) en utilisant setTimeout.

EDIT: mois plus tard, je ne suis pas totalement satisfait de cette solution. donc j'ai creted 2 étapes intermédiaires qui garantissent que je charge toutes mes données:

  1. au lieu de tirer le fichier php directement, je fais de l'analyseur php kml un fichier kml. J'utilise ensuite un simple lecteur php pour lire ce fichier.

pourquoi cela fonctionne mieux:

attendant le fichier php pour analyser comme une source pour une couche kml, souvent dehors. MAIS, si vous appelez l'analyseur PHP en tant qu'appel ajax, il devient synchrone et votre code attend que l'analyseur php termine son travail, avant d'actualiser la couche.

étant donné que le fichier kml a déjà été analysé et enregistré lors de mon actualisation, mon simple lecteur php n'expire pas.

également, puisque vous n'avez pas besoin de boucler la couche autant de fois (vous réussissez généralement la première fois), même si le traitement prend plus de temps, il fait les choses la première fois (habituellement - je vérifie toujours si les fonctionnalités ont été chargées).

<?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

Ma réponse était beaucoup plus ancienne mais c'est mieux maintenant. Actualisé. – Sphvn

10

FIGURED vu comme il était assez difficile pour moi de trouver des informations sur ce que je voudrais ajouter ceci:


1)

Créer la couche 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)

Définissez l'URL de la couche KML:

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

3)

Régler l'intervalle dans lequel pour vous rafraîchir la couche:

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

4)

Le fonction pour mettre à jour la couche:

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

Espoirs ce qui rend plus facile pour d'autres là-bas.

+2

Je serais heureux de savoir pourquoi cela a eu -1. J'ai posé une question et trouvé moi-même la solution environ 4 jours plus tard et l'ai mise à jour? S'il vous plaît expliquer pourquoi aider la communauté SO mérite une downvote? – Sphvn

+2

Pourquoi n'utilisez-vous pas OpenLayers.Strategy.Refresh (http://dev.openlayers.org/apidocs/files/OpenLayers/Strategy/Refresh-js.html) au lieu de la stratégie fixe? Il a été conçu exactement pour votre objectif. – fbuchinger

+1

J'utilise refresh .. Le reste est d'arrêter les problèmes de mise en cache à travers les broswers IE/FF/Chrome/Safari/Opera ... et la raison de l'avoir dans une fonction est que je peux l'appeler plusieurs fois pour plusieurs couches. Utiliser visiblity à true FORCES pour recharger même si elle décide de le mettre en cache normalement dans IE7- – Sphvn