Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / provider / tile / TileDownloaderForFiles.java @ 2236

History | View | Annotate | Download (7.25 KB)

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

    
24
import java.io.IOException;
25

    
26
import org.gvsig.fmap.dal.coverage.RasterLocator;
27
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
29
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
30
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
31
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
32
import org.gvsig.fmap.dal.coverage.exception.QueryException;
33
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
34
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
35
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
36
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
37
import org.gvsig.raster.cache.tile.Tile;
38
import org.gvsig.raster.cache.tile.exception.TileGettingException;
39
import org.gvsig.raster.cache.tile.provider.CacheStruct;
40
import org.gvsig.raster.impl.DefaultRasterManager;
41
import org.gvsig.raster.impl.datastruct.ExtentImpl;
42

    
43
/** 
44
 * Tile getter 
45
 * @author Nacho Brodin (nachobrodin@gmail.com)
46
 */
47
public class TileDownloaderForFiles extends BaseTileDownloader {
48
        private CacheStruct               struct     = null;
49
        private String                    extension  = null;
50
        
51
        public TileDownloaderForFiles(RasterDataStore store, 
52
                        CacheStruct struct,
53
                        int tileWidth,
54
                        int tileHeight,
55
                        String extension) {
56
                super(store, tileWidth, tileHeight);
57
                this.struct = struct;
58
                this.extension = extension;
59
        }
60
        
61
        public synchronized Tile downloadTile(Tile tile) throws TileGettingException {
62
                Extent tileExtent = new ExtentImpl(tile.getUl(), tile.getLr());
63
                ColorInterpretation ci = store.getColorInterpretation();
64
                
65
                //Escribe todas las bandas a disco
66
                BandList newBandList = store.getDefaultBandList();//createBandList(prov);
67
                
68
                Buffer bufResult = null;
69
                
70
                double pixelSize = struct.getPixelSizeByLevel(tile.getLevel());
71
                
72
                try {
73
                        Extent ex = store.getExtent().intersection(tileExtent);
74
                        
75
                        //newBuf ser?n distintas de tilePx cuando haya zonas con valores no data. Las de los bordes
76
                        int newBufWidth = (int)Math.ceil((ex.width() * this.tilePxWidth) / tileExtent.width());
77
                        int newBufHeight = (int)Math.ceil((ex.height() * this.tilePxHeight) / tileExtent.height());
78
                        boolean alphaBand = false;
79
                        int nBandsBuffer = store.getBandCount();
80
                        
81
                        if(store.getColorInterpretation().hasAlphaBand())
82
                                alphaBand = true;
83
                        
84
                        //Si no hay parte del tile que cae fuera de la imagen no se usa una nueva banda de transparencia ni valores nodata
85
                        if(newBufHeight == this.tilePxHeight && newBufWidth == this.tilePxWidth) {
86
                                bufResult = readSupersampledBuffer(tileExtent, newBandList, this.tilePxWidth, this.tilePxHeight, nBandsBuffer);
87
                                if(bufResult == null) {
88
                                        RasterQuery q = RasterLocator.getManager().createQuery();
89
                                        q.setAreaOfInterest(tileExtent, this.tilePxWidth, this.tilePxHeight);
90
                                        q.setAdjustToExtent(true); 
91
                                        bufResult = store.query(q);
92
                                }
93
                        } else {
94
                                //Hay parte del tile que cae fuera de la imagen
95
                                if(store.getDataType()[0] == Buffer.TYPE_BYTE) {
96
                                        //Para imagenes byte se crea una banda de transparencia
97
                                        alphaBand = true;
98
                                        if(!store.getColorInterpretation().hasAlphaBand())
99
                                                nBandsBuffer ++; 
100
                                } 
101
                                
102
                                Buffer smallBuf = readSupersampledBuffer(ex, newBandList, newBufWidth, newBufHeight, nBandsBuffer);
103
                                
104
                                if(smallBuf == null) { //No ha habido resampleo
105
                                        RasterQuery q = RasterLocator.getManager().createQuery();
106
                                        q.setAreaOfInterest(ex, newBufWidth, newBufHeight);
107
                                        q.setAllDrawableBands();
108
                                        q.setAdjustToExtent(true); 
109
                                        smallBuf = store.query(q);
110
                                }
111
                                
112
                                bufResult = buildTileBuffer(nBandsBuffer, this.tilePxWidth, this.tilePxHeight);
113
                                RasterLocator.getManager().getRasterUtils().copyToBuffer(
114
                                                bufResult, 
115
                                                tileExtent, 
116
                                                smallBuf, 
117
                                                ex, 
118
                                                pixelSize, 
119
                                                store.getColorInterpretation().hasAlphaBand());
120
                        }
121
                        
122
                        saveTile(bufResult, pixelSize, extension, alphaBand, tile, tileExtent, ci);
123
                        //Si borramos el rmf no se puede leer la etiqueta Alpha. En caso de que se modifique jgdal para
124
                        //poder guardar esta etiqueta deberiamos borrar el rmf para ahorrar ficheros
125
                        //File rmf = new File(tile.getFile().getAbsolutePath() + ".rmf");
126
                        //if(rmf.exists())
127
                                //rmf.delete();
128
                } catch (ProcessInterruptedException e) {
129
                } catch (RasterDriverException e) {
130
                        throw new TileGettingException(e);
131
                } catch (NotSupportedExtensionException e) {
132
                        throw new TileGettingException(e);
133
                } catch (IOException e) {
134
                        throw new TileGettingException(e);
135
                } catch (QueryException e) {
136
                        throw new TileGettingException(e);
137
                }
138
                readTileFromDisk(tile);
139
                return tile;
140
        }
141
        
142
        /**
143
         * When the buffer of the request is greater than the original raster (> scale 1:1) then the request 
144
         * has to be resampled. 
145
         * @param tileExtent
146
         * @param newBandList
147
         * @param bufWidth
148
         * @param bufHeight
149
         * @param nBands
150
         * @return
151
         * @throws ProcessInterruptedException
152
         * @throws TileGettingException
153
         */
154
        private Buffer readSupersampledBuffer(Extent tileExtent, BandList newBandList, int bufWidth, int bufHeight, int nBands) throws ProcessInterruptedException, TileGettingException {
155
                int widthImgPx = (int)Math.abs(tileExtent.width() / store.getPixelSizeX());
156
                int heightImgPx = (int)Math.abs(tileExtent.height() / store.getPixelSizeY());
157
                boolean supersampling = ((bufWidth > widthImgPx) || (bufHeight > heightImgPx)) ? true : false;
158
                
159
                if(supersampling) {
160
                        RasterQuery q = RasterLocator.getManager().createQuery();
161
                        q.setAreaOfInterest(tileExtent, widthImgPx, heightImgPx);
162
                        q.setAllDrawableBands();
163
                        q.setAdjustToExtent(true); 
164
                        Buffer buf = null;
165
                        try {
166
                                buf = store.query(q);
167
                        } catch (QueryException e) {
168
                                throw new TileGettingException(e);
169
                        }
170
                        Buffer result = buf.getAdjustedWindow(bufWidth, bufHeight, Buffer.INTERPOLATION_NearestNeighbour);
171
                        if(result != buf)
172
                                buf.dispose();
173
                        return result;
174
                }
175
                return null;
176
        }
177
        
178
        /**
179
         * Builds a buffer using the specified number of bands and initialize it
180
         * @param nbands
181
         * @return
182
         */
183
        private Buffer buildTileBuffer(int nbands, int w, int h) {
184
                Buffer bufResult = DefaultRasterManager.getInstance().createMemoryBuffer(store.getDataType()[0], w, h, nbands, true);
185
                if(store.getDataType()[0] != Buffer.TYPE_BYTE) {
186
                        for (int i = 0; i < bufResult.getBandCount(); i++) {
187
                                clearMaskBuffer(bufResult, i);
188
                        }
189
                } else
190
                        clearMaskBuffer(bufResult, nbands - 1);
191
                return bufResult;
192
        }
193
}