Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.tilecache / org.gvsig.raster.tilecache.provider / src / main / java / org / gvsig / raster / tilecache / provider / MemoryTileStructImage.java @ 6520

History | View | Annotate | Download (7.51 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2016 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.raster.tilecache.provider;
24

    
25
import java.util.HashMap;
26
import java.util.Iterator;
27
import java.util.Map.Entry;
28
import java.util.Set;
29

    
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
35
import org.gvsig.fmap.dal.raster.api.RasterQuery;
36
import org.gvsig.fmap.dal.raster.spi.RasterStoreProvider;
37
import org.gvsig.fmap.dal.raster.spi.TiledRasterStoreProvider;
38
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
39
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
40
import org.gvsig.fmap.geom.GeometryLocator;
41
import org.gvsig.fmap.geom.GeometryManager;
42
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
43
import org.gvsig.fmap.geom.primitive.Envelope;
44
import org.gvsig.raster.lib.buffer.api.Band;
45
import org.gvsig.raster.lib.buffer.api.Buffer;
46
import org.gvsig.raster.lib.buffer.api.TileStruct;
47
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
48
import org.gvsig.tools.ToolsLocator;
49
import org.gvsig.tools.dispose.Disposable;
50
import org.gvsig.tools.dispose.DisposeUtils;
51
import org.gvsig.tools.exception.BaseException;
52

    
53
/**
54
 * Represents a tiled image
55
 *
56
 * @author dmartinezizquierdo
57
 *
58
 */
59
public class MemoryTileStructImage extends AbstractTileCacheStructImage {
60

    
61
    private static final Logger logger = LoggerFactory.getLogger(MemoryTileStructImage.class);
62
    private static final int MAX_RECENT_ACCEDED_TILES_NUMBER = 50;
63

    
64

    
65

    
66
    /**
67
     * @param innerProvider
68
     * @param query
69
     */
70
    public MemoryTileStructImage(RasterStoreProvider innerProvider, RasterQuery query) {
71
        super(innerProvider, query);
72

    
73
        tileStruct = getTileStruct();
74

    
75
        recentAccededTiles = new HashMap<String, Tile>();
76

    
77
    }
78

    
79

    
80

    
81
    /**
82
     * @param buffer
83
     * @param bandNumber
84
     * @param zoomLevel
85
     * @param tileRow
86
     * @param tileCol
87
     * @return Band
88
     * @throws CreateEnvelopeException
89
     * @throws CloneNotSupportedException
90
     * @throws ValidateDataParametersException
91
     */
92
    public Band fetchTile(int bandNumber, int zoomLevel, int structRow, int structCol) throws CreateEnvelopeException,
93
        ValidateDataParametersException, CloneNotSupportedException {
94

    
95
        String keyTile = composeKeyForRecentTiles(zoomLevel, structRow, structCol);
96
        Tile tile = recentAccededTiles.get(keyTile);
97

    
98
        if (tile != null) {
99
            // Devolver la banda del buffer del tile
100
            return tile.getBuffer().getBand(bandNumber);
101
        } else {
102
            // Cargar un tile nuevo
103
            Buffer buffer = null;
104
            try {
105
                buffer = requestTile(zoomLevel, structRow, structCol);
106
                ToolsLocator.getDisposableManager().bind(buffer);
107

    
108
                if (recentAccededTiles.size() >= MAX_RECENT_ACCEDED_TILES_NUMBER) {
109
                    removeOlderTile();
110
                }
111
                recentAccededTiles.put(keyTile, new Tile(buffer, keyTile));
112

    
113
                Band band = buffer.getBand(bandNumber);
114
                ToolsLocator.getDisposableManager().bind(band);
115
                return band;
116
            } catch (DataException | BufferException e) {
117
                logger.warn("Can't fetch tile: zoomLevel = " + zoomLevel + ", tileRow = " + structRow
118
                    + ", tileColumn = " + structCol + ", band = " + bandNumber + ".", e);
119
                return null;
120
            } finally {
121
                DisposeUtils.dispose(buffer);
122
                buffer = null;
123
            }
124
        }
125
    }
126

    
127
    private Buffer requestTile(int zoomLevel, int structRow, int structCol) throws CreateEnvelopeException,
128
        CloneNotSupportedException, BufferException, ValidateDataParametersException, DataException {
129

    
130
        RasterQuery rasterQuery = (RasterQuery) this.query.clone();
131

    
132
        Double pixelSize = this.tileStruct.getPixelSizePerZoomLevel().get(zoomLevel);
133
        rasterQuery.setPixelSize(pixelSize);
134

    
135
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
136

    
137
        Envelope structExtent = this.tileStruct.getEnvelope();
138
        int rowsPerTile = this.tileStruct.getRowsPerTile();
139
        int columnsPerTile = this.tileStruct.getColumnsPerTile();
140
        double minX = structExtent.getMinimum(DIMENSIONS.X) + structCol * (pixelSize * columnsPerTile);
141
        double minY = structExtent.getMaximum(DIMENSIONS.Y) - ((structRow + 1) * (pixelSize * rowsPerTile));
142
        double maxX = minX + pixelSize * columnsPerTile;
143
        double maxY = minY + pixelSize * rowsPerTile;
144
        Envelope envelope = geomManager.createEnvelope(minX, minY, maxX, maxY, SUBTYPES.GEOM2D);
145

    
146
        Buffer buffer = null;
147
        Buffer clippedBuffer = null;
148
        Buffer interpolatedBuffer = null;
149

    
150
        try {
151
            buffer = innerProvider.createBuffer(rasterQuery);
152
            clippedBuffer = buffer.clip(envelope);
153
            interpolatedBuffer =
154
                clippedBuffer.createInterpolated(
155
                    (int) (Math.round(clippedBuffer.getPixelSizeY() * clippedBuffer.getRows() / pixelSize)),
156
                    (int) (Math.round(clippedBuffer.getPixelSizeX() * clippedBuffer.getColumns() / pixelSize)),
157
                    Buffer.INTERPOLATION_NearestNeighbour, null);
158

    
159
            return interpolatedBuffer;
160

    
161
        } finally {
162
            DisposeUtils.dispose(buffer);
163
            DisposeUtils.dispose(clippedBuffer);
164
//            DisposeUtils.dispose(interpolatedBuffer);
165
        }
166

    
167
    }
168

    
169
    @Override
170
    protected void doDispose() throws BaseException {
171
        if (recentAccededTiles != null) {
172
            Set<Entry<String, Tile>> entrySet = recentAccededTiles.entrySet();
173
            for (Iterator<Entry<String, Tile>> iterator = entrySet.iterator(); iterator.hasNext();) {
174
                Entry<String, Tile> entry = (Entry<String, Tile>) iterator.next();
175
                DisposeUtils.dispose(entry.getValue());
176
            }
177
            recentAccededTiles.clear();
178
        }
179
        DisposeUtils.dispose(innerProvider);
180
        innerProvider = null;
181
        DisposeUtils.dispose((Disposable) tileStruct);
182
        tileStruct = null;
183

    
184
        query = null;
185
        colorInterpretation = null;
186
        legend = null;
187
        colorTable = null;
188
    }
189

    
190
    public TileStruct getTileStruct() {
191
        if(this.tileStruct==null){
192
            if (innerProvider != null && innerProvider instanceof TiledRasterStoreProvider) {
193
                this.tileStruct = ((TiledRasterStoreProvider) innerProvider).getTileStruct();
194
            } else {
195
                throw new UnsupportedOperationException("Can't be applied the memory tile cache to the provider "+innerProvider.getFullName());
196
            }
197
        }
198
        return this.tileStruct;
199
    }
200

    
201
}