📄 dtedframe.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/dataAccess/dted/DTEDFrame.java,v $// $RCSfile: DTEDFrame.java,v $// $Revision: 1.1.2.4 $// $Date: 2005/08/04 18:11:16 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.dataAccess.dted;import java.io.FileNotFoundException;import java.io.IOException;import com.bbn.openmap.io.BinaryBufferedFile;import com.bbn.openmap.io.BinaryFile;import com.bbn.openmap.io.Closable;import com.bbn.openmap.io.FormatException;import com.bbn.openmap.omGraphics.OMGrid;import com.bbn.openmap.omGraphics.OMRaster;import com.bbn.openmap.omGraphics.grid.OMGridData;import com.bbn.openmap.omGraphics.grid.SlopeGenerator;import com.bbn.openmap.proj.CADRG;import com.bbn.openmap.proj.EqualArc;import com.bbn.openmap.proj.Length;import com.bbn.openmap.util.Debug;/** * The DTEDFrame is the representation of the DTED (Digital Terrain * Elevation Data) data from a single dted data file. It keeps track * of all the attribute information of its data. It can return an * OMGrid object that can be configured to create a visual * representation of the data, depending on what OMGridGenerators are * used on the OMGrid object. */public class DTEDFrame implements Closable { public final static int UHL_SIZE = 80; public final static int DSI_SIZE = 648; public final static int ACC_SIZE = 2700; public final static int ACC_SR_SIZE = 284; /** The binary buffered file to read the data from the file. */ protected BinaryFile binFile; /** The path to the frame, including the frame name. */ protected String path; /** * The array of elevation posts. Note: the 0 index of the array in * both directions is in the lower left corner of the matrix. As * you increase indexes in both dimensions, you go up-right. */ protected short[][] elevations; // elevation posts /** Data set indentification section of the file. */ public DTEDFrameDSI dsi; /** User header label section of the file. */ public DTEDFrameUHL uhl; /** Accuracy description section of the file. */ public DTEDFrameACC acc; /** Validity flag for the quality of the data file. */ public boolean frame_is_valid = false; // //////////////// // Administrative methods // //////////////// /** * Simplest constructor. * * @param filePath complete path to the DTED frame. */ public DTEDFrame(String filePath) { this(filePath, false); } /** * Constructor with colortable and presentation information. * * @param filePath complete path to the DTED frame. * @param readWholeFile If true, all of the elevation data will be * read at load time. If false, elevation post data will be * read in per longitude column depending on the need. * False is recommended for DTEd level 1 and 2. */ public DTEDFrame(String filePath, boolean readWholeFile) { try { binFile = new BinaryBufferedFile(filePath); read(binFile, readWholeFile); if (readWholeFile) close(true); else BinaryFile.addClosable(this); } catch (FileNotFoundException e) { Debug.error("DTEDFrame: file " + filePath + " not found"); } catch (IOException e) { Debug.error("DTEDFrame: File IO Error!\n" + e.toString()); } path = filePath; } /** * Reads the DTED frame file. Assumes that the File f is * valid/exists. * * @param binFile the binary buffere file opened on the DTED frame * file * @param readWholeFile flag controlling whether all the row data * is read at this time. Otherwise, the rows are read as * needed. */ protected void read(BinaryFile binFile, boolean readWholeFile) { binFile.byteOrder(true); // boolean msbfirst dsi = new DTEDFrameDSI(binFile); uhl = new DTEDFrameUHL(binFile); acc = new DTEDFrameACC(binFile); // Allocate just the columns now - we'll do the rows as // needed... elevations = new short[uhl.num_lon_lines][]; if (readWholeFile) readDataRecords(); frame_is_valid = true; } /** * This must get called to break a reference cycle that prevents * the garbage collection of frames. */ public void dispose() { // System.out.println("DTED Frame Disposed " + me); this.close(true); BinaryFile.removeClosable(this); } /** * Part of the Closable interface. Closes the BinaryFile pointer, * because someone else needs another file open, and the system * needs a file pointer. Sets the binFile variable to null. */ public boolean close(boolean done) { try { binFile.close(); binFile = null; return true; } catch (IOException e) { Debug.error("DTEDFrame close(): File IO Error!\n" + e.toString()); return false; } } /** * If the BinaryBufferedFile was closed, this method attempts to * reopen it. * * @return true if the opening was successful. */ protected boolean reopen() { try { binFile = new BinaryBufferedFile(path); return true; } catch (FileNotFoundException e) { Debug.error("DTEDFrame reopen(): file " + path + " not found"); return false; } catch (IOException e) { Debug.error("DTEDFrame close(): File IO Error!\n" + e.toString()); return false; } } // //////////////// // These functions can be called from the outside, // as queries about the data // //////////////// /** * The elevation at the closest SW post to the given lat/lon. This * is just a go-to-the-closest-post solution. * * @param lat latitude in decimal degrees. * @param lon longitude in decimal degrees. * @return elevation at lat/lon in meters. */ public int elevationAt(float lat, float lon) { if (frame_is_valid == true) { if (lat >= dsi.sw_lat && lat <= dsi.ne_lat && lon >= dsi.sw_lon && lon <= dsi.ne_lon) { // lat/lon_post_intervals are *10 too big - // extra 0 in 36000 to counteract int lat_index = Math.round((lat - dsi.sw_lat) * 36000 / uhl.lat_post_interval); int lon_index = Math.round((lon - dsi.sw_lon) * 36000 / uhl.lon_post_interval); if (elevations[lon_index] == null) readDataRecord(lon_index); return (int) elevations[lon_index][lat_index]; } } return -32767; // Considered a null elevation value } /** * Interpolated elevation at a given lat/lon - should be more * precise than elevationAt(), but that depends on the resolution * of the data. * * @param lat latitude in decimal degrees. * @param lon longitude in decimal degrees. * @return elevation at lat/lon in meters. */ public int interpElevationAt(float lat, float lon) { if (frame_is_valid == true) { if (lat >= dsi.sw_lat && lat <= dsi.ne_lat && lon >= dsi.sw_lon && lon <= dsi.ne_lon) { // lat/lon_post_intervals are *10 too big - // extra 0 in 36000 to counteract float lat_index = (lat - dsi.sw_lat) * 36000F / uhl.lat_post_interval; float lon_index = (lon - dsi.sw_lon) * 36000F / uhl.lon_post_interval; int lflon_index = (int) Math.floor(lon_index); int lclon_index = (int) Math.ceil(lon_index); // int lflat_index = (int) Math.floor(lat_index); int lclat_index = (int) Math.ceil(lat_index); if (elevations[lflon_index] == null) readDataRecord(lflon_index); if (elevations[lclon_index] == null) readDataRecord(lclon_index); // //////////////////////////////////////////////////// // Print out grid of 20x20 elevations with // the "asked for" point being in the middle // System.out.println("***Elevation Map***"); // for(int l = lclat_index + 5; l > lflat_index - 5; // l--) { // System.out.println(); // for(int k = lflon_index - 5; k < lclon_index + 5; // k++) { // if (elevations[k]==null) readDataRecord(k); // System.out.print(elevations[k][l] + " "); // } // } // System.out.println();System.out.println(); // //////////////////////////////////////////////////// int ul = elevations[lflon_index][lclat_index]; int ur = elevations[lclon_index][lclat_index]; int ll = elevations[lflon_index][lclat_index]; int lr = elevations[lclon_index][lclat_index]; float answer = resolveFourPoints(ul, ur, lr, ll, lat_index, lon_index); return Math.round(answer); } } return -32767; // Considered a null elevation value } /** * Return an index of ints representing the starting x, y and * ending x, y of elevation posts given a lat lon box. It does * check to make sure that the upper lat is larger than the lower, * and left lon is less than the right. * * @param ullat upper latitude in decimal degrees. * @param ullon left longitude in decimal degrees. * @param lrlat lower latitude in decimal degrees. * @param lrlon right longitude in decimal degrees. * @return int[4] array of start x, start y, end x, and end y. */ public int[] getIndexesFromLatLons(float ullat, float ullon, float lrlat, float lrlon) { float upper = ullat; float lower = lrlat; float right = lrlon; float left = ullon; // Since matrix indexes depend on these being in the right // order, we'll double check and flip values, just to make // sure lower is lower, and higher is higher. if (ullon > lrlon) { right = ullon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -