Local tiles in the cesium viewer

5,758 views
Skip to first unread message

shad...@gmail.com

unread,
Oct 9, 2013, 2:47:22 PM10/9/13
to cesiu...@googlegroups.com
Hi,
It may be obvious question to others but it is making my work difficult. I have setup cesium 3d globe locally and accessing different imagery as WMS, TMS etc. While globe is sending the request to the local tiles and retrieving also, it is not visible on the globe. What could be reason for this?

Thanks,
S Shadab

Kevin Ring

unread,
Oct 9, 2013, 2:55:11 PM10/9/13
to cesiu...@googlegroups.com
What do you mean by local?  The tiles must come from a web server of some sort; loading files directly from the file system (file:// URL) will not work due to browser restrictions.  While the the browser may successfully go download such files, they can't be used within WebGL because they are considered "cross origin".  This is true even if the Cesium Viewer page is accessed with a similar file:// URL as well.

If you mean a web server running on localhost, the problem is probably different.  Are you getting any errors in the console?

Kevin



--
You received this message because you are subscribed to the Google Groups "cesium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cesium-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

shad...@gmail.com

unread,
Oct 9, 2013, 3:03:56 PM10/9/13
to cesiu...@googlegroups.com
Local tiles mean they are being served by a web server say apache. In my ImageryProviders, I am using TileMapServiceImageryProvider. URL for this is http://localhost/folder path for tiles.
When we see the firebug request, we could understand that globe is calling the tile correctly and it is retrieving also but it is not displayed on the globe.

Kevin Ring

unread,
Oct 9, 2013, 3:54:24 PM10/9/13
to cesiu...@googlegroups.com
Is the HTML page also served from the same server as your tiles?  If not, you'll need to configure the tile server to provide a CORS header to enable the images to be used in WebGL.  This page has background information and instructions: http://enable-cors.org/

Could you share the code you're using to configure and add the imagery provider?

Kevin

Pooja Agrawal

unread,
Oct 10, 2013, 2:25:30 AM10/10/13
to cesiu...@googlegroups.com, shad...@gmail.com
code which is showing error when i am using tms is 
 // code to make widget and to remove the previous layer
var widget = new Cesium.CesiumWidget('cesiumContainer');
    var layers = widget.centralBody.getImageryLayers();
    layers.removeAll();

// code to put local tiles on 3d globe in cesium viewer by using tms
layers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({
        url : 'http://localhost/for3dviewer',   
        fileExtension: 'png',
        maximumLevel: 10      
    }));

but when i am using openstreetmap service then it is showing image on 3d globe so this is the code of osm service
layers.addImageryProvider(new Cesium.OpenStreetMapImageryProvider({
        url : 'http://tile.openstreetmap.org/'      
    }));

Kevin Ring

unread,
Oct 10, 2013, 6:22:13 AM10/10/13
to cesiu...@googlegroups.com, shad...@gmail.com
Hi,

The code looks reasonable, so I can think of two possibilities.  One is that it's a CORS problem, as I mentioned before.  Is the HTML file also running on http://localhost/...?  It has to be the exact same port, even.

The other possibility is that your TMS tileset is somehow bad.  I would expect an error in the console in that case, but maybe not.   Does your TMS tilset have a tilemapresource.xml file?  If so, can you share it?

Kevin

Pooja Agrawal

unread,
Oct 10, 2013, 6:36:16 AM10/10/13
to cesiu...@googlegroups.com, shad...@gmail.com
yes it has tilemapresource.xml file n its here

<?xml version="1.0" encoding="utf-8"?>
<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
 <Title>c1-19feb11-geo.img</Title>
 <Abstract></Abstract>
 <SRS>EPSG:900913</SRS>
 <BoundingBox minx="14.24362194746284" miny="77.15469993580402" maxx="14.79488515919288" maxy="77.53654132285806"/>
 <Origin x="14.24362194746284" y="77.15469993580402"/>
 <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>
 <TileSets profile="mercator">
   <TileSet href="9" units-per-pixel="305.74811308593752" order="9"/>
   <TileSet href="10" units-per-pixel="152.87405654296876" order="10"/>
   <TileSet href="11" units-per-pixel="76.43702827148438" order="11"/>
   <TileSet href="12" units-per-pixel="38.21851413574219" order="12"/>
   <TileSet href="13" units-per-pixel="19.10925706787110" 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"/>
 </TileSets>
