繁体   English   中英

在OpenLayers(KML)网络链接自动刷新中刷新/重绘图层

[英]Refresh / Redraw a Layer in OpenLayers (KML) Network-Link Auto Refresh

TLDR我想在计时器上刷新一层,以便绘制新的kml数据(如更新链接/网络链接)


到目前为止,我已经尝试了如下动作功能:

                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的url随机数学,因此它不会缓存:

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

我原本以为这会刷新图层。 通过将其加载设置为false来卸载它。 真实的可见性重新加载它和随机数学不应该允许它缓存? 那么以前是否有人这样做过或者知道如何让它发挥作用?

想看,因为我很难找到有关这方面的信息,我想补充一下:


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)

设置KML图层的URL:

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

希望这会让其他人更容易。

注意:虽然@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);

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

编辑:几个月后,我对这个解决方案并不完全满意。 所以我创建了2个中间步骤,保证我加载所有数据:

  1. 而不是直接拉动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);
}

?>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM