📄 rpftochandler.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/RpfTocHandler.java,v $// $RCSfile: RpfTocHandler.java,v $// $Revision: 1.7.2.6 $// $Date: 2005/11/23 20:48:28 $// $Author: dietrick $//// **********************************************************************/** * Modifications: * 1. Changed getBestCoverageEntry() to consider more than one zone. * 2. Changed getBestCoverageEntry() to return multiple entries. *//* * The meat of this code is based on source code provided by The MITRE * Corporation, through the browse application source code. Many * thanks to Nancy Markuson who provided BBN with the software, and to * Theron Tock, who wrote the software, and Daniel Scholten, who * revised it - (c) 1994 The MITRE Corporation for those parts, and * used/distributed with permission. The RPF TOC reading mechanism is * the contributed part. */package com.bbn.openmap.layer.rpf;import java.io.File;import java.io.IOException;import java.util.List;import java.util.Vector;import com.bbn.openmap.io.BinaryBufferedFile;import com.bbn.openmap.io.BinaryFile;import com.bbn.openmap.io.FormatException;import com.bbn.openmap.proj.CADRG;import com.bbn.openmap.util.Debug;/** * The RpfTocHandler knows how to read A.TOC files for RPF raster * data. The A.TOC file describes the coverage found in the tree of * data that accompanies it. This coverage is described as a series of * rectangles describing the frame of groups of coverage, with * common-scale maps, types for different CADRG zones. The * RpfTocHandler can also provide a description of the frames and * subframes to use for a screen with a given projection. * <P> * * The RPF specification says that the frame paths and file names, * from the RPF directory, should be in upper-case letters. The paths * and file names are stored in the A.TOC file this way. Sometimes, * however, through CDROM and downloading quirks, the paths and file * names, as stored on the hard drive, are actually transferred to * lower-case letters. This RpfTocHandler will check for lower case * letter paths, but only for all the letters to be lower case. The * frame will be marked as non-existant if some of the directories or * filenames have be transformed to uppercase. */public class RpfTocHandler { public final static String RPF_TOC_FILE_NAME = "A.TOC"; public final static String LITTLE_RPF_TOC_FILE_NAME = "a.toc"; public final static int DEFAULT_FRAME_SPACE = 300; // frame file // in kilobytes protected RpfHeader head; protected BinaryFile binFile; protected RpfFileSections.RpfLocationRecord[] locations; /** The boundary rectangles in the A.TOC file. */ protected RpfTocEntry[] entries; protected String dir; protected boolean Dchum; protected long estimateDiskSpace; // uint protected int numBoundaries; protected long currencyTime; protected boolean valid = false; /** * Set by the RpfFrameProvider, and used to track down this * particular TOC to get to the frames offered by it's coverages. */ private int tocNumber = 0; /** * Used to return the valid entries for a coverage query. */ protected Vector entryResponses = new Vector(); /** * Flag to note whether absolute pathnames are used in the A.TOC. * Set to false, because it's not supposed to be that way, * according to the specification. This is reset automatically * when the A.TOC file is read. If the first two characters of the * directory paths are ./, then it stays false. */ protected boolean fullPathsInATOC = false; protected boolean DEBUG_RPF = false; protected boolean DEBUG_RPFTOC = false; protected boolean DEBUG_RPFTOCDETAIL = false; protected boolean DEBUG_RPFTOCFRAMEDETAIL = false; // Added zone extents private static final int CADRG_zone_extents[] = { 0, 32, 48, 56, 64, 68, 72, 76, 80, 90 }; public RpfTocHandler() { DEBUG_RPF = Debug.debugging("rpf"); DEBUG_RPFTOC = Debug.debugging("rpftoc"); DEBUG_RPFTOCDETAIL = Debug.debugging("rpftocdetail"); DEBUG_RPFTOCFRAMEDETAIL = Debug.debugging("rpftocframedetail"); estimateDiskSpace = DEFAULT_FRAME_SPACE; if (Debug.debugging("rpftoc")) { Debug.error("RpfTocHandler: No TOC parent directory name in constructor"); } } /** * Should be used in situations where it is certain that this is * the only A.TOC in town. */ public RpfTocHandler(String parentDir) { this(parentDir, 0); } /** * Used when there is more than one A.TOC being used, or where * there is a possibility of that happening, like in the RPF * layer. The TOC number should be unique for a certain * RpfFrameProvider. * * @param parentDir the RPF directory * @param TOCNumber a unique number to identify this TOC for a * RpfFrameProvider. */ public RpfTocHandler(String parentDir, int TOCNumber) { tocNumber = TOCNumber; estimateDiskSpace = DEFAULT_FRAME_SPACE; /* DKS. Open input "A.TOC" */ valid = loadFile(parentDir); if (!valid) { Debug.error("RpfTocHandler: Invalid TOC File in " + parentDir); } } /** * Given a parent RPF directory, find the a.toc file directly * inside it, as dictated by the specification. Not called anymore - * the BinaryFile does the searching, and can find URL and jar * files. * * @param parentDir Path to the RPF directory. * @return File */ public File getTocFile(String parentDir) { /* DKS. Open input "A.TOC" */ File file = new File(parentDir + "/" + RPF_TOC_FILE_NAME); if (!file.exists()) { file = new File(parentDir + "/" + LITTLE_RPF_TOC_FILE_NAME); if (!file.exists()) { // Debug.error("RpfTocHandler: getTocFile(): file in // "+ // parentDir + " not found"); return null; } } if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: getTocFile(): TOC file is " + file); } return file; } /** * True if the A.TOC file is readable/present/good. */ public boolean isValid() { return valid; } /** * A way to check if the status of the A.TOC file is different, in * case another one has taken its place. Handy if the A.TOC is on * a CDROM drive and the disk has been swapped. Not valid anymore, * with the advent of the new BinaryFile, where the file * information may not be available. */ public boolean hasChanged() { // File tmpFile = getTocFile(dir); // if (tmpFile == null) { // return valid; // } // if (tmpFile.lastModified() != currencyTime && valid) { // valid = false; // return true; // } return false; } /** Re-read the A.TOC file in the parent directory. */ public boolean reload() { return loadFile(dir); } /** Read the file and load its parameters into this object. */ public boolean loadFile(String parentDir) { boolean ret = true; String upperCaseVersion = parentDir + "/" + RPF_TOC_FILE_NAME; String lowerCaseVersion = parentDir + "/" + LITTLE_RPF_TOC_FILE_NAME; try { if (BinaryFile.exists(upperCaseVersion)) { binFile = new BinaryBufferedFile(upperCaseVersion); } else if (BinaryFile.exists(lowerCaseVersion)) { binFile = new BinaryBufferedFile(lowerCaseVersion); } if (binFile == null) return false; if (DEBUG_RPFTOC) { Debug.output("RpfTocHandler: TOC file is in " + parentDir); } dir = parentDir + "/"; // With the new BinaryFile, we can't get to this // info, because we aren't using File objects anymore. // currencyTime = file.lastModified(); if (!parseToc(binFile)) { ret = false; Debug.error("RpfTocHandler: loadFile(): error parsing A.TOC file!!"); } binFile.close(); } catch (IOException e) { ret = false; } binFile = null; return ret; } protected boolean parseToc(BinaryFile binFile) { RpfTocEntry entry; RpfFrameEntry frame; int n, pathLength; // ushort int i, currentPosition; int boundaryId, frameRow, frameCol; // ushort long numFrameIndexRecords; // uint # frame file index records // DKS new long pathOffset; // uint, offset of frame file pathname int boundaryRecordLength; // ushort int numPathnameRecords; //ushort int indexRecordLength; //ushort, frame file index record // length //int indexSubheaderLength = 9; //ushort, frame file index // subheader length long boundRectTableOffset; // uint, Bound. rect. table offset long frameIndexTableOffset; // uint, Frame file index table // offset if (DEBUG_RPFTOC) { Debug.output("ENTER TOC parsing..."); } // Stuff that used this is now commented out below...// boolean local = false;// if (binFile.getInputReader() instanceof FileInputReader) {// local = true;// } try { // binFile should be set to the beginning at this point binFile.seek(0); // Read header head = new RpfHeader(); if (!head.read(binFile)) return false; if (DEBUG_RPFTOC) { Debug.output("RpfTocHandler.parseToc: read header:\n" + head); } binFile.seek(head.locationSectionLocation); RpfFileSections rfs = new RpfFileSections(binFile); // Everything must be OK to reach here... // DKS. fseek to start of location section: 48 // DFD not necessarily 48! New A.TOCs are different. RpfFileSections.RpfLocationRecord[] locations = rfs.getLocations(RpfFileSections.TOC_LOCATION_KEY); // Read boundary rectangles // Number of Boundary records // DKS: now phys_index, not index if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): fseek to Boundary section subheader: " + locations[0].componentLocation); } binFile.seek(locations[0].componentLocation); // NEW boundRectTableOffset = (long) binFile.readInteger(); if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): BoundRectTableOffset: " + boundRectTableOffset); } n = (int) binFile.readShort(); if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): # Boundary rect. recs: " + n); } numBoundaries = n; // DKS new // Boundary record length boundaryRecordLength = (int) binFile.readShort(); if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): should be 132: " + boundaryRecordLength); } if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): fseek to Boundary Rectangle Table: " + locations[1].componentLocation); } binFile.seek(locations[1].componentLocation); entries = new RpfTocEntry[numBoundaries]; // Read Boundary rectangle records for (i = 0; i < n; i++) { if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): read boundary rec#: " + i); } // All this stuff moved to RpfTocEntry.java - DFD // 8/18/99 entries[i] = new RpfTocEntry(binFile, tocNumber, i); if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): entry " + i + " has scale " + entries[i].scale + ", type " + (entries[i].Cib ? "CIB" : "CADRG") + " in zone " + entries[i].zone); if (entries[i].Cib) Debug.output("RpfTocHandler: parseToc(): entry noted as a Cib entry."); } } if (DEBUG_RPFTOCDETAIL) { Debug.output("RpfTocHandler: parseToc(): Read frame file index section subheader at loc: " + locations[2].componentLocation); } // Read # of frame file index records // Skip 1 byte security classification // locations[2] is loc of frame file index section // subheader binFile.seek(locations[2].componentLocation + 1); // NEW frameIndexTableOffset = (long) binFile.readInteger(); numFrameIndexRecords = (long) binFile.readInteger(); numPathnameRecords = (int) binFile.readShort(); // indexRecordLength should now be 33, not 35 indexRecordLength = (int) binFile.readShort(); if (DEBUG_RPFTOCDETAIL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -