1

In my OL3 application at present I have many OL Tile layers that use the same Source object. This source is a TileArcGISRest. The idea is that when users turn layers on/off I build up the layers param and update the source so that the system is only making one request to the ArcGIS server for images.

I'm doing this by watching for the layer visible change event, finding all visible layers and then constructing the param query like so:

/* Construct layers parameter */
var layersParam = 'show:';
for(var i = 0; i < visibleDataLayerIds.length; i++) {
    if(i != 0) {
        layersParam += ',';
    }
    layersParam += visibleDataLayerIds[i];
}

source.updateParams({
    'layers': layersParam
});
source.dispatchEvent('change');

The issue here is that OL still uses cached tiles even after the parameters have changed and I manually dispatch a 'change' event. For example I can turn on a layer and have it display fine, then if I turn off the layer and turn on a different layer without navigating OL will bring back tile images containing the first layer.

I presume this is because these have been cached and OL thinks they are ok to use even though the params on the source have changed which I thought would force the layer/source to detect a change and re-request new tiles.

The workaround I have at the moment is to force the source to clear all its cache, I couldn't find a convenience method to do this so I'm doing the following:

/* Clear cache */
var cache = source.tileCache;
while(cache.count_ > 0) {
    cache.pop().dispose();
}

This feels quite nasty and at present I don't know if this is going to have any adverse affects, it is having the desired affect at present and forcing new tiles to be requested.

So my question is this: is there a better way to do this? It feels odd that after changing the params and firing a 'change' event OL still decides that cached images from a previous call using a different param string are ok to use.

Also as an aside is it possible to get OL not to remove a tile until it has fetched its replacement? Or is that the normal behavior and because I'm clearing the cache the tiles all disappear at once and then get re-requested?

2 Answers 2

2

It's a workaround but that's what we use in our app:

source.setTileLoadFunction(source.getTileLoadFunction());
2
  • I'm using the method you've mentioned here as it appears to have the same effect and isn't using internal variables.
    – marlowp
    Jul 28, 2015 at 12:07
  • For the record, source.changed() seems to work, but any cached tiles will not be re-requested, so in practice it isn't very useful. This works great, +1 Dec 3, 2015 at 1:39
1

Oterral's answer is the only one I have found to work.

//Called everytime a layer parameter inside a MapService needs to be changed
function changeLayerVisibility(sID, oItem, bOn)
{
    var sPID = oItem.parentId;
    if(sPID !== null)
    {
        //Parent layer is the actual layer with the MapService Url
        var acLayer = getParentLayer(sPID)

        //Generate a "show" string EX: "show:1,2,3" based on layer toggles
        var sLayers = getParentLayerString(sPID)

        /*If string is null then all layers for this service are off
         *and the layer's visible set to false
         *otherwise update params and force new tiles
         */
        if(sLayers !== null)
        {
            var oSource = acLayer.getSource();
            acLayer.setVisible(true)

            //Essentially
            //url/MapServer/Export?otherQueryParams="stuff"&LAYERS=show:1,2,3
            oSource.updateParams({LAYERS:sLayers})
            oSource.setTileLoadFunction(oSource.getTileLoadFunction());|
        }
        else
        {
            acLayer.setVisible(false)
        }
    }
    else
    {
        //handle non ArcGis layer visibility here.
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.