是否可以定义一个将重试加载的图层,例如指数后退?

时间:2014-02-02 21:54:36

标签: javascript openlayers leaflet

我正在使用OpenLayers连接到本土服务器,与Google或Cloudmade等专业级服务器不同,该框实际上需要一段时间来计算特定磁贴的结果。因为它是我正在绘制的数学函数,所以没有很大的机会加速服务器甚至预渲染瓷砖。

我对Leaflet的初步试验很快得出结论,Leaflet实际上将所有重新加载和加载错误处理留给浏览器,而OpenLayers至少有一个事件在tile服务器确实返回错误代码时被触发

我所遵循的想法是在请求时基本上开始渲染磁贴并立即触发HTTP 503,依靠客户端再次尝试。

再试一次,我实现了一个这样的简单图层:

    var myLayer = new OpenLayers.Layer.OSM.MYLayer("mine", {
        'transparent':"true",
        'format':"image/png",
        'isBaseLayer':false});
    myLayer.events.register("tileerror", myLayer, function (param) {
        // Try again:
        var targetURL = param.tile.layer.getURL(param.tile.bounds);
        var tile = param.tile;
        tile.timeout = tile.hasOwnProperty("timeout") ? tile.timeout * 2 : 1000;
        setTimeout(function (tileToLoad, url) {
            if (tileToLoad.url === url) {
                tileToLoad.clear();
                tileToLoad.url = url;
                tileToLoad.initImage();
            }
        }.bind(undefined, tile, targetURL), tile.timeout);
    });

我想出了从OpenLayers源重新加载磁贴所需的代码,但也许有一种更简洁的方法来实现这一点。

我的问题是:tile本身被重用,DOM中的div也是如此,因此重载过程实际上可能会尝试将tile重新加载到DIV中,该DIV只要成功重用,例如因为用户滚动到服务器能够快速提供数据的其他地方。

我想这个问题归结为 - 是否有官方方法使用tileerror事件来简单地尝试重新加载,或者至少在API中更简单的方式来触发重新加载?我在OpenLayers本身的源代码中花了很长时间,但无法解释为什么它仍然出错(对于tileToLoad.url == url的测试并没有真正做到这一点)。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

好的,经过一些更多的试验和错误后,我发现我实际上可以将一个eventListener添加到我的Layer类中,这将完成我想要的操作 - 尝试在等待一段时间后再次重新加载磁贴。诀窍是连续调用setImgSrc()进行清理并使用true参数进行绘制,该参数实际上是一个(未记录的)强制标志。感谢代码!

OpenLayers.Layer.OSM.MyLayer= OpenLayers.Class(OpenLayers.Layer.OSM, {
initialize:function (name, options) {
    var url = [
       "xxxx"
    ];
    options = OpenLayers.Util.extend({
        "tileOptions":{
            eventListeners:{
                'loaderror':function (evt) {
                    // Later reload
                    window.setTimeout(function () {
                        console.log("Drawing ", this);
                        this.setImgSrc();
                        this.draw(true);
                    }.bind(this), 3000); // e.g. after 3 seconds
                }
            }
        }
    }, options);
    var newArguments = [name, url, options];
    OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},

CLASS_NAME:"OpenLayers.Layer.OSM.MyLayer"
});

答案 1 :(得分:0)