📄 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/dataAccess/dted/DTEDFrameCache.java,v $// $RCSfile: DTEDFrameCache.java,v $// $Revision: 1.2.2.4 $// $Date: 2005/08/11 21:03:27 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.dataAccess.dted;import java.util.Iterator;import java.util.Properties;import java.util.Vector;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.PropertyConsumer;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.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 determined by * startup settings. * <P> * * The DTEDFrameCache can be placed in the MapHandler, where other * objects can share it in order to all use the same DTED data. It can * be configured with properties: * <P> * * <pre> * * * frameCache.cacheSize=40 * frameCache.directoryHandlers=dteddir1 dteddir2 * frameCache.dteddir1.translator=com.bbn.openmap.dataAccess.dted.StandardDTEDNameTranslator * frameCache.dteddir1.path=/data/dted * frameCache.dteddir2.translator=com.bbn.openmap.dataAccess.dted.StandardDTEDNameTranslator * frameCache.dteddir2.path=/data/dted * * * </pre> * * A DTEDDirectoryHandler needs to be specified for each DTED * directory you want to use. If a translator isn't specified in the * properties for a directory handler, the StandardDTEDNameTranslator * will be used. If you have DTED data that doesn't conform to the * naming conventions specified in the Military Standard, you can use * a different DTEDNameTranslator instead for your particular * directory handler. */public class DTEDFrameCache extends CacheHandler implements PropertyConsumer { /** * The elevation value returned if there is no data at a lat/lon * (-32767). */ public final static int NO_DATA = -32767; public static final String DTEDDirectoryHandlerProperty = "directoryHandlers"; public static final String DTEDFrameCacheSizeProperty = "cacheSize"; public int DEFAULT_CACHE_SIZE = 20; protected String propertyPrefix = null; protected Vector directories = new Vector(); 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 max_size max number of frames to keep in the cache.. */ public DTEDFrameCache(int max_size) { super(max_size); } /** * Add a DTED DirectoryHandler to be used for the DTEDFrameCache. */ public void addDTEDDirectoryHandler(DTEDDirectoryHandler handler) { directories.add(handler); } /** * Remove a DTED DirectoryHandler from the list used for the * DTEDFrameCache. */ public void removeDTEDDirectoryHandler(DTEDDirectoryHandler handler) { directories.remove(handler); } /** * Get the Vector of DTEDDirectoryHandlers used by the * DTEDFrameCache. */ public Vector getDTEDDirectoryHandlers() { return directories; } /** * Set the Vector of DTEDDirectoryHandlers used by the * DTEDFrameCache. You might want to use this to set the order of * directories that are searched for a DTED frame. */ public void setDTEDDirectoryHandlers(Vector handlers) { directories = handlers; } /** * 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) { if (directories != null) { for (Iterator it = directories.iterator(); it.hasNext();) { DTEDDirectoryHandler ddh = (DTEDDirectoryHandler) it.next(); DTEDNameTranslator dnt = ddh.getTranslator(); dnt.set(lat, lon, level); String dtedFileName = dnt.getName(); if (Debug.debugging("dtedfile")) { Debug.output("DTEDFrameCache translator returns " + dtedFileName + " for " + lat + ", " + lon + ", level " + level); } 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) { if (Debug.debugging("dtedfile")) { Debug.output("DTEDFrameCache: returning " + name + " for " + lat + ", " + lon + ", level " + level); } return (DTEDFrame) get(name); } else { if (Debug.debugging("dtedfile")) { Debug.output("DTEDFrameCache: couldn't find frame for " + lat + ", " + lon + ", level " + level); } } 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) { DTEDFrame frame = new DTEDFrame(dtedFramePath, true); if (frame.frame_is_valid) { return new DTEDCacheObject(dtedFramePath, frame); } } return 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) { 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 (oldObjs == objs) { continue; } if (i < oldObjs.length) { objs[i] = oldObjs[i]; } else { objs[i] = null; } } oldObjs = null; } /** * 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--) { String dtedFileName = findFileName((double) lat, (double) lon, i); if (dtedFileName != null) { DTEDFrame 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 * that's why the rectangle is defined by the projection * parameters. * * @param proj the projection describing the wanted area * @param dtedLevel the DTED level (0, 1, 2) to be used, which * describes the geographicsal spacing between the posts. * @return array of elevations, in meters. Spacing depends on the * DTED level. */ public short[][] getElevations(EqualArc proj, int dtedLevel) { LatLonPoint ul = proj.getUpperLeft(); LatLonPoint lr = proj.getLowerRight(); return getElevations(ul.getLatitude(), ul.getLongitude(), lr.getLatitude(), lr.getLongitude(), dtedLevel); } /** * 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. Doesn't * handle projections which cross the dateline - You must handle * that yourself by making two inquiries. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -