Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / provider / tile / BaseTileDownloader.java @ 867

History | View | Annotate | Download (10.7 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.awt.geom.AffineTransform;
25
import java.io.IOException;
26

    
27
import org.gvsig.fmap.dal.coverage.RasterLocator;
28
import org.gvsig.fmap.dal.coverage.RasterManager;
29
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
30
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
31
import org.gvsig.fmap.dal.coverage.datastruct.DatasetBand;
32
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
33
import org.gvsig.fmap.dal.coverage.datastruct.Params;
34
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
35
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
36
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
37
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
38
import org.gvsig.fmap.dal.coverage.store.DataServerWriter;
39
import org.gvsig.fmap.dal.coverage.store.RasterWriter;
40
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
41
import org.gvsig.fmap.dal.exception.InitializeException;
42
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
43
import org.gvsig.raster.cache.tile.Tile;
44
import org.gvsig.raster.cache.tile.exception.TileGettingException;
45
import org.gvsig.raster.cache.tile.provider.Downloader;
46
import org.gvsig.raster.impl.DefaultRasterManager;
47
import org.gvsig.raster.impl.datastruct.BandListImpl;
48
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
49
import org.gvsig.raster.impl.provider.DefaultRasterProvider;
50
import org.gvsig.raster.impl.provider.RasterProvider;
51
import org.gvsig.raster.util.DefaultProviderServices;
52

    
53
/** 
54
 * Base class for downloaders  
55
 * @author Nacho Brodin (nachobrodin@gmail.com)
56
 */
57
public abstract class BaseTileDownloader implements Downloader {
58
        protected int                       tilePxWidth  = 0;
59
        protected int                       tilePxHeight = 0;
60
        protected DefaultRasterProvider     prov         = null;
61
        protected byte                      byteNoData   = (byte)0x00;
62
        protected short                     shortNoData  = Short.MIN_VALUE;
63
        protected int                       intNoData    = Integer.MIN_VALUE;
64
        protected float                     floatNoData  = -99999;
65
        protected double                    doubleNoData = -99999;
66
        
67
        public BaseTileDownloader(DefaultRasterProvider prov, int tilePxWidth, int tilePxHeight) {
68
                this.prov = prov;
69
                this.tilePxWidth = tilePxWidth;
70
                this.tilePxHeight = tilePxHeight;
71
        }
72
        
73
        /**
74
         * Gets the size of a tile in pixels 
75
         * @return Array of two integers. The first integer is the width and the second the height in pixels
76
         */
77
        public int[] getTileSize() {
78
                return new int[]{tilePxWidth, tilePxHeight};
79
        }
80
        
81
        /**
82
         * Sets the nodata value
83
         * @param noData
84
         */
85
        public void setNoDataValue(Object noData) {
86
                switch (prov.getDataType()[0]) {
87
                case Buffer.TYPE_BYTE:
88
                        byteNoData = ((Byte)noData).byteValue();
89
                        break;
90
                case Buffer.TYPE_SHORT:
91
                        shortNoData = ((Short)noData).shortValue();
92
                        break;
93
                case Buffer.TYPE_INT:
94
                        intNoData = ((Integer)noData).intValue();
95
                        break;
96
                case Buffer.TYPE_FLOAT:
97
                        floatNoData = ((Float)noData).floatValue();
98
                        break;
99
                case Buffer.TYPE_DOUBLE:
100
                        doubleNoData = ((Double)noData).doubleValue();
101
                        break;
102
                }
103
        }
104

    
105
        /*
106
         * (non-Javadoc)
107
         * @see org.gvsig.raster.cache.tile.provider.Downloader#readTile(org.gvsig.raster.cache.tile.Tile)
108
         */
109
        public Tile readTileFromDisk(Tile tile) throws TileGettingException {
110
                if(!tile.getFile().exists()) {
111
                        tile.setCorrupt(true);
112
                        return null;
113
                }
114
                
115
                BandList bandList = (BandList)tile.getDownloaderParams("BandList");
116
                for (int j = 0; j < bandList.getBandCount(); j++) {
117
                        bandList.getBand(j).setFileName(tile.getFile().getAbsolutePath());
118
                }
119
                
120
                int mallocNBands = 0;
121
                if(bandList.getDrawableBands() != null)
122
                        mallocNBands = bandList.getDrawableBands().length;
123
                else
124
                        mallocNBands = bandList.getDrawableBandsCount();
125
                
126
                try {
127
                        DefaultRasterProvider provider = DefaultProviderServices.loadProvider(tile.getFile());
128
                        
129
                        //int mallocNBands = prov.getDataType()[0] == Buffer.TYPE_BYTE ? provider.getBandCount() - 1 : provider.getBandCount();
130
                        Buffer buf = DefaultRasterManager.getInstance().createMemoryBuffer(prov.getDataType()[0], this.tilePxWidth, this.tilePxHeight, mallocNBands, true);
131
                        Buffer transparency = DefaultRasterManager.getInstance().createMemoryBuffer(prov.getDataType()[0], this.tilePxWidth, this.tilePxHeight, 1, true);
132
                        
133
                        //buf = provider.getWindow((int)0, (int)0, createBandListFromProvider(provider), buf);
134
                        buf = provider.getWindow((int)0, (int)0, bandList, buf);
135
                        
136
                        if(provider.getTransparency().getAlphaBandNumber() >= 0) {
137
                                //Lee la banda de transparencia para eliminar la zona del tile que est? fuera de la imagen
138
                                BandList newBandList = new BandListImpl(tile.getFile().getAbsolutePath(), provider.getBandCount(), provider.getDataType()[0]);
139
                                newBandList.clearDrawableBands();
140
                                newBandList.addDrawableBand(0, provider.getBandCount() - 1);
141
                                transparency = provider.getWindow((int)0, (int)0, newBandList, transparency);
142
                                tile.setData(new Object[]{buf, transparency, null});
143
                        } else
144
                                tile.setData(new Object[]{buf, null, provider.getColorTable()});
145
                        
146
                        buf.setDataExtent(provider.getExtent().toRectangle2D());
147
                        provider.close();
148
                        return tile;
149
                } catch (ProcessInterruptedException e) {
150
                        throw new TileGettingException(e);
151
                } catch (RasterDriverException e) {
152
                        throw new TileGettingException(e);
153
                } catch (ProviderNotRegisteredException e) {
154
                        throw new TileGettingException(e);
155
                } catch (InitializeException e) {
156
                        throw new TileGettingException(e);
157
                }
158
        }
159
        
160
        /**
161
         * Builds a BandList structure using all bands of a raster provider
162
         * @param prov
163
         * @return
164
         */
165
        @SuppressWarnings("unused")
166
        private BandList createBandListFromProvider(RasterProvider prov) {
167
                BandList bandList = new BandListImpl();
168
                bandList.clear();
169
                int nBands = prov.getDataType()[0] == Buffer.TYPE_BYTE ? prov.getBandCount() - 1 : prov.getBandCount();
170
                
171
                int[] drawableBands = new int[nBands];
172
                for(int i = 0; i < nBands; i++) {
173
                        try {
174
                                int dataType = prov.getDataType()[i];
175
                                DatasetBand band = new DatasetBandImpl(prov.getURIByBand(i), 
176
                                                                                                        prov.getBandPositionByProvider(i), 
177
                                                                                                        dataType, 
178
                                                                                                        nBands);
179
                                bandList.addBand(band, i);
180
                                drawableBands[i] = i;
181
                        } catch(BandNotFoundInListException ex) {
182
                                //No a?adimos la banda
183
                        }
184
                }
185
                bandList.setDrawableBands(drawableBands);
186
                return bandList;
187
        }
188
        
189
        /**
190
         * Sets a band to NODATA value 
191
         * @param bufResult
192
         * @param tileExtent
193
         * @param buf
194
         * @param ex
195
         * @param pixelSize
196
         */
197
        protected void clearMaskBuffer(Buffer buf, int nBand) {
198
                if(buf.getDataType() == Buffer.TYPE_BYTE) {
199
                        for (int i = 0; i < buf.getHeight(); i++) {
200
                                for (int j = 0; j < buf.getWidth(); j++) {
201
                                        buf.setElem(i, j, nBand, byteNoData);
202
                                }
203
                        }
204
                        return;
205
                }
206
                if(buf.getDataType() == Buffer.TYPE_SHORT) {
207
                        for (int i = 0; i < buf.getHeight(); i++) {
208
                                for (int j = 0; j < buf.getWidth(); j++) {
209
                                        buf.setElem(i, j, nBand, shortNoData);
210
                                }
211
                        }
212
                        return;
213
                }
214
                if(buf.getDataType() == Buffer.TYPE_INT) {
215
                        for (int i = 0; i < buf.getHeight(); i++) {
216
                                for (int j = 0; j < buf.getWidth(); j++) {
217
                                        buf.setElem(i, j, nBand, intNoData);
218
                                }
219
                        }
220
                        return;
221
                }
222
                if(buf.getDataType() == Buffer.TYPE_FLOAT) {
223
                        for (int i = 0; i < buf.getHeight(); i++) {
224
                                for (int j = 0; j < buf.getWidth(); j++) {
225
                                        buf.setElem(i, j, nBand, floatNoData);
226
                                }
227
                        }
228
                        return;
229
                }
230
                if(buf.getDataType() == Buffer.TYPE_DOUBLE) {
231
                        for (int i = 0; i < buf.getHeight(); i++) {
232
                                for (int j = 0; j < buf.getWidth(); j++) {
233
                                        buf.setElem(i, j, nBand, doubleNoData);
234
                                }
235
                        }
236
                        return;
237
                }
238
        }
239
        
240
        /**
241
         * Saves a buffer to disk
242
         * @param bufResult Buffer to save
243
         * @param pixelSize Pixel size
244
         * @param extension output file format
245
         * @param alphaBand true if it has alpha band
246
         * @param path Path to the new file
247
         * @param tileExtent Bounding box of the tile
248
         * @throws NotSupportedExtensionException
249
         * @throws RasterDriverException
250
         * @throws ProcessInterruptedException
251
         * @throws IOException
252
         */
253
        protected void saveTile(Buffer bufResult, 
254
                        double pixelSize, 
255
                        String extension, 
256
                        boolean alphaBand, 
257
                        Tile tile, 
258
                        Extent tileExtent,
259
                        ColorInterpretation colorInterpretation) throws NotSupportedExtensionException, RasterDriverException, ProcessInterruptedException, IOException {
260
                //Escritura en disco del tile
261
                RasterManager rManager = RasterLocator.getManager();
262
                DataServerWriter dataWriter = RasterLocator.getManager().createDataServerWriter();
263
                dataWriter.setBuffer(bufResult, -1);
264
                Params params = rManager.createWriter("_." + extension).getParams();
265
                AffineTransform affineTransform = new AffineTransform(pixelSize, 0, 0, -pixelSize,
266
                                tileExtent.getULX(),
267
                                tileExtent.getULY());
268
                RasterWriter rw = rManager.createWriter(dataWriter, tile.getFile().getAbsolutePath(),
269
                                bufResult.getBandCount(), affineTransform, bufResult.getWidth(),
270
                                bufResult.getHeight(), bufResult.getDataType(), params, null);
271
                
272
                if(colorInterpretation != null) {
273
                        String[] values = colorInterpretation.getValues();
274
                        if(alphaBand) {
275
                                String[] newValues = values;
276
                                boolean exists = false;
277
                                for (int i = 0; i < values.length; i++) {
278
                                        if(values[i].compareTo("Alpha") == 0)
279
                                                exists = true;
280
                                }
281
                                if(!exists) {
282
                                        newValues = new String[values.length + 1];
283
                                        for (int i = 0; i < values.length; i++) {
284
                                                newValues[i] = values[i];
285
                                        }
286
                                        newValues[newValues.length - 1] = "Alpha";
287
                                }
288
                                rw.setColorBandsInterpretation(newValues);
289
                        }
290
                        
291
                } else {
292
                        if(alphaBand) {
293
                                String[] ci = new String[bufResult.getBandCount()];
294
                                if(bufResult.getBandCount() == 4) {
295
                                        ci[0] = "Red";
296
                                        ci[1] = "Green";
297
                                        ci[2] = "Blue";
298
                                        ci[3] = "Alpha";
299
                                } else {
300
                                        for (int i = 0; i < bufResult.getBandCount(); i++) {
301
                                                ci[i] = "Gray";
302
                                        }
303
                                }
304
                                rw.setColorBandsInterpretation(ci);
305
                        }
306
                }
307
                rw.dataWrite();
308
                rw.writeClose();
309
                tile.setCorrupt(false);
310
        }
311
}