📄 rpfcachehandler.java
字号:
} // The percent coverage should be greater than zero here. // That should be checked by the RpfTocHandler. // Base the cache off the coverage in the first box. It's // supposed to have the best coverage. currentBox = (RpfCoverageBox) coverageBoxes.elementAt(0); if (!currentBox.getID().equals(oldID)) { resetSubframeIndex(currentBox.verticalSubframes(), currentBox.horizontalSubframes()); initCache(false); } start = currentBox.startIndexes; end = currentBox.endIndexes; goodData = true; } // Set the backup indexes, just in case. for (i = 1; i < coverageBoxes.size(); i++) { ((RpfCoverageBox) coverageBoxes.elementAt(i)).setPercentCoverage(ullat, ullon, lrlat, lrlon); } if (DEBUG_RPF) { Debug.output("RpfCachehandler: ####################"); Debug.output("" + currentBox); Debug.output(" Starting point " + start); Debug.output(" Ending point " + end); } // Figure out how much to scale the cached images. This would // be one of the big problems if we were going to merge // different data types. if (viewAttributes.scaleImages) { //Do the work for a great scaling factor here... // Need to figure how much this will change for this scale // chart at this screen scale // Reference at 0, 0 LatLonPoint refllpt = viewAttributes.proj.getUpperLeft(); refllpt.setLongitude(refllpt.getLongitude() + (float) currentBox.subframeLonInterval); refllpt.setLatitude(refllpt.getLatitude() - (float) currentBox.subframeLatInterval); Point refpt = viewAttributes.proj.forward(refllpt); scalingWidth = refpt.x; scalingHeight = refpt.y; } else { scalingWidth = RpfSubframe.PIXEL_EDGE_SIZE; scalingHeight = RpfSubframe.PIXEL_EDGE_SIZE; } // See NOTE below on setScalingTo if (cache != null) { // (cache.subframe[0].image.getFilteredHeight() != // scalingHeight || // cache.subframe[0].image.getFilteredWidth() != // scalingWidth)) { for (i = 0; i < subframeCacheSize; i++) { cache.subframe[i].setScalingTo(scalingWidth, scalingHeight); } } } /** * Resets the indicators in the subframe cache, so that none of * the current contents will be used - they'll have to be loaded * with data first. The cache mananagement is also set for the * current main RpfCoverageBox. */ protected void resetSubframeIndex(int vertFrames, int horizFrames) { /* Allocate the indices into the subframe cache */ int matrixheight = (vertFrames * 6) + (subframeBuffer * 2); int matrixwidth = (horizFrames * 6) + (subframeBuffer * 2); subframeIndex = new int[matrixheight][matrixwidth]; subframeVersion = new int[matrixheight][matrixwidth]; clearCache(); } /** * Clear the subframes in the cache, marking them as NOT_CACHED. */ public void clearCache() { if (subframeIndex != null && subframeVersion != null) { /* Initialize the subframe indices */ for (int i = 0; i < subframeIndex.length; i++) { for (int j = 0; j < subframeIndex[0].length; j++) { subframeIndex[i][j] = NOT_CACHED; subframeVersion[i][j] = -1; } } } } /** * Return true if the cache handler knows about good data in the * current situation. */ public boolean getGoodData() { return goodData; } /////////////////////////////////////////////////////////// // SUBFRAME CACHE HANDLING /////////////////////////////////////////////////////////// protected void initCache(boolean newCache) { int i; // Don't have a cache. if (subframeCacheSize <= 0) { cache = null; return; } if (newCache || cache == null) { cache = new SubframeCache(subframeCacheSize); } cache.LRU_head = 0; cache.LRU_tail = subframeCacheSize - 1; for (i = 0; i < subframeCacheSize; i++) { if (newCache) { try { cache.subframe[i] = new RpfSubframe(viewAttributes.colorModel); } catch (java.lang.OutOfMemoryError oome) { Debug.error("RpfCacheHandler: \n\tRan out of memory allocating the image cache.\tConsider increasing the java memory heap using the -Xmx option."); cache = null; subframeCacheSize = i; Debug.output("RpfCacheHandler: reseting cache size to " + subframeCacheSize); initCache(true); return; } } // See NOTE below on setScalingTo cache.subframe[i].setScalingTo(scalingWidth, scalingHeight); cache.subframe[i].version = 0; // Here's where I messed up - forgot to hook up the ends // of the chain... if (i < subframeCacheSize - 1) { cache.subframe[i].nextSubframe = i + 1; } else { cache.subframe[i].nextSubframe = 0; } if (i > 0) { cache.subframe[i].prevSubframe = i - 1; } else { cache.subframe[i].prevSubframe = subframeCacheSize - 1; } } } /** * Get the index of the least recently used entry from the * subframe cache. */ protected int getLRU() { if (cache != null) { return cache.LRU_tail; } else { return NOT_CACHED; } } protected void freeCache(int index) { if (cache == null) { return; } if (index == cache.LRU_tail) { return; } else if (index == cache.LRU_head) { cache.LRU_head = cache.subframe[cache.LRU_head].nextSubframe; } else { int next = cache.subframe[index].nextSubframe; int prev = cache.subframe[index].prevSubframe; cache.subframe[next].prevSubframe = prev; cache.subframe[prev].nextSubframe = next; } cache.subframe[cache.LRU_tail].nextSubframe = index; cache.subframe[index].prevSubframe = cache.LRU_tail; cache.LRU_tail = index; } /** * Mark a cache entry as being recently used. */ protected void referenceCache(int index) { if (cache == null) { return; } /* First unlink the cache entry from the list */ if (index == cache.LRU_head) { return; } else if (index == cache.LRU_tail) { cache.LRU_tail = cache.subframe[cache.LRU_tail].prevSubframe; } else { int next = cache.subframe[index].nextSubframe; int prev = cache.subframe[index].prevSubframe; cache.subframe[next].prevSubframe = prev; cache.subframe[prev].nextSubframe = next; } /* Now add the entry as the most recently referenced */ cache.subframe[cache.LRU_head].prevSubframe = index; cache.subframe[index].nextSubframe = cache.LRU_head; cache.LRU_head = index; } /** * Find out the size of the subframe cache. From the start and end * indexes, you can figure out the number of subframes the map * needs. If that number is bigger than this cache size, you'll * need to use the getCached that lets you supply the subframe * number that you are requesting, so that the RpfCacheHandler * knows when to stop caching subframes during a retrival.. * Otherwise, the cache will overwrite data and subframes will not * show up on the map. */ public int getCacheSize() { return subframeCacheSize; } /** * Get a subframe from one of the other RpfCoverageBoxes. Keep * going through them until there is a subframe returned, or if * there's nothing. Use this method when you are sure that the * subframe cache is big enough to handle all the subframes on the * map. * * @param x the x index of subframe in the FIRST RpfCoverageBox * space - translation needed. * @param y the y index of subframe in the FIRST RpfCoverageBox * space - translation needed. */ protected RpfSubframe getSubframeFromOtherTOC(int x, int y) { return getSubframeFromOtherTOC(x, y, -1); } /** * Get a subframe from one of the other RpfCoverageBoxes. Keep * going through them until there is a subframe returned, or if * there nothing. If you are not sure that the number of subframes * that go on the map is less than or equal to the size of the * subframe cache, then use this method to provide a running count * of how many subframes you've already called for to use in the * current map. If this number gets bigger than the cache size, * then the RpfCacheHandler will keep fetching data without * storing the extra subframes in the cache. Otherwise, the * previous images in the cache would be replaced before they were * painted, and they would not appear on the map. If subframeCount * is less than subframe size, then the latest retrieved subframe * will be stored in the cache. * * @param x the x index of subframe in the FIRST RpfCoverageBox * space - translation needed. * @param y the y index of subframe in the FIRST RpfCoverageBox * space - translation needed. * @param subframeCount a running count of the number of subframes * retrieved so far for the current map. Should be used it * there is concern that the number of subframes needed for * the map is greater than the size of the subframe. */ protected RpfSubframe getSubframeFromOtherTOC(int x, int y, int subframeCount) { int size = coverageBoxes.size(); RpfCoverageBox currentBox = null; // Decision to never cache if it's coming from another TOC. // Problems arose in areas that had 3 coverage boxes // converging. // They kept writing over each others' cache. boolean cacheIt = false; RpfSubframe ret = null; int index = 0; // There isn't anything else to check. if (size < 2) { return null; } else { /* If beyond the cache boundary, don't cache it. */ if (y < 0 || x < 0 || y >= subframeIndex.length || x >= subframeIndex[0].length || subframeCount >= subframeCacheSize) { cacheIt = false; } for (int i = 1; i < size; i++) { try { currentBox = (RpfCoverageBox) coverageBoxes.elementAt(i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -