gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / grid / render / RasterRenderReprojection.java @ 2308
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 |
} |