Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataaccess / cache / CacheDataServer.java @ 11072

History | View | Annotate | Download (15.7 KB)

1

    
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 */
20
package org.gvsig.raster.dataaccess.cache;
21

    
22
import java.io.BufferedInputStream;
23
import java.io.BufferedOutputStream;
24
import java.io.DataInputStream;
25
import java.io.DataOutputStream;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.io.FileOutputStream;
30
import java.io.IOException;
31

    
32
import org.gvsig.raster.RasterLibrary;
33
import org.gvsig.raster.dataset.Band;
34
import org.gvsig.raster.dataset.BandFoundInListException;
35
import org.gvsig.raster.dataset.BandList;
36
import org.gvsig.raster.dataset.GeoRasterWriter;
37
import org.gvsig.raster.dataset.IBuffer;
38
import org.gvsig.raster.dataset.IDataWriter;
39
import org.gvsig.raster.dataset.NotSupportedExtensionException;
40
import org.gvsig.raster.dataset.RasterDataset;
41
import org.gvsig.raster.dataset.RasterDriverException;
42
import org.gvsig.raster.shared.Extent;
43

    
44

    
45
/** 
46
 * Servidor de datos de cach?. Esta clase es la encargada de volcar a disco las p?ginas de cach? y recuperar
47
 * las cuando le son solicitadas. Por ello debe implementar el interfaz ICacheDataSource con dos m?todos
48
 * loadPage y savePage. Ambos a partir del n?mero de p?gina recuperaran o salvaran de/a disco una p?gina. 
49
 * 
50
 * @author Nacho Brodin (nachobrodin@gmail.com)
51
 *
52
 */
53
public class CacheDataServer implements ICacheDataSource{
54
        
55
        /**
56
         * Directorio temporal para la cach?. Si gastamos el mismo que andami este se ocupar? de gestionar su
57
         * destrucci?n al cerrar gvSIG.
58
         */
59
        private String                                 tempDirectoryPath = RasterLibrary.tempCacheDirectoryPath;
60
        private String                                 id = null; //Identificador de fichero.
61
        private int                                        numBand = -1;
62
        private int                                        numPag = -1;
63
         
64
        /**
65
         * Constructor. 
66
         * Crea el identificador para todos los trozos de cach? que se guardar?n en disco. 
67
         * @param id Identificador de fichero. Si este es null se calcula uno autom?ticamente
68
         * @param numBand N?mero de banda
69
         * @param numPag N?mero de p?gina
70
         */
71
        public CacheDataServer(String id, int numBand, int numPag) {
72
                setName(id, numBand, numPag);
73
        }
74

    
75
        /**
76
         * Crea el identificador para todos los trozos de cach? que se guardar?n en disco. 
77
         * @param id Identificador de fichero. Si este es null se calcula uno autom?ticamente
78
         * @param numBand N?mero de banda
79
         * @param numPag N?mero de p?gina
80
         */
81
        public void setName(String id, int numBand, int numPag){
82
                String oldFileName =  tempDirectoryPath + File.separator + this.id;
83
                
84
                this.numBand = numBand;
85
                this.numPag = numPag;
86
                if(id == null)
87
                        this.id = Long.toString(System.currentTimeMillis()) + "-" + numPag + "-" + numBand;
88
                else
89
                        this.id = id + "-" + numPag + "-" + numBand;
90
                
91
                String newFileName =  tempDirectoryPath + File.separator + this.id;
92
                File newFile = new File(newFileName); 
93
                File oldFile = new File(oldFileName);
94
                if(oldFile.exists())
95
                        oldFile.renameTo(newFile);
96
        }
97
        
98
        /* (non-Javadoc)
99
         * @see org.gvsig.fmap.dataaccess.cache.ICacheDataSource#loadPage(int, org.gvsig.fmap.dataaccess.cache.PageBuffer)
100
         */
101
        public void loadPage(PageBandBuffer pageBuffer) {
102
                String inFileName =  tempDirectoryPath + File.separator + id;
103
                                
104
                File file = new File(inFileName);
105
                if(!file.exists())
106
                        return;
107
        
108
                DataInputStream dis;
109
                try {
110
                        dis = new DataInputStream( new BufferedInputStream(new FileInputStream(file)));        
111
                        read(dis, pageBuffer);
112
                dis.close();
113
                }catch (FileNotFoundException e) {
114
                        return;
115
                }catch(IOException ex){
116
                        //TODO: EXCEPTION: Lanzar IO y FileNotFound
117
                        ex.printStackTrace();
118
                return;
119
        } 
120
        }
121

    
122
        /* (non-Javadoc)
123
         * @see org.gvsig.fmap.dataaccess.cache.ICacheDataSource#savePage(int, org.gvsig.fmap.dataaccess.cache.PageBuffer)
124
         */
125
        public void savePage(PageBandBuffer pageBuffer) throws IOException {
126
                createTempDirectory();
127
                String fileName =  tempDirectoryPath + File.separator + id;
128
                
129
                File f = new File(fileName);
130
                DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
131
                save(dos, pageBuffer);
132
        dos.close();
133
        }
134
        
135
        /*
136
         * (non-Javadoc)
137
         * @see org.gvsig.raster.dataaccess.cache.ICacheDataSource#delete()
138
         */
139
        public void delete() {
140
                String fileName =  tempDirectoryPath + File.separator + id;
141
                File f = new File(fileName);
142
                if(f.exists()){
143
                        f.delete();
144
                }
145
        }
146
        
147
        /*
148
         *  (non-Javadoc)
149
         * @see org.gvsig.raster.dataaccess.cache.ICacheDataSource#getPath()
150
         */
151
        public String getPath() {
152
                return tempDirectoryPath + File.separator + id;
153
        }
154
        
155
        /**
156
         * Esta funci?n crea el directorio para temporales y devuelve el nombre de este.
157
         * @return
158
         */
159
        private String createTempDirectory(){
160
                File tempDirectory = new File(tempDirectoryPath);
161
            if (!tempDirectory.exists())
162
                    tempDirectory.mkdir();
163
            return tempDirectoryPath;
164
        }
165
        
166
        //TODO: TEST: Implementar y probar el cacheado para tipos de datos != de byte
167
        /**
168
         * Tilea un raster en disco para que sea accesible por la cach?.
169
         * @param fileName Nombre del fichero a tilear
170
         * @param pageLines N?mero de l?neas de cada tile
171
         * @throws IOException
172
         * @throws RasterDriverException 
173
         * @throws NotSupportedExtensionException 
174
         */
175
        public void cachear(String fileName, int pageLines)throws IOException, NotSupportedExtensionException, RasterDriverException{
176
                if(id == null)
177
                        id = Long.toString(System.currentTimeMillis());
178
                
179
                RasterDataset grf = RasterDataset.openFile(null, fileName);
180
                
181
                //Creamos un BandList con todas las bandas del fichero
182
                BandList bandList = new BandList();
183
                for(int i = 0; i < grf.getBandCount();i++){
184
                        try{
185
                                Band band = new Band(grf.getFName(), i, grf.getDataType());
186
                                bandList.addBand(band, i);
187
                                bandList.addDrawableBand(i, i);
188
                        }catch(BandFoundInListException ex){
189
                                //No a?adimos la banda
190
                        }
191
                }
192

    
193
                int pages = (int)Math.ceil(grf.getHeight() / pageLines);
194
        
195
                createTempDirectory();
196
                
197
                PageBandBuffer pageBuffer = new PageBandBuffer(grf.getDataType(), grf.getWidth(), pageLines, grf.getBandCount(), true, 0);
198
                int y = 0;
199
                for(int i = 0; i < pages; i++){
200
                        grf.getWindowRaster(0, y, grf.getWidth(), pageLines, bandList, pageBuffer);
201
                        String outFileName =  tempDirectoryPath + File.separator + id + "-" + i;
202
                                                
203
                        File f = new File(outFileName);
204
                        DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
205
                        save(dos, pageBuffer);
206
            dos.close();
207
                        y += pageLines;
208
                }
209
                
210
                //Solo para pruebas
211
                //convertFromByteFileToTif(grf, pageBuffer, pageLines);
212
        }
213
        
214
        /**
215
         * Funci?n para pruebas.
216
         * Convierte los ficheros generados por la funci?n cachear en ficheros tif para comprobar que est?n
217
         * bien generados.
218
         * @param grf
219
         * @param pageBuffer
220
         * @param pageLines
221
         * @throws IOException
222
         */
223
        private void convertFromByteFileToTif(RasterDataset grf, PageBandBuffer pageBuffer, int pageLines)throws IOException{
224
                int w = pageBuffer.getWidth();
225
                int h = pageBuffer.getHeight();
226
                int pages = (int)Math.ceil(grf.getHeight() / pageLines);
227
                
228
                GeoRasterWriter grw = null;
229
                PageBandBuffer pageBuffer2 = new PageBandBuffer(grf.getDataType(), grf.getWidth(), pageLines, grf.getBandCount(), true, 0);
230
                for(int i = 0; i < pages; i++){
231
                        String inFileName =  tempDirectoryPath + File.separator + id + "-" + i;
232
                        File f = new File(inFileName);
233
                        DataInputStream dis = new DataInputStream( new BufferedInputStream(new FileInputStream(f)));
234
                        byte[] b;
235
            switch(pageBuffer.getDataType()){
236
            case 0:        b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
237
                            dis.readFully(b);
238
                            for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
239
                                            for(int line = 0; line < pageBuffer.getHeight(); line ++){
240
                                                            byte[] linea = new byte[w];
241
                                                            for(int d = 0; d < linea.length; d ++)
242
                                                                    linea[d] = b[(iBand * w * h) + (line * w) + d];
243
                                                            pageBuffer2.setLineInBandByte(linea, line, iBand);
244
                                            }
245
                            }
246
                                    break;                
247
            }
248
            dis.close();
249
            IDataWriter dataWriter1 = new WriterBufferServer(pageBuffer2);
250
            grw = GeoRasterWriter.getWriter(dataWriter1, 
251
                                                                                        inFileName + ".tif", 
252
                                                                                        pageLines, //Block size 
253
                                                                                        pageBuffer2.getBandCount(),
254
                                                                                        new Extent(0, 0, pageBuffer2.getWidth() - 1, pageBuffer2.getHeight() - 1), 
255
                                                                                        0, 
256
                                                                                        pageBuffer2.getWidth(), 
257
                                                                                        pageBuffer2.getHeight(), 
258
                                                                                        pageBuffer2.getDataType());
259
            grw.dataWrite();
260
                        grw.writeClose();
261
                }
262
        }
