📄 dtedframecache.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/layer/dted/DTEDFrameCache.java,v $// $RCSfile: DTEDFrameCache.java,v $// $Revision: 1.4.2.4 $// $Date: 2005/08/09 19:23:03 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.layer.dted;import java.util.Properties;import com.bbn.openmap.io.BinaryFile;import com.bbn.openmap.layer.util.cacheHandler.CacheHandler;import com.bbn.openmap.layer.util.cacheHandler.CacheObject;import com.bbn.openmap.proj.EqualArc;import com.bbn.openmap.PropertyConsumer;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.util.Debug;import com.bbn.openmap.util.PropUtils;/** * The DTEDFrameCache is an object that retrieves DTED paths, frames * or elevation values, given a latitude, logitude and dted level. It * maintains a collection of the frames it has already used for * quicker access later. The size of the cache is user-determined, and * the cache also relies on user provided paths to the dted directory, * which is the top level directory in a dted file structure. The * paths are provided in a String array, so you can have data in * different places on a system, including a CDROM drive. Because * older DTED Level 2 data has the same name extension as Level 1 * data, a separate array of pathnames is available for that old data. * Level 0 and 1 data should be lumped together, or listed in the same * array of paths. Newer level 2 data with the .dt2 extension should * be listed in the regular dted path property with the level 0 and 1 * data. */public class DTEDFrameCache extends CacheHandler implements PropertyConsumer { /** The elevation value returned if there is no data at a lat/lon. */ public final static int NO_DATA = -500; /** * The maxumim DTED level to check for data, given a lat/lon and a * path to a dted data directory. */ public final static int MAX_DTED_LEVEL = 1; /** An array of strings representing data directory paths. */ protected String[] dtedDirPaths; /** * An array of strings available to represent old level 2 data * directory paths. We have to do this because you couldn't tell * the difference between level 1 and level 2 just by looking at * it, which is done by looking at the data extension. Newer data * is fixed, meaning that the new data meets the data * specification. */ protected String[] dted2DirPaths; /** * Number of subframes used by each frame. Calculated by the * DTEDCacheHandler when it is given a projection. */ protected int numXSubframes; // per frame, at the current scale /** * Number of subframes used by each frame. Calculated by the * DTEDCacheHandler when it is given a projection. */ protected int numYSubframes; public static final String DTEDPathsProperty = "paths"; public static final String DTED2PathsProperty = "level2.paths"; public static final String DTEDFrameCacheSizeProperty = "cacheSize"; protected String propertyPrefix = null; public DTEDFrameCache() { super(); } /** * Create the cache with paths to search for frames, and the * maximum number of frames to keep on hand. Assumes the paths * given are for level 0 and 1 data. * * @param dtedPaths path to the level 0 and level 1 dted * directories * @param max_size max number of frames to keep in the cache.. */ public DTEDFrameCache(String[] dtedPaths, int max_size) { super(max_size); dtedDirPaths = dtedPaths; } /** * Create the cache with paths to search for frames, and the * maximum number of frames to keep on hand. * * @param dtedPaths path to the level 0 and level 1 dted * directories * @param dted2Paths paths to the level 2 dted directories * @param max_size max number of frames to keep in the cache.. */ public DTEDFrameCache(String[] dtedPaths, String[] dted2Paths, int max_size) { super(max_size); dtedDirPaths = dtedPaths; dted2DirPaths = dted2Paths; } /** * Set the data paths. * * @param paths paths to the dted level 0 and 1 directories. */ public void setDtedDirPaths(String[] paths) { dtedDirPaths = paths; } /** * Set the data paths. * * @param paths paths to the dted level 0 and 1 directories. * @param paths2 paths to the dted level 2 directories. */ public void setDtedDirPaths(String[] paths, String[] paths2) { dtedDirPaths = paths; dted2DirPaths = paths2; } /** * A utility to find the path to a dted file, given a lat, lon and * a dted level. Assumes that paths have been given to the cache. * Lat/lons in decimal degrees. * * @return complete path to file with lat/lon. * @param lat latitude of point * @param lon longitude of point * @param level the dted level wanted (0, 1) */ public String findFileName(double lat, double lon, int level) { String lonString = DTEDFrameUtil.lonToFileString((float) lon); String latString = DTEDFrameUtil.latToFileString((float) lat, level); String partialFile = "/" + lonString + "/" + latString; String ret = findFileName(dtedDirPaths, partialFile); // HACK to handle old DTED level 2 data, not needed for new // data with .dt2 extension that should be included in the // first dted path. if (ret == null && level == 2) { latString = DTEDFrameUtil.latToFileString((float) lat, 1); partialFile = "/" + lonString + "/" + latString; ret = findFileName(dted2DirPaths, partialFile); } return ret; } /** * Method to check the searchPaths for a file. * * @param searchPaths an array of dted root directories * @param partialFile the relative pathname of a dted frame file * from the dted root. * @return the name of the file, or null if not found. */ protected String findFileName(String[] searchPaths, String partialFile) { if (searchPaths == null || searchPaths.length == 0) { return null; } for (int i = 0; i < searchPaths.length; i++) { String dtedFileName = searchPaths[i] + partialFile; if (BinaryFile.exists(dtedFileName)) { return dtedFileName; } } return null; } /** * Return The Dted Frame, Given A Lat, Lon And Dted Level. * * @return Dted frame. * @param lat latitude of point * @param lon longitude of point * @param level the dted level wanted (0, 1, 2) */ public DTEDFrame get(double lat, double lon, int level) { String name = findFileName(lat, lon, level); if (name != null) { return (DTEDFrame) get(name); } return null; } /** * A private class that makes sure that cached frames get disposed * properly. */ private static class DTEDCacheObject extends CacheObject { /** * Construct a DTEDCacheObject, just calls superclass * constructor * * @param id passed to superclass * @param obj passed to superclass */ public DTEDCacheObject(String id, DTEDFrame obj) { super(id, obj); } /** * Calls dispose() on the contained frame, to make it eligible * for garbage collection. */ public void finalize() { ((DTEDFrame) obj).dispose(); } } /** * Load a dted frame into the cache, based on the path of the * frame as a key. * * @param dtedFramePath complete path to the frame. * @return DTED frame, hidden as a CacheObject. */ public CacheObject load(String dtedFramePath) { if (dtedFramePath != null) { // If it's a DTED level 0 frame, read it all in, // otherwise, read just what you need. DTEDFrame frame = new DTEDFrame(dtedFramePath, dtedFramePath.endsWith("dt0")); frame.initSubframes(numXSubframes, numYSubframes); if (frame.frame_is_valid) { return new DTEDCacheObject(dtedFramePath, frame); } } return null; } /** * This version of resizeCache is for projection changes, where * the post/pixel spacing of the images has changed, and the * images need to be rebuilt. The cache size will change based on * scale, because more frames are needed for smaller scales. If * the number of subframes in either direction is zero, then the * resize becomes non-destructive, which means that the frames * will not delete their subframes. If the scale of the map * changes, then the frame subframe sizes need to be recalculated, * and a destructive resizing is necessary. * * @param max_size the maximum number of frames in the cache. * @param num_x_subframes the number of horizontal subframes in * each frame. * @param num_y_subframes the number of vertical subframes in each * frame. */ public void resizeCache(int max_size, int num_x_subframes, int num_y_subframes) { boolean destructive = false; if (num_x_subframes > 0 && num_y_subframes > 0) { numXSubframes = num_x_subframes; numYSubframes = num_y_subframes; destructive = true; Debug.message("dted", "DTEDFrameCache: destructive resizing"); } else { Debug.message("dted", "DTEDFrameCache: passive resizing"); } CacheObject[] oldObjs = objs; if (max_size != objs.length && max_size > 0) { objs = new CacheObject[max_size]; } for (int i = 0; i < objs.length; i++) { if (i >= oldObjs.length) { break; } DTEDCacheObject dco = (DTEDCacheObject) oldObjs[i]; if (dco == null) { // We load from the front to the back 0 -> length - 1; // Once you hit a null, the rest should be null, too. objs[i] = null; continue; } DTEDFrame frame = (DTEDFrame) (dco.obj); dco.cachedTime = 0; if (frame == null) { Debug.output("DTEDFrameCache: No Frame for key!"); continue; } if (destructive) { frame.initSubframes(num_x_subframes, num_y_subframes); } else { // If it's not destructive, and the size didn't // change, then just continue through the loop // resetting the cachedTime for the CacheObjects. if (oldObjs == objs) { continue; } } if (i < oldObjs.length) { objs[i] = oldObjs[i]; } else { objs[i] = null; } } oldObjs = null; } /** * This version of resizeCache is for screen size changes, where * the number of frames kept on hand in the cache must change, but * the images themselves don't have to because the pixel/posting * spacing hasn't changed in the projection. The frames already in * the cache are re-added to the new cache, if the cache size is * increasing. If the cache size is shrinking, then as many as * will fit are added to the new cache. * * @param max_size the new size of the cache. */ public void resizeCache(int max_size) { resizeCache(max_size, 0, 0); } /** * Return the elevation of a lat/lon point, in meters. * * @return elevation in meters. * @param lat in decimal degrees. * @param lon in decimal degrees. */ public int getElevation(float lat, float lon) { for (int i = /* dted level */1; i >= /* dted level */0; i--) { DTEDFrame frame = null; String dtedFileName = findFileName((double) lat, (double) lon, i); if (dtedFileName != null) frame = (DTEDFrame) get(dtedFileName); if (frame != null) return (int) frame.elevationAt(lat, lon); } return NO_DATA; } /** * Return the two-dimensional matrix of elevation posts (heights) * representing coverage of a given geographical rectangle. The * matrix represents coverage in an Equal Arc projection, and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -