Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / org.gvsig.desktop.library / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / AbstractTiledBand.java @ 43803

History | View | Annotate | Download (8.17 KB)

1
package org.gvsig.raster.lib.buffer.impl;
2

    
3
import java.io.IOException;
4
import java.nio.Buffer;
5

    
6
import org.gvsig.raster.lib.buffer.api.Band;
7
import org.gvsig.raster.lib.buffer.api.BandInfo;
8
import org.gvsig.raster.lib.buffer.api.BandNotification;
9
import org.gvsig.raster.lib.buffer.api.BandTileManager;
10
import org.gvsig.raster.lib.buffer.api.BufferLocator;
11
import org.gvsig.raster.lib.buffer.api.NoData;
12
import org.gvsig.raster.lib.buffer.impl.exceptions.CopyFromBandException;
13
import org.gvsig.tools.dispose.DisposeUtils;
14
import org.gvsig.tools.exception.BaseException;
15

    
16

    
17
/**
18
 * @author fdiaz
19
 *
20
 */
21
public abstract class AbstractTiledBand extends AbstractBand implements Band {
22

    
23
    protected Buffer data; //data loaded
24
    protected int firstRowOfTile;
25
    protected int firstColumnOfTile;
26
    protected int rowsPerTile;
27
    protected int columnsPerTile;
28
    protected BandTileManager tileManager;
29
    private boolean loaded;
30
    protected int rowsInTile;
31
    protected int columnsInTile;
32

    
33
    /**
34
     * @param rows
35
     * @param columns
36
     * @param noData
37
     * @param tileManager
38
     */
39
    public AbstractTiledBand(int rows, int columns, NoData noData, BandTileManager tileManager) {
40
        this.rows = rows;
41
        this.columns = columns;
42
        this.loaded=false;
43
        this.rowsPerTile=tileManager.getRowsPerTile();
44
        this.columnsPerTile=tileManager.getColumnsPerTile();
45
        this.rowsInTile=rowsPerTile;
46
        this.columnsInTile=columnsPerTile;
47

    
48
        if (noData == null) {
49
            this.noData = BufferLocator.getBufferManager().createNoData(null, null);
50
        } else {
51
            this.noData = noData;
52
        }
53
        this.tileManager = tileManager;
54
    }
55

    
56
    @Override
57
    protected void doCopyFrom(Band source) throws CopyFromBandException {
58
        if (this.getColumns() != source.getColumns() || this.getRows() != source.getRows()
59
            || this.getDataType()!=source.getDataType() ) {
60
            throw new CopyFromBandException(source, this);
61
        }
62
        Object rowBuffer = this.createRowBuffer();
63
        for(int row = 0; row<=this.rows; row++){
64
            source.fetchRow(row, rowBuffer);
65
            this.putRow(row, rowBuffer);
66
        }
67
    }
68

    
69
    @Override
70
    protected void doCopyFrom(Band source, int row, int column) throws CopyFromBandException {
71
        if (this.getColumns() <= row+source.getColumns() || this.getRows() <= column+source.getRows()
72
            || this.getDataType()!=source.getDataType() ) {
73
            throw new CopyFromBandException(source, this);
74
        }
75
        //FIXME:
76
        Object rowBuffer = source.createRowBuffer();
77
        for(int r=0; r<Math.min(this.getRows()-row, source.getRows()); r++){
78
            source.fetchRow(r, rowBuffer);
79
            System.arraycopy(rowBuffer, 0, this.data, (r+row)*this.getColumns()+column, Math.min(this.getColumns()-column, source.getColumns()));
80
            this.putRow(r, rowBuffer);
81
        }
82
    }
83

    
84
    protected void loadTile(int row, int column) {
85
        //The tile to be loaded must be inside the band's limits
86
        if (loaded &&
87
            row >= firstRowOfTile &&
88
            row < firstRowOfTile + rowsPerTile &&
89
            column >= firstColumnOfTile &&
90
            column < firstColumnOfTile + columnsPerTile
91
            ) {
92
            return;
93
        }
94
        if(loaded) {
95
            saveCurrentTile();
96
        }
97
        loaded=false;
98

    
99
        int currentTileRow = row / rowsPerTile; //Divisi?n entera
100
        firstRowOfTile = currentTileRow * rowsPerTile;
101
        int currentTileColumn = column / columnsPerTile; //Divisi?n entera
102
        firstColumnOfTile = currentTileColumn * columnsPerTile;
103
        Band loadedBand = null;
104
        try {
105
            rowsInTile = rowsPerTile;
106
            if(firstRowOfTile + rowsPerTile > this.rows){
107
                rowsInTile = this.rows - firstRowOfTile;
108
            }
109
            columnsInTile = columnsPerTile;
110
            if(firstColumnOfTile + columnsPerTile > this.columns){
111
                columnsInTile = this.columns - firstColumnOfTile;
112
            }
113
            loadedBand = this.tileManager.load(firstRowOfTile,
114
                firstColumnOfTile,
115
                this.getDataType());
116
//            DisposeUtils.bind(loadedBand);
117
            Object rowBuffer = loadedBand.createRowBuffer();
118
            //TODO: for development time only. Remove after.
119
            /*
120
            logger.info("---------------------------------- ");
121
            logger.info("row = "+row+" column = "+column);
122
            logger.info("loadedBand.getRows() = " + loadedBand.getRows());
123
            logger.info("loadedBand.getColumns() = " + loadedBand.getColumns());
124
            logger.info("rowsInTile = " + rowsInTile);
125
            logger.info("columnsInTile = " + columnsInTile);
126
            logger.info("rowsPerTile = " + rowsPerTile);
127
            logger.info("columnsPerTile = " + columnsPerTile);
128
            logger.info("firstRowOfTile = " + firstRowOfTile);
129
            logger.info("firstColumnOfTile = " + firstColumnOfTile);
130
            logger.info("data.capacity() = " + data.capacity());
131
            */
132
            for (int loadedRow = 0; loadedRow < rowsInTile; loadedRow++) { //< loadedBand.getRows()
133
                loadedBand.fetchRow(loadedRow, rowBuffer);
134
                int pos = loadedRow * columnsInTile; //loadedBand.getColumns();
135
                //TODO: for development time only. Remove after.
136
                /*
137
                if(pos >= data.limit()){
138
                  logger.info("Posible error copiando el array: pos = " + pos+ " limit = "+data.limit());
139
                  continue;
140
                }
141
                */
142
                System.arraycopy(rowBuffer, 0, data.array(), pos, loadedBand.getColumns());
143
            }
144
//            logger.info("---------------------------------- ");
145
            loaded=true;
146
            this.notifyObservers(new DefaultBufferNotification(BandNotification.LOADED_PAGE, new Object[] { this }));
147

    
148
        } catch (IOException e) {
149
            throw new RuntimeException("Can't load current tile", e);
150
        } finally {
151
            DisposeUtils.dispose(loadedBand);
152
        }
153
    }
154

    
155
    protected void saveCurrentTile() {
156
        try {
157
            int rowsInTile = rowsPerTile;
158
            if(firstRowOfTile + rowsPerTile > this.rows){
159
                rowsInTile = this.rows - firstRowOfTile;
160
            }
161
            int columnsInTile = columnsPerTile;
162
            if(firstColumnOfTile + columnsPerTile > this.columns){
163
                columnsInTile = this.columns - firstColumnOfTile;
164
            }
165
            this.tileManager.save(data,
166
                firstRowOfTile, rowsInTile,
167
                firstColumnOfTile, columnsInTile,
168
                this.getDataType());
169
        } catch (UnsupportedOperationException e) {
170
            // Do nothing, operation not supported
171
        } catch (IOException e) {
172
            throw new RuntimeException("Can't save current tile", e);
173
        }
174
    }
175

    
176
    protected abstract int getDataSize();
177

    
178
    @Override
179
    public boolean isReadOnly() {
180
        if(this.tileManager==null){
181
            return false;
182
        }
183
        return !this.tileManager.isSupportedSave();
184
    }
185

    
186

    
187
    @Override
188
    public boolean isPaginated() {
189
        //FIXME: ?????
190
        return true;
191
    }
192

    
193
    @Override
194
    public BandInfo getBandInfo() {
195
        return this.tileManager == null ? null : this.tileManager.getBandInfo();
196
    }
197

    
198
    /**
199
     * Calculate buffer size than must be allocated.
200
     * @param rows
201
     * @param columns
202
     * @return
203
     */
204
    protected int calculateBufferSizeToAllocate(int rows, int columns){
205
        // If the number of requested cells is less than the default number of
206
        // cells, it is unnecessary to reserve the maximum possible size.
207

    
208
        int allocateRows = rowsInTile;
209
        if(rows<rowsInTile){
210
            allocateRows = rows;
211
        }
212

    
213
        int allocateColumns = columnsInTile;
214
        //FIXME: Comprobar si se puede utilizar la condici?n de abajo antes de descomentarizarla
215
//        if(columns<columnsInTile){
216
//            allocateColumns = columns;
217
//        }
218

    
219
        return allocateRows*allocateColumns;
220
    }
221

    
222
    @Override
223
    public void doDispose() throws BaseException {
224
        super.doDispose();
225
        data = null;
226
        //FIXME: ?hacer disposables los pageManagers?
227
        tileManager = null;
228
    }
229

    
230
}