Обновить / перерисовать слой в OpenLayers (KML) Network-Link Auto Refresh - PullRequest
5 голосов
/ 08 июня 2010

TLDR Я хочу обновить слой по таймеру, чтобы он отображал новые данные kml (например, update-link / network link)


До сих пор я пробовал функцию действия следующим образом:

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

установить интервал функции:

                window.setInterval(RefreshKMLData, 5000, KMLLAYER);

сам слой:

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

URL для KMLLAYER со случайным Math, поэтому он не кэшируется:

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

Я бы подумал, что это обновит слой. Как установив его загружено в ложь, выгружает его. Видимость к истине перезагружает его, и случайное математическое вычисление не должно позволить ему кэшироваться? Так кто-нибудь делал это раньше или знает, как я могу заставить это работать?

Ответы [ 2 ]

11 голосов
/ 08 июня 2010

Похоже, мне было трудно найти информацию по этому поводу, я бы добавил:


1)

Создайте слой 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)

Установить URL для слоя KML:

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

3)

Установите интервал обновления слоя:

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

4)

Функция обновления слоя:

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

Надеется, что это облегчит жизнь другим.

2 голосов
/ 04 июля 2012

ВНИМАНИЕ: хотя метод @Lavabeams работает отлично (я адаптировал его под свои нужды без проблем), загрузка слоя kml НЕ ВСЕГДА ЗАВЕРШАЕТСЯ должным образом.

очевидно, в зависимости от того, сколько времени занимает анализ динамического kml, процесс обновления слоя прерывается и считает загруженный слой.

поэтому целесообразно также использовать прослушиватель событий загрузки (перед добавлением слоя на карту) и проверить, что было эффективно загружено и соответствует ли оно ожиданиям.

ниже очень простой проверки:

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

при динамическом обновлении слоя kml иногда вы можете получить только частичные результаты, поэтому вы можете также проверить, равно ли число загруженных объектов ожидаемому числу объектов.

предостерегающие слова: поскольку этот слушатель зацикливается, используйте счетчик, чтобы ограничить количество попыток перезагрузки.

ps: вы можете также захотеть сделать обновление слоя асинхронной задачей, используя:

setTimeout(UpdateKmlLayer(layerKMLStops),0);

последнее состояние браузера в приведенном выше коде: хорошо работает в chrome 20.01132.47, а не в firefox 13.0.1, если вы одновременно вызываете различные функции (для загрузки нескольких динамических слоев kml [track, stop, poi's]), используя setTimeout.

РЕДАКТИРОВАТЬ: несколько месяцев спустя я не полностью удовлетворен этим решением. поэтому я сделал 2 промежуточных шага, которые гарантируют, что я загружу все свои данные:

  1. вместо того, чтобы извлекать файл php напрямую, я заставляю парсер php kml сохранять файл kml. Затем я использую простую программу чтения PHP, чтобы прочитать этот файл.

почему это работает лучше:

ожидание, пока php-файл не будет проанализирован как источник для слоя kml, часто заканчивается. НО, если вы вызываете парсер php как вызов ajax, он становится синхронным, и ваш код ожидает, пока парсер php завершит свою работу, прежде чем приступить к обновлению слоя.

, так как файл kml уже был проанализирован и сохранен при обновлении, мой простой php reader не истекает.

также, так как вам не нужно проходить через слой столько раз (вы обычно добиваетесь успеха в первый раз), даже если обработка занимает больше времени, в первый раз все получается (обычно - я все еще проверяю, функции были загружены).

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

?>
...