TileMapServiceImageryProvider minimum level problem

We’re trying to use multiple TileMapServiceImageryProvider, each with different minimum and maximum levels to that we display tiles from a different source depending on the current LOD level.

However, either we’re doing something wrong or Cesium does not support this yet.

We’re adding multiple TileMapServiceImageryProvider to “viewer.scene.imageryLayers” (before we call removeAll()), each provider is configured with different levels defined, first one from levels 0 to 7, and then multiple ones from 8 to 11 (each with different rectangle areas defined, eg: Africa or Europe).

The problem is that Cesium is requesting tiles from those smaller subsets at the wrong levels (eg: requesting level 2 of Africa layer when this was configured with minimum level of 8 and maximum of 11).
Is this a know problem or is there anything we can do to fix?

I checked the code from TileMapServiceImageryProvider and actually the minimum and maximum size dont are used anywhere, but since the class exposes them as properties I guess they are being used somewhere else.

Some new details I found.

This code can be found in TileMapServiceImageryProvider.js

        // Check the number of tiles at the minimum level.  If it's more than four,
        // try requesting the lower levels anyway, because starting at the higher minimum
        // level will cause too many tiles to be downloaded and rendered.
        var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(that._rectangle), that._minimumLevel);
        var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(that._rectangle), that._minimumLevel);
        var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
        if (tileCount > 4) {
            that._minimumLevel = 0;
        }

``

If I understand corrrectly, this codes makes Cesium ignore the minimumLevel in the case there are more than 4 tiles in the minimumLevel.
But does that mean that this makes it impossible to combine multiple providers, by letting one handle lower levels of detail and then another one provides fallback tiles for all levels?

`A TilingScheme with non-default values could be used to bypass this If, but I not sure if that would work, because our provider uses the same style of subdivisions as the others, just does not have tiles for levels 7 and lower.

`

Hi,

Sorry, the minimumLevel and maximumLevel properties aren’t meant to be used this way. Cesium will always show the layer at all zoom levels. Those properties just control which level tiles it should request in order to do so.

I’ve generally seen people do what you’re describing on the server instead of asking Cesium to do it. For example, if you have 3 TMS layers, A, B, and C, and you want to show different layers for different zoom levels, you can create a new TMS directory that, for example, has a copy of the A tiles for level 0-2, the B tiles for 3-8, and the C tiles for 9-12. You could use symlinks to do this without copying the data. Other imagery servers, including Geoserver, ArcGIS Server, and probably most others as well, have support for doing this kind of thing.

But if you really need Cesium to do it, it wouldn’t be a hard feature to add. I’d probably add minimumLevelToShow and maximumLevelToShow properties to ImageryLayer and change ImageryLayer._createTileImagerySkeletons to honor the new properties. We’d welcome a pull request if you feel like tackling it.

Thanks,

Kevin

We actually have an issue for this already: https://github.com/AnalyticalGraphicsInc/cesium/issues/2612 We would be willing to take a pull request for it.

I just checked the code of ImageryLayer, that createskeletons have the following lines:

    if (defined(this._minimumTerrainLevel) && tile.level < this._minimumTerrainLevel) {
        return false;
    }
    if (defined(this._maximumTerrainLevel) && tile.level > this._maximumTerrainLevel) {
        return false;
    }

``

Isnt this exactly what we’re already asking?
I think the problem is that the constructor for the layer actually does some calculation and then always set the minimumLevel as zero.

Or you guys really want to have a separate minimumDisplayLevel property? In that case, would I add a similar If to the skeletons methods, basically, just returning false is enough?

Hi guys, here’s my pull request for this:
https://github.com/AnalyticalGraphicsInc/cesium/pull/2671

We tested it in our app and now we no longer get exceptions and the layers get displayed correctly by taking the minimum/maximum levels into account.