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 @ 2259

History | View | Annotate | Download (7.28 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.setAllDrawableBands();
91
                                        q.setAdjustToExtent(true); 
92
                                        bufResult = store.query(q);
93
                                }
94
                        } else {
95
                                //Hay parte del tile que cae fuera de la imagen
96
                                if(store.getDataType()[0] == Buffer.TYPE_BYTE) {
97
                                        //Para imagenes byte se crea una banda de transparencia
98
                                        alphaBand = true;
99
                                        if(!store.getColorInterpretation().hasAlphaBand())
100
                                                nBandsBuffer ++; 
101
                                } 
102
                                
103
                                Buffer smallBuf = readSupersampledBuffer(ex, newBandList, newBufWidth, newBufHeight, nBandsBuffer);
104
                                
105
                                if(smallBuf == null) { //No ha habido resampleo
106
                                        RasterQuery q = RasterLocator.getManager().createQuery();
107
                                        q.setAreaOfInterest(ex, newBufWidth, newBufHeight);
108
                                        q.setAllDrawableBands();
109
                                        q.setAdjustToExtent(true); 
110
                                        smallBuf = store.query(q);
111
                                }
112
                                
113
                                bufResult = buildTileBuffer(nBandsBuffer, this.tilePxWidth, this.tilePxHeight);
114
                                RasterLocator.getManager().getRasterUtils().copyToBuffer(
115
                                                bufResult, 
116
                                                tileExtent, 
117
                                                smallBuf, 
118
                                                ex, 
119
                                                pixelSize, 
120
                                                store.getColorInterpretation().hasAlphaBand());
121
                        }
122
                        
123
                        saveTile(bufResult, pixelSize, extension, alphaBand, tile, tileExtent, ci);
124
                        //Si borramos el rmf no se puede leer la etiqueta Alpha. En caso de que se modifique jgdal para
125
                        //poder guardar esta etiqueta deberiamos borrar el rmf para ahorrar ficheros
126
                        //File rmf = new File(tile.getFile().getAbsolutePath() + ".rmf");
127
                        //if(rmf.exists())
128
                                //rmf.delete();
129
                } catch (ProcessInterruptedException e) {
130
                } catch (RasterDriverException e) {
131
                        throw new TileGettingException(e);
132
                } catch (NotSupportedExtensionException e) {
133
                        throw new TileGettingException(e);
134
                } catch (IOException e) {
135
                        throw new TileGettingException(e);
136
                } catch (QueryException e) {
137
                        throw new TileGettingException(e);
138
                }
139
                readTileFromDisk(tile);
140
                return tile;
141
        }
142
        
143
        /**
144
         * When the buffer of the request is greater than the original raster (> scale 1:1) then the request 
145
         * has to be resampled. 
146
         * @param tileExtent
147
         * @param newBandList
148
         * @param bufWidth
149
         * @param bufHeight
150
         * @param nBands
151
         * @return
152
         * @throws ProcessInterruptedException
153
         * @throws TileGettingException
154
         */
155
        private Buffer readSupersampledBuffer(Extent tileExtent, BandList newBandList, int bufWidth, int bufHeight, int nBands) throws ProcessInterruptedException, TileGettingException {
156
                int widthImgPx = (int)Math.abs(tileExtent.width() / store.getPixelSizeX());
157
                int heightImgPx = (int)Math.abs(tileExtent.height() / store.getPixelSizeY());
158
                boolean supersampling = ((bufWidth > widthImgPx) || (bufHeight > heightImgPx)) ? true : false;
159
                
160
                if(supersampling) {
161
                        RasterQuery q = RasterLocator.getManager().createQuery();
162
                        q.setAreaOfInterest(tileExtent, widthImgPx, heightImgPx);
163
                        q.setAllDrawableBands();
164
                        q.setAdjustToExtent(true); 
165
                        Buffer buf = null;
166
                        try {
167
                                buf = store.query(q);
168
                        } catch (QueryException e) {
169
                                throw new TileGettingException(e);
170
                        }
171
                        Buffer result = buf.getAdjustedWindow(bufWidth, bufHeight, Buffer.INTERPOLATION_NearestNeighbour);
172
                        if(result != buf)
173
                                buf.dispose();
174
                        return result;
175
                }
176
                return null;
177
        }
178
        
179
        /**
180
         * Builds a buffer using the specified number of bands and initialize it
181
         * @param nbands
182
         * @return
183
         */
184
        private Buffer buildTileBuffer(int nbands, int w, int h) {
185
                Buffer bufResult = DefaultRasterManager.getInstance().createMemoryBuffer(store.getDataType()[0], w, h, nbands, true);
186
                if(store.getDataType()[0] != Buffer.TYPE_BYTE) {
187
                        for (int i = 0; i < bufResult.getBandCount(); i++) {
188
                                clearMaskBuffer(bufResult, i);
189
                        }
190
                } else
191
                        clearMaskBuffer(bufResult, nbands - 1);
192
                return bufResult;
193
        }
194
}