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 / grid / render / RasterRenderReprojection.java @ 2443

History | View | Annotate | Download (8.96 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.grid.render;
23

    
24
import java.awt.geom.Point2D;
25

    
26
import org.cresques.cts.ICoordTrans;
27
import org.gvsig.fmap.dal.coverage.RasterLocator;
28
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
29
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
30
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
31
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
32
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
33
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
34
import org.gvsig.fmap.dal.coverage.exception.QueryException;
35
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
36
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
37
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
38
import org.gvsig.raster.impl.DefaultRasterManager;
39
import org.gvsig.timesupport.Time;
40
import org.gvsig.tools.locator.LocatorException;
41
import org.gvsig.tools.task.TaskStatus;
42

    
43
/**
44
 * Reprojects a RasterDataStore. 
45
 *
46
 * @author Nacho Brodin nachobrodin@gmail.com
47
 */
48
public class RasterRenderReprojection {
49
        private RasterDataStore      store                  = null;
50
        private ICoordTrans          coordTrans             = null;
51
        private ICoordTrans          invertedCoordTrans     = null;
52
        private NoData               noData                 = null;
53
        private int                  dataType               = Buffer.TYPE_BYTE;
54
        private TaskStatus           status                 = null;
55
        private int                  lastAlphaBandNumber    = 0;  
56
        
57
        public RasterRenderReprojection(RasterDataStore store, 
58
                        ICoordTrans coordTrans, 
59
                        TaskStatus status) {
60
                this.store = store;
61
                this.status = status;
62
                this.coordTrans = coordTrans;
63
                this.invertedCoordTrans = coordTrans.getInverted();
64
                dataType = store.getDataType()[0];
65
                noData = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(
66
                                store.getBandCount(), dataType);
67
        }
68
        
69
        public Buffer warp(Extent bbox, 
70
                        int w, 
71
                        int h, 
72
                        Time time,
73
                        int[] renderBands,
74
                        Transparency lastTransparency) throws QueryException, ProcessInterruptedException {
75
                Point2D ul = new Point2D.Double(bbox.getULX(), bbox.getULY());
76
                Point2D lr = new Point2D.Double(bbox.getLRX(), bbox.getLRY());
77
                ul = invertedCoordTrans.convert(ul, ul);
78
                lr = invertedCoordTrans.convert(lr, lr);
79
                
80
                if(ul.getX() < store.getExtent().getULX())
81
                        ul.setLocation(store.getExtent().getULX(), ul.getY());
82
                if(ul.getY() > store.getExtent().getULY())
83
                        ul.setLocation(ul.getX(), store.getExtent().getULY());
84
                if(lr.getX() > store.getExtent().getLRX())
85
                        lr.setLocation(store.getExtent().getLRX(), lr.getY());
86
                if(lr.getY() < store.getExtent().getLRY())
87
                        lr.setLocation(lr.getX(), store.getExtent().getLRY());
88
                
89
                Extent newBbox = RasterLocator.getManager().getDataStructFactory().createExtent(ul, lr);
90
                
91
                double[] size = getSize(bbox, newBbox, w, h);
92
                int newW = (int)size[0];
93
                int newH = (int)size[1];
94
                double cellSize = size[2];
95
                
96
                BufferParam bufParam = RasterLocator.getManager().getBufferFactory().createBufferParams(
97
                                store.getDataType()[0], newW, newH, 3, true);
98
                Buffer bufReprojected = null;
99
                try {
100
                        bufReprojected = RasterLocator.getManager().getBufferFactory().createBuffer(bufParam);
101
                } catch (LocatorException e) {
102
                        throw new QueryException("Error creating the buffer", e);
103
                } catch (BufferCreationException e) {
104
                        throw new QueryException("Error creating the buffer", e);
105
                }
106
                
107
                RasterQuery query = DefaultRasterManager.getInstance().createQuery();
108
                query.setTaskStatus(status);
109
                query.setTime(time);
110
                query.setSupersamplingOption(false); // Desactivamos el supersampleo en la carga del buffer.
111
                query.forceARGBRequest();
112
                query.setAreaOfInterest(newBbox, newW, newH);
113
                query.setDrawableBands(renderBands);
114
                Buffer sourceBuffer = store.query(query);
115
                query.setSupersamplingOption(true);
116
                
117
                for (int row = 0; row < bufReprojected.getHeight(); row++) {
118
                        for (int col = 0; col < bufReprojected.getWidth(); col++) {
119
                                Point2D p = transformPoint(newBbox, col, row, cellSize, coordTrans);
120
                                writePixel(dataType, sourceBuffer, bufReprojected, p, col, row, noData);
121
                        }
122
                        //percent = (int)((row * 100) / buf.getHeight());
123
                }
124
                bufReprojected.setDataExtent(bbox.toRectangle2D());
125
                return bufReprojected;
126
        }
127
        
128
        public int getAlphaBandNumber() {
129
                return lastAlphaBandNumber;
130
        }
131
        
132
        /**
133
         * Transforms the upper left coordinate of a pixel using the transformation 
134
         * which is passed by parameter
135
         * @param p
136
         * @param newBbox
137
         * @param col
138
         * @param row
139
         * @param cellSize
140
         * @param t
141
         */
142
        private Point2D transformPoint(Extent newBbox, int col, int row, double cellSize, ICoordTrans t) {
143
                Point2D p = new Point2D.Double(
144
                                newBbox.getULX() + (col * cellSize), 
145
                                newBbox.getULY() - (row * cellSize));
146
                p = t.convert(p, p);
147
                p = store.worldToRaster(p);
148
                return p;
149
        }
150
        
151
        /**
152
         * Writes one pixel in the destination buffer
153
         * @param type
154
         * @param sourceBuffer
155
         * @param buf
156
         * @param p
157
         * @param col
158
         * @param row
159
         */
160
        private void writePixel(int type, Buffer sourceBuffer, Buffer buf, Point2D p, int col, int row, NoData nd) {
161
                if(type == Buffer.TYPE_BYTE) {
162
                        if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight())
163
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
164
                                        buf.setElem(row, col, iBand, sourceBuffer.getElemByte((int)p.getY(), (int)p.getX(), iBand));
165
                        else
166
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
167
                                        buf.setElem(row, col, iBand, nd.getValue().byteValue());
168
                } else if(type == Buffer.TYPE_DOUBLE) {
169
                        if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight())
170
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
171
                                        buf.setElem(row, col, iBand, sourceBuffer.getElemDouble((int)p.getY(), (int)p.getX(), iBand));
172
                        else
173
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
174
                                        buf.setElem(row, col, iBand, nd.getValue().doubleValue());
175
                } else if(type == Buffer.TYPE_FLOAT) {
176
                        if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight())
177
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
178
                                        buf.setElem(row, col, iBand, sourceBuffer.getElemFloat((int)p.getY(), (int)p.getX(), iBand));
179
                        else
180
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
181
                                        buf.setElem(row, col, iBand, nd.getValue().floatValue());
182
                } else if(type == Buffer.TYPE_SHORT) {
183
                        if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight())
184
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
185
                                        buf.setElem(row, col, iBand, sourceBuffer.getElemShort((int)p.getY(), (int)p.getX(), iBand));
186
                        else
187
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
188
                                        buf.setElem(row, col, iBand, nd.getValue().shortValue());
189
                } else if(type == Buffer.TYPE_INT) {
190
                        if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight())
191
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
192
                                        buf.setElem(row, col, iBand, sourceBuffer.getElemInt((int)p.getY(), (int)p.getX(), iBand));
193
                        else
194
                                for (int iBand = 0; iBand < store.getBandCount(); iBand++)
195
                                        buf.setElem(row, col, iBand, nd.getValue().intValue());
196
                } 
197
        }
198
        
199
        /**
200
         * Gets the size of the new image
201
         * @param bbox
202
         * @param newBbox
203
         * @return
204
         */
205
        private double[] getSize(Extent bbox, Extent newBbox, int p1x, int p1y) {
206
        //      d1x                 d2x
207
                //   ---------           ---------
208
                //   |  p1x  |           |  p2x  |
209
                //d1y|p1y    |        d2y|p2y    |
210
                //   |       |           |       |
211
                //   ---------           ---------
212
                double sumSideOldBBox = bbox.width() + bbox.height();
213
                double sumSideNewBBox = newBbox.width() + newBbox.height();
214
                double d1x = (bbox.width() * 100) / sumSideOldBBox; 
215
                double d1y = (bbox.height() * 100) / sumSideOldBBox;
216
                double d2x = (newBbox.width() * 100) / sumSideNewBBox;
217
                double d2y = (newBbox.height() * 100) / sumSideNewBBox;
218
                double p2y = (p1y * d2y) / d1y;
219
                double p2x = (p1x * d2x) / d1x;
220
                double newCellSize = newBbox.width() / p2x;
221
                return new double[]{Math.round(p2x), Math.round(p2y), newCellSize};
222
        }
223
}