Search code examples
openlayers

What is proper way to clear the image cache on an Openlayers ImageWMS source?


I have an ImageLayer with an ImageWMS source. When the user changes the map time I use wmsLayer.getSource().updateParams() to update its TIME parameter. This works fine if the time exists on the server. Openlayers generates a new getMap request with the new TIME parameter. But if the new time doesn't exist and the server returns an error, the map layer continues to display the old image. I want the old image to be cleared and nothing to be displayed on the map (I show a failure indicator elsewhere).

To fix this I use

wmsLayer.getSource().on('imageloaderror', onLoadError).

Then in onLoadError I was doing this, which used to work:

wmsLayer.renderer_.image_=null;

This stopped working at some point and I recently had to change it to this:

wmsLayer.getRenderer().image=null;

The problem is that I think I'm reaching into implementation details with a club fist, so I'm wondering what the proper, forward compatible way to clear the image cache is after a request fails to return an image. I am currently using openlayers 10.2.


Solution

  • If you cannot use opacity a better way would be to prevent errors reaching the image. Typically a WMS will return a status even with a invalid request as the response will be xml instead of an image. You can check the response content type in a custom imageLoadFunction and set the OpenLayers image src to an empty data url if the response is not an image:

    const canvas = document.createElement('canvas');
    canvas.width = 1;
    canvas.height = 1;
    const empty = canvas.toDataURL();
    
    const source =  new ol.source.ImageWMS({
      url: 'https://....',
      params: {'LAYERS': '....'},
      imageLoadFunction: function(img, src) {
        fetch(src).then((response) => {
          if (response.headers.get('content-type').startsWith('image/')) {
            response.blob().then((blob) => {
              img.getImage().src = URL.createObjectURL(blob);
            });
          } else {
            img.getImage().src = empty;
          }
        });
      },
    });