gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.algorithm / org.gvsig.raster.tools.algorithm.reproject / src / main / java / org / gvsig / raster / tools / algorithm / reproject / Reproject.java @ 1747
History | View | Annotate | Download (12.3 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.tools.algorithm.reproject; |
23 |
|
24 |
import java.awt.geom.AffineTransform; |
25 |
import java.awt.geom.Point2D; |
26 |
import java.io.File; |
27 |
|
28 |
import org.cresques.cts.ICoordTrans; |
29 |
import org.cresques.cts.IProjection; |
30 |
import org.gvsig.fmap.dal.coverage.RasterLocator; |
31 |
import org.gvsig.fmap.dal.coverage.RasterManager; |
32 |
import org.gvsig.fmap.dal.coverage.dataset.Buffer; |
33 |
import org.gvsig.fmap.dal.coverage.datastruct.Extent; |
34 |
import org.gvsig.fmap.dal.coverage.datastruct.NoData; |
35 |
import org.gvsig.fmap.dal.coverage.datastruct.Params; |
36 |
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException; |
37 |
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException; |
38 |
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException; |
39 |
import org.gvsig.fmap.dal.coverage.store.DataServerWriter; |
40 |
import org.gvsig.fmap.dal.coverage.store.RasterDataStore; |
41 |
import org.gvsig.fmap.dal.coverage.store.RasterQuery; |
42 |
import org.gvsig.fmap.dal.coverage.store.RasterWriter; |
43 |
import org.gvsig.raster.tools.algorithm.base.process.RasterProcess; |
44 |
import org.gvsig.raster.tools.algorithm.base.util.Interpolation; |
45 |
|
46 |
|
47 |
/**
|
48 |
* Reprojects a RasterDataStore.
|
49 |
*
|
50 |
* @version 30/04/2008
|
51 |
* @author Nacho Brodin nachobrodin@gmail.com
|
52 |
*/
|
53 |
public class Reproject { |
54 |
private RasterDataStore store = null; |
55 |
private String pathDest = null; |
56 |
private int percent = 0; |
57 |
private int interpolationMethod = 0; |
58 |
private Interpolation interpolation = null; |
59 |
private RasterProcess process = null; |
60 |
|
61 |
/**
|
62 |
* Constructor de la clase.
|
63 |
* @param lyr
|
64 |
* @param pathDest Ruta de destino
|
65 |
*/
|
66 |
public Reproject(RasterDataStore store, String pathDest, int inter, RasterProcess process) { |
67 |
this.store = store;
|
68 |
this.pathDest = pathDest;
|
69 |
this.interpolationMethod = inter;
|
70 |
this.process = process;
|
71 |
} |
72 |
|
73 |
/**
|
74 |
* M?todo para la transformaci?n del raster.
|
75 |
* @param destinationSrs Proyecci?n destino
|
76 |
*/
|
77 |
public int warp(IProjection destinationSrs, IProjection sourceSrs, int w, int h, double cellSize) throws ReprojectException { |
78 |
if (store == null) |
79 |
throw new ReprojectException("Capa no valida."); |
80 |
if (!store.isReproyectable())
|
81 |
throw new ReprojectException("Esta capa no se puede reproyectar."); |
82 |
if (destinationSrs == null || destinationSrs.getAbrev() == null) |
83 |
throw new ReprojectException("Proyecci?n de destino no valida."); |
84 |
|
85 |
|
86 |
File file = new File(pathDest); |
87 |
if (!file.getParentFile().canWrite())
|
88 |
throw new ReprojectException("Ruta de destino no valida."); |
89 |
|
90 |
ICoordTrans transf = sourceSrs.getCT(destinationSrs); |
91 |
Extent bbox = store.getExtent(); |
92 |
Point2D ul = new Point2D.Double(bbox.getULX(), bbox.getULY()); |
93 |
Point2D lr = new Point2D.Double(bbox.getLRX(), bbox.getLRY()); |
94 |
//Point2D p = new Point2D.Double(lyr.getFullRasterExtent().getULX(), lyr.getFullRasterExtent().getULY());
|
95 |
ul = transf.convert(ul, ul); |
96 |
lr = transf.convert(lr, lr); |
97 |
Extent newBbox = RasterLocator.getManager().getDataStructFactory().createExtent(ul, lr); |
98 |
|
99 |
if(w <= 0 || h <= 0 ) { |
100 |
double[] size = getSize(bbox, newBbox); |
101 |
w = (int)size[0]; |
102 |
h = (int)size[1]; |
103 |
cellSize = size[2];
|
104 |
} |
105 |
int dataType = store.getDataType()[0]; |
106 |
Buffer buf = RasterLocator.getManager().createBuffer(
|
107 |
store.getDataType()[0], w, h, store.getBandCount(), true); |
108 |
|
109 |
NoData nd = RasterLocator.getManager().getDataStructFactory().createDefaultNoData( |
110 |
store.getBandCount(), dataType); |
111 |
|
112 |
RasterQuery query = RasterLocator.getManager().createQuery(); |
113 |
query.setAllDrawableBands(); |
114 |
query.setAreaOfInterest(); |
115 |
query.setReadOnly(true);
|
116 |
try {
|
117 |
ICoordTrans t = destinationSrs.getCT(sourceSrs); |
118 |
Buffer sourceBuffer = store.query(query);
|
119 |
if(interpolationMethod < 0) { |
120 |
for (int row = 0; row < buf.getHeight(); row++) { |
121 |
for (int col = 0; col < buf.getWidth(); col++) { |
122 |
Point2D p = transformPoint(newBbox, col, row, cellSize, t);
|
123 |
writePixel(dataType, sourceBuffer, buf, p, col, row, nd); |
124 |
} |
125 |
process.updatePercent(row, buf.getHeight()); |
126 |
} |
127 |
} else {
|
128 |
interpolation = new Interpolation(sourceBuffer);
|
129 |
for (int row = 0; row < buf.getHeight(); row++) { |
130 |
for (int col = 0; col < buf.getWidth(); col++) { |
131 |
Point2D p = transformPoint(newBbox, col, row, cellSize, t);
|
132 |
writePixelInterpolated(dataType, sourceBuffer, buf, p, col, row, nd, interpolationMethod); |
133 |
} |
134 |
process.updatePercent(row, buf.getHeight()); |
135 |
} |
136 |
} |
137 |
|
138 |
export(pathDest, buf, cellSize, newBbox.getULX(), newBbox.getULY());
|
139 |
} catch (RasterDriverException e) {
|
140 |
new ReprojectException("", e); |
141 |
} catch (ProcessInterruptedException e) {
|
142 |
} catch (InvalidSetViewException e) {
|
143 |
new ReprojectException("", e); |
144 |
} |
145 |
|
146 |
return 0; |
147 |
} |
148 |
|
149 |
/**
|
150 |
* Writes one pixel in the destination buffer
|
151 |
* @param type
|
152 |
* @param sourceBuffer
|
153 |
* @param buf
|
154 |
* @param p
|
155 |
* @param col
|
156 |
* @param row
|
157 |
*/
|
158 |
private void writePixel(int type, Buffer sourceBuffer, Buffer buf, Point2D p, int col, int row, NoData nd) { |
159 |
if(type == Buffer.TYPE_BYTE) { |
160 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
161 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) { |
162 |
//if(iBand == 0)
|
163 |
//System.out.println("Row:" + row + " Col:" + col + " Y:" + (int)p.getY() + " X:" + (int)p.getX());
|
164 |
buf.setElem(row, col, iBand, sourceBuffer.getElemByte((int)p.getY(), (int)p.getX(), iBand)); |
165 |
} |
166 |
else
|
167 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
168 |
buf.setElem(row, col, iBand, nd.getValue().byteValue()); |
169 |
} else if(type == Buffer.TYPE_DOUBLE) { |
170 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
171 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
172 |
buf.setElem(row, col, iBand, sourceBuffer.getElemDouble((int)p.getY(), (int)p.getX(), iBand)); |
173 |
else
|
174 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
175 |
buf.setElem(row, col, iBand, nd.getValue().doubleValue()); |
176 |
} else if(type == Buffer.TYPE_FLOAT) { |
177 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
178 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
179 |
buf.setElem(row, col, iBand, sourceBuffer.getElemFloat((int)p.getY(), (int)p.getX(), iBand)); |
180 |
else
|
181 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
182 |
buf.setElem(row, col, iBand, nd.getValue().floatValue()); |
183 |
} else if(type == Buffer.TYPE_SHORT) { |
184 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
185 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
186 |
buf.setElem(row, col, iBand, sourceBuffer.getElemShort((int)p.getY(), (int)p.getX(), iBand)); |
187 |
else
|
188 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
189 |
buf.setElem(row, col, iBand, nd.getValue().shortValue()); |
190 |
} else if(type == Buffer.TYPE_INT) { |
191 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
192 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
193 |
buf.setElem(row, col, iBand, sourceBuffer.getElemInt((int)p.getY(), (int)p.getX(), iBand)); |
194 |
else
|
195 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) |
196 |
buf.setElem(row, col, iBand, nd.getValue().intValue()); |
197 |
} |
198 |
} |
199 |
|
200 |
/**
|
201 |
* Writes one pixel in the destination buffer
|
202 |
* @param type
|
203 |
* @param sourceBuffer
|
204 |
* @param buf
|
205 |
* @param p
|
206 |
* @param col
|
207 |
* @param row
|
208 |
*/
|
209 |
private void writePixelInterpolated(int type, Buffer sourceBuffer, Buffer buf, Point2D p, int col, int row, NoData nd, int interpMethod) { |
210 |
double value = 0; |
211 |
if(p.getX() > 0 && p.getX() < sourceBuffer.getWidth() && p.getY() > 0 && p.getY() < sourceBuffer.getHeight()) |
212 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) { |
213 |
if(interpMethod == 0) //Nearest neighbor |
214 |
value = interpolation.getNearestNeighbour(p.getX(), p.getY(), iBand); |
215 |
if(interpMethod == 1) //Bilinear |
216 |
value = interpolation.getBilinearValue(p.getX(), p.getY(), iBand); |
217 |
if(interpMethod == 2) //Inverse distance |
218 |
value = interpolation.getInverseDistance(p.getX(), p.getY(), iBand); |
219 |
if(type == Buffer.TYPE_BYTE) |
220 |
buf.setElem(row, col, iBand, (byte)value);
|
221 |
else if(type == Buffer.TYPE_DOUBLE) |
222 |
buf.setElem(row, col, iBand, (double)value);
|
223 |
else if(type == Buffer.TYPE_FLOAT) |
224 |
buf.setElem(row, col, iBand, (float)value);
|
225 |
else if(type == Buffer.TYPE_SHORT) |
226 |
buf.setElem(row, col, iBand, (short)value);
|
227 |
else if(type == Buffer.TYPE_INT) |
228 |
buf.setElem(row, col, iBand, (int)value);
|
229 |
} |
230 |
else
|
231 |
for (int iBand = 0; iBand < store.getBandCount(); iBand++) { |
232 |
if(type == Buffer.TYPE_BYTE) |
233 |
buf.setElem(row, col, iBand, nd.getValue().byteValue()); |
234 |
else if(type == Buffer.TYPE_DOUBLE) |
235 |
buf.setElem(row, col, iBand, nd.getValue().doubleValue()); |
236 |
else if(type == Buffer.TYPE_FLOAT) |
237 |
buf.setElem(row, col, iBand, nd.getValue().floatValue()); |
238 |
else if(type == Buffer.TYPE_SHORT) |
239 |
buf.setElem(row, col, iBand, nd.getValue().shortValue()); |
240 |
else if(type == Buffer.TYPE_INT) |
241 |
buf.setElem(row, col, iBand, nd.getValue().intValue()); |
242 |
} |
243 |
} |
244 |
|
245 |
/**
|
246 |
* Transforms the upper left coordinate of a pixel using the transformation
|
247 |
* which is passed by parameter
|
248 |
* @param p
|
249 |
* @param newBbox
|
250 |
* @param col
|
251 |
* @param row
|
252 |
* @param cellSize
|
253 |
* @param t
|
254 |
*/
|
255 |
private Point2D transformPoint(Extent newBbox, int col, int row, double cellSize, ICoordTrans t) { |
256 |
Point2D p = new Point2D.Double( |
257 |
newBbox.getULX() + (col * cellSize), |
258 |
newBbox.getULY() - (row * cellSize)); |
259 |
p = t.convert(p, p); |
260 |
p = store.worldToRaster(p); |
261 |
return p;
|
262 |
} |
263 |
|
264 |
/**
|
265 |
* Gets the size of the new image
|
266 |
* @param bbox
|
267 |
* @param newBbox
|
268 |
* @return
|
269 |
*/
|
270 |
private double[] getSize(Extent bbox, Extent newBbox) { |
271 |
double sumSideOldBBox = bbox.width() + bbox.height();
|
272 |
double sumSideNewBBox = newBbox.width() + newBbox.height();
|
273 |
double d1x = (bbox.width() * 100) / sumSideOldBBox; |
274 |
double d1y = (bbox.height() * 100) / sumSideOldBBox; |
275 |
double d2x = (newBbox.width() * 100) / sumSideNewBBox; |
276 |
double d2y = (newBbox.height() * 100) / sumSideNewBBox; |
277 |
double p2y = (store.getHeight() * d2y) / d1y;
|
278 |
double p2x = (store.getWidth() * d2x) / d1x;
|
279 |
double newCellSize = newBbox.width() / p2x;
|
280 |
return new double[]{Math.round(p2x), Math.round(p2y), newCellSize}; |
281 |
} |
282 |
|
283 |
public boolean export(final String sFilename, Buffer buf, double cellsize, double minX, double minY) { |
284 |
|
285 |
try {
|
286 |
RasterManager manager = RasterLocator.getManager(); |
287 |
final DataServerWriter writerBufferServer =
|
288 |
manager.createDataServerWriter(); |
289 |
writerBufferServer.setBuffer(buf, -1);
|
290 |
final Params params = manager.createWriterParams(sFilename);
|
291 |
final AffineTransform affineTransform = |
292 |
new AffineTransform(cellsize, 0, 0, |
293 |
-cellsize, minX, minY); |
294 |
|
295 |
final RasterWriter writer =
|
296 |
manager.createWriter(writerBufferServer, sFilename, |
297 |
buf.getBandCount(), affineTransform, buf.getWidth(), |
298 |
buf.getHeight(), buf.getDataType(), params, null);
|
299 |
writer.dataWrite(); |
300 |
writer.writeClose(); |
301 |
|
302 |
} catch (final Exception e) { |
303 |
e.printStackTrace(); |
304 |
return false; |
305 |
} |
306 |
|
307 |
return true; |
308 |
|
309 |
} |
310 |
|
311 |
/**
|
312 |
* Obtiene el porcentaje de progreso de la tarea de reproyecci?n para
|
313 |
* mostrarlo por pantalla.
|
314 |
* @return
|
315 |
*/
|
316 |
public int getPercent() { |
317 |
return percent;
|
318 |
} |
319 |
} |