Michael Laffargue
Michael Laffargue

Reputation: 10314

Clear WMS layer before redraw on OpenLayers

I'm currently successfully displaying multiple layers using OpenLayers (Vector and WMS). My application allow the user to modify some parameters, which will :
* modify bound
* modify map center
* modify the WMS image
I use Ajax to avoid page reload, it works nicely, however when some layers take a while to load, the others which are not yet redrawn are still shown in the background (but aren't related at all to my new context). I would like to clear WMS layers (if possible) before re-asking the server for the new image but didn't find anything yet. I do this on the vector layer by calling removeAllFeature();

Thanks for any help !

Here is my pseudo-code when the user click the button :

$.getJSON("url/updateMapConfig.php",
    {  
      data: $(this).serialize() ,   
      ajax: 'true',   
      cache: 'false'  
    },   
    function(j){  
      if (j.result == 'ok') {  
        var layersToShow = [];  
        // Refresh vector layer  
        for(var i=0;i<map.layers.length;i++) {  
          if (map.layers[i].isVector) {  
            map.layers[i].removeAllFeatures();  
            map.layers[i].refresh({force:true}); // Vector layer  
          }   
        }  
        // Refresh visible layers  
        for(var i=0;i<map.layers.length;i++) {  
          if (map.layers[i].visibility && !map.layers[i].isBaseLayer && !map.layers[i].isVector) { // Refresh visible non base  
              map.layers[i].redraw(true); // Other layer  
          }  
        }  
        // Set new bounds  
        var bounds = new OpenLayers.Bounds();  
          bounds.extend(new OpenLayers.LonLat(j.bounds.xmin-100, j.bounds.ymin-100));  
          bounds.extend(new OpenLayers.LonLat(parseInt(j.bounds.xmax)+100, parseInt(j.bounds.ymax)+100));  
        map.zoomToExtent(bounds);  
        // Move to destination point  
        if (j.poiCenter != "") {  
          eval("map.setCenter(new OpenLayers.LonLat("+j.poiCenter+"))");  
        }  
      }  
    }  
);  

Upvotes: 1

Views: 8766

Answers (3)

Michael Laffargue
Michael Laffargue

Reputation: 10314

I finally found out an happy ending using the clearGrid() function on every layer before redrawing them.

I also found that this function will stop tile loading if any is running. Example I had two base layer : EmptyLayer and WhateverTiledBGLayer. if it tooks 20s to load WhateverTiledBGLayer tiles, even if the user chose to switch to empty layer, I could see the request done to the server for the remaining tiles on WhateverTiledBGLayer.

Simply calling WhateverTiledBGLayer.clearGrid() will stop requesting layers.

Thanks for help.

Upvotes: 1

igorti
igorti

Reputation: 3856

You could listen to WMS layer's loadstart and loadend event and hide/show layer accordingly.

A quick test showed though that you can't set visibility of the layer to false on loadstart because OpenLayers will then stop requesting new images for the layer and it will never be completely loaded. You could though try with layer.display(false/true) and see if it solves your problem. The code should look something like this:

  yourWmsLayer.events.on({
        "loadstart" : function(){
            this.display(false);
        },
        "loadend" : function(){
            this.display(true);
        } 
    });

BTW, if you don't set transitionEffect to "resize" on your WMS layer then the default behavior is that old images are removed before new ones are loaded. Isn't that what you want?

Upvotes: 0

Niklas Wulff
Niklas Wulff

Reputation: 3524

I would use mergeNewParams to set a param that makes the layer draw blank. That method triggers a redraw of the layer. When your callback returns from your update request, you do the opposite to make it draw the layer correctly again.

(I have done something similar to this, but I don't have the source for now)

EDIT:

Or - of course - hide the layers with the visibility property of the layers. :-)

Upvotes: 2

Related Questions