Using regional data in Cesium

I've added a tile set using an imageryProvider. The tiles covers an area in Norway within these bounds: 7.2, 60.9, 9.0, 61.7 (shown with a rectangle in the screenshot). It looks like this i Cesium:
https://dl.dropboxusercontent.com/u/2306934/cesium/cesium-regional-tiles.png

Question: Is it possible to tell Cesium not to render the areas outside the bounds to get rid of the artifacts.

BTW, Cesium is a great tool!

First off, thanks for the complement. The artifacts you are seeing are caused by the shader which is attempting to fill in gaps at the poles (since most world imagery only goes to something like 89.5 degrees). Currently Cesium always expects a root tile that covers the entire world. I think the correct way to handle this (without changing Cesium) is to generate tiles all the way up from your region but I don’t normally work in this area of the code so hopefully Scott or Kevin can chime in with a more complete answer. We’ve had others run into this issue before so maybe we should consider adding an easy toggle or automatic detection of this case.

I don’t think it’s the pole filling. It appears that the feature to limit imagery to a rectangle simply doesn’t work at all.

Try this Sandcastle example:

var viewer = new Cesium.Viewer(‘cesiumContainer’, {

imageryProvider : new Cesium.TileCoordinatesImageryProvider(),

baseLayerPicker : false

});

var layers = viewer.scene.imageryLayers;

var blackMarbleProvider = new Cesium.TileMapServiceImageryProvider({

url : ‘//cesiumjs.org/blackmarble’,

maximumLevel : 8,

credit : ‘Black Marble imagery courtesy NASA Earth Observatory’

});

var blackMarbleLayer = new Cesium.ImageryLayer(blackMarbleProvider, {

rectangle : Cesium.Rectangle.fromDegrees(7.2, 60.9, 9.0, 61.7)

});

layers.add(blackMarbleLayer);

Imagery is drawn for the entire tile regardless of the rectangle, which you can see as you zoom in and out. I don’t know how long this has been broken, but I’ll try to debug it a bit to see where the missing intersection is supposed to be.

Yeah it’s been a known problem for awhile:
https://github.com/AnalyticalGraphicsInc/cesium/issues/416

I had tried (not very hard) to fix it awhile back, but it wasn’t especially high priority at the time.

Kevin

Scott, I’m happy to work on this, assuming you don’t beat me to it.

Go for it. I haven’t done much after reproducing it for my earlier email.

Ok, this commit fixes it:
https://github.com/AnalyticalGraphicsInc/cesium/commit/c1d6b33c48bbe69823cf4f033aae53d08472d36f

I’ll write some tests and open a pull request by Tuesday morning.

Your fix works great Kevin:
https://dl.dropboxusercontent.com/u/2306934/cesium/cesium-regional-tiles-fix.png

The main artifacts were due to adding my regional tile layer as the baselayer, and not as an overlay using scene.imageryLayers.add.

Is there a global base layer that simply sets a black background?

Bjørn

kl. 08:43:59 UTC+2 søndag 5. oktober 2014 skrev Kevin Ring følgende:

This one I CAN answer correctly. :slight_smile: With the 1.2 release, we added a baseColor property on Globe that sets the color in places without imagery. You can set this property at any time and change it on the fly.

scene.globe.baseColor = Color.BLACK;

But I can’t see the baseColor because my globe is already covered. If I don’t set a imageryProvider in the Viewer, Cesium uses BingMaps. If I set my regional layer in the Viewer, I get the artifacts as shown above. Is it possible to set the imageryProvider to empty?

Yes, you can call scene.imageryLayers.removeAll() and that will cause the entire globe to be globe.baseColor.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

viewer.scene.globe.baseColor = Cesium.Color.BLACK;

viewer.scene.imageryLayers.removeAll();

However, I just tried this with a TMS provider in Kevin’s imageryWithLimitedExtent branch and there are still issues.

Kevin, here’s the complete Sandcastle example. Am I correct in that nothing should be drawn outside of the rectangle?

var viewer = new Cesium.Viewer(‘cesiumContainer’);

viewer.scene.globe.baseColor = Cesium.Color.BLACK;

viewer.scene.imageryLayers.removeAll();

var west = -75.0;

var south = 28.0;

var east = -67.0;

var north = 29.75;

var layers = viewer.scene.imageryLayers;

layers.removeAll();

layers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({

url : ‘…/images/cesium_maptiler/Cesium_Logo_Color’,

rectangle : Cesium.Rectangle.fromDegrees(west, south, east, north)

}));

// Show a primitive for the imagery layer rectangle.

var polylines = viewer.scene.primitives.add(new Cesium.PolylineCollection());

polylines.add({

positions : Cesium.Cartesian3.fromDegreesArray([

west, south,

west, north,

east, north,

east, south,

west, south

])

});

viewer.scene.camera.viewRectangle(Cesium.Rectangle.fromDegrees(west, south, east, north));

I also get the artifacts when I remove all layers, and add my layer:
https://dl.dropboxusercontent.com/u/2306934/cesium/cesium-regional-tiles-no-baselayer.png

It seems that a regional layer can’t be the only one.

You’re right that the base layer is still stretched, which is a separate bug that we should also fix at some point.

For now, try adding another layer to be the base layer.

This code adds a 1x1 transparent PNG to cover the entire world, which will then let the baseColor setting of the globe work properly. Add this layer before your regional layer, so it’s at the “bottom” of the stack.

viewer.scene.globe.baseColor = Cesium.Color.BLACK;

layers.addImageryProvider(new Cesium.SingleTileImageryProvider({

url : ‘data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=’

}));

It works - thanks Scott!

The base layer stretching is intentional, not a bug. It’s important when using Web Mercator imagery (including our default, Bing Maps) because without it we’d have “baseColor” holes at the poles. Stretching looks much better.

My (perhaps incorrect) assumption was that people would always want to have a global base layer, even if it’s something simple and low-res like our Natural Earth II layer, because otherwise things like pretty poor when the user zooms out.

But we could easily add a manual way to turn off the stretching if that would be useful to people. We could also perhaps be smarter about when we stretch. Only for global Web Mercator base layers? Only if the layer is “almost” global?

Kevin

I see the rationale behind base layer stretching, but I think it should be possible to turn it off.

I guess using Columbus View is also an alternative for regional data.

Bjørm

kl. 07:22:30 UTC+2 tirsdag 7. oktober 2014 skrev Kevin Ring følgende:

The same streching happen in Columbus View:
https://dl.dropboxusercontent.com/u/2306934/cesium/cesium-regional-tiles-columbus.png

Bjørn

kl. 12:30:20 UTC+2 tirsdag 7. oktober 2014 skrev bjorn....@gmail.com følgende:

Hi Kevin,

I am wondering if the manual way to turn off the stretching is added in 1.17?

Thanks,

Steven

No, sorry. But an easy workaround is to add a base layer. It can be a SingleTileImageryProvider where the image is a single-pixel PNG of whatever color you want the globe to be outside of your small region.

Yeah, that is the way I am doing it now, however, a parameter to turn it off would be useful.
Thanks for the reply.