Lat/lon graticule layers like in WorldWind

Maybe I’m just overlooking it but does Cesium allow you to show lat/lon or utm grids on the globe?

Hi Matt,

You are right, Cesium doesn’t currently have a simple boolean to turn on/off a grid layer. It is on the roadmap. In the meantime, it is easy to code with a few for loops using the PolylineCollection.


I need it too :wink:

Only I went another way. I tried the ImageLayerProvider way, having seen the Grid example. It sorts of work only I would really need to have it rendering on one big tile (for each zoom level obviously) otherwise I am having refresh problems when zooming (tiles on the side are not refreshed and they are displaying a grid for the previous zoom level). is there any way to force that behavior?

hi Patrick

a static grid is very simple to draw, but I think the grid need to be dynamically changed as camera distance and view angle changes.
I've tried to dynamically construct the grid every frame, right before terrain tile update routine. but it blinks heavily. If I use a collection of geometries(quad geometry) to represent the grid, and want to update(delete old and new) geometry into that collection, where should I put the update routine?

Thanks for your attention!

Thomas - we can’t force the terrain/imagery to render all tiles at the same LOD; this would be impractical for views that require a high LOD. For an image-based approach, you could draw a worldwide Extent primitive and use a custom material based on the grid material (under procedural textures) or just use the grid material.

If we are removing and adding new geometries, this can be done in the app’s animation loop; make sure to create the Primitive with asynchronous set to false.


Yes, I gave up on this idea. The labels don’t display too well over the poles…

I actually recycled it into a hybrid version, mixing tiling and graphics vector.

This is the idea:

  • the graticule is an ImageryProvider but it only returns empty canvases. It uses the requestImage call to refresh the vector graphics I overlay for the grid.

  • to draw the grid I use a PolylineCollection and a LabelCollection

  • when the requireImage is called, I get the extent of the view and I use the extent to redraw the lat, long lines and the text based on the extent. I add a bit of margin all around to compensate for moves where the requestImage is not called.

This works reasonably well, except when the sky is visible at low zoom level. It then defaults to the full globe extent - I use the camera view to calculate the extent.

Cool. Are you up for providing this as a Cesium plugin?


I don't think it is good enough right now.

I put it online so people can have a look at it @

There is still plenty to do to make it nice(r). I will put it on Github a bit later.

Looks like it is off to a nice start. I could see a number of configuration options for changing the lines and labels being useful. Looking forward it being on github.


OK, I created a new repo for the graticule and some other little things I might add later on. The repo is here and the live version is here

Very nice. Once again, open a pull request to cesium-plugins-list when you are ready and we’ll get it listed with the other plugins.


Hi Thomas,
  I am looking into a grid layer scheme much like yours. I cloned your repo but need to use cesium b26 or newer, however, I am unable to get your software to work; an empty globe renders with the info button only, none of the grid lines render. I have updated all the get/set methods and replaced with properties but still no dice. Firefox does not report any errors either. Any help would be appreciated.

Hi Michael, my Bing key has expired so the globe is rendered empty. I need to update the repo with a newer version indeed. I might find some time to do it next week.

  I have updated your software (my clone) to the latest cesium (b29). The modifications were mainly those required as part of the getter/setter to property replacements (b26-28). My biggest issue dealt with a no method found error when calling tilingScheme.tileXYToRectangle (within the imageryProvider construction in Cesium.js). Not understanding JS prototypes that well, I resolved the issue by removing the Graticule.js prototype functions and making those attributes properties on the Graticule object itself, i.e.

this._tilingScheme = description.tilingScheme || new Cesium.GeographicTilingScheme();
_.prototype.tilingScheme = function() {
        return this._tilingScheme;


this.tilingScheme = description.tilingScheme || new Cesium.GeographicTilingScheme();

then Cesium could call the tilingScheme function tileXYTo (as well as other methods on the ImageryProvider, Graticule.

Keep in mind I am fairly new to javascript, however, I could not figure out how to do it otherwise.

I am sure I have other comments too. Regardless, I could post my code if desired, and even work collabortively. Just let me know.


thanks. I looked into this morning and pushed a new version. This is really a temp version as I was trying to fix things quickly. I need to spend more time catching up on the latest changes in Cesium. I plan to do this for the 1.0 release, when things are more stable. In the mean time you can check my changes on the repo and see if it fixes your issue?

  Thank you for the updates - I have integrated your changes with no problem. And the changes provide good insight into the javascript prototype including properties.


I found there is problem when switch among 3D, 2.5D, and 2D views.

Below is the error,

An error occurred while rendering. Rendering has stopped.

This may indicate an incompatibility with your hardware or web browser, or it may indicate a bug in the application. Visit to verify that your web browser and hardware support WebGL. Consider trying a different web browser or updating your video drivers. Detailed error information is below:

TypeError: Cannot read property ‘longitude’ of undefined
TypeError: Cannot read property ‘longitude’ of undefined
at Function.Rectangle.fromCartographicArray (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Core/Rectangle.js:119:47)
at _._getExtentView (http://localhost:8080/xGlobe-0.2.0/Application/Graticule.js:309:30)
at _.requestImage (http://localhost:8080/xGlobe-0.2.0/Application/Graticule.js:267:37)
at doRequest (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/ImageryLayer.js:622:48)
at ImageryLayer._requestImagery (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/ImageryLayer.js:637:9)
at TileImagery.processStateMachine (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/TileImagery.js:53:26)
at Tile.processStateMachine (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/Tile.js:422:51)
at processTileLoadQueue (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/GlobeSurface.js:672:18)
at GlobeSurface.update (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/GlobeSurface.js:180:9)
at Globe.update (http://localhost:8080/xGlobe-0.2.0/Libs/Cesium/Scene/Globe.js:778:27)


在 2014年1月22日星期三UTC-8下午4时42分05秒,Matt Barber写道:

  Again, thanks for the updates. In lieu of Cesium 1.0, I have been attempting to troubleshoot the refresh issues I am seeing. The grid disappears on zoom out or does not redraw to the larger extent. Some basic testing has revealed only that keeping the detail drawn to a minimum (setting min/max level btw 0-5 or so) and drawing once OR NOT removing the previous detail level's lines prevents this behavior. The latter test may be how imagery providers work in general, they don't undraw content just draw extent-relevant detail. However, neither of these are actually solutions for this grid. I need to undraw the higher levels of detail but the requestImage function is not fired on zooming out. I have no idea how to proceed from here. Please pipe in if you have an idea.


Hi Michael,

yes indeed it’s the problem with using the Imagery Providers, the redraw is subject to the imagery provider triggering a tile request. Another way of doing it would be to add a handler on zoom changed event, if there is any, and redraw accordingly. I will look into that.

Thanks for the reply - I wasn't sure if this behavior, which you mentioned in one of your early posts was still a factor or if it was just on my end. I am looking into both of these options as well, though, I will try the latter (event handler) as the redraw trigger is buried in the depths of Cesium.js file and seems contrary to imageryProviders default/expected behavior. There is a cesium demo which remaps the mouse zoom to keyboard buttons that I think I can use as a template.

I will post if I figure anything out. Thank you.