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

带有数学随机性的KMLLAYER的网址,因此它不会缓存:
var MYKMLURL = var currentanchorpositionurl = 'http://' + host + '/data?_salt=' + Math.random();

我以为这会刷新图层。如通过将其load设置为false来卸载它。 visibility 为true会重新加载它,并且使用Math random应该不允许它缓存吗?那么,有人做过此事还是知道我如何使它工作?

最佳答案

注意:虽然@Lavabeams的方法工作得很好(我完全没有问题地适应了我的需要),但kml层加载始终无法正确完成。

显然,取决于动态kml解析所花费的时间,层刷新过程会超时并考虑已加载的层。

因此,明智的方法是也使用加载事件监听器(在将图层添加到 map 之前)并检查有效加载的内容以及它是否符合预期。

下面是一个非常简单的检查:

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

以上代码的最新浏览器状态:如果您同时使用setTimeout调用各种函数(以加载多个动态kml图层[track,stops,poi's),则在chrome 20.01132.47上运行良好,而在Firefox 13.0.1上则无法运行。

编辑:几个月后,我对这个解决方案并不完全满意。所以我创建了2个中间步骤,以确保我加载所有数据:
  • 而不是直接拉出php文件,而是使php kml解析器保存一个kml文件。然后,我使用一个简单的PHP阅读器读取此文件。

  • 为什么这样做更好:

    等待php文件解析为kml层的源,通常会超时。但是,如果您将php解析器作为ajax调用进行调用,它将变为同步,并且您的代码将等待php解析器完成其工作,然后再刷新该层。

    由于kml文件已经在我刷新时被解析并保存,因此我的简单php阅读器不会超时。

    另外,由于不必遍历整个图层多次(通常第一次成功),即使处理时间较长,也可以在第一次完成(通常-我仍然检查是否加载了功能) )。
    <?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);
    }
    
    ?>
    

    10-08 08:42
    查看更多