263
        
264
        /**
265
         * Salva un PageBuffer sobre un stream DataOutpuStream dependiendo del tipo de dato del 
266
         * buffer.
267
         * @param dos DataOutputStream 
268
         * @param pageBuffer PageBuffer
269
         * @throws IOException
270
         */
271
        private void save(DataOutputStream dos, PageBandBuffer pageBuffer) throws IOException{
272
                switch(pageBuffer.getDataType()){
273
        case IBuffer.TYPE_BYTE:        
274
                for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++)
275
                        for(int line = 0; line < pageBuffer.getHeight(); line ++)
276
                                //for(int col = 0; col < pageBuffer.getWidth(); col ++)
277
                                                //dos.writeByte(pageBuffer.getElemByte(line, col, iBand));
278
                                dos.write(pageBuffer.getLineFromBandByte(line, iBand));
279
                break;                
280
        case IBuffer.TYPE_SHORT:        
281
                    for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++)
282
                                for(int line = 0; line < pageBuffer.getHeight(); line ++)
283
                                        for(int col = 0; col < pageBuffer.getWidth(); col ++)
284
                                                dos.writeShort(pageBuffer.getElemShort(line, col, iBand));
285
                        break;
286
        case IBuffer.TYPE_INT:        
287
                    for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++)
288
                                for(int line = 0; line < pageBuffer.getHeight(); line ++)
289
                                        for(int col = 0; col < pageBuffer.getWidth(); col ++)
290
                                                dos.writeInt(pageBuffer.getElemInt(line, col, iBand));
291
                        break;
292
        case IBuffer.TYPE_FLOAT:        
293
                    for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++)
294
                                for(int line = 0; line < pageBuffer.getHeight(); line ++)
295
                                        for(int col = 0; col < pageBuffer.getWidth(); col ++)
296
                                                dos.writeFloat(pageBuffer.getElemFloat(line, col, iBand));
297
                        break;
298
        case IBuffer.TYPE_DOUBLE:        
299
                    for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++)
300
                                for(int line = 0; line < pageBuffer.getHeight(); line ++)
301
                                        for(int col = 0; col < pageBuffer.getWidth(); col ++)
302
                                                dos.writeDouble(pageBuffer.getElemDouble(line, col, iBand));
303
                        break;
304
                        
305
        }
306
        }
307
        
308
        /**
309
         * Carga un PageBuffer desde un stream DataInputStream dependiendo del tipo de dato del 
310
         * buffer.
311
         * @param dis DataInputStream
312
         * @param pageBuffer PageBuffer
313
         * @throws IOException
314
         */
