OpenLayers Clipping – Clipping TileLayer with Vector Polygon: Step-by-Step Guide

clipjavascriptopenlayersrendering

I would like to add a mask to clip layer (Tile) in a way that only the part bounded by a ol.Feature (polygon or multipolygon or layer) is visible and the rest is hidden (left transparent). The geometry is generated dynamically so I need a way to do that programatically.

I presented the question Clipping TileLayer with georeferenced polygon (clipping mask) (see).
Clipping map with vector layer (only layers zIndex == 0):

var style = new ol.style.Style({
    fill: new ol.style.Fill({
    color: 'black'
  })
});

var clipLayer = new ol.layer.Image({
  source: new ol.source.ImageVector({
    source: new ol.source.Vector({
      url: '//openlayers.org/en/v4.6.5/examples/data/geojson/countries.geojson',
      format: new ol.format.GeoJSON()
    }),
    style: style
  })
});
clipLayer.on('postcompose', function(e) {
  e.context.globalCompositeOperation = 'source-over';
});
clipLayer.on('precompose', function(e) {
  e.context.globalCompositeOperation = 'destination-in';
});

Example result: OSM (BaseLayer), TileLayer (Stamen) and vector layer

World map with a clipped overlay on Australia

Two layers were clipped (!) – OSM and TileLayer.

I need clipping TileLayer with vector layer (support zIndex).
Example: OSM (BaseLayer), TileLayer and vector layer

Australia map with a clipped overlay on South Australia

One layer were clipped – TileLayer.

Does anybody have some clues or examples to achieve this?

Best Answer

Solution 1:

You will find an example to do this using ol.source.Raster, quickly illustrated with an animated GIF.

Filter a particular layer with a vector source

I'm using it to combined an ol.source.ImageVector with an ol.source.Stamen (for this demo but any raster ol.source.* would work) FYI, the function ol.source.ImageVector is normally deprecated but with the new recommanded way, I don't see how to do it as I can't access to a source to mix both raster and vector layers sources within ol.source.Raster. (any clue is welcome to upgrade)

Solution 2:

Use an OpenLayers ol-ext plugin, see the demo that do more or less the same as solution 1 I've done (but I didn't look how it's done)

Related Question