Maps are an important tool in the toolbox, and Cesium provides the best combination of cross platform compatibility, end-user accessibility (via web delivery), and powerful feature capabilities compared with the plug-in-based alternatives such as Google Earth or NASA WorldWind.
This article introduces Cesium-GWT, how to develop with the Cesium-GWT APIs, and a little about the patterns and practices used to create the GWT interface for Cesium—hopefully to encourage others to contribute as well.
GWT and JSNI
This brief sample demonstrates several important aspects of JSNI:
- The method is declared as
- JSNI methods can be static or instance methods. A static method is shown here, constructing
PolygonGeometryobject. Not shown in this example, the Java
- GWT does include support for what they call
and is heavily used in Cesium-GWT. The example shows three such classes:
Cartesian, and the GWT built-in type
Hello World in Cesium-GWT
In short, you will need to set up a GWT module file (in XML) to define your project and its Java "EntryPoint" (the Java class to invoke at web page initialization), and a basic GWT-enabled HTML file (which can be as short as about five lines). Once setup, here is a very simple Hello, World example for Cesium-GWT:
Our primary GWT Widget is a
CesiumWidgetPanel, which essentially becomes a
<div> block to be managed by GWT in the
Document Object Model (DOM) of the web page.
CesiumWidgetPanel extends GWT's
SimplePanel and adds logic to automatically initialize Cesium and load its required resources.
Note that GWT starts by invoking the EntryPoint's constructor,
HelloCesium(), then GWT automatically invokes
onModuleLoad(). At this point, it is safe to add your GWT component to the
RootPanel (consuming the entire web page, by default).
When Cesium is ready, an abstract method that you define—
createCesiumWidget(Element)—is invoked so you can create your CesiumWidget. This gives you the opportunity to save a handle to the CesiumWidget as a field in your Java class, for later use, and to perform other initialization actions with the CesiumWidget, prior to returning from the method.
A More Complex Example
CesiumWidget is the most basic implementation of a Cesium display object, and that Cesium also includes a more feature-rich display object called
Viewer. Cesium-GWT also supports Viewer, which can be created by extending the
ViewerPanel, instead of the
CesiumWidgetPanel. This excerpt
is from the bundled Cesium-GWT sample class
This code segment creates the
Viewer, adds a
(providing access to methods from Cesium's
and assigns these two objects to fields in the
We use these fields in the click-event handlers for GWT
as in the following example for the two
In the click handlers for both buttons, the
onClick() method starts by loading CZML data
for satellites orbiting over time. The first simply loads the data and displays the orbiting
satellites and their orbit tracks. The second extends the first by leveraging the
viewerEntityMixin to connect the camera to (and follow) one of the satellites.
This example code also shows the Cesium-GWT implementation of Cesium's
function reference. GWT's support for
callback handlers. As of Cesium-GWT 0.2.0, this capability was greatly expanded, and
extracted into its own GitHub project, the
The simplest example of this library is the
NoArgsFunction class, used
to declare a simple callback in response to the
CzmlDataSource loading event.
We need to wait for the CZML file to be loaded asynchronously before we can start
tracking one of the entities built from the CZML file contents.
Besides no-arg function references, JsFunction-GWT also supports single-argument functions—modeling the standard pattern for event listeners (
and variable argument (
VarArgFunction) functions (zero or more arguments). This
pattern requires the Java anonymous class implementations for now. Rumor has it that GWT
will be supporting Java 8 Lambda
Expressions soon, which will make these types of calls less verbose and even more like their
As you peruse the samples, you should notice that the Java code in the
sandcastle package largely mirrors the equivalent code in each of the
Cesium Sandcastle demos
few (mostly just syntax) changes.
As a new contributor, please take the time to review the existing API implementations so you can follow the same general practices, such as:
- How to implement Enums and Constants
- Naming conventions for Event fields (implementing "onSomeEvent()" methods in Java)
- Proper implementation of JsFunction callbacks (with a Java method wrapper to perform the conversion of the Java anonymous class into the JsFunction reference)
- A strong preference for Java Generics when feasible
- Using the static
create()method with required parameters (if any) and a separate inner class
Optionsfor optional parameters; and
- Returning the
Contributions are strongly encouraged, so if you are interested in contributing, please fork the GitHub project and submit a pull request when your additions are tested and commited to your fork.
Recommendations for Developing with Super Dev Mode
After writing your class, you would continue to follow the GWT processes—as needed—for compiling and deploying your GWT app, and then invoke this app by loading your GWT app's web page. Again, there are plenty of resources on the web describing the process, so I won't repeat them here; but I will make a couple of recommendations, for development:
- Learn about and use GWT's Super Dev Mode.
GWT supports two ways to perform on-the-fly compiles and line-by-line debugging:
Dev Mode and Super Dev Mode. Dev Mode requires browser support for a special two-way interaction between a Dev Mode runtime (typically
from the browser's debugger, just like a regular Java app, but it has several drawbacks:
- Debugging in Dev Mode is not robust. Sometimes I can inspect values and sometimes I can't.
- Dev Mode is only supported by Google Chrome. You cannot debug browser-specific problems. Firefox used to support Dev Mode, but hasn't in over a year.