315
        private void read(DataInputStream dis, PageBandBuffer pageBuffer) throws IOException{
316
                int w = pageBuffer.getWidth();
317
                int h = pageBuffer.getHeight();
318
                int wxh = w * h;
319
                int j = 0;
320
                switch(pageBuffer.getDataType()){
321
                case IBuffer.TYPE_BYTE:        
322
                        byte[] b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
323
                        dis.readFully(b);
324
                        //while(j < b.length){ b[j] = dis.readByte(); j ++; }
325
                        for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
326
                                        for(int line = 0; line < pageBuffer.getHeight(); line ++){
327
                                                        byte[] linea = new byte[w];
328
                                                        for(int d = 0; d < linea.length; d ++)
329
                                                                linea[d] = b[(iBand * wxh) + (line * w) + d];
330
                                                        pageBuffer.setLineInBandByte(linea, line, iBand);
331
                                        }
332
                        }
333
                                break;
334
                case IBuffer.TYPE_SHORT:
335
                        short[] s = new short[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
336
                        while(j < s.length){ s[j] = dis.readShort(); j ++; }
337
                        for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
338
                                        for(int line = 0; line < pageBuffer.getHeight(); line ++){
339
                                                        short[] linea = new short[w];
340
                                                        for(int x = 0; x < linea.length; x ++)
341
                                                                linea[x] = s[(iBand * wxh) + (line * w) + x];
342
                                                        pageBuffer.setLineInBandShort(linea, line, iBand);
343
                                        }
344
                        }
345
                                break;
346
                case IBuffer.TYPE_INT:
347
                        int[] i = new int[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
348
                        while(j < i.length){ i[j] = dis.readInt(); j ++; }
349
                        for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
350
                                        for(int line = 0; line < pageBuffer.getHeight(); line ++){
351
                                                        int[] linea = new int[w];
352
                                                        for(int x = 0; x < linea.length; x ++)
353
                                                                linea[x] = i[(iBand * wxh) + (line * w) + x];
354
                                                        pageBuffer.setLineInBandInt(linea, line, iBand);
355
                                        }
356
                        }
357
                                break;
358
                case IBuffer.TYPE_FLOAT:
359
                        float[] f = new float[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
360
                        while(j < f.length){ f[j] = dis.readFloat(); j ++; }
361
                        for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
362
                                        for(int line = 0; line < pageBuffer.getHeight(); line ++){
363
                                                        float[] linea = new float[w];
364
                                                        for(int x = 0; x < linea.length; x ++)
365
                                                                linea[x] = f[(iBand * wxh) + (line * w) + x];
366
                                                        pageBuffer.setLineInBandFloat(linea, line, iBand);
367
                                        }
368
                        }
369
                                break;
370
                case IBuffer.TYPE_DOUBLE:
371
                        double[] d = new double[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
372
                        while(j < d.length){ d[j] = dis.readDouble(); j ++; }
373
                        for(int iBand = 0; iBand < pageBuffer.getBandCount(); iBand ++){
374
                                        for(int line = 0; line < pageBuffer.getHeight(); line ++){
375
                                                        double[] linea = new double[w];
376
                                                        for(int x = 0; x < linea.length; x ++)
377
                                                                linea[x] = d[(iBand * wxh) + (line * w) + x];
378
                                                        pageBuffer.setLineInBandDouble(linea, line, iBand);
379
                                        }
380
                        }
381
                                break;
382
                }
383
        }
384
        
385
        //---------------------------------------------------------------
386
        //TILEADO A BASE DE TIFF: Desechado porque es muy lento
387
        
388
        /*public void loadPage(int nPag, PageBuffer pageBuffer) {
389
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
390
                File file = new File(id);
391
                if(!file.exists())
392
                        return; //El trozo no ha sido volcado a disco por lo que no se carga.
393
                
394
                GeoRasterFile grf = GeoRasterFile.openFile(null, fileName);
395
                
396
                //Creamos un BandList con todas las bandas del fichero
397
                BandList bandList = new BandList();
398
                for(int i = 0; i < grf.getBandCount();i++){
399
                        try{
400
                                Band band = new Band(grf.getName(), i, grf.getDataType());
401
                                bandList.addBand(band, i);
402
                        }catch(BandFoundInListException ex){
403
                                //No a?adimos la banda
404
                        }
405
                }
406
                grf.getWindowRaster(0, 0, grf.getWidth(), grf.getHeight(), bandList, pageBuffer);
407
        }*/
408

    
409
        
410
        /*public void savePage(int nPag, PageBuffer pageBuffer) throws IOException {
411
                createTempDirectory();
412
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
413
                IDataWriter dataWriter = new WriterBufferServer(pageBuffer);
414
                GeoRasterWriter grw = GeoRasterWriter.getWriter(dataWriter, 
415
                                                                                                                fileName, 
416
                                                                                                                pageBuffer.getHeight(), //Block size 
417
                                                                                                                pageBuffer.getBandCount(),
418
                                                                                                                new Extent(0, 0, pageBuffer.getWidth() - 1, pageBuffer.getHeight() - 1), 
419
                                                                                                                0, 
420
                                                                                                                pageBuffer.getWidth(), 
421
                                                                                                                pageBuffer.getHeight(), 
422
                                                                                                                pageBuffer.getDataType());
423
                grw.dataWrite();
424
                grw.writeClose();
425
                
426
        }*/
427
}
428