Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 6
Main: based on JFrame, creates the application's framework
InstructionPanel: based on JPanel, displays mouse and keyboard commands available to the user
View3DPanel: based on JPanel, responsible for creating the Java 3D environment (lights and view platforms) and terrain data
DemFile: based on ElevationFile, responsible for parsing and loading DEM data into memory
ElevationModel: based on BranchGroup, divides the terrain data into segments and creates a LODSegment for each
LODSegment: based on BranchGroup, responsible for creating ElevationSegments at various resolutions and setting up the level-of-detail optimization
ElevationSegment: based on Shape3D, creates the geometry for a given segment of the terrain data at a given resolution
InterleavedTriangleStripArray: based on TriangleStripArray, provides in-place generation of normal vectors
The following sections describe how critical aspects of these objects were implemented and factors related to their design. In particular, I detail DEM data parsing, creation of Java 3D geometry objects, and user viewpoint manipulation.
DEM files are available from the USGS as compressed text files. Resources provides links for downloading these files and file format specifications. Each file is composed of 1,024 byte records with fixed-length fields. The first record is referred to as a type "A" record and contains header information, including the quadrangle name, maximum and minimum elevations, latitude and longitude coordinates, and the number of data rows and data columns. One "B" record also exists for each column of data. B records hold the actual elevations (in meters). As a rule, the DEM files contain 1,201 rows by 1,201 columns of data. The specification also mentions an optional type "C" record that has information about data accuracy. Double precision numbers are stored in the old FORTRAN format using a "D" record instead of an "E" record, e.g., 0.1404000000000D+06. Therefore, as the code reads and parses the data, the D must be changed to an E.
I created two classes to handle terrain data. ElevationFile is an abstract class used as a basis for creating format-specific files. ElevationFile defines the minimum common fields needed for constructing 3D images from terrain data, including the minimum and maximum
elevations, latitude and longitude of the ground coordinates being mapped, number of rows and columns of data, and a 2D array
of elevations (row-column order). By generalizing the file's common aspects, I can more easily modify my application in the
future to support other file formats. The source for ElevationFile is shown below:
/**
* ElevationFile is an abstract base class used to define the interface
* between files holding terrain data and the Java 3D classes that
* convert the terrain data into geometric primitives.
*
* @author Mark Pendergast
* @version 1.0 February 2003
* Known subclasses @see DemFile
*/
public abstract class ElevationFile{
/** Data file name. */
public String fileName;
/** Geographic name or title of the data. */
public String quadrangleName = "";
/** Minimum elevation in meters. */
public int minElevation = 0;
/** Maximum elevation in meters. */
public int maxElevation = 0;
/** Two-dimensional array of elevation data in meters, array represents equally
spaced data points across the groundCoordinates. The first dimension is
the row, the second, the column.*/
public int elevations[][] = null; // array of raw elevation data
/** Number of data rows. */
public int nRows;
/** Number of data columns. */
public int nColumns;
/** Holds ground coordinates of the four corners in arc seconds. */
public GroundCoordinates groundCoordinates = new GroundCoordinates();
public ElevationFile()
{ }
}
The second class I created, DemFile, inherits ElevationFile and provides code to handle DEM file format specifics. The constructor is passed a filename, which it opens as a BufferedReader. The entire A record is then read into a character array, and the desired fields parsed out and stored in appropriate class
variables. I wrote the parseDemDouble() method to parse the old FORTRAN double precision format. Once the A record is read in and processed, the code can read in
and parse each B record. To ease this job, I converted BufferedReader into a StreamTokenizer. Since the A record is read in its entirety, the stream is already positioned at the beginning of the first B record.
Archived Discussions (Read only)