【问题标题】:Refresh / Redraw a Layer in OpenLayers (KML) Network-Link Auto Refresh在 OpenLayers (KML) 网络链接自动刷新中刷新/重绘图层
【发布时间】:2010-06-08 06:40:49
【问题描述】:

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 卸载它。对 true 的可见性重新加载它并且使用 Math random 不应该允许它缓存?那么有没有人这样做过或者知道我怎样才能让它工作?

【问题讨论】:

    标签: javascript kml openlayers


    【解决方案1】:

    认为我很难找到这方面的信息,所以我会添加以下内容:


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

    希望这能让其他人更轻松。

    【讨论】:

    • 很高兴知道为什么这是-1。我问了一个问题,大约 4 天后自己找到了解决方案并更新了它?请解释为什么帮助 SO 社区值得一票否决?
    • 为什么不使用 OpenLayers.Strategy.Refresh (dev.openlayers.org/apidocs/files/OpenLayers/Strategy/…) 而不是固定策略?它是专为您的目的而设计的。
    • 我正在使用 refresh.. 剩下的就是停止跨浏览器 IE/FF/Chrome/Safari/Opera 的缓存问题...而将它放在函数中的原因是我可以调用它多次用于多层。使用可见性来真正强制它重新加载,即使它决定在 IE7 中正常缓存它-
    • 它可能被否决了,因为您编辑了原始问题,现在没有问题了吗?它假装是“操作方法”或其他东西。始终留下您的问题,即使您对其进行了编辑,也将其作为问题留下。
    • 这行得通!建议在动态 kml 层刷新时使用事件侦听器进行 loadend。请参阅下面的答案。
    【解决方案2】:

    注意:虽然@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's]),则在 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);
    }
    
    ?>
    

    【讨论】:

    • 我的回答老了很多,但现在好多了。已更新。
    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2011-07-22
    相关资源
    最近更新 更多