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

发布于 2024-09-04 21:01:24 字数 1316 浏览 7 评论 0原文

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

带有 Math random 的 KMLLAYER 的 url,因此它不会缓存:

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

我本以为这会刷新图层。通过将其已加载设置为 false 可以卸载它。对 true 的可见性会重新加载它,并且数学随机不应允许它缓存?那么有人以前做过这个或者知道我如何让它发挥作用吗?

TLDR I want to refresh a layer on a timer so it plots the new kml data (like update-link / network link)


So far I have tried action function as follows:

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

set interval of the function:

                window.setInterval(RefreshKMLData, 5000, KMLLAYER);

the layer itself:

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

the url for KMLLAYER with Math random so it doesnt cache:

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

I would have thought that this would Refresh the layer. As by setting its loaded to false unloads it. Visibility to true reloads it and with the Math random shouldn't allow it to cache? So has anyone done this before or know how I can get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╄→承喏 2024-09-11 21:01:24

我认为找到这方面的信息已经够困难了,所以我会添加以下内容:


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

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

Figured seen as it was hard enough for me to find information on this I would add this:


1)

Create the KML Layer:

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

Set the URL for the KML Layer:

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

3)

Set the interval in which to refresh your layer:

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

4)

The function to update the layer:

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

Hopes this makes it easier for some others out there.

遮云壑 2024-09-11 21:01:24

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

上面代码上的最新浏览器状态:如果您同时调用各种函数(以加载多个动态kml图层),则在chrome 20.01132.47上运行良好,但在firefox 13.0.1上运行不佳[轨迹、停靠站、POI's]) 使用 setTimeout。

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

  1. 我让 php kml 解析器保存一个 kml 文件,而不是直接提取 php 文件。然后我使用一个简单的 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);
}

?>

ATTENTION: while @Lavabeams' method works perfectly well (i have adapted it to my needs with no problem at all), kml layer loading DOES NOT ALWAYS COMPLETE properly.

apparently, depending on how long your dynamic kml takes to parse, the layer refresh process times out and considers the layer loaded.

therefore, it is wise to also use a loading event listener (before adding layer to map) and check what was effectively loaded and if it matches expectations.

below a very simple check:

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

with dynamic kml layer refreshing, you might sometimes get only partial results, so you might want to ALSO check if the number of features loaded equals the expected number of features.

words of caution: since this listener loops, use a counter to limit the number of reload attempts.

ps: you might also want to make layer refresh an asynchronous task by using:

setTimeout(UpdateKmlLayer(layerKMLStops),0);

latest browser status on above code: works well on chrome 20.01132.47, not on firefox 13.0.1 if you simultaneously call various functions (to load multiple dynamic kml layers [track, stops, poi's]) using setTimeout.

EDIT: months later, i am not totally satisfied with this solution. so i creted 2 intermediate steps which guarantee that i load all my data:

  1. instead of pulling the php file directly, i make the php kml parser save a kml file. i then use a simple php reader to read this file.

why this works better:

waiting for the php file to parse as a source for a kml layer, often times out. BUT, if you call the php parser as an ajax call, it becomes synchronous and your code waits for the php parser to complete its job, before going on to refresh the layer.

since the kml file has already been parsed and saved when i refresh, my simple php reader does not time out.

also, since you do not have to loop thru the layer as many times (you usually are successful the first time around), even though processing takes longer, it gets things done the first time around (usually - i still check if features were loaded).

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

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文