📄 rpfframecachehandler.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/rpf/RpfFrameCacheHandler.java,v $// $RCSfile: RpfFrameCacheHandler.java,v $// $Revision: 1.5.2.5 $// $Date: 2006/01/13 16:09:38 $// $Author: dietrick $//// **********************************************************************/** * Modifications: * * 1. Changed getCoverage() * */package com.bbn.openmap.layer.rpf;import java.util.List;import java.util.Vector;import com.bbn.openmap.layer.util.cacheHandler.CacheHandler;import com.bbn.openmap.layer.util.cacheHandler.CacheObject;import com.bbn.openmap.proj.CADRG;import com.bbn.openmap.util.Debug;/** * The RpfFrameCacheHandler does everything involved with handling RAW RPF * frames. If used locally, it can also deal with filling the role of * RpfFrameProvider. You create one of these with the paths to the RPF * directories, and then hand it to something that needs a RpfFrameProvider, or * that acts like one. */public class RpfFrameCacheHandler extends CacheHandler implements RpfFrameProvider { /* Default frame cache size. */ public final static int FRAME_CACHE_SIZE = 5; /** Colortable used on the frames. */ protected RpfColortable colortable; /** For future use... */ protected boolean Dchum = true; /** Special outlining for chummed subframes */ protected boolean outlineChum = false; /** The Table of Contents files, parsed and ready to use. */ protected RpfTocHandler[] tocs; /** View and display attributes for the data. */ protected RpfViewAttributes viewAttributes = new RpfViewAttributes(); /** * The default constructor. * * @param RpfPaths the directory paths to the RPF directories. */ public RpfFrameCacheHandler(String[] RpfPaths) { this(RpfPaths, FRAME_CACHE_SIZE); } /** * The constructor to use if you want to modify the number of frames held in * the cache.. * * @param RpfPaths the directory paths to the RPF directories. */ public RpfFrameCacheHandler(String[] RpfPaths, int max_size) { super(max_size); tocs = createTocHandlers(RpfPaths); colortable = new RpfColortable(); } /** * When you pre-initialize the RpfTocHandlers before giving them to the * RpfFrameCacheHandler. */ public RpfFrameCacheHandler(RpfTocHandler[] tocHandlers) { tocs = tocHandlers; colortable = new RpfColortable(); } // public void finalize() { // Debug.message("gc", "RpfFrameCacheHandler: getting GC'd"); // } /** * RpfFrameProvider interface method. If this is being used as a frame * provider, it's local, right? */ public boolean needViewAttributeUpdates() { return false; } /** * Should only be set via the object it is sending frame data to. Don't send * in a null value, since this is assumed to be valid in other parts of the * code. */ public void setViewAttributes(RpfViewAttributes va) { viewAttributes = va; if (va != null && colortable != null) { colortable.setOpaqueness(va.opaqueness); colortable.setNumColors(va.numberOfColors); } } /** * RpfFrameProvider interface method. Return all the RpfCoverageBoxes that * fall in the area of interest. * * @param ullat NW latitude. * @param ullon NW longitude. * @param lrlat SE latitude. * @param lrlon SE longitude * @param proj CADRG projection to use for zone decisions. * @param chartSeries RpfProductInfo.seriesCode entry, null for all/any. * @return Vector of RpfCoverageBoxes. */ public Vector getCatalogCoverage(float ullat, float ullon, float lrlat, float lrlon, CADRG proj, String chartSeries) { int i; Vector coverages = new Vector(); for (i = 0; i < tocs.length; i++) { // Check the tochandlers for differences, and reload them // if necessary. if (tocs[i].hasChanged()) tocs[i].reload(); if (!tocs[i].isValid()) continue; tocs[i].getCatalogCoverage(ullat, ullon, lrlat, lrlon, proj, chartSeries, coverages); } return coverages; } /** * Given an area and a two-letter chart series code, find the percentage of * coverage on the map that that chart series can offer. If you want * specific coverage information, use the getCatalogCoverage call. Don't * send a chart series code of ANY, since that doesn't make sense. * * @param ullat NW latitude. * @param ullon NW longitude. * @param lrlat SE latitude. * @param lrlon SE longitude * @param p projection to use for zone decisions. * @param chartSeries RpfProductInfo.seriesCode entry. * @return percentage of map covered by specific chart type. * @see #getCatalogCoverage */ public float getCalculatedCoverage(float ullat, float ullon, float lrlat, float lrlon, CADRG p, String chartSeries) { if (chartSeries.equalsIgnoreCase(RpfViewAttributes.ANY)) { return 0f; } Vector results = getCatalogCoverage(ullat, ullon, lrlat, lrlon, p, chartSeries); int size = results.size(); if (size == 0) { return 0f; } // Now interpret the results and figure out the real total // percentage coverage for the chartSeries. First need to // figure out the current size of the subframes. Then create // a boolean matrix of those subframes that let you figure out // how many of them are available. Calculate the percentage // off that. int i, x, y; double frameLatInterval = Double.MAX_VALUE; double frameLonInterval = Double.MAX_VALUE; RpfCoverageBox rcb; for (i = 0; i < size; i++) { rcb = (RpfCoverageBox) results.elementAt(i); if (rcb.subframeLatInterval < frameLatInterval) { frameLatInterval = rcb.subframeLatInterval; } if (rcb.subframeLonInterval < frameLonInterval) { frameLonInterval = rcb.subframeLonInterval; } } if (frameLatInterval == Double.MAX_VALUE || frameLonInterval == Double.MAX_VALUE) { return 0.0f; } int numHFrames = (int) Math.ceil((lrlon - ullon) / frameLonInterval); int numVFrames = (int) Math.ceil((ullat - lrlat) / frameLatInterval); boolean[][] coverage = new boolean[numHFrames][numVFrames]; for (i = 0; i < size; i++) { rcb = (RpfCoverageBox) results.elementAt(i); if (rcb.percentCoverage == 100) { return 1.0f; } for (y = 0; y < numVFrames; y++) { for (x = 0; x < numHFrames; x++) { // degree location of indexs float yFrameLoc = (float) (lrlat + (y * frameLatInterval)); float xFrameLoc = (float) (ullon + (x * frameLonInterval)); if (coverage[x][y] == false) { if (rcb.within(yFrameLoc, xFrameLoc)) { coverage[x][y] = true; } } } } } float count = 0; for (y = 0; y < numVFrames; y++) { for (x = 0; x < numHFrames; x++) { if (coverage[x][y] == true) { // System.out.print("X"); count++; } else { // System.out.print("."); } } // System.out.println(""); } return count / (float) (numHFrames * numVFrames); } /** * Given a projection which describes the map (or area of interest), return * the best RpfTocEntry, from all the A.TOC, that covers the area. * RpfFrameProvider method. * * 1. Fixed bug that was preventing it from actually returning the best * coverage box in the first position of the Vector. 2. Prevented the method * from returning early when it found a box that claimed perfect coverage. * This was causing problems in some areas, where boxes that claimed * coverage didn't actually have it. This could be a data problem, so maybe * we can add the early return back in in the future. 3. Changed < to <= * below. 4. Iterates thru list returned by RpcTocHandler since the return * type for getBestCoverageEntry changed from RpfTocEntry to List. * * @param ullat NW latitude. * @param ullon NW longitude. * @param lrlat SE latitude. * @param lrlon SE longitude * @param proj CADRG projection to use for zone decisions. * @return Vector of RpfCoverageBoxes. */ public Vector getCoverage(float ullat, float ullon, float lrlat, float lrlon, CADRG proj) { int i; RpfTocEntry currentEntry; RpfCoverageBox rcb; List coverageEntries; Debug.message("rpf", "RpfFrameCacheHandler: getCoverage()"); Vector coverageBoxes = new Vector(); for (i = 0; i < tocs.length; i++) { // Check the tochandlers for differences, and reload them // if necessary. if (tocs[i].hasChanged()) tocs[i].reload(); if (!tocs[i].isValid()) continue; // NOTE: returning a list of best coverage entries. // Added inner loop to deal with iterating over list of // results. coverageEntries = tocs[i].getBestCoverageEntry(ullat, ullon, lrlat, lrlon, proj, viewAttributes); for (int k = 0; k < coverageEntries.size(); k++) { currentEntry = (RpfTocEntry) coverageEntries.get(k); // This is a test for total coverage. If we get total // coverage of an exact scale match, just return this // coverage box right away. If the scale is not a // perfect // match, then we will return the box that has // complete // coverage with the best scale. A boundaryHit of 8 // means // total coverage. Trust me. if (currentEntry != null) { if (Debug.debugging("rpftoc")) { System.out.println("RFCH: Toc " + i + " returned an entry"); } RpfCoverageBox currentCoverage = currentEntry.coverage; // NOTE: // removed because some areas had boxes that // claimed perfect // coverage but didn't actually have it. // This could be a data problem, but in any case, // this work-around returns all relevant coverage // boxes. // if (currentCoverage.percentCoverage >= 100f && // scaleDifference(proj, currentCoverage) == 0) { // coverageBoxes.removeAllElements(); // coverageBoxes.addElement(currentCoverage); // return coverageBoxes; // } else { // You now ought to at least make sure that the // scales are the same for all A.TOCs. That way, // the subframe spacing will be the same. Put the // best coverage (smallest scale difference) at // the front of the list, and whittle it down from // there. Object[] coverageArray = new Object[coverageBoxes.size()]; coverageBoxes.copyInto(coverageArray); coverageBoxes.removeAllElements(); int size = coverageArray.length; // Set this here in case the vector is empty... // float currentScale = currentEntry.info.scale; if (size == 0) { coverageBoxes.addElement(currentCoverage); } else { boolean addedCurrent = false; boolean okToAddCurrent = true; for (int j = 0; j < size; j++) { rcb = (RpfCoverageBox) coverageArray[j]; if (!addedCurrent) { if (j == 0) { // So first, check to see if the // current // coverage is a better match than // the // current best, first considering
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -