Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / cache / CacheDataServer.java @ 12899

History | View | Annotate | Download (16.1 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.buffer.cache;
21

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

    
33
import org.gvsig.raster.RasterLibrary;
34
import org.gvsig.raster.dataset.Band;
35
import org.gvsig.raster.dataset.BandList;
36
import org.gvsig.raster.dataset.BandNotFoundInListException;
37
import org.gvsig.raster.dataset.GeoRasterWriter;
38
import org.gvsig.raster.dataset.IBuffer;
39
import org.gvsig.raster.dataset.IDataWriter;
40
import org.gvsig.raster.dataset.NotSupportedExtensionException;
41
import org.gvsig.raster.dataset.Params;
42
import org.gvsig.raster.dataset.RasterDataset;
43
import org.gvsig.raster.dataset.RasterDriverException;
44

    
45

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

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

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

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

    
419
        
420
        /*public void savePage(int nPag, PageBuffer pageBuffer) throws IOException {
421
                createTempDirectory();
422
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
423
                IDataWriter dataWriter = new WriterBufferServer(pageBuffer);
424
                GeoRasterWriter grw = GeoRasterWriter.getWriter(dataWriter, 
425
                                                                                                                fileName, 
426
                                                                                                                pageBuffer.getHeight(), //Block size 
427
                                                                                                                pageBuffer.getBandCount(),
428
                                                                                                                new Extent(0, 0, pageBuffer.getWidth() - 1, pageBuffer.getHeight() - 1), 
429
                                                                                                                0, 
430
                                                                                                                pageBuffer.getWidth(), 
431
                                                                                                                pageBuffer.getHeight(), 
432
                                                                                                                pageBuffer.getDataType());
433
                grw.dataWrite();
434
                grw.writeClose();
435
                
436
        }*/
437
}
438