Although these codes have been written and compiled on a Macintosh, the source code is fairly standard Fortran save for some Open statements and could be ported easily to other systems. (Though some caution is warranted--some systems have interesting i/o characteristics to binary files). So the Mac interface isn't really well used, but given the filterish nature of these codes, this isn't a serious drawback.
The basic idea is that you specify a source illumination (sun angle) and the input elevation file and the program generates an output binary file of brightnesses of each pixel (the exact tricks are discussed below). The output file is a binary file of IEEE format real (4 byte) values (floating point numbers) ranging from 0 to some value less than 1. (All slopes considered to be shaded are forced to be 0). This same algorithm can be used within Transform, but this code is usually more convinient (and allows for larger files to be made).
You are asked for the input file and then asked to tell the code how long each input line is (namely, how many pixels wide is this image). If you saved the height x width information in the file name from TopoToAlbersFull, this is simple--use the second number (it is the same value you gave TopoToAlbersFull). The code then figures out how many lines (i.e., how high the bitmap is) and outputs this for your verification. If the output is not an integer, you may have input the wrong value for the width of the bitmap. You then name the output file and provide the illumination parameters.
The illumination parameters are mostly simple. The first number is most confusing; it is the ratio of the distance between grid points and integral increments of the function. This allows the use of non-topographic inputs. For output from TopoToAlbersFull, you should have seen an estimate of the grid spacing in meters; this is the number you want to input here. It need not be exact; in fact, you could be quite far off and still produce an acceptable looking image. Next you give the azimuth and elevation of the sun, where the azimuth is the direction, in degrees clockwise from "up" on the bitmap that the sun (source of illumination) is. In general, this should be to the left or upwards (even though this doesn't often occur on the Earth!) as this produces images usually recognizable to most people. Using illumination azimuths of 0, 90, 180, or 270 degrees runs the risk of highlighting grid edges from some databases (though the use of a projection in TopoToAlbersFull reduces this problem); if you see strange lines running across your output, you might change the sun azimuth. The sun elevation is in degrees upward from "the horizon" (flat). Moderately low values (20-30 degrees) seem to produce an acceptable amount of shading. Having the sun overhead (90 degrees) will produce a very flat image. The final value is the vertical exaggeration; you could recover from a bad estimate of the ratio here. This tends to exaggerate the difference between steep slopes of different orientations. Values of 1-2 seem to work fine.
You then sit and wait awhile (depending mainly on the speed of your hard drive) for the code to finish.
Details. What happens in this code is that the orientation of the bitmap surface is calculated for a series of triangles, where the vertices are the point in question, the point to the right and the point below. Purists will note that this isn't really the most desireable way to figure slopes, but it is (1) fast and (2) preserves high resolution variations in slope. Because of the biases, if you were being finicky about using the output file, the output grid is really down and to the right of the input grid by about 1/3 to 1/2 of a grid spacing. At the right edge, the three points are the point, the point to the left, and the point below. At the bottom, the three points are the point, the point to the right, and the point above. Again, this is not technically legal, particularly as it means that the edges have a different offset from the original grid than the main body of the output bitmap, but in practice the results look ok. The output value (illumination) is given by the equation I = 1/(1+[cos e / cos i]), where e is the angle between observer and slope normal and i is the angle between the illumination source and the slope normal. The rest is simply algebra.
To begin with, you must have two files with the same number of points; they need not be the same format. The files from the codes above will generally be a topography file, which has 2- byte integers, and a shaded relief file, which has 4-byte real (float) values. After launching the program, you first select file 1. This file will be put in the higher bits of the output file; for the colormaps I use (and included in this package) this variable will be the one colored. You are then asked for the type of data in this file, where the choices are short integers (2-byte integers) (Int*2), long integers (4 byte integers) (Int*4), floats (IEEE 4 byte floating point numbers) (Real*4), and long floats (IEEE 8 byte floating point numbers) (Real*8). You next enter the length of the line (=width of the bitmap), which once again is the same value used in both TopoToAlbersFull and Shadow. You are then told how many records are in the file (i.e., how high the bitmap is); if this is not an integer, you might have entered either the wrong type for this file or the wrong length of each line.
You now repeat the same steps for the second file, which will go into the lower bits of the output file. If the lengths of this file and file 1 disagree, you will be questioned; if you continue, the shorter length of the two files will be used.
Now you specify how the two files are to be combined. First you indicate how many bits you wish to use for the first array (=file 1). Larger numbers allow for more gradations of this first file at the expense of the second file. It's all a matter of taste; 4 is a decent choice to start with. The code next tells you how it will bin the data in file 1, indicating the bin size and the base value (which is the minimum of the file). The defaults will include all the data in the file. You might not wish this if the datafile includes "not real data" values from TopoToAlbersFull and so you might specify a new minimum value and bin size. Data values that fall outside the range specified will be grouped with the closest possible values. You are allowed the same options for file 2, and then you designate the output file. The output file will be a binary file of 2-byte integers organized in the same manner as the input files. (note that space could be saved if this were output as single byte values). The output values will range from 1 to 254 (values of 0 and 255 are omitted to assure Transform of having black and white in the colormap).
An an example, imagine that file 1 has a value of 12 and file 2 a value of 0.4. You selected 5 for the number of bits for file 1, it has a minimum value of 0 and a bin size of 5. File 2 has a minimum of 0 and a binsize of 0.3. Then the output value for this point will have "2" in the left 5 bits (= 2 * 8) and "1" in the right 3 bits for a total value of 17. Other points with the same value of 12 in file 1 will range from 16 to 23 (as will the other points in that bin, namely values of 10.00+ to 15.0).
Although only the low byte is used, the output file is a binary file of 2-byte integers.
MergeHDFBitmaps is similar but uses 2 HDF files (only the first dataset in each) as inputs.
The output file is in raw palette format and can be loaded by Transform or View; see the discussion below for the exact strategy for viewing shaded images.
(The raw palette format is a string of 256x3=768 bytes with the three sets of 256 bytes (unsigned single-byte integers) being the red (1st 256), green (2nd 256) and blue (3rd 256) values for each palette element. The first and 256th element are usually reserved to be white and black.)
To input: Select "Open..." and select the desired file. You are then asked what file type this is (binary array) and some particulars about the array (the number type is 2-byte (16-bit) signed integer (signed short) for outputs from TopoToAlbersFull and MergeBitmaps and is 32-bit (4-byte) IEEE floating point for Shadow output files). The array size can be determined by later version of Transform if you use the suffix (aaaxbbb) at the end of the file, as is suggested by the TopoToAlbersFull code, where aaa is the number of rows (height of bitmap) and bbb is the number of columns (width of bitmap). If you didn't use this file naming convention, you have to enter the proper values. You want to skip 0 bytes at the beginning, you don't want byte-swapping or a 3-D matrix.
You should now have a display of the numbers in your file. Generate an image, using an appropriate color table, and see how it looks. Some of the possible problems you might see include: the map being rotated or flipped (check the "When Importing..." things in the Preferences dialog--you might be transposing or flipping there), and the data being apparent garbage (probably chose the wrong data type, asked for byte swapping, gave the wrong size for the number of rows or columns, or let the number of bytes skipped be more than zero). For best results, you should probably make sure that the aspect ratio is 1 (check the "rectangle size" either from the toolbar in the image window or from the image menu). The aspect ratio being 1 means that both axes have an equal zoom value.
Display: For files from TopoToAlbersFull (topography) the Earth or Earth-land color maps provided with Transform can produce some nice results (these might not be in your Table menu by default, in which case you can use these colormaps by opening the color map file using "Load Color Table" and searching the Color Tables folder(s) from application disks). A trick is to get the Earth color table to put the green/blue contact at sea level; by experimentation I know that if you reset the limits of the data to -9999 and +7446, you will get sea level at the right spot. Output from Shadow looks fine with the grayscale map.
Output from CombineBitmaps is trickier, because none of the standard colormaps are made for this peculiar combination (though ShadePalette will do this). I have made several color tables (which should be with this file) for use in some possible situations. These are editted versions of the Earth-Land and Rainbow color tables and generally indicate the bit assignments within the name (3x5 bit indicates that the colored variable has 3 bits assigned it and the black-to-white variable has 5 bits) and whether the black-to-white gradients go from solid black to solid white ("linear") or from a very dark color to a very light color ("subdued"). You must also make the limits of the data 1 and 254 (the Min and Max of the second tool in the image window or af an associated Color Bar); it is quite possible that your data do not extend to these values, and the slight offset can make the image appear bizarre. Note that the CombineBitmaps trick does not allow for interpolated images or resampling of data.
Getting the right color table: If you don't like the way things look, you may have to edit the color table. The View utility that ships with Transform lets you do this, starting from any color map that is available (but you have to open an image first within the code to make the color editor option active). View is also where you can add color tables in older Spyglass products (this got broken in Fortner's upgrade of View to 3.0.2-- I know of no way to add to me color tables in Transform since then). The fastest way to make a color table (palette) for CombineBitmaps output is with ShadePalette program. You can look at the color tables used with the CombineBitmaps outputs to get an idea how this trick works and develop your own using the Color Table Editor in View.
Return to C.H. Jones home page
Craig Jones, cjones@mantle.colorado.edu