I have two Image services that I would like to combine into one layer; one has higher resolution imagery that draws only at a larger scale, and other has lower resolution imagery that draws at all scales. I'd like to combine them so that when you are zoomed in, the detailed imagery draws on top of the lower res imagery. I tried to load in the 2 urls like this:

var USGSimagery = new ol.layer.Tile({
    source: new ol.source.TileWMS(({
    urls: ['http://raster.nationalmap.gov/arcgis/services/Orthoimagery/USGS_EROS_Ortho_SCALE/ImageServer/WMSServer','http://basemap.nationalmap.gov/arcgis/services/USGSImageryOnly/MapServer/WmsServer'],
    params: {
                  'LAYERS': 0

But when I load the layer in the map - it draws funny, like in alternating strips where it shows one service and then the other. So this obviously isn't the way to do it. Does anyone know if it's possible to combine two services into one layer with one drawing on top of the other?

  • Why not just have two layers, and control their zorder, min zoom, and max zoom? Apr 25, 2017 at 6:08

1 Answer 1


Use an XYZ source and a tileUrlFunction:

//function for retrieving tile extent for a given tile
var tileExtent = function (tileCoord, source) {
    var z = tileCoord[0];
    var x = tileCoord[1];
    var y = tileCoord[2];
    var tileGrid = source.getTileGrid();
    var tileGridOrigin = tileGrid.getOrigin();
    var tileSizeAtResolution = tileGrid.getTileSize(z) * tileGrid.getResolution(z);
    return [
        tileGridOrigin[0] + tileSizeAtResolution * x,
        tileGridOrigin[1] + tileSizeAtResolution * y,
        tileGridOrigin[0] + tileSizeAtResolution * (x + 1),
        tileGridOrigin[1] + tileSizeAtResolution * (y + 1)

var currentSource = new ol.source.XYZ({
    tileUrlFunction: function (coordinate, pixelRatio, proj) {
        var urls ['http://raster.nationalmap.gov/arcgis/services/Orthoimagery/USGS_EROS_Ortho_SCALE/ImageServer/WMSServer',
        var res = map.getView().getResolution();
        var tileUrl = '';

        if (res > YOUR_RESOLUTION_THRESHOLD) {
            tileUrl = urls[0];
        else {
            tileUrl = urls[1];
        var extent = tileExtent(coordinate, this);
        //WMS Url may be constructed wrongly this way, but I'm too lazy to look up the actual WMS parameters. You should get the idea.
        tileUrl = tileUrl + '?width=256&height=256&bbox=' + extent[0] + ',' + extent[1] + ',' + extent[2] + ',' + extent[3] + '&Layers=0';
        return tileUrl;
    projection: projectProjection

var currentMapLayer = new ol.layer.Tile({
    title: 'Layers',
    source: currentSource

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.