Need help using UrlTemplateImageryProvider

We are trying to use the UrlTemplateImageryProvider to render tiles that we are also rendering in OpenLayers. These tiles are served from our server in a z,x,-y format, and we have put together an url as follows: /bla/{z}/{x}/{reverseY}.png
We built the tiles using gdal2tiles. tilemapresource.xml included below.

We are having complete difficulty with passing in options and having CesiumJS request the right tiles.

If we just pass in the url, we get requests for images with the correct z and x values but the y value is off by thousands, for example a y value (it is in Hawaii) that is requested is 29166 but the y tiles that we have for that z and x run in the range of 363xx.

This is our main question -- why are these Y values incorrect?

Secondary question: how do we use a bounding rectangle:

If we pass in a rectangle in the options, there is no rectangle defined in the constructed UrlTemplateImageryProvider, and in ImageryLayer.js on line 442, rectangle is undefined for our imageryProvider:
var imageryBounds = Rectangle.intersection(imageryProvider.rectangle, this._rectangle, imageryBoundsScratch);

(here is our rectangle:
east: 0.3392507670702749
north: -2.709084989512464
south: -2.710495394056505
west: 0.3381396085358207)

In UrlTemplateImageryProvider on line 561 when it is initializing, it calls:
that._rectangle = defaultValue(properties.rectangle, that._tilingScheme.rectangle);
// at this point it has our rectangle
that._rectangle = Rectangle.intersection(that._rectangle, that._tilingScheme.rectangle);
In this case the intersection fails, and that._rectangle becomes undefined.

If we construct our own tiling scheme with bounds:
tilingScheme: new WebMercatorTilingScheme({rectangleSouthwestInMeters: new Cartesian2(258425.85, 2143816.56),
                                      rectangleNortheastInMeters: new Cartesian2(267007.87, 2150754.24)})

the intersection still fails and that._rectangle is undefined.
However in this case, we shouldn't have to use a rectangle as it's already set in our tiling scheme
If we set imageryProvider.rectangle after we construct it and it is ignored, then the imagery is never requested.

The tilemapresource.xml is as follows:
<?xml version="1.0" encoding="utf-8"?>
    <TileMap version="1.0.0" tilemapservice="">
      <BoundingBox minx="19.37397245530835" miny="-155.29994646908671" maxx="19.43763714970252" maxy="-155.21913624130707"/>
      <Origin x="19.37397245530835" y="-155.29994646908671"/>
      <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>
      <TileSets profile="mercator">
        <TileSet href="12" units-per-pixel="38.21851413574219" order="12"/>
        <TileSet href="13" units-per-pixel="19.10925706787109" order="13"/>
        <TileSet href="14" units-per-pixel="9.55462853393555" order="14"/>
        <TileSet href="15" units-per-pixel="4.77731426696777" order="15"/>
        <TileSet href="16" units-per-pixel="2.38865713348389" order="16"/>
        <TileSet href="17" units-per-pixel="1.19432856674194" order="17"/>
        <TileSet href="18" units-per-pixel="0.59716428337097" order="18"/>
        <TileSet href="19" units-per-pixel="0.29858214168549" order="19"/>
        <TileSet href="20" units-per-pixel="0.14929107084274" order="20"/>

We are on Cesium 1.38.0, OSX and Chrome.

Unfortunately we have left this until the last minute and it is now urgent. Any help is greatly greatly appreciated.


p.s. we tried to also include the naturalearthii example but the url in the documentation no longer points to the tiles, what is the correct url? The documentation states:
var tms = new Cesium.UrlTemplateImageryProvider({
    url : '{z}/{x}/{reverseY}.jpg',
    credit : '© Analytical Graphics, Inc.',
    tilingScheme : new Cesium.GeographicTilingScheme(),
    maximumLevel : 5

Tile coordinates can either be numbered with 0 in the north, or 0 in the south (TMS). If your Y tiles aren’t matching, try using {y} in the URL template instead of {reverseY}.

We tried that first thing, no joy.

If you have a tilemapresource.xml, try using


instead of the low-level UrlTemplateImageryProvider.

The createTileMapServiceImageryProvider function will download and parse metadata from the XML file, such as the bounding box.

Oddly, with either y or reverseY, the requested Y tiles values are the same.

The createTileMapServiceImageryProvider is fantastic. Unfortunately we are still having no success with that. Our bounding box in the tilemapresource.xml is:

I think the y values are a problem so we have experimented with constructing the tile map service imagery provider with our own bounding rectangle. We tried these two with no success:

[19.37397245530835, 24.70005353091329, 19.43763714970252, 24.78086375869293], // west south east north in degrees

[19.37397245530835, -90, 19.43763714970252, 90], // west south east north in degrees

It’s just never asking for the tiles now.

We also tried switching x and y because it actually seems that the tilemapresource.xml has it backwards.


[-155.29994646908671, 19.37397245530835, -155.21913624130707, 19.43763714970252], // west south east north in degrees

still never has it asking for the image tiles.

More suggestions? thanks so much.

createTileMapServiceImageryProvider has a flipXY option to work around incorrect output from old versions of gdal2tiles.

Ah, just as I suspected. I passed that flag in, which is great, and I stepped through the construction of the imagery provider and the new rectangle is all good.
Unfortunately, no image tiles are being requested still. I have added the imagery provider (via viewer.scene.imageryLayers.addImageryProvider).

What else could be causing the images to not be requested now that it is just reading from the tilemapresource.xml?

Thanks a ton for your help.

Check the browser console to see if you see errors related to CORS. If you do, then the server providing the tiles will need to be configured to add the appropriate CORS headers.

I don’t think it’s CORS; CORS is enabled on the other server (providing the tiles) plus I am successfully getting the tilemapresource.xml.

Now I am seeing this error:

An error occurred in “CesiumTerrainProvider”: Failed to obtain terrain tile X: 0 Y: 0 Level: 0.

I have made sure to create a 0.png in 0/0/ and 0/1/ and I have verified that I can download them.

I have also experimented with removing the username and password from the url. I will now experiment with hosting the data on the same server building the cesium app.



Your error says CesiumTerrainProvider? That suggests the problem is with the terrain data, not your imagery provider.

Oops. Indeed, I commented out that reference to nonexisting files. I am working to provide the imagery from the same server … will post progress. However I am still baffled, it should be possible and in fact IS documented pulling from a remote server.

Do you know where the naturalearthii files went?

Ok now I’m serving the imagery from the same server. Just as before, cesiumJS is getting and reading the tilemapresource.xml file and building the imagery layer, and never asking for any png files.
I’m feeling like it’s a problem with the data. I upgraded gdal and tiled a new set, with the same problem.

I have created the 0/0/0.png and 0/1/0.png files.

Do you know where there is a working sample set on a notehr server that I can try?



A small subset of Natural Earth II (only up to zoomlevel 2) is available in Cesium, in Assets/Textures/NaturalEarthII. Data up to zoomlevel 5 is in in the imagery/NaturalEarthII folder.

Perfect, I will test against the natural earth imagery. Thanks so much!

Ok, I have installed the natural earth imagery locally and am referring to it locally by URL and see the SAME BEHAVIOR where the tilemapresource.xml file is downloaded and parsed but no images are ever requested. This is a perfect test case.
Is there some flag I have to set for the viewer as a whole?



ahem. Er, it was user error. I had some bad javascript referring to an undefined variable, and I’m not sure why that was not caught by the compiler.
Sorry for the noise, THANK you for your support.

I do think I’ve uncovered the fact that the urls do not support username:password in them, but I can work around that with a proxy.

Thank you! And thank for the tip about the CreateTileMapServiceImageryProvider.