Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / cache / CacheDataServer.java @ 27361

History | View | Annotate | Download (17 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.buffer.cache;
20

    
21
import java.awt.geom.AffineTransform;
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.BandList;
35
import org.gvsig.raster.dataset.BandNotFoundInListException;
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.Params;
41
import org.gvsig.raster.dataset.RasterDataset;
42
import org.gvsig.raster.dataset.Params.Param;
43
import org.gvsig.raster.dataset.io.RasterDriverException;
44
import org.gvsig.raster.process.RasterTask;
45
import org.gvsig.raster.process.RasterTaskQueue;
46

    
47
/**
48
 * Servidor de datos de cach?. Esta clase es la encargada de volcar a disco las
49
 * p?ginas de cach? y recuperar las cuando le son solicitadas. Por ello debe
50
 * implementar el interfaz ICacheDataSource con dos m?todos loadPage y savePage.
51
 * 
52
 * Ambos a partir del n?mero de p?gina recuperaran o salvaran de/a disco una p?gina.
53
 * 
54
 * @author Nacho Brodin (nachobrodin@gmail.com)
55
 */
56
public class CacheDataServer implements ICacheDataSource {
57
        
58
        /**
59
         * Directorio temporal para la cach?. Si gastamos el mismo que andami este se ocupar? de gestionar su
60
         * destrucci?n al cerrar gvSIG.
61
         */
62
        private String tempDirectoryPath;
63
        private String id = null;        // Identificador de fichero.
64

    
65
         
66
        /**
67
         * Constructor. 
68
         * Crea el identificador para todos los trozos de cach? que se guardar?n en disco. 
69
         * @param id Identificador de fichero. Si este es null se calcula uno autom?ticamente
70
         * @param numBand N?mero de banda
71
         * @param numPag N?mero de p?gina
72
         */
73
        public CacheDataServer(String id, int numBand, int numPag) {
74
                tempDirectoryPath = RasterLibrary.getTemporalPath();
75
                setName(id, numBand, numPag);
76
        }
77

    
78
        /**
79
         * Crea el identificador para todos los trozos de cach? que se guardar?n en disco. 
80
         * @param id Identificador de fichero. Si este es null se calcula uno autom?ticamente
81
         * @param numBand N?mero de banda
82
         * @param numPag N?mero de p?gina
83
         */
84
        public void setName(String id, int numBand, int numPag) {
85
                String oldFileName = tempDirectoryPath + File.separator + this.id;
86

    
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) throws InterruptedException {
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, InterruptedException {
127
                tempDirectoryPath = RasterLibrary.getTemporalPath();
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
        //TODO: TEST: Implementar y probar el cacheado para tipos de datos != de byte
157
        /**
158
         * Tilea un raster en disco para que sea accesible por la cach?.
159
         * @param fileName Nombre del fichero a tilear
160
         * @param pageLines N?mero de l?neas de cada tile
161
         * @throws IOException
162
         * @throws RasterDriverException 
163
         * @throws NotSupportedExtensionException 
164
         */
165
        public void cachear(String fileName, int pageLines)throws IOException, NotSupportedExtensionException, RasterDriverException, InterruptedException{
166
                if (id == null)
167
                        id = Long.toString(System.currentTimeMillis());
168

    
169
                RasterDataset grf = RasterDataset.open(null, fileName);
170

    
171
                // Creamos un BandList con todas las bandas del fichero
172
                BandList bandList = new BandList();
173
                for (int i = 0; i < grf.getBandCount(); i++) {
174
                        try {
175
                                Band band = new Band(grf.getFName(), i, grf.getDataType()[i]);
176
                                bandList.addBand(band, i);
177
                                bandList.addDrawableBand(i, i);
178
                        } catch (BandNotFoundInListException ex) {
179
                                // No a?adimos la banda
180
                        }
181
                }
182

    
183
                int pages = (int) Math.ceil(grf.getHeight() / pageLines);
184

    
185
                tempDirectoryPath = RasterLibrary.getTemporalPath();
186

    
187
                PageBandBuffer pageBuffer = new PageBandBuffer(grf.getDataType()[0], grf.getWidth(), pageLines, grf.getBandCount(), true, 0);
188
                int y = 0;
189
                for (int i = 0; i < pages; i++) {
190
                        grf.getWindowRaster(0, y, grf.getWidth(), pageLines, bandList, pageBuffer);
191
                        String outFileName = tempDirectoryPath + File.separator + id + "-" + i;
192

    
193
                        File f = new File(outFileName);
194
                        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
195
                        save(dos, pageBuffer);
196
                        dos.close();
197
                        y += pageLines;
198
                }
199
                
200
                //Solo para pruebas
201
                //convertFromByteFileToTif(grf, pageBuffer, pageLines);
202
        }
203
        
204
        /**
205
         * Funci?n para pruebas.
206
         * Convierte los ficheros generados por la funci?n cachear en ficheros tif para comprobar que est?n
207
         * bien generados.
208
         * @param grf
209
         * @param pageBuffer
210
         * @param pageLines
211
         * @throws IOException
212
         * @deprecated Este m?todo no se usa pero es necesario para testeo
213
         */
214
        public void convertFromByteFileToTif(RasterDataset grf, PageBandBuffer pageBuffer, int pageLines)throws IOException, InterruptedException {
215
                int w = pageBuffer.getWidth();
216
                int h = pageBuffer.getHeight();
217
                int pages = (int) Math.ceil(grf.getHeight() / pageLines);
218

    
219
                GeoRasterWriter grw = null;
220
                PageBandBuffer pageBuffer2 = new PageBandBuffer(grf.getDataType()[0], grf.getWidth(), pageLines, grf.getBandCount(), true, 0);
221
                for (int i = 0; i < pages; i++) {
222
                        String inFileName = tempDirectoryPath + File.separator + id + "-" + i;
223
                        File f = new File(inFileName);
224
                        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
225
                        byte[] b;
226
                        switch (pageBuffer.getDataType()) {
227
                                case 0:
228
                                        b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
229
                                        dis.readFully(b);
230
                                        for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
231
                                                for (int line = 0; line < pageBuffer.getHeight(); line++) {
232
                                                        byte[] linea = new byte[w];
233
                                                        for (int d = 0; d < linea.length; d++)
234
                                                                linea[d] = b[(iBand * w * h) + (line * w) + d];
235
                                                        pageBuffer2.setLineInBandByte(linea, line, iBand);
236
                                                }
237
                                        }
238
                                        break;
239
                        }
240
                        dis.close();
241
                        IDataWriter dataWriter1 = new WriterBufferCompleteServer(pageBuffer2);
242
                        try {
243
                                GeoRasterWriter writer = GeoRasterWriter.getWriter(inFileName + ".tif");
244
                                Params params = writer.getParams();
245
                                int newPosBlockSize = 7;
246
                                Param p = params.getParamById("blocksize");
247
                                for (int j = 0; j < p.list.length; j++) {
248
                                        if (p.list[i].equals(String.valueOf(pageLines)))
249
                                                newPosBlockSize = j;
250
                                }
251
                                params.changeParamValue("blocksize", new Integer(newPosBlockSize));
252
                                grw = GeoRasterWriter.getWriter(dataWriter1, 
253
                                                                                                inFileName + ".tif", 
254
                                                                                                pageBuffer2.getBandCount(),
255
                                                                                                new AffineTransform(),
256
                                                                                                pageBuffer2.getWidth(), 
257
                                                                                                pageBuffer2.getHeight(), 
258
                                                                                                pageBuffer2.getDataType(), 
259
                                                                                                params,
260
                                                                                                null);
261
                        } catch (NotSupportedExtensionException e) {
262
                                e.printStackTrace();
263
                        } catch (RasterDriverException e) {
264
                                e.printStackTrace();
265
                        }
266
                        grw.dataWrite();
267
                        grw.writeClose();
268
                }
269
        }
270
        
271
        /**
272
         * Salva un PageBuffer sobre un stream DataOutpuStream dependiendo del tipo de dato del 
273
         * buffer.
274
         * @param dos DataOutputStream 
275
         * @param pageBuffer PageBuffer
276
         * @throws IOException
277
         * @throws InterruptedException 
278
         */
279
        private void save(DataOutputStream dos, PageBandBuffer pageBuffer) throws IOException, InterruptedException {
280
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
281
                switch (pageBuffer.getDataType()) {
282
                        case IBuffer.TYPE_BYTE:
283
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
284
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
285
//                                                for(int col = 0; col < pageBuffer.getWidth(); col ++)
286
//                                                        dos.writeByte(pageBuffer.getElemByte(line, col, iBand));
287
                                                dos.write(pageBuffer.getLineFromBandByte(line, iBand));
288
                                                if(task.getEvent() != null)
289
                                                        task.manageEvent(task.getEvent());
290
                                        }
291
                                }
292
                                break;
293
                        case IBuffer.TYPE_SHORT:
294
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++)
295
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
296
                                                for (int col = 0; col < pageBuffer.getWidth(); col++)
297
                                                        dos.writeShort(pageBuffer.getElemShort(line, col, iBand));
298
                                                if(task.getEvent() != null)
299
                                                        task.manageEvent(task.getEvent());
300
                                        }
301
                                break;
302
                        case IBuffer.TYPE_INT:
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.writeInt(pageBuffer.getElemInt(line, col, iBand));
307
                                                if(task.getEvent() != null)
308
                                                        task.manageEvent(task.getEvent());
309
                                        }
310
                                break;
311
                        case IBuffer.TYPE_FLOAT:
312
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++)
313
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
314
                                                for (int col = 0; col < pageBuffer.getWidth(); col++)
315
                                                        dos.writeFloat(pageBuffer.getElemFloat(line, col, iBand));
316
                                                if(task.getEvent() != null)
317
                                                        task.manageEvent(task.getEvent());
318
                                        }
319
                                break;
320
                        case IBuffer.TYPE_DOUBLE:
321
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++)
322
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
323
                                                for (int col = 0; col < pageBuffer.getWidth(); col++)
324
                                                        dos.writeDouble(pageBuffer.getElemDouble(line, col, iBand));
325
                                                if(task.getEvent() != null)
326
                                                        task.manageEvent(task.getEvent());
327
                                        }
328
                                break;
329
                }
330
        }
331
        
332
        /**
333
         * Carga un PageBuffer desde un stream DataInputStream dependiendo del tipo de dato del 
334
         * buffer.
335
         * @param dis DataInputStream
336
         * @param pageBuffer PageBuffer
337
         * @throws IOException
338
         * @throws InterruptedException 
339
         */
340
        private void read(DataInputStream dis, PageBandBuffer pageBuffer) throws IOException, InterruptedException {
341
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
342
                int w = pageBuffer.getWidth();
343
                int h = pageBuffer.getHeight();
344
                int wxh = w * h;
345
                int j = 0;
346
                switch (pageBuffer.getDataType()) {
347
                        case IBuffer.TYPE_BYTE:
348
                                byte[] b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
349
                                dis.readFully(b);
350
                                // while(j < b.length){ b[j] = dis.readByte(); j ++; }
351
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
352
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
353
                                                byte[] linea = new byte[w];
354
                                                for (int d = 0; d < linea.length; d++)
355
                                                        linea[d] = b[(iBand * wxh) + (line * w) + d];
356
                                                pageBuffer.setLineInBandByte(linea, line, iBand);
357
                                        }
358
                                        if(task.getEvent() != null)
359
                                                task.manageEvent(task.getEvent());
360
                                }
