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 / buffer / cache / CacheDataServer.java @ 2623

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

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

    
36
import org.gvsig.fmap.dal.coverage.RasterLocator;
37
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
38
import org.gvsig.fmap.dal.coverage.datastruct.Params;
39
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
40
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
41
import org.gvsig.fmap.dal.coverage.exception.QueryException;
42
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
43
import org.gvsig.fmap.dal.coverage.store.DataServerWriter;
44
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
45
import org.gvsig.fmap.dal.coverage.store.RasterWriter;
46
import org.gvsig.fmap.dal.coverage.util.FileUtils;
47
import org.gvsig.raster.impl.DefaultRasterManager;
48
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
49
import org.gvsig.raster.impl.store.DefaultRasterStore;
50
import org.gvsig.raster.impl.store.ParamImpl;
51

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

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

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

    
93
                if (id == null)
94
                        this.id = Long.toString(System.currentTimeMillis()) + "-" + numPag + "-" + numBand;
95
                else
96
                        this.id = id + "-" + numPag + "-" + numBand;
97

    
98
                String newFileName = tempDirectoryPath + File.separator + this.id;
99
                File newFile = new File(newFileName);
100
                File oldFile = new File(oldFileName);
101
                if (oldFile.exists())
102
                        oldFile.renameTo(newFile);
103
        }
104
        
105
        /* (non-Javadoc)
106
         * @see org.gvsig.fmap.dataaccess.cache.ICacheDataSource#loadPage(int, org.gvsig.fmap.dataaccess.cache.PageBuffer)
107
         */
108
        public void loadPage(PageBandBuffer pageBuffer) {
109
                String inFileName = tempDirectoryPath + File.separator + id;
110

    
111
                File file = new File(inFileName);
112
                if (!file.exists())
113
                        return;
114

    
115
                DataInputStream dis;
116
                try {
117
                        dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
118
                        read(dis, pageBuffer);
119
                        dis.close();
120
                } catch (FileNotFoundException e) {
121
                        return;
122
                } catch (IOException ex) {
123
                        // TODO: EXCEPTION: Lanzar IO y FileNotFound
124
                        ex.printStackTrace();
125
                        return;
126
                } 
127
        }
128

    
129
        public void savePage(PageBandBuffer pageBuffer) throws IOException {
130
                tempDirectoryPath = file.getTemporalPath();
131
                String fileName = tempDirectoryPath + File.separator + id;
132

    
133
                File f = new File(fileName);
134
                DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
135
                save(dos, pageBuffer);
136
                dos.close();
137
        }
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
        public String getPath() {
148
                return tempDirectoryPath + File.separator + id;
149
        }
150
        
151
        //TODO: TEST: Implementar y probar el cacheado para tipos de datos != de byte
152
        /**
153
         * Tilea un raster en disco para que sea accesible por la cach?.
154
         * @param fileName Nombre del fichero a tilear
155
         * @param pageLines N?mero de l?neas de cada tile
156
         * @throws IOException
157
         * @throws RasterDriverException 
158
         * @throws NotSupportedExtensionException 
159
         * @throws QueryException 
160
         */
161
        public void cachear(String fileName, int pageLines)
