rpfcachehandler.java

来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 950 行 · 第 1/3 页

JAVA
950
字号
            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) {        if (subframeCacheSize > 0) {            /* Allocate the indices into the subframe cache */            int matrixheight = (vertFrames * 6) + (subframeBuffer * 2);            int matrixwidth = (horizFrames * 6) + (subframeBuffer * 2);            subframeIndex = new byte[matrixheight][matrixwidth];            subframeVersion = new byte[matrixheight][matrixwidth];            clearCache();        } else {            subframeIndex = null;            subframeVersion = null;        }    }    /**     * 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;                    if (DEBUG_RPF) {                        Debug.output("RpfCacheHandler: reseting cache size to "                                + subframeCacheSize);                    }                    initCache(true);                    return;                }            }            RpfSubframe subframe = cache.subframe[i];            // See NOTE below on setScalingTo            subframe.setScalingTo(scalingWidth, scalingHeight);            subframe.version = 0;            // Here's where I messed up - forgot to hook up the ends            // of the chain...            if (i < subframeCacheSize - 1) {                subframe.nextSubframe = i + 1;            } else {                subframe.nextSubframe = 0;            }            if (i > 0) {                subframe.prevSubframe = i - 1;            } else {                subframe.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 (subframeIndex == null || 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);                } catch (ArrayIndexOutOfBoundsException aioobe) {                    return null;                }                // Changed offsets because they were                // incorrect, and this was preventing other RCBs from                // finding the box

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?