361
                                break;
362
                        case IBuffer.TYPE_SHORT:
363
                                short[] s = new short[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
364
                                while (j < s.length) {
365
                                        s[j] = dis.readShort();
366
                                        j++;
367
                                }
368
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
369
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
370
                                                short[] linea = new short[w];
371
                                                for (int x = 0; x < linea.length; x++)
372
                                                        linea[x] = s[(iBand * wxh) + (line * w) + x];
373
                                                pageBuffer.setLineInBandShort(linea, line, iBand);
374
                                        }
375
                                        if(task.getEvent() != null)
376
                                                task.manageEvent(task.getEvent());
377
                                }
378
                                break;
379
                        case IBuffer.TYPE_INT:
380
                                int[] i = new int[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
381
                                while (j < i.length) {
382
                                        i[j] = dis.readInt();
383
                                        j++;
384
                                }
385
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
386
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
387
                                                int[] linea = new int[w];
388
                                                for (int x = 0; x < linea.length; x++)
389
                                                        linea[x] = i[(iBand * wxh) + (line * w) + x];
390
                                                pageBuffer.setLineInBandInt(linea, line, iBand);
391
                                        }
392
                                        if(task.getEvent() != null)
393
                                                task.manageEvent(task.getEvent());
394
                                }
395
                                break;