162
                        throws IOException, NotSupportedExtensionException, RasterDriverException, ProcessInterruptedException, QueryException {
163
                if (id == null)
164
                        id = Long.toString(System.currentTimeMillis());
165

    
166
                AbstractRasterProvider provider = AbstractRasterProvider.singleDatasetInstance(null, fileName);
167

    
168
                int pages = (int) Math.ceil(provider.getHeight() / pageLines);
169

    
170
                tempDirectoryPath = file.getTemporalPath();
171

    
172
                //PageBandBuffer pageBuffer = new PageBandBuffer(provider.getDataType()[0], (int)provider.getWidth(), pageLines, provider.getBandCount(), true, 0);
173
                Buffer pageBuffer = null;
174
                DefaultRasterStore store = new DefaultRasterStore();
175
                store.setProvider(provider);
176
                int y = 0;
177
                for (int i = 0; i < pages; i++) {
178
                        RasterQuery q = RasterLocator.getManager().createQuery();
179
                        q.setAreaOfInterest(new Rectangle((int)0, y, (int)provider.getWidth(), pageLines));
180
                        q.setAllDrawableBands();
181
                        pageBuffer = store.query(q);
182
                        
183
                        //grf.getWindow(0, y, pageBuffer.getWidth(), pageBuffer.getHeight(), bandList, pageBuffer);
184
                        String outFileName = tempDirectoryPath + File.separator + id + "-" + i;
185

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

    
212
                RasterWriter grw = null;
213
                PageBandBuffer pageBuffer2 = new PageBandBuffer(grf.getDataType()[0], (int)grf.getWidth(), pageLines, grf.getBandCount(), true, 0);
214
                for (int i = 0; i < pages; i++) {
215
                        String inFileName = tempDirectoryPath + File.separator + id + "-" + i;
216
                        File f = new File(inFileName);
217
                        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
218
                        byte[] b;
219
                        switch (pageBuffer.getDataType()) {
220
                                case 0:
221
                                        b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
222
                                        dis.readFully(b);
223
                                        for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
224
                                                for (int line = 0; line < pageBuffer.getHeight(); line++) {
225
                                                        byte[] linea = new byte[w];
226
                                                        for (int d = 0; d < linea.length; d++)
227
                                                                linea[d] = b[(iBand * w * h) + (line * w) + d];
228
                                                        pageBuffer2.setLineInBandByte(linea, line, iBand);
229
                                                }
230
                                        }
231
                                        break;
232
                        }
233
                        dis.close();
234
                        DataServerWriter dataWriter1 = new WriterBufferCompleteServer(pageBuffer2);
235
                        try {
236
                                RasterWriter writer = DefaultRasterManager.getInstance().createWriter(inFileName + ".tif");
237
                                Params params = writer.getParams();
238
                                int newPosBlockSize = 7;
239
                                ParamImpl p = (ParamImpl)params.getParamById("blocksize");
240
                                for (int j = 0; j < p.getList().length; j++) {
241
                                        if (p.getList()[i].equals(String.valueOf(pageLines)))
242
                                                newPosBlockSize = j;
243
                                }
244
                                params.changeParamValue("blocksize", new Integer(newPosBlockSize));
245
                                grw = DefaultRasterManager.getInstance().createWriter(dataWriter1, 
246
                                                                                                inFileName + ".tif", 
247
                                                                                                pageBuffer2.getBandCount(),
248
                                                                                                new AffineTransform(),
249
                                                                                                pageBuffer2.getWidth(), 
250
                                                                                                pageBuffer2.getHeight(), 
251
                                                                                                pageBuffer2.getDataType(), 
252
                                                                                                params,
253
                                                                                                null);
254
                        } catch (NotSupportedExtensionException e) {
255
                                e.printStackTrace();
256
                        } catch (RasterDriverException e) {
257
                                e.printStackTrace();
258
                        }
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, Buffer pageBuffer) throws IOException {
272
                switch (pageBuffer.getDataType()) {
273
                        case Buffer.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 Buffer.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 Buffer.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 Buffer.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 Buffer.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
         * Carga un PageBuffer desde un stream DataInputStream dependiendo del tipo de dato del 
309
         * buffer.
310
         * @param dis DataInputStream
311
         * @param pageBuffer PageBuffer
312
         * @throws IOException
313
         */
314
        private void read(DataInputStream dis, PageBandBuffer pageBuffer) throws IOException {
315
                int w = pageBuffer.getWidth();
316
                int h = pageBuffer.getHeight();
317
                int wxh = w * h;
318
                int j = 0;
319
                switch (pageBuffer.getDataType()) {
320
                        case Buffer.TYPE_BYTE:
321
                                byte[] b = new byte[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
322
                                dis.readFully(b);
323
                                // while(j < b.length){ b[j] = dis.readByte(); j ++; }
324
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
325
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
326
                                                byte[] linea = new byte[w];
327
                                                for (int d = 0; d < linea.length; d++)
328
                                                        linea[d] = b[(iBand * wxh) + (line * w) + d];
329
                                                pageBuffer.setLineInBandByte(linea, line, iBand);
330
                                        }
331
                                }
332
                                break;
333
                        case Buffer.TYPE_SHORT:
334
                                short[] s = new short[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
335
                                while (j < s.length) {
336
                                        s[j] = dis.readShort();
337
                                        j++;
338
                                }
339
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
340
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
341
                                                short[] linea = new short[w];
342
                                                for (int x = 0; x < linea.length; x++)
343
                                                        linea[x] = s[(iBand * wxh) + (line * w) + x];
344
                                                pageBuffer.setLineInBandShort(linea, line, iBand);
345
                                        }
346
                                }
347
                                break;
348
                        case Buffer.TYPE_INT:
349
                                int[] i = new int[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
350
                                while (j < i.length) {
351
                                        i[j] = dis.readInt();
352
                                        j++;
353
                                }
354
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
355
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
356
                                                int[] linea = new int[w];
357
                                                for (int x = 0; x < linea.length; x++)
358
                                                        linea[x] = i[(iBand * wxh) + (line * w) + x];
359
                                                pageBuffer.setLineInBandInt(linea, line, iBand);
360
                                        }
361
                                }
362
                                break;
363
                        case Buffer.TYPE_FLOAT:
364
                                float[] f = new float[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
365
                                while (j < f.length) {
366
                                        f[j] = dis.readFloat();
367
                                        j++;
368
                                }
369
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
370
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
371
                                                float[] linea = new float[w];
372
                                                for (int x = 0; x < linea.length; x++)
373
                                                        linea[x] = f[(iBand * wxh) + (line * w) + x];
374
                                                pageBuffer.setLineInBandFloat(linea, line, iBand);
375
                                        }
376
                                }
377
                                break;
378
                        case Buffer.TYPE_DOUBLE:
379
                                double[] d = new double[pageBuffer.getWidth() * pageBuffer.getHeight() * pageBuffer.getBandCount()];
380
                                while (j < d.length) {
381
                                        d[j] = dis.readDouble();
382
                                        j++;
383
                                }
384
                                for (int iBand = 0; iBand < pageBuffer.getBandCount(); iBand++) {
385
                                        for (int line = 0; line < pageBuffer.getHeight(); line++) {
386
                                                double[] linea = new double[w];
387
                                                for (int x = 0; x < linea.length; x++)
388
                                                        linea[x] = d[(iBand * wxh) + (line * w) + x];
389
                                                pageBuffer.setLineInBandDouble(linea, line, iBand);
390
                                        }
391
                                }
392
                                break;
393
                }
394
        }
395
        
396
        //---------------------------------------------------------------
397
        //TILEADO A BASE DE TIFF: Desechado porque es muy lento
398
        
399
        /*public void loadPage(int nPag, PageBuffer pageBuffer) {
400
                String fileName =  tempDirectoryPath + File.separator + id + "-" + nPag + ".tif";
401
                File file = new File(id);
402
                if(!file.exists())
403
                        return; //El trozo no ha sido volcado a disco por lo que no se carga.
404
                
405
                GeoRasterFile grf = GeoRasterFile.openFile(null, fileName);
406
                
407
                //Creamos un BandList con todas las bandas del fichero
408
                BandList bandList = new BandList();
409
                for(int i = 0; i < grf.getBandCount();i++){
410
                        try{
411
                                Band band = new Band(grf.getName(), i, grf.getDataType());
412
                                bandList.addBand(band, i);
413
                        }catch(BandFoundInListException ex){
414
                                //No a?adimos la banda
415
                        }
416
                }
417
                grf.getWindowRaster(0, 0, grf.getWidth(), grf.getHeight(), bandList, pageBuffer);
418
        }*/
419

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