public OMRaster getSubframeOMRaster(DTEDFrameSubframeInfo dfsi,
DTEDFrameColorTable colortable) {
if (!frame_is_valid)
return null;
OMRaster raster = null;
if (dfsi.viewType == DTEDFrameSubframe.NOSHADING)
return null;
if (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING)
colortable.setGreyScale(false);
else
colortable.setGreyScale(true);
float lat_origin = dfsi.lat;
float lon_origin = dfsi.lon;
if (subframes == null) {
// Need to set a couple of things up if the DTEDFrameCache
// isn't being used to set up the subframe information in
// the dfsi.
initSubframes(1, 1);
// NOTE!! The algorithm uses the cordinates of the top
// left corner as a reference!!!!!!!!
lat_origin = dsi.lat_origin + 1;
lon_origin = dsi.lon_origin;
}
DTEDFrameSubframe subframe = subframes[dfsi.subx][dfsi.suby];
if (Debug.debugging("dteddetail")) {
Debug.output("Subframe lat/lon => lat= " + lat_origin + " vs. "
+ dfsi.lat + " lon= " + lon_origin + " vs. " + dfsi.lon
+ " subx = " + dfsi.subx + " suby = " + dfsi.suby);
Debug.output("Height/width of subframe => height= " + dfsi.height
+ " width= " + dfsi.width);
}
if (subframe != null) {
// The subframe section will not be null, because it is
// created when the subframe is.
if (subframe.image != null && subframe.si.equals(dfsi)) {
// IF there is an image in the cache and the drawing
// parameters are correct
raster = subframe.image;
if (Debug.debugging("dted"))
Debug.output("######## DTEDFrame: returning cached subframe");
return raster;
}
if (Debug.debugging("dted")) {
Debug.output(" *** DTEDFrame: changing image of cached subframe");
}
if (subframe.image == null) {
if (Debug.debugging("dted")) {
Debug.output(" +++ DTEDFrame: creating subframe image");
}
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
subframe.image = new OMRaster(lat_origin, lon_origin, dfsi.width, dfsi.height, new int[dfsi.height
* dfsi.width]);
else
subframe.image = new OMRaster(lat_origin, lon_origin, dfsi.width, dfsi.height, null, colortable.colors, 255);
}
// If there is an image, the types are different and it
// needs to be
// redrawn
subframe.si = dfsi.makeClone();
} else {
if (Debug.debugging("dted")) {
Debug.output(" +++ DTEDFrame: creating subframe");
}
subframes[dfsi.subx][dfsi.suby] = new DTEDFrameSubframe(dfsi);
subframe = subframes[dfsi.subx][dfsi.suby];
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT) {
subframe.image = new OMRaster(lat_origin, lon_origin, dfsi.width, dfsi.height, new int[dfsi.height
* dfsi.width]);
} else {
subframe.image = new OMRaster(lat_origin, lon_origin, dfsi.width, dfsi.height, null, colortable.colors, 255);
}
}
raster = subframe.image;
// lat/lon_post_intervals are *10 too big - // extra 0 in
// 36000 to counteract
// start in lower left of subframe
double start_lat_index = (lat_origin - (double) dsi.sw_lat) * 36000.0
/ (double) uhl.lat_post_interval;
double start_lon_index = (lon_origin - (double) dsi.sw_lon) * 36000.0
/ (double) uhl.lon_post_interval;
double end_lat_index = ((lat_origin - ((double) dfsi.height * dfsi.yPixInterval)) - (double) dsi.sw_lat)
* 36000.0 / (double) uhl.lat_post_interval;
double end_lon_index = ((lon_origin + ((double) dfsi.width * dfsi.xPixInterval)) - (double) dsi.sw_lon)
* 36000.0 / (double) uhl.lon_post_interval;
double lat_interval = (start_lat_index - end_lat_index)
/ (double) dfsi.height;
double lon_interval = (end_lon_index - start_lon_index)
/ (double) dfsi.width;
if (Debug.debugging("dteddetail"))
Debug.output(" start_lat_index => " + start_lat_index + "\n"
+ " end_lat_index => " + end_lat_index + "\n"
+ " start_lon_index => " + start_lon_index + "\n"
+ " end_lon_index => " + end_lon_index + "\n"
+ " lat_interval => " + lat_interval + "\n"
+ " lon_interval => " + lon_interval);
short e1, e2;
short xc = 0;
short yc = 0;
short xnw = 0;
short ynw = 0;
short xse = 0;
short yse = 0;
double slope;
double distance = 1.0;
float value = 0.0f;
int assignment = 0;
double modifier = (double) 0;
double xw_offset = 0;
double xe_offset = 0;
double yn_offset = 0;
double ys_offset = 0;
int elevation = (int) 0;
// Calculations needed once for slope shading
if (dfsi.viewType == DTEDFrameSubframe.SLOPESHADING
|| (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING && colortable.colors.length > DTEDFrameColorTable.NUM_ELEVATION_COLORS)) {
// to get to the right part of the frame, kind of like a
// subframe
// indexing thing
xw_offset = start_lon_index - Math.ceil(lon_interval);
xe_offset = start_lon_index + Math.ceil(lon_interval);
yn_offset = start_lat_index + Math.ceil(lat_interval);
ys_offset = start_lat_index - Math.ceil(lat_interval);
switch (dfsi.dtedLevel) {
//larger numbers make less contrast
case 0:
modifier = (double) 4;
break;//1000 ideal
case 1:
modifier = (double) .02;
break;//2 ideal
case 2:
modifier = (double) .0001;
break;
case 3:
modifier = (double) .000001;
break;
default:
modifier = (double) 1;
}
// With more colors, contrast tends to be a little light
// for the
// default - brighten it up more
if (colortable.colors.length > 215)
modifier = modifier / 10;
for (int h = dfsi.slopeAdjust; h < 5; h++)
modifier = modifier * 10;
distance = Math.sqrt((modifier * lon_interval * lon_interval)
+ (modifier * lat_interval * lat_interval));
}
for (short x = 0; x < dfsi.width; x++) {
//used for both elevation banding and slope
xc = (short) (start_lon_index + ((x) * lon_interval));
if (xc < 0)
xc = 0;
if (xc > dsi.num_lon_points - 1)
xc = (short) (dsi.num_lon_points - 1);
if ((elevations[xc] == null) && !read_data_record(xc)) {
Debug.error("DTEDFrame: Problem reading lat point line in data record");
return null;
}
if (dfsi.viewType == DTEDFrameSubframe.SLOPESHADING
|| (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING && colortable.colors.length > DTEDFrameColorTable.NUM_ELEVATION_COLORS)) {
// This is actually finding the right x post for this
// pixel,
// within the subframe measurements.
xnw = (short) (xw_offset + Math.floor(x * lon_interval));
xse = (short) (xe_offset + Math.floor(x * lon_interval));
// trying to smooth out the edge of the frame
if (xc == 0 || xnw < 0) {
xnw = xc;
xse = (short) (xnw + 2.0 * Math.ceil(lon_interval));
}
if (xc == dsi.num_lon_points - 1
|| xse > dsi.num_lon_points - 1) {
xse = (short) (dsi.num_lon_points - 1);
xnw = (short) (xse - 2.0 * Math.ceil(lon_interval));
}
if (((elevations[xnw] == null) && !read_data_record(xnw))
|| ((elevations[xse] == null) && !read_data_record(xse))) {
Debug.error("DTEDFrame: Problem reading lat point line in data record");
return null;
}
}
// Now, calculate the data and assign the pixels based on
// y
for (short y = 0; y < dfsi.height; y++) {
// used for elevation band and slope
yc = (short) (start_lat_index - ((y) * lat_interval));
if (yc < 0)
yc = 0;
elevation = (int) elevations[xc][yc];
// elevation shading
if (dfsi.viewType == DTEDFrameSubframe.METERSHADING
|| dfsi.viewType == DTEDFrameSubframe.FEETSHADING) {
// Just use the top two-thirds of the colors
if (elevation == 0)
assignment = 0; // color water Blue
else {
if (elevation < 0)
elevation *= -1; // Death Valley
if (dfsi.viewType == DTEDFrameSubframe.FEETSHADING)
elevation = (int) (elevation * 3.2);
// Start at the darkest color, and then go up
// through the
// colormap for each band height, the start
// back at the
// darkest when you get to the last color. To
// make this
// more useful, I limit the number of colors
// (10) used - if
// there isn;t enough contrast between the
// colors, you can't
// see the bands. The contrast adjustment in
// 24-bit color
// mode(216 colors) lets you add a few colors.
if (colortable.colors.length < 216) {
try {
assignment = (int) ((elevation / dfsi.bandHeight)
% (colortable.colors.length - 6) + 6);
} catch (java.lang.ArithmeticException ae) {
assignment = 1;
}
} else {
try {
assignment = (int) (((elevation / dfsi.bandHeight)
% (10 - 2 * (3 - dfsi.slopeAdjust)) * (colortable.colors.length / (10 - 2 * (3 - dfsi.slopeAdjust)))) + 6);
} catch (java.lang.ArithmeticException ae) {
assignment = 1;
}
}
}
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
raster.setPixel(x,
y,
colortable.colors[assignment].getRGB());
else
raster.setByte(x, y, (byte) assignment);
}
// Slope shading
else if (dfsi.viewType == DTEDFrameSubframe.SLOPESHADING
|| (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING && colortable.colors.length > DTEDFrameColorTable.NUM_ELEVATION_COLORS)) {
// find the y post indexes within the subframe
ynw = (short) (yn_offset - Math.floor(y * lat_interval));
yse = (short) (ys_offset - Math.floor(y * lat_interval));
// trying to smooth out the edge of the frame by
// handling the
// frame limits
if (yse < 0)
yse = 0;
if (yc == dsi.num_lat_lines - 1
|| ynw > dsi.num_lat_lines - 1)
ynw = (short) (dsi.num_lat_lines - 1);
e2 = elevations[xse][yse]; // down & right
// elevation
e1 = elevations[xnw][ynw]; // up and left
// elevation
slope = (e2 - e1) / distance; // slope relative to
// nw sun
// colormap value darker for negative slopes,
// brighter for
// positive slopes
if (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING) {
assignment = 1;
elevation = (int) (elevation * 3.2);// feet
for (int l = 1; l < DTEDFrameColorTable.NUM_ELEVATION_COLORS; l++)
if (elevation <= colortable.elevation_color_cutoff[l]) {
if (slope < 0)
assignment = (int) (l + DTEDFrameColorTable.NUM_ELEVATION_COLORS);
else if (slope > 0)
assignment = (int) (l + (DTEDFrameColorTable.NUM_ELEVATION_COLORS * 2));
else
assignment = (int) l;
break;
}
if (elevation == 0)
assignment = 0;
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
raster.setPixel(x,
y,
colortable.colors[assignment].getRGB());
else
raster.setByte(x, y, (byte) assignment);
}
else {
value = (float) (((colortable.colors.length - 1) / 2) + slope);
// not water, but close in the colormap - max
// dark
if (slope != 0 && value < 1)
value = 1;
if (elevation == 0)
value = 0; // water?!?
if (value > (colortable.colors.length - 1))
value = colortable.colors.length - 1; // max
// bright
assignment = (int) value;
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
raster.setPixel(x,
y,
colortable.colors[assignment].getRGB());
else
raster.setByte(x, y, (byte) assignment);
}
}
// Subframe outlines - different colors for each side
// of the frame
// This is really for debugging purposes, really.
else if (dfsi.viewType == DTEDFrameSubframe.BOUNDARYSHADING) {
int c;
if (x < 1)
c = 1;
else if (x > dfsi.width - 2)
c = 12;
else if (y < 1)
c = 1;
else if (y > dfsi.height - 2)
c = 12;
else
c = 7;
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
raster.setPixel(x, y, colortable.colors[c].getRGB());
else
raster.setByte(x, y, (byte) c);
} else if (dfsi.viewType == DTEDFrameSubframe.COLOREDSHADING) {
assignment = 1;
elevation = (int) (elevation * 3.2);// feet
for (int l = 1; l < DTEDFrameColorTable.NUM_ELEVATION_COLORS; l++)
if (elevation <= colortable.elevation_color_cutoff[l]) {
assignment = (int) l;
break;
}
if (elevation == 0)
assignment = 0;
if (elevation < 0)
assignment = 1;
if (elevation > 33000)
assignment = 1;
if (dfsi.colorModel == OMRasterObject.COLORMODEL_DIRECT)
raster.setPixel(x,
y,
colortable.colors[assignment].getRGB());
else
raster.setByte(x, y, (byte) assignment);
}
}
}
if (Debug.debugging("dteddetail"))