Monday, February 18, 2008

Procedural Image Layers for WorldWind Java

Here are some experimental classes to produce procedural (computed) tiled image layers. The test layer will create elevation colored tiles on the fly:

Download (updated Sept 2009) and (updated feb. 24). Remove the .txt extension and add to your SDK layers package.

To use the test layer, add an instance to your layer list and set its wwd reference - setWwd(), otherwise it wont be able to produce the tiles (it needs to query the globe elevations).

A couple things to note: once a tile has been created it will be cached and wont be recomputed. That means that if you change the 'formula' that produced those tiles, you must either direct them to a different cache folder, or clear the previous one.

There are many potential applications for procedural tiles. Just with the elevation data, you can produce a great variety of 'elevation colored' maps, you can compute shading, cast shadows or even draw 'line of sight' areas. However, when querying elevations from the globe, you get the 'best available' elevations, meaning that if elevation data has not yet been loaded, the tiles will be produced out of less precise data and would need to be recomputed once better data is available - which it is not doing right now.

Edit feb. 28: to get the best results, i recommend to keep the layer off until you have zoomed onto the area of interest and elevation data has been properly downloaded and then loaded into memory. Tilt the view and look around to force loading on a wider range, then turn on the procedural layer.

Other potential applications include multi resolution rasterized vector data (country borders, roads...). I have to see how this could alleviate some limitations of the actual surface shapes. But that would only work well with static data - not the kind that changes all the time.

See this related WWJ Forum thread.


jfolson said...

I'm using WWJ and this procedural tiled image layer to show kernel-smoothed social network statistics on a map. You guys are doing awesome things and making it feasible for lots of other awesome things to happen!

moovida said...

Hi, this really sounds to me as a nice solution also for different data formats, that are not easy to be tiled?

I mean, would it make sense to use this to read data at different resolutions levels (and as such gain a quick reading) and serve them on WW?

Also. would it be possible also to do the same to get an elevation model loaded, instead of an image?

moovida said...

Shame on me, noticed only now the last part were you mention the multiresolution raster data. Sorry.

Still I am wondering about using this to serve an alternative elevation model.

Patrick Murris said...

I'm not sure what you mean with 'serve' and 'elevation model'. This layer is not 'serving' any data, it just produces surface tiles on the fly using any recipe you may want - involving external data or not. Those tiles are then cached as if they has come from a server.

Elevation data can only be used here to produce texture tiles as in the example, but it cannot be fed to the tessellator to produce a different terrain geometry that way.

moovida said...

Thanks for the reply. Yeah, you got it right. I am doing a test to load GRASS raster data tiles on the fly as images.

But what I really would have prefered, was using those for elevation data, which you teach me is not possible this way.

Anyway, this class gives a funky flexibility. Very appreciated. As everything in this blog that is helping me in my start with WW. Thanks.

moovida said...

I hope I am not spamming too much here, but permit me a last question. Then I will take it to one of the forums, if I need more :)

I have successfully used your classes, slightly modified, to load maps from a GRASS workspace into WW. A first example of an elevation model is here.

But back to the last question: why would it not be possible to produce bil files with the elevation information instead of pngs and save them into the srtm data folders? Wouldn't that work and substitute the elevation with the high resolution one?

Anonymous said...
This comment has been removed by a blog administrator. said...

"To use the test layer, add an instance to your layer list and set its wwd reference - setWwd(), otherwise it wont be able to produce the tiles (it needs to query the globe elevations)."

I am not sure where in an application you would "add an instance" and how you would provide a tile and image for this layer to use... can you give me a clue?

Patrick Murris said...

...well, if you have a look at the sample applications in the examples package you will see how a new layer instance can be created and added to the layer list. You dont need to provide any image, the layer will create images (tiles) on the fly that will then be drapped over the terrain like any other raster based dataset. Hope this helps. said...

woot! thanks for responding

its not that obvious to a nube like me

I have modified several examples to try and get this to work and spent a lot of time in the debugger tracing call stacks to see if I could figure out where to insert this add

this code seem intuitive to me from the text above:
public AppFrame()
super(true, true, false);

WorldWindowGLCanvas localGLCanvas = super.getWwd();
ProceduralTestLayer localLayer = new ProceduralTestLayer();

this.getLayerPanel().add(makeControlPanel(), BorderLayout.SOUTH);
(from a modified NetworkOfflineMode example - which seems like a simple example to try this on)

after the super call - I think the XML has been read and all the layers defined in the worldwind layers xml have been (fully) loaded, right?

so the code above does not appear to invoke the createTileImage method auto magically

so I conclude that either I need to know about a tile and image object and call it myself or I am not "adding" in the right place or correctly cause if I was then the "layer loader" code would invoke the createTileImage with the tile and image data ...

I suspect the later but I can't find an example that is better - crtainly more complicated ones...

Any help is appreciated

Patrick Murris said...

Honestly i haven't used this procedural layer for years and i'm not sure it is still valid with the current WWJ SDK. This blog post dates more then two years and the SDK has evolved quite a lot since then. I suggest you search on the WWJ forum and possibly ask whether someone is actually using it (or a modified version) successfully. Sorry, i can't provide much help on this particular matter right now.

Thomas Haberkorn said...

Using the ProceduralTestLayer,
I get an exception thrown: no protocol: *?T=*&L=0&X=84&Y=63

It would be very helpful for our team's research project if I could get the layer to run on the current WWJ SDK. We're trying to improve avionics displays to avoid mid-air collisions in the future.

please respond,

Thomas Haberkorn said...


Got it to run after all:
in class ProceduralTiledImageLayer
change the name of the method "downloadTexture" to "retrieveRemoteTexture"

this will overwrite the correct method from class "BasicTiledImageLayer".

.. and you're good to go!


Daniel said...

@Thomas Haberkorn: You rock, thanks a lot! (I had the same problem.)