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 / RasterReadOnlyBuffer.java @ 2438

History | View | Annotate | Download (18.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.Point2D;
26
import java.io.FileNotFoundException;
27

    
28
import org.gvsig.fmap.dal.coverage.RasterLibrary;
29
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
30
import org.gvsig.fmap.dal.coverage.datastruct.Band;
31
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
32
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
33
import org.gvsig.fmap.dal.coverage.exception.FileNotExistsException;
34
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
35
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
36
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
37
import org.gvsig.fmap.dal.coverage.exception.QueryException;
38
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
39
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
40
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
41
import org.gvsig.raster.impl.DefaultRasterManager;
42
import org.gvsig.raster.impl.buffer.RasterBuffer;
43
import org.gvsig.raster.impl.datastruct.ExtentImpl;
44
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
45
import org.gvsig.raster.impl.store.QueryableRaster;
46

    
47
/**
48
 * 
49
 * @author Nacho Brodin (nachobrodin@gmail.com)
50
 *
51
 */
52
public class RasterReadOnlyBuffer extends RasterBuffer {
53
        /**
54
         * Pagina cargada
55
         */
56
        private Buffer            page              = null;
57
        private Buffer            secondPage        = null;
58
        /**
59
         * N?mero de p?gina cargada en Buffer
60
         */
61
        private int                loadedPage       = -1;
62
        private int                loadedSecondPage = -1;
63
        
64

    
65
        private int                heightLastPage   = 0;
66
        
67
        private RasterDataStore   datasource       = null;
68
        
69
        private int                bitsPag          = 0;
70
        /**
71
         * N?mero de p?ginas
72
         */
73
        private int                nPages           = 0;
74
        /**
75
         * Lista de bandas
76
         */
77
        private BandList           bandList         = null;
78
        private int[]              drawableBands    = null;
79
        /**
80
         * Extensi?n asociada al buffer
81
         */
82
        private int                minX = 0, minY = 0, maxX = 0, maxY = 0;
83
        /**
84
         * Query para las cargas de p?ginas. Lleva asociado un IRasterDatasource de un raster
85
         * de disco. 
86
         */
87
        private RasterQuery        query            = null;
88
        
89
        
90
        /**
91
         * Para extraer el desplazamiento de una direcci?n (l?nea de raster) hay que hacer una operaci?n And con 
92
         * con la altura de la p?gina -1. Por ejemplo, una p?gina de 16 l?neas de altura el desplazamiento ser?
93
         * 16 - 1 = 15 porque 15 en binario es 1111.
94
         * 
95
         * Si queremos acceder a la linea del raster n?mero 83 (1010011) realizando la operaci?n And con el valor del
96
         * desplazamiento obtenemos (0001111 & 1010011 = 0000011), es decir el valor 3 en decimal. Esto quiere decir
97
         * que la l?nea 83 del raster es la 3 de su p?gina. 
98
         */
99
        private int            offset = 1;
100
        
101
        private int            bufWidth, bufHeight;
102
        private int            blockHeight  = RasterLibrary.blockHeight;
103
        
104
        /**
105
         * Constructor. Asigna las variables de inicializaci?n y crea la estructura de 
106
         * la cach? con los datos pasados.
107
         * @param dataType Tipo de dato
108
         * @param width Ancho
109
         * @param height Alto
110
         * @param bandNr Banda
111
         * @param orig
112
         * @throws RasterDriverException 
113
         * @throws NotSupportedExtensionException 
114
         * @throws FileNotFoundException 
115
         */
116
        public RasterReadOnlyBuffer(int dataType, int width, int height, int nBand) {
117
                this.dataType = dataType;
118
                this.width = width;
119
                this.height = height;
120
                this.nBands = nBand;        
121
        }
122
        
123
        /**
124
         * Asigna los parametros relativos al buffer. Estos son el nombre del fichero asociado 
125
         * y la extensi?n asignada
126
         * @param fileName Nombre del fichero asociado
127
         * @param ext Extensi?n
128
         */
129
        public void setBufferParams(QueryableRaster q, Extent ext, BandList bandList) 
130
                throws InvalidSetViewException, FileNotExistsException, NotSupportedExtensionException {
131
                this.bandList = bandList;
132
                this.datasource = (RasterDataStore)q;
133
                                
134
                if(        ext.minX() < datasource.getExtent().minX() || ext.minY() < datasource.getExtent().minY() ||
135
                        ext.maxX() > datasource.getExtent().maxX() || ext.maxY() > datasource.getExtent().maxY())
136
                        throw new InvalidSetViewException("");
137
                
138
                Point2D p1 = datasource.worldToRaster(new Point2D.Double(minX, maxY));
139
                Point2D p2 = datasource.worldToRaster(new Point2D.Double(maxX, minY));
140
                adjustPoints(p1, p2);
141
                this.minX = (int)p1.getX();
142
                this.minY = (int)p1.getY();
143
                this.maxX = (int)p2.getX();
144
                this.maxY = (int)p2.getY();
145
                
146
                init();
147
        }
148
        
149
        private void adjustPoints(Point2D ul, Point2D lr) {
150
                double a = (ul.getX() - (int)ul.getX());
151
                double b = (ul.getY() - (int)ul.getY());
152
                ul.setLocation(        (a > 0.99 || a < 0.005) ? Math.round(ul.getX()) : ul.getX(), 
153
                                                (b > 0.99 || b < 0.005) ? Math.round(ul.getY()) : ul.getY());
154
                lr.setLocation(        (a > 0.99 || a < 0.005) ? Math.round(lr.getX()) : lr.getX(), 
155
                                                (b > 0.99 || b < 0.005) ? Math.round(lr.getY()) : lr.getY());
156
        }
157
                        
158
        /**
159
         * Asigna los parametros relativos al buffer. Estos son el nombre del fichero asociado 
160
         * y la extensi?n asignada
161
         * @param dataStore Dataset del fichero asociado
162
         * @param minX Coordenada pixel X m?nima
163
         * @param minY Coordenada pixel Y m?nima
164
         * @param maxX Coordenada pixel X m?xima
165
         * @param maxY Coordenada pixel Y m?xima
166
         * @exception InvalidSetViewException
167
         * @exception FileNotExistsException
168
         * @exception NotSupportedExtensionException
169
         */
170
        public void setBufferParams(QueryableRaster q, int minX, int minY, int maxX, int maxY, BandList bandList) 
171
                throws InvalidSetViewException, FileNotExistsException, NotSupportedExtensionException {
172
                this.bandList = bandList;
173
                this.datasource = (RasterDataStore)q;
174
                
175
                this.minX = minX;
176
                this.minY = minY;
177
                this.maxX = maxX;
178
                this.maxY = maxY;
179
                
180
                if(Math.abs(maxX - minX) != width || Math.abs(maxY - minY) != height) {
181
                        bufWidth = width;
182
                        bufHeight = height;
183
                }
184
                                        
185
                init();
186
        }
187
                
188
        /**
189
         * Acciones de inicializaci?n. 
190
         * Crear el buffer de memoria y la lista de bandas, as? comno los bits empleados
191
         * por cada p?gina de memoria y el desplazamiento que supone para el calculo
192
         * de direcciones.
193
         */
194
        private void init() {
195
                //Calculo de los bits por p?gina
196
                int h = blockHeight; 
197
                while(h > 1) {
198
                        h >>= 1;
199
                        bitsPag ++;
200
                }
201
                
202
                //Calculo del desplazamiento
203
                offset = blockHeight - 1;    
204
                
205
                //Creamos el bufferFactory asociado a la carga de p?ginas. Cada p?gina se fuerza
206
                //a que sea cargada en memoria.
207
                query = DefaultRasterManager.getInstance().createQuery();
208
                query.setMemoryBuffer(true);
209
                query.setDrawableBands(bandList.getDrawableBands());
210
                
211
                nPages = (int)Math.ceil((double)height / (double)blockHeight);
212
                //double aux = ((double)height / (double)RasterLibrary.blockHeight);
213
                //heightLastPage = (int)((aux - (int)aux) * RasterLibrary.blockHeight);
214
                if(height % blockHeight == 0)
215
                        heightLastPage = blockHeight;
216
                else {
217
                        double aux = ((double)height / (double)blockHeight);
218
                        heightLastPage = (int)((aux - (int)aux) * blockHeight);
219
                }
220
                
221
                drawableBands = new int[datasource.getBandCount()];
222
                for (int i = 0; i < drawableBands.length; i++) 
223
                        drawableBands[i] = i;
224
        }
225
        
226
        public void addDrawableBands(int[] db) {
227
                if(db == null || db.length > this.bandList.getBandCount())
228
                        return;
229
                this.bandList.setDrawableBands(db);
230
                query = DefaultRasterManager.getInstance().createQuery();
231
                query.setMemoryBuffer(true);
232
                query.setDrawableBands(bandList.getDrawableBands());
233
        }
234
        
235
        public int getBandCount() {
236
                return this.bandList.getDrawableBandsCount();
237
        }
238
        
239
        /**
240
         * Calcula la extensi?n de las p?ginas en coordenadas del mundo real
241
         * @param dataset Dataset
242
         * @param nPages N?mero de p?ginas en que se divide el raster
243
         * @deprecated
244
         * @return Extensi?n de cada p?gina
245
         */
246
        public Extent[] calcExtentPages(AbstractRasterProvider dataset, int nPages) {
247
                Extent datasetExtent = dataset.getExtent();
248
                double h = (blockHeight * dataset.getExtent().height()) / dataset.getHeight();
249
                Extent[] ext = new Extent[nPages];
250
                
251
                double minX = datasetExtent.getMin().getX();
252
                double maxX = datasetExtent.getMax().getX();
253
                double maxY = datasetExtent.getMax().getY();
254
                double minY = maxY - h;
255
                for (int i = 0; i < ext.length; i++) {
256
                        ext[i] = new ExtentImpl(minX, maxY, maxX, minY);
257
                        maxY = minY;
258
                        minY -= h;
259
                        if(minY < datasetExtent.minY())
260
                                minY = datasetExtent.minY();
261
                }
262
                return ext;
263
        }
264
        
265
        public void malloc(int dataType, int width, int height, int bandNr) {
266
        }
267

    
268
        public boolean isBandSwitchable() {
269
                return false;
270
        }
271
        
272
        private Buffer queryPage(int pag) throws ProcessInterruptedException, QueryException {
273
                int w = maxX - minX + 1;
274
                int h = maxY - minY + 1;
275
                
276
                if((minX + w) > datasource.getWidth())
277
                        w = (int)(datasource.getWidth() - minX);
278
                
279
                if(bufWidth == 0 && bufHeight == 0) {
280
                        if(pag == nPages - 1) {
281
                                Rectangle r = new Rectangle(minX, (blockHeight * pag) + minY, w, heightLastPage);
282
                                query.setAreaOfInterest(r);
283
                        } else { 
284
                                Rectangle r = new Rectangle(minX, (blockHeight * pag) + minY, w, blockHeight);
285
                                query.setAreaOfInterest(r);
286
                        }
287
                } else {
288
                        int hPage = (int)Math.round((blockHeight * h) / (double)bufHeight);
289
                        if(pag == nPages - 1) {
290
                                int hLastPage = 0;
291
                                if(heightLastPage == bufHeight) {
292
                                        hLastPage = h;
293
                                        hPage = 0;
294
                                } else
295
                                        hLastPage = (int)Math.round((heightLastPage * h) / (double)bufHeight);
296
                                int newMiY = (hPage * pag) + minY;
297
                                if((newMiY + hLastPage) > datasource.getHeight())
298
                                        hLastPage = (int)(datasource.getHeight() - newMiY);
299
                                Rectangle r = new Rectangle(minX, newMiY, w, hLastPage);
300
                                query.setAreaOfInterest(r, bufWidth, heightLastPage);
301
                        } else { 
302
                                Rectangle r = new Rectangle(minX, (hPage * pag) + minY, w, hPage);
303
                                query.setAreaOfInterest(r, bufWidth, blockHeight);
304
                        }
305
                }
306
                return datasource.query(query);
307
        }
308

    
309
        /**
310
         * Carga las p?ginas de memoria cuando hay un fallo en el acceso al dato
311
         * @param pag N?mero de p?gina a cargar
312
         */
313
        private void loadPage(int pag) {
314
                try {
315
                        if(page == null) {
316
                                page = queryPage(pag);
317
                                loadedPage = pag;
318
                                if((pag + 1) < nPages) {
319
                                        secondPage = queryPage(pag + 1);//datasource.query(query);
320
                                        loadedSecondPage = pag + 1;
321
                                }
322
                        } else {
323
                                if(pag == loadedSecondPage)
324
                                        switchPage();
325
                                else {
326
                                        switchPage();
327
                                        page =         queryPage(pag);
328
                                        loadedPage = pag;
329
                                }
330
                        }
331

    
332
                } catch (ProcessInterruptedException e) {
333

    
334
                } catch (QueryException e) {
335

    
336
                } finally {
337
                        //Al interrumpir la carga de datos de un buffer o producirse una excepci?n page quedar? como null. 
338
                        //Tenemos que asignarle alg?n valor para que las ?ltimas consultas no den error.
339
                        if(page ==  null) {
340
                                page = DefaultRasterManager.getInstance().createBuffer(dataType, width, height, nBands, true);
341
                                loadedPage = pag;
342
                        }
343
                }
344
        }
345

    
346

    
347
        /**
348
         * Intercambia las dos p?ginas de memoria
349
         */
350
        private void switchPage() {
351
                Buffer aux = secondPage;
352
                secondPage = page;
353
                page = aux;
354
                int auxint = loadedSecondPage;
355
                loadedSecondPage = loadedPage;
356
                loadedPage = auxint;
357
        }
358
                         
359
        //*********************************************************
360
        
361
        public byte[][] getLineByte(int line) {
362
                int pag = line >> bitsPag;
363
                if(pag != loadedPage)
364
                        loadPage(pag);
365
                return page.getLineByte(line & offset);
366
        }
367

    
368
        public short[][] getLineShort(int line) {
369
                int pag = line >> bitsPag;
370
                if(pag != loadedPage)
371
                        loadPage(pag);
372
                return page.getLineShort(line & offset);
373
        }
374

    
375
        public int[][] getLineInt(int line) {
376
                int pag = line >> bitsPag;
377
                if(pag != loadedPage)
378
                        loadPage(pag);
379
                return page.getLineInt(line & offset);
380
        }
381

    
382
        public float[][] getLineFloat(int line) {
383
                int pag = line >> bitsPag;
384
                if(pag != loadedPage)
385
                        loadPage(pag);
386
                return page.getLineFloat(line & offset);
387
        }
388

    
389
        public double[][] getLineDouble(int line) {
390
                int pag = line >> bitsPag;
391
                if(pag != loadedPage)
392
                        loadPage(pag);
393
                return page.getLineDouble(line & offset);
394
        }
395

    
396
        //*********************************************************
397
        
398
        public byte[] getLineFromBandByte(int line, int band) {
399
                int pag = line >> bitsPag;
400
                if(pag != loadedPage)
401
                        loadPage(pag);
402
                return page.getLineFromBandByte(line & offset, band);
403
        }
404

    
405
        public short[] getLineFromBandShort(int line, int band) {
406
                int pag = line >> bitsPag;
407
                if(pag != loadedPage)
408
                        loadPage(pag);
409
                return page.getLineFromBandShort(line & offset, band);
410
        }
411

    
412
        public int[] getLineFromBandInt(int line, int band) {
413
                int pag = line >> bitsPag;
414
                if(pag != loadedPage)
415
                        loadPage(pag);
416
                return page.getLineFromBandInt(line & offset, band);
417
        }
418

    
419
        public float[] getLineFromBandFloat(int line, int band) {
420
                int pag = line >> bitsPag;
421
                if(pag != loadedPage)
422
                        loadPage(pag);
423
                return page.getLineFromBandFloat(line & offset, band);
424
        }
425

    
426
        public double[] getLineFromBandDouble(int line, int band) {
427
                int pag = line >> bitsPag;
428
                if(pag != loadedPage)
429
                        loadPage(pag);
430
                return page.getLineFromBandDouble(line & offset, band);
431
        }
432

    
433
        //*********************************************************
434
        
435
        public byte getElemByte(int line, int col, int band) {
436
                int pag = line >> bitsPag;
437
                if(pag != loadedPage)
438
                        loadPage(pag);
439
                return page.getElemByte(line & offset, col, band);
440
        }
441

    
442
        public short getElemShort(int line, int col, int band) {
443
                int pag = line >> bitsPag;
444
                if(pag != loadedPage)
445
                        loadPage(pag);
446
                return page.getElemShort(line & offset, col, band);
447
        }
448

    
449
        public int getElemInt(int line, int col, int band) {
450
                int pag = line >> bitsPag;
451
                if(pag != loadedPage)
452
                        loadPage(pag);
453
                return page.getElemInt(line & offset, col, band);
454
        }
455

    
456
        public float getElemFloat(int line, int col, int band) {
457
                int pag = line >> bitsPag;
458
                if(pag != loadedPage)
459
                        loadPage(pag);
460
                return page.getElemFloat(line & offset, col, band);
461
        }
462

    
463
        public double getElemDouble(int line, int col, int band) {
464
                int pag = line >> bitsPag;
465
                if(pag != loadedPage)
466
                        loadPage(pag);
467
                return page.getElemDouble(line & offset, col, band);
468
        }
469
        
470
        //*********************************************************
471

    
472
        public void getElemByte(int line, int col, byte[] data) {
473
                int pag = line >> bitsPag;
474
                if(pag != loadedPage)
475
                        loadPage(pag);
476
                page.getElemByte(line & offset, col, data);
477
        }
478

    
479
        public void getElemShort(int line, int col, short[] data) {
480
                int pag = line >> bitsPag;
481
                if(pag != loadedPage)
482
                        loadPage(pag);
483
                page.getElemShort(line & offset, col, data);
484
        }
485

    
486
        public void getElemInt(int line, int col, int[] data) {
487
                int pag = line >> bitsPag;
488
                if(pag != loadedPage)
489
                        loadPage(pag);
490
                page.getElemInt(line & offset, col, data);
491
        }
492

    
493
        public void getElemFloat(int line, int col, float[] data) {
494
                int pag = line >> bitsPag;
495
                if(pag != loadedPage)
496
                        loadPage(pag);
497
                page.getElemFloat(line & offset, col, data);
498
        }
499

    
500
        public void getElemDouble(int line, int col, double[] data) {
501
                int pag = line >> bitsPag;
502
                if(pag != loadedPage)
503
                        loadPage(pag);
504
                page.getElemDouble(line & offset, col, data);
505
        }
506
        
507
        //***********************************************
508
        //Obtiene una banda entera
509

    
510
        public Band getBand(int band){
511
                return null;
512
        }
513

    
514
        public Buffer getBandBuffer(int Band){
515
                return null;
516
        }
517

    
518
        public void replicateBand(int orig, int dest) {
519
        }
520

    
521
        public void switchBands(int[] bandPosition){
522

    
523
        }
524

    
525
        //*********************************************************
526

    
527
        public Buffer cloneBuffer(){
528
                return null;
529
        }
530

    
531
        public void mallocOneBand(int dataType, int width, int height, int band) {
532

    
533
        }
534

    
535
        public void copyBand(int nBand, Band band) {
536
                                
537
        }
538

    
539
        public void assignBand(int nBand, Band band) {
540
                                
541
        }
542

    
543
        public Band createBand(byte defaultValue) {
544
                
545
                return null;
546
        }
547

    
548
        public void assignBandToNotValid(int Band) {}
549
        public void assign(int band, byte value) {}
550
        public void assign(int band, short value) {}
551
        public void assign(int band, int value) {}
552
        public void assign(int band, float value) {}
553
        public void assign(int band, double value) {}
554
        public void interchangeBands(int band1, int band2) {}
555
        public void setElem(int line, int col, int band, byte data) {}
556
        public void setElem(int line, int col, int band, short data) {}
557
        public void setElem(int line, int col, int band, int data) {}
558
        public void setElem(int line, int col, int band, float data) {}
559
        public void setElem(int line, int col, int band, double data) {}
560
        public void setElemByte(int line, int col, byte[] data) {}
561
        public void setElemDouble(int line, int col, double[] data) {}
562
        public void setElemFloat(int line, int col, float[] data) {}
563
        public void setElemInt(int line, int col, int[] data) {}
564
        public void setElemShort(int line, int col, short[] data) {}
565
        public void setLineByte(byte[][] data, int line) {}
566
        public void setLineDouble(double[][] data, int line) {}
567
        public void setLineFloat(float[][] data, int line) {}
568
        public void setLineInBandByte(byte[] data, int line, int band) {}
569
        public void setLineInBandDouble(double[] data, int line, int band) {}
570
        public void setLineInBandFloat(float[] data, int line, int band) {}
571
        public void setLineInBandInt(int[] data, int line, int band) {}
572
        public void setLineInBandShort(short[] data, int line, int band) {}
573
        public void setLineInt(int[][] data, int line) {}
574
        public void setLineShort(short[][] data, int line) {}
575

    
576
        public boolean isReadOnlyBuffer() {
577
                return true;
578
        }
579
        
580
        public boolean isCached() {
581
                return true;
582
        }
583
        
584
        public int getBlockHeight() {
585
                return RasterLibrary.blockHeight;
586
        }
587
        
588
        public void dispose() {
589
                if(page != null) {
590
                        page.dispose();
591
                }
592
                if(secondPage != null) {
593
                        secondPage.dispose();
594
                }
595
                try {
596
                        finalize();
597
                } catch (Throwable e) {
598
                }
599
        }
600
        
601
        protected void finalize() throws Throwable {
602
                page = null;
603
                secondPage = null;
604
                query            = null;
605
                drawableBands    = null;
606
                bandList         = null;
607
                datasource       = null;
608
                super.finalize();
609
        }
610
}