396
                        case IBuffer.TYPE_FLOAT:
397
                                float[] f = new float[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
398
                                while (j < f.length) {
399
                                        f[j] = dis.readFloat();
400
                                        j++;
401
                                }
402
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
403
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
404
                                                float[] linea = new float[w];
405
                                                for (int x = 0; x < linea.length; x++)
406
                                                        linea[x] = f[(iBand * wxh) + (line * w) + x];
407
                                                pageBuffer.setLineInBandFloat(linea, line, iBand);
408
                                        }
409
                                        if(task.getEvent() != null)
410
                                                task.manageEvent(task.getEvent());
411
                                }
412
                                break;
413
                        case IBuffer.TYPE_DOUBLE:
414
                                double[] d = new double[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
415
                                while (j < d.length) {
416
                                        d[j] = dis.readDouble();
417
                                        j++;
418
                                }
419
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
420
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
421
                                                double[] linea = new double[w];
422
                                                for (int x = 0; x < linea.length; x++)
423
                                                        linea[x] = d[(iBand * wxh) + (line * w) + x];
424
                                                pageBuffer.setLineInBandDouble(linea, line, iBand);
425
                                        }
426
                                        if(task.getEvent() != null)
427
                                                task.manageEvent(task.getEvent());
428
                                }
429
                                break;
430
                }
431
        }
432
        
433
        //---------------------------------------------------------------
434
        //TILEADO A BASE DE TIFF: Desechado porque es muy lento
435
        
436
        /*public void loadPage(int nPag, PageBuffer pageBuffer) {
437
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
438
                File file = new File(id);
439
                if(!file.exists())
440
                        return; //El trozo no ha sido volcado a disco por lo que no se carga.
441
                
442
                GeoRasterFile grf = GeoRasterFile.openFile(null, fileName);
443
                
444
                //Creamos un BandList con todas las bandas del fichero
445
                BandList bandList = new BandList();
446
                for(int i = 0; i < grf.getBandCount();i++){
447
                        try{
448
                                Band band = new Band(grf.getName(), i, grf.getDataType());
449
                                bandList.addBand(band, i);
450
                        }catch(BandFoundInListException ex){
451
                                //No a?adimos la banda
452
                        }
453
                }
454
                grf.getWindowRaster(0, 0, grf.getWidth(), grf.getHeight(), bandList, pageBuffer);
455
        }*/
456

    
457
        
458
        /*public void savePage(int nPag, PageBuffer pageBuffer) throws IOException {
459
                createTempDirectory();
460
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
461
                IDataWriter dataWriter = new WriterBufferServer(pageBuffer);
462
                GeoRasterWriter grw = GeoRasterWriter.getWriter(dataWriter, 
463
                                                                                                                fileName, 
464
                                                                                                                pageBuffer.getHeight(), //Block size 
465
                                                                                                                pageBuffer.getBandCount(),
466
                                                                                                                new Extent(0, 0, pageBuffer.getWidth() - 1, pageBuffer.getHeight() - 1), 
467
                                                                                                                0, 
468
                                                                                                                pageBuffer.getWidth(), 
469
                                                                                                                pageBuffer.getHeight(), 
470
                                                                                                                pageBuffer.getDataType());
471
                grw.dataWrite();
472
                grw.writeClose();
473
                
474
        }*/
475
}