</TileMap>




On Thursday, October 10, 2013 12:17:22 AM UTC+5:30, shad...@gmail.com wrote:

Kevin Ring

unread,
Oct 10, 2013, 6:42:12 AM10/10/13
to cesiu...@googlegroups.com
Looks reasonable.  This is only going to cover a tiny part of the globe, though.  The rest will appear blue.  Which version of Cesium are you using?  Some older versions of Cesium may have had trouble with this TMS tileset because it starts at level 9, but newer versions should work fine.

Also, you didn't answer my question about the servers.


--

Pooja Agrawal

unread,
Oct 10, 2013, 7:02:56 AM10/10/13
to cesiu...@googlegroups.com, shad...@gmail.com
no html file is running on localhost:8080
and i am using Cesium- b19 version of cesium


On Thursday, October 10, 2013 12:17:22 AM UTC+5:30, shad...@gmail.com wrote:

Kevin Ring

unread,
Oct 10, 2013, 7:06:21 AM10/10/13
to cesiu...@googlegroups.com
Ok, I recommend you upgrade to the latest version of Cesium.  Then, change your code to use the proxy, like this:

layers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({
        url : 'http://localhost/for3dviewer',   
        fileExtension: 'png',
        maximumLevel: 10,
proxy: new Cesium.DefaultProxy('/proxy/')
    }));

Better yet, enable CORS on the tile server, as I described before.  But if you can't do that, this proxy should work, assuming your localhost:8080 server is the standard web server that comes with Cesium.


--

Evan Thoms

unread,
Nov 14, 2013, 7:39:16 PM11/14/13
to cesiu...@googlegroups.com
Same problem here:

I can start up the node js server and browse to localhost:8080 and get index.html
I have a TMS sitting in a folder called /HRquad in the root folder.
I have edited HelloWorld.html to be:

    var cesiumWidget = new Cesium.CesiumWidget('cesiumContainer');
var layers = cesiumWidget.centralBody.getImageryLayers();
var tms = layers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({
proxy: new Cesium.DefaultProxy('/proxy/'),
}));

When I load that in firebug it looks like my tilremapresource.xml is getting found because it shows up as the response to the GET call.
With the break-on-all-errors property set, the error that gets thrown is 'n is undefined' on line 434 in Cesium.js in function T(e). That's as far as I can track the problem. 

Any suggestions?

I am using version b22

Evan Thoms

unread,
Nov 14, 2013, 7:52:49 PM11/14/13
to cesiu...@googlegroups.com
Wait, the 'n is undefined' error is not within function T(e). The first place n is defined in that line is in

