Wednesday, April 2, 2014

WebGL code: shaded grids and maps

In a previous post, I described a generic specification for a WebGL representation of continuum data on a spherical Earth that you can rotate like Google Earth. Examples were cited. The idea was to separate out the task of geometry specification from the nuts and bolts of WebGL (which were hidden). But you still had to specify the geometry.

In this post, I want to simplify three common tasks:
• Drawing a shaded plot of gridded data.
• Specifying a palette (there's a default for grid shading).
• Adding a world map (just coast outlines)

It's reduced to the extent where you have to simply supply the gridded data as a comma separated list. In the example below, you can enter it by pasting into a text box, and press the "Plot New" button.

To enter a world coast outline map, just define an object with new type MAP. Nothing else required. I have also added a "title" attribute of an object. If supplied, the title will appear top left. It can be any HTML (including plain text).

So here is the new plot, showing GISS LOTI temperatures for January 2014. You can rotate to see the pattern of the Polar vortex. (Currently replaced with BEST trends). Below, I'll show the user code, and how you can add your own data.

The user JS file that I supply is:
function PxDat(p){
var C,M,p;
C=p[1];  //The grid
M=p[2]; M.type=MAP;
C.title="GISS LOTIJanuary 2014"
C.nodes=[1.42,1.42,...];
}
Easiest is object 2, the map. Just give the type.

For object 1, C (the grid), instead of node coordinates, in "nodes" I put the grid values, starting at (or near) the corner (90S,180W), and then in latitude bands. In "links" I give a single integer. This can be the number of horizontal cells, but if the cells are square, as usual, the digit 1 will do. Such grids usually are 2n x n, or maybe 2n x (n+1); the program will work out which. If it is neither of these, you should set .links to the number of grids in a latitude band.
You can still define a palette, as described previously. But for a grid, if you do not, the default is a rainbow palette with 256 colors, seen here.
You'll see that a color key is provided. This is centred at the mean of your data (as is the palette), and color spacing is finest there, dropping rather exponentially as you go away, so coarse for outlying values.

User data entry

You don't even have to do this much programming. If you have grid data as a comma separated list (from 90S, 180W), just paste it into the text box top right. There seems to be a limit of about 16000 characters. You can put a title in the box below. Then click "Plot New".
Here are some trivial examples, which still give some idea of how the shading is done. Try pasting in:
1,1,1,1,2,2,2,2
This is a 4x2 grid; you'll see uniform shading from bottom to top, Vary the numbers if you like. If the number of latitudes is even, it is treated as nodes at cell centres. So thete is a gap at each pole. It looks huge here, but of course is small in real grids. Now try:
-9,-9,-9,-9,3,-3,3,-3,9,9,9,9
This is a 4x3 array, and so the nodes are assumed at the corners of cells. So there's a row of nodes at each pole, and the cells show here as faces of an octahedron. The colors are mixed up a bit. Note how the color key adapts.

Where next?

Usually, providers such as GISS and HADCRUT supply gridded data on NCDF files. I use the R package "ncdf" to unravel there. Unfortunately, they usually pack a huge lot of data into these files; typically a century or so of months, for monthly data. Often there are several variables. Files can be tens, hundreds or thousands of megabytes. You'll need to extract a single grid, and even those can be big. JS input has to be text. Make sure to use rounding.
I have found good data rather hard to come by. Coarse grids like the GISS one above don't make good use of the much better WebGL resolution. Much better is something like the 1/4° SST data here. But there there is extra work to keep the land/sea boundary sharp. HYCOM has 1/12° data, but I'm finding the files just too big. I'd be glad of any suggestions.
If I can find interesting and regularly updated data, I'll rig up a scheme for updating and install a page like that for SST.

Code

I've updated the zip file from the previous post, here. The main JS is now in grid.js; the example here is grid0.js. But the HTML file is still Moygl.html. I think everything is backward compatible.