var r=new c({attributes:{position:new h({componentDatatype:n.FLOAT

Scott Hunter

unread,
Nov 14, 2013, 8:00:48 PM11/14/13
to cesiu...@googlegroups.com
Try it with the unminified version of Cesium.js to more easily see what the error is.  You can either download the "full" Cesium zip file, or you can change the script tag at the top of your HelloWorld.html to point to http://cesium.agi.com/releases/b22/Unminified/Cesium.js to load directly off the website.

Evan Thoms

unread,
Nov 14, 2013, 8:52:13 PM11/14/13
to cesiu...@googlegroups.com
Cool, that is much better.
I see now I am getting errors because of discrepancies in case between my .xml file and the loadXML function. 
For instance, the loadXML function defines:
  var format = xml.getElementsByTagName('TileFormat')[0]; and the element in my file is 'tileformat'

I can fix the problems manually, obviously, but I wonder if the function could re-written to be case-insensitive.

For the record, I used Global Mapper to export my TMS.

Evan Thoms

unread,
Nov 14, 2013, 9:37:18 PM11/14/13
to cesiu...@googlegroups.com
There seems to be more of an issue than just case. Here is the tilemapresource.xml that GlobalMapper is spitting out, edited for case by me:

<?xml version="1.0"?>
<TileMap tilemapservice="http://www.osgeo.org/services/tilemapservice.xml" version="1.0.0">
<Title>HRquad</Title>
<Abstract></Abstract>
<SRS>EPSG:900913</SRS>
<VSRS></VSRS>
<BoundingBox maxx="-13540972.4347754" maxy="5743172.5572349" minx="-13570324.2536369" miny="5713820.7383734">
</BoundingBox>
<Origin x="-20037508.3427890" y="-20037508.3427890"></Origin>
<TileFormat extension="png" height="256" mime-type="image/png" width="256">
</TileFormat>
<TileSets profile="global-mercator">
  <TileSet href="12" order="12" units-per-pixel="38.2185141"></TileSet>
  <TileSet href="13" order="13" units-per-pixel="19.1092571"></TileSet>
  <TileSet href="14" order="14" units-per-pixel="9.5546285"></TileSet>
  <TileSet href="15" order="15" units-per-pixel="4.7773143"></TileSet>
  <TileSet href="16" order="16" units-per-pixel="2.3886571"></TileSet>
</TileSets>
</TileMap>

and the error that gets thrown now is 'neTile is undefined'. I have been tracking the problem backwards and it appears that the tilingScheme is maybe getting incorrectly defined? not sure.

Kevin Ring

unread,
Nov 15, 2013, 12:19:45 PM11/15/13
to cesiu...@googlegroups.com
Hey Evan,

I think the problem is that the BoundingBox specifies the extent in Web Mercator meters, instead of geodetic decimal degrees like Cesium expects.  Arguably this is correct, although I swear I've seen EPSG:900913 TMS resources that use decimal degrees there.  I'll check into it and get back to you.

Kevin

Kevin Ring

unread,
Nov 15, 2013, 5:27:00 PM11/15/13
to cesiu...@googlegroups.com
Evan,

So the TMS specification (http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification), such as it is, is not completely clear about what the units of the BoundingBox property should be.  It's never stated explicitly, but the examples clearly include some BoundingBoxes that are not geodetic degrees.  Meanwhile, MapTiler, which is the main tool I've used to create TMS tilesets, uses geodetic longitude and latitude even when the SRS is EPSG:900913.  Ugh.  I think supporting both will require Cesium to guess the units based on the magnitude of the numbers or some such nonsense.

Regarding case, XML tags are case sensitive, and both the spec and MapTiler agree that PascalCase should be used.  So in that case I'd say that GlobalMapper is generating incorrect output.  We can change Cesium to be more tolerant of this, though.  Scott wrote an issue for that: https://github.com/AnalyticalGraphicsInc/cesium/issues/1299.

Another gotcha: Cesium expects the profile to say "geodetic" or "mercator", consistent with the output produced by MapTiler.  But the spec says those should be called "global-geodetic" and "global-mercator".  It will be easy enough to change Cesium to support either.  In your particular case, you should be ok, though, because the default tiling scheme for unrecognized profiles is WebMercator.

As a workaround prior to a fix, you should be able to use Cesium's WebMercatorProjection class to manually transform the BoundingBox coordinates from 900913 to 4326 and update your tilemapresource.xml.

Kevin

Evan Thoms

unread,
Nov 18, 2013, 2:54:06 PM11/18/13
to cesiu...@googlegroups.com
Ok, that's kind of what I thought was going on. Thanks for checking. I have seen the developer of GM react pretty quickly to requests and suggestions, so I will post something over there.

Lia

unread,
Jun 18, 2015, 6:05:59 AM6/18/15
to cesiu...@googlegroups.com
Hi,
i have a similar problem and my tiles cover just a part for the globe. i generated the tiles with gdal2tles. How can i fit it to the entire globe. I don't know where the problem is? Can you help me please. It works fine if i replace with 'NaturalEarthII' which is in the same folder and look like it has the "same propreties". Here is the code:

var viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider : new Cesium.TileMapServiceImageryProvider({
url : Cesium.buildModuleUrl('Assets/Textures/newglobe'), credit : 'New Globe'
}),
baseLayerPicker : false,
geocoder : false
});

and tilemapressource.xml

<?xml version="1.0" encoding="utf-8"?>
<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">

<Title>newglobe.vrt</Title>
<Abstract></Abstract>
<SRS>EPSG:4326</SRS>
<BoundingBox minx="-90.00000000000000" miny="-180.00000000000000" maxx="90.00000000000000" maxy="180.00000000000000"/>
<Origin x="-90.00000000000000" y="-180.00000000000000"/>


<TileFormat width="256" height="256" mime-type="image/png" extension="png"/>

<TileSets profile="geodetic">
<TileSet href="0" units-per-pixel="0.70312500000000" order="0"/>
<TileSet href="1" units-per-pixel="0.35156250000000" order="1"/>
<TileSet href="2" units-per-pixel="0.17578125000000" order="2"/>
<TileSet href="3" units-per-pixel="0.08789062500000" order="3"/>
<TileSet href="4" units-per-pixel="0.04394531250000" order="4"/>
<TileSet href="5" units-per-pixel="0.02197265625000" order="5"/>
<TileSet href="6" units-per-pixel="0.01098632812500" order="6"/>
</TileSets>
</TileMap>

Thanks
Lia

Mike LP

unread,
Jun 21, 2015, 2:25:33 PM6/21/15
to cesiu...@googlegroups.com, shad...@gmail.com
Can you share a sample of the imagery you sent through gdal2tiles?

Lia

unread,
Jun 22, 2015, 4:14:28 AM6/22/15
to cesiu...@googlegroups.com
Am Sonntag, 21. Juni 2015 20:25:33 UTC+2 schrieb Mike LP:
> Can you share a sample of the imagery you sent through gdal2tiles?
>

Hi, i fix my problem using SingleTileImageryProvider. It was a .png file that i tried to generate as Tiles.

Mike LP

unread,
Jun 23, 2015, 12:15:54 PM6/23/15
to cesiu...@googlegroups.com, halimatou...@gmail.com, halimatou...@gmail.com
Glad to hear.  As a follow up though you can still use gdal2tiles to make it into TMS, but you need to use gdal_translate as an intermediary step to convert to a geotiff that contains the bounding and projection information.

This is how I've been able to use the NASA's blue marble PNG files and make a TMS out of them.

hanokh...@gmail.com

unread,
Mar 3, 2016, 10:05:23 AM3/3/16
to cesium-dev
Kevin,
Have you ever tried to run from chrome with the with --allow-file-access-from-files in the command-line. ?

evert....@stonethree.com

unread,
Jun 23, 2016, 12:06:31 PM6/23/16
to cesium-dev, halimatou...@gmail.com
Hi Mike,
I am trying to do something very similar to what you said here, I grabbed one of NASAs blue marble images, and used gdal_translate, gdalwarp and gdal2tiles.py to make a TMS out of the image. Here are my steps:

gdal_translate -of VRT -a_srs EPSG:4326 -gcp 0 0 -180 90 -gcp 21600 0 180 90 -gcp 21600 10800 180 -90 world_200401.jpg bluemarble1.vrt

gdalwarp -of VRT -t_srs EPSG:4326 bluemarble1.vrt bluemarble2.vrt

gdal2tiles.py -p geodetic bluemarble2.vrt

After this, I can successfully open the image in Cesium using the following bit of code:

var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker: false,
geocoder: false,
imageryProvider: new Cesium.createTileMapServiceImageryProvider({
url: '../data/NASA/bluemarble2',
// minimumLevel: 0,
credit: 'NASA'
})
});

HOWEVER, it seems that the image is not wrapped correctly around the globe...it only wraps it half way around, and halfway down from the centre. Leaving a lot of blue.

Any idea what I could be doing wrong? Here is a link to the image I used and some output files I got: https://drive.google.com/folderview?id=0B97NtaPJrVz-a3EwbXhkdlYyM00&usp=sharing

Here is my tilemapresource.xml file:

<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0"><Title>bluemarble2.vrt</Title><Abstract/><SRS>EPSG:4326</SRS><BoundingBox minx="-180.00000000000000" miny="-90.00000000000000" maxx="180.00000000000000" maxy="90.00000000000000"/><Origin x="-180.00000000000000" y="-90.00000000000000"/><TileFormat width="256" height="256" mime-type="image/png" extension="png"/><TileSets profile="geodetic"><TileSet href="0" units-per-pixel="0.70312500000000" order="0"/><TileSet href="1" units-per-pixel="0.35156250000000" order="1"/><TileSet href="2" units-per-pixel="0.17578125000000" order="2"/><TileSet href="3" units-per-pixel="0.08789062500000" order="3"/><TileSet href="4" units-per-pixel="0.04394531250000" order="4"/><TileSet href="5" units-per-pixel="0.02197265625000" order="5"/><TileSet href="6" units-per-pixel="0.01098632812500" order="6"/></TileSets></TileMap>



Hannah Pinkos

unread,
Jun 23, 2016, 1:57:15 PM6/23/16
to cesium-dev, halimatou...@gmail.com, evert....@stonethree.com
Hello,

You may need to set the option 'flipXY: true'
See this example with NASA black marble:

var blackMarble = layers.addImageryProvider(Cesium.createTileMapServiceImageryProvider({
    url
: 'https://cesiumjs.org/blackmarble',
    credit
: 'Black Marble imagery courtesy NASA Earth Observatory',
    flipXY
: true // Only old gdal2tile.py generated tilesets need this flag.
}));

Best,

Hannah

evert....@stonethree.com

unread,
Jun 24, 2016, 4:09:51 AM6/24/16
to cesium-dev, halimatou...@gmail.com, evert....@stonethree.com
Hi Hannah,

Thanks for the response.

I actually tried that but it didn't work. My tilesets generated with gdal2tiles.py is not old as the comment suggests I guess.

Even if it did though, half of the globe will still be left uncovered...

Any other ideas?

Thanks again!

evert....@stonethree.com

unread,
Jun 24, 2016, 5:05:57 AM6/24/16
to cesium-dev, halimatou...@gmail.com, evert....@stonethree.com
Hi all,

I actually found the solution to my problem: according to the API reference, Cesium uses the mercator tiling scheme.

"A tiling scheme for geometry referenced to a WebMercatorProjection, EPSG:3857. This is the tiling scheme used by Google Maps, Microsoft Bing Maps, and most of ESRI ArcGIS Online."

Thus, instead of using EPSG:4326 I needed to use the EPSG:3857 mercator projection...

gdal_translate -of VRT -a_srs EPSG:3857 -gcp 0 0 -180 90 -gcp 21600 0 180 90 -gcp 21600 10800 180 -90 world_200401.jpg bluemarble1.vrt

gdalwarp -of VRT -t_srs EPSG:3857 bluemarble1.vrt bluemarble2.vrt

gdal2tiles.py bluemarble2.vrt

Hope this helps someone else.

Regards,
Evert

Lia

unread,
Aug 31, 2016, 4:47:48 AM8/31/16
to cesium-dev, halimatou...@gmail.com, evert....@stonethree.com
Hi,
i actually try Evert solution but it didn't work. I flip also XY.

it only wraps it half way around, and halfway down from the centre.
File example:
https://www.dropbox.com/s/1j0mhzvc8m1xpwj/ghillany.jpg?dl=0

Is there any other solution to generate cesium tiles for free (maybe with cesium)? I have around 6 maps(.jpg with 100mb) to load and it is faster to do it with tiles.

Regards,
Lia

juho...@gmail.com

unread,
May 31, 2017, 12:32:20 PM5/31/17
to cesium-dev, halimatou...@gmail.com, evert....@stonethree.com, hps.v...@gmail.com
Hi

Evert do you find any good solution for image quality? i need to re-project my maps from epsg:3067 to epsg:3857 so that i can use them with my cesiumin application. I found that image quality will get bad when i re-project them i'll use gdalwarp.

Cheers

Juho

Reply all
Reply to author
Forward
0 new messages