root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / FeatherProcessBuff.java @ 21794
History | View | Annotate | Download (12.9 KB)
1 | 21790 | dguerrero | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2008 Instituto de Desarrollo Regional and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Iba?ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * Instituto de Desarrollo Regional (Universidad de Castilla La-Mancha)
|
||
34 | * Campus Universitario s/n
|
||
35 | * 02071 Alabacete
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 967 599 200
|
||
39 | */
|
||
40 | |||
41 | package org.gvsig.remotesensing.mosaic.process; |
||
42 | |||
43 | import java.awt.geom.AffineTransform; |
||
44 | import java.awt.geom.Line2D; |
||
45 | import java.awt.geom.Point2D; |
||
46 | import java.awt.geom.Rectangle2D; |
||
47 | import java.io.IOException; |
||
48 | |||
49 | import org.gvsig.fmap.raster.layers.FLyrRasterSE; |
||
50 | import org.gvsig.raster.RasterProcess; |
||
51 | import org.gvsig.raster.buffer.BufferFactory; |
||
52 | import org.gvsig.raster.buffer.RasterBuffer; |
||
53 | import org.gvsig.raster.buffer.RasterBufferInvalidException; |
||
54 | import org.gvsig.raster.buffer.WriterBufferServer; |
||
55 | import org.gvsig.raster.dataset.GeoRasterWriter; |
||
56 | import org.gvsig.raster.dataset.IBuffer; |
||
57 | import org.gvsig.raster.dataset.IRasterDataSource; |
||
58 | import org.gvsig.raster.dataset.InvalidSetViewException; |
||
59 | import org.gvsig.raster.dataset.NotSupportedExtensionException; |
||
60 | import org.gvsig.raster.dataset.io.RasterDriverException; |
||
61 | import org.gvsig.raster.datastruct.Extent; |
||
62 | import org.gvsig.raster.grid.Grid; |
||
63 | import org.gvsig.raster.grid.GridExtent; |
||
64 | import org.gvsig.raster.grid.GridInterpolated; |
||
65 | import org.gvsig.raster.grid.OutOfGridException; |
||
66 | import org.gvsig.raster.util.RasterToolsUtil; |
||
67 | |||
68 | import com.iver.andami.PluginServices; |
||
69 | import com.iver.cit.gvsig.exceptions.layers.LoadLayerException; |
||
70 | |||
71 | /**
|
||
72 | * Proceso para la obtenci?n de una imagen mosaico a partir de un conjunto de
|
||
73 | * im?genes por el metodo de degradado (Feathering).
|
||
74 | *
|
||
75 | * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
|
||
76 | *
|
||
77 | */
|
||
78 | public class FeatherProcessBuff extends RasterProcess { |
||
79 | |||
80 | private FLyrRasterSE inputRasterLayers[] = null; |
||
81 | private IBuffer inputBuffers[] = null; |
||
82 | private int xResolution, yResolution = 0; |
||
83 | 21794 | dguerrero | |
84 | 21790 | dguerrero | private FLyrRasterSE outputRasterLayer = null; |
85 | 21794 | dguerrero | |
86 | 21790 | dguerrero | private Line2D borders[][] = null; |
87 | 21794 | dguerrero | |
88 | 21790 | dguerrero | private Rectangle2D inputExtents[] = null; |
89 | private Rectangle2D intersection = null; |
||
90 | |||
91 | private Grid resultGrid = null; |
||
92 | private GridExtent resultGridExtent = null; |
||
93 | private int resultbandCount = 0; |
||
94 | 21794 | dguerrero | |
95 | 21790 | dguerrero | private WriterBufferServer writerBufferServer = null; |
96 | private String fileName = null; |
||
97 | int percent = 0; |
||
98 | |||
99 | public void init() { |
||
100 | |||
101 | // Obtener las capas que intervienen en el mosaico.
|
||
102 | inputRasterLayers = (FLyrRasterSE[]) getParam("inputRasterLayers"); |
||
103 | |||
104 | inputExtents = new Rectangle2D.Double[inputRasterLayers.length]; |
||
105 | 21794 | dguerrero | for (int i = 0; i < inputRasterLayers.length; i++) |
106 | 21790 | dguerrero | inputExtents[i] = inputRasterLayers[i].getFullExtent(); |
107 | 21794 | dguerrero | |
108 | 21790 | dguerrero | intersection = new Rectangle2D.Double(); |
109 | Rectangle2D.intersect(inputExtents[0], inputExtents[1], intersection); |
||
110 | |||
111 | Rectangle2D resultExtent = new Rectangle2D.Double(); |
||
112 | Rectangle2D.union(inputExtents[0], inputExtents[1], resultExtent); |
||
113 | |||
114 | // TODO: Contemplar el caso de capas con distinto tama?o de celda.
|
||
115 | double cellSizeX = inputRasterLayers[0].getAffineTransform() |
||
116 | .getScaleX(); |
||
117 | double cellSizeY = inputRasterLayers[0].getAffineTransform() |
||
118 | .getScaleY(); |
||
119 | |||
120 | resultGridExtent = new GridExtent(new Extent(resultExtent), cellSizeX, |
||
121 | cellSizeY); |
||
122 | xResolution = resultGridExtent.getNX(); |
||
123 | yResolution = resultGridExtent.getNY(); |
||
124 | |||
125 | // Grid Resultante
|
||
126 | try {
|
||
127 | // TODO: Determiar el tipo de dato y n?mero de bandas.
|
||
128 | resultGrid = new Grid(resultGridExtent, resultGridExtent,
|
||
129 | IBuffer.TYPE_BYTE, new int[] { 0, 1, 2 }); |
||
130 | resultGrid.setNoDataValue(0);
|
||
131 | resultbandCount = resultGrid.getBandCount(); |
||
132 | } catch (RasterBufferInvalidException e) {
|
||
133 | RasterToolsUtil.messageBoxError("buffer_incorrecto", this, e); |
||
134 | } |
||
135 | fileName = getStringParam("filename");
|
||
136 | |||
137 | } |
||
138 | |||
139 | public void process() throws InterruptedException { |
||
140 | // Calculara las lineas de borde (entre 0, 3 o 4 lineas)
|
||
141 | calculateBorders(); |
||
142 | |||
143 | // Construccion de los grid de entrada:
|
||
144 | IRasterDataSource dsetCopy = null;
|
||
145 | 21794 | dguerrero | |
146 | 21790 | dguerrero | inputBuffers = new IBuffer[inputRasterLayers.length];
|
147 | 21794 | dguerrero | int drawableBands[] = { 0, 1, 2 }; |
148 | 21790 | dguerrero | for (int l = 0; l < inputRasterLayers.length; l++) { |
149 | dsetCopy = inputRasterLayers[l].getDataSource().newDataset(); |
||
150 | BufferFactory bufferFactory = new BufferFactory(dsetCopy);
|
||
151 | 21794 | dguerrero | bufferFactory.setAdjustToExtent(false);
|
152 | 21790 | dguerrero | bufferFactory.setDrawableBands(drawableBands); |
153 | 21794 | dguerrero | |
154 | 21790 | dguerrero | try {
|
155 | 21794 | dguerrero | if (RasterBuffer.isBufferTooBig(new double[] { |
156 | resultGridExtent.getMin().getX(), |
||
157 | resultGridExtent.getMin().getY(), |
||
158 | resultGridExtent.getMax().getX(), |
||
159 | resultGridExtent.getMax().getY() }, |
||
160 | drawableBands.length)) |
||
161 | 21790 | dguerrero | bufferFactory.setReadOnly(true);
|
162 | |||
163 | 21794 | dguerrero | bufferFactory.setAreaOfInterest(resultGridExtent.getMin() |
164 | .getX(), resultGridExtent.getMax().getY(), |
||
165 | resultGridExtent.getMax().getX() |
||
166 | - resultGridExtent.getMin().getX(), |
||
167 | resultGridExtent.getMax().getY() |
||
168 | - resultGridExtent.getMin().getY()); |
||
169 | 21790 | dguerrero | } catch (InvalidSetViewException e) {
|
170 | // TODO Auto-generated catch block
|
||
171 | e.printStackTrace(); |
||
172 | } catch (RasterDriverException e) {
|
||
173 | // TODO Auto-generated catch block
|
||
174 | e.printStackTrace(); |
||
175 | } |
||
176 | inputBuffers[l] = bufferFactory.getRasterBuf(); |
||
177 | |||
178 | insertLineLog(RasterToolsUtil.getText(this, "interpolando")); |
||
179 | |||
180 | 21794 | dguerrero | inputBuffers[l] = ((RasterBuffer) inputBuffers[l]) |
181 | .getAdjustedWindow(xResolution, yResolution, |
||
182 | GridInterpolated.INTERPOLATION_NearestNeighbour); |
||
183 | 21790 | dguerrero | } |
184 | |||
185 | // Recorrido del grid resultante
|
||
186 | 21794 | dguerrero | // for (int band = 0; band < resultGrid.getBandCount(); band++){
|
187 | // resultGrid.setBandToOperate(band);
|
||
188 | for (int col = 0; col < resultGrid.getNX(); col++) { |
||
189 | // percent =
|
||
190 | // col*resultGrid.getBandCount()*100/resultGrid.getNX()*resultGrid.getBandCount();
|
||
191 | for (int row = 0; row < resultGrid.getNY(); row++) { |
||
192 | try {
|
||
193 | setValue(col, row); |
||
194 | // resultGrid.setCellValue(col, row, getValue(col, row,
|
||
195 | // band));
|
||
196 | } catch (OutOfGridException e) {
|
||
197 | RasterToolsUtil.messageBoxError(PluginServices.getText( |
||
198 | this, "bad_access_grid"), this, e); |
||
199 | 21790 | dguerrero | } |
200 | } |
||
201 | 21794 | dguerrero | } |
202 | // }
|
||
203 | 21790 | dguerrero | createLayer(); |
204 | if (externalActions != null) |
||
205 | externalActions.end(outputRasterLayer); |
||
206 | } |
||
207 | |||
208 | private void createLayer() { |
||
209 | writerBufferServer = new WriterBufferServer(resultGrid.getRasterBuf());
|
||
210 | AffineTransform aTransform = new AffineTransform(resultGridExtent |
||
211 | .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(), |
||
212 | resultGridExtent.getMin().getX(), resultGridExtent.getMax() |
||
213 | .getY()); |
||
214 | GeoRasterWriter grw; |
||
215 | try {
|
||
216 | grw = GeoRasterWriter.getWriter(writerBufferServer, fileName, |
||
217 | resultGrid.getBandCount(), aTransform, resultGridExtent |
||
218 | .getNX(), resultGridExtent.getNY(), resultGrid |
||
219 | .getDataType(), GeoRasterWriter.getWriter(fileName) |
||
220 | .getParams(), null);
|
||
221 | grw.dataWrite(); |
||
222 | grw.writeClose(); |
||
223 | |||
224 | outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
|
||
225 | fileName, null);
|
||
226 | } catch (NotSupportedExtensionException e) {
|
||
227 | RasterToolsUtil.messageBoxError(PluginServices.getText(this,
|
||
228 | "error_writer_notsupportedextension"), this, e); |
||
229 | } catch (RasterDriverException e) {
|
||
230 | RasterToolsUtil.messageBoxError(PluginServices.getText(this,
|
||
231 | "raster_buffer_invalid_extension"), this, e); |
||
232 | } catch (IOException e) { |
||
233 | RasterToolsUtil.messageBoxError(PluginServices.getText(this,
|
||
234 | "error_writer"), this, e); |
||
235 | } catch (InterruptedException e) { |
||
236 | Thread.currentThread().interrupt();
|
||
237 | } catch (LoadLayerException e) {
|
||
238 | RasterToolsUtil.messageBoxError("error_cargar_capa", this, e); |
||
239 | } |
||
240 | } |
||
241 | |||
242 | private void setValue(int col, int row) throws OutOfGridException { |
||
243 | 21794 | dguerrero | // ?Est? el punto en la intersecci?n?
|
244 | Point2D worldCoords = rasterToWorld(col, row);
|
||
245 | if (intersection.contains(worldCoords)) {
|
||
246 | 21790 | dguerrero | setFeatherValue(col, row); |
247 | 21794 | dguerrero | /*
|
248 | * for (int band = 0; band<resultbandCount; band++){
|
||
249 | * resultGrid.setBandToOperate(band); resultGrid.setCellValue(col,
|
||
250 | * row, (byte)255); }
|
||
251 | */
|
||
252 | 21790 | dguerrero | return;
|
253 | } |
||
254 | 21794 | dguerrero | |
255 | 21790 | dguerrero | byte values[] = new byte[resultbandCount]; |
256 | for (int g = 0; g < inputBuffers.length; g++) { |
||
257 | inputBuffers[g].getElemByte(row, col, values); |
||
258 | 21794 | dguerrero | for (int band = 0; band < resultbandCount; band++) { |
259 | 21790 | dguerrero | resultGrid.setBandToOperate(band); |
260 | 21794 | dguerrero | if (inputBuffers[g].getNoDataValue() != values[band]) {
|
261 | 21790 | dguerrero | resultGrid.setCellValue(col, row, values[band]); |
262 | 21794 | dguerrero | } else {
|
263 | resultGrid.setCellValue(col, row, (byte) resultGrid
|
||
264 | .getNoDataValue()); |
||
265 | 21790 | dguerrero | } |
266 | } |
||
267 | return;
|
||
268 | } |
||
269 | } |
||
270 | |||
271 | private void setFeatherValue(int col, int row) throws OutOfGridException { |
||
272 | Point2D worldPoint = rasterToWorld(col, row);
|
||
273 | 21794 | dguerrero | |
274 | 21790 | dguerrero | double distances[] = new double[borders.length]; |
275 | 21794 | dguerrero | byte values[] = new byte[resultbandCount]; |
276 | 21790 | dguerrero | double totalD = 0; |
277 | double result[] = new double[resultbandCount]; |
||
278 | 21794 | dguerrero | |
279 | for (int i = 0; i < borders.length; i++) { |
||
280 | |||
281 | // C?lculo de la distancia m?nima a los bordes de cada imagen
|
||
282 | distances[i] = Double.POSITIVE_INFINITY;
|
||
283 | for (int j = 0; j < borders[0].length; j++) |
||
284 | if (borders[i][j] != null) { |
||
285 | 21790 | dguerrero | double newDistance = borders[i][j].ptLineDist(worldPoint);
|
286 | 21794 | dguerrero | if (distances[i] > newDistance)
|
287 | distances[i] = newDistance; |
||
288 | 21790 | dguerrero | } |
289 | totalD = totalD + distances[i]; |
||
290 | 21794 | dguerrero | |
291 | 21790 | dguerrero | inputBuffers[i].getElemByte(row, col, values); |
292 | 21794 | dguerrero | for (int band = 0; band < resultbandCount; band++) { |
293 | result[band] = result[band] + values[band] * distances[i]; |
||
294 | 21790 | dguerrero | } |
295 | } |
||
296 | 21794 | dguerrero | |
297 | // Escribir el resultado de cada banda.
|
||
298 | for (int band = 0; band < resultbandCount; band++) { |
||
299 | result[band] = result[band] / totalD; |
||
300 | 21790 | dguerrero | resultGrid.setBandToOperate(band); |
301 | 21794 | dguerrero | resultGrid.setCellValue(col, row, (byte) result[band]);
|
302 | result[band] = 0;
|
||
303 | } |
||
304 | 21790 | dguerrero | } |
305 | |||
306 | public int getPercent() { |
||
307 | // TODO Auto-generated method stub
|
||
308 | return 0; |
||
309 | } |
||
310 | |||
311 | public String getTitle() { |
||
312 | return PluginServices.getText(this, "calculando_feather"); |
||
313 | } |
||
314 | |||
315 | /**
|
||
316 | * Calcula los bordes que interesan para la obtenci?n de distancias en el
|
||
317 | * proceso.
|
||
318 | */
|
||
319 | private void calculateBorders() { |
||
320 | 21794 | dguerrero | |
321 | 21790 | dguerrero | borders = new Line2D.Double[2][4]; |
322 | |||
323 | 21794 | dguerrero | Line2D.Double border = new Line2D.Double(inputExtents[0].getMinX(), |
324 | inputExtents[0].getMaxY(), inputExtents[0].getMaxX(), |
||
325 | inputExtents[0].getMaxY());
|
||
326 | 21790 | dguerrero | if (inputExtents[1].intersectsLine(border)) |
327 | borders[0][0] = border; |
||
328 | else
|
||
329 | borders[0][0] = null; |
||
330 | |||
331 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0] |
332 | .getMaxY(), inputExtents[0].getMaxX(), inputExtents[0] |
||
333 | .getMinY()); |
||
334 | 21790 | dguerrero | if (inputExtents[1].intersectsLine(border)) |
335 | borders[0][1] = border; |
||
336 | else
|
||
337 | borders[0][1] = null; |
||
338 | |||
339 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0] |
340 | .getMinY(), inputExtents[0].getMinX(), inputExtents[0] |
||
341 | .getMinY()); |
||
342 | 21790 | dguerrero | if (inputExtents[1].intersectsLine(border)) |
343 | borders[0][2] = border; |
||
344 | else
|
||
345 | borders[0][2] = null; |
||
346 | |||
347 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[0].getMinX(), inputExtents[0] |
348 | .getMinY(), inputExtents[0].getMinX(), inputExtents[0] |
||
349 | .getMaxY()); |
||
350 | 21790 | dguerrero | if (inputExtents[1].intersectsLine(border)) |
351 | borders[0][3] = border; |
||
352 | else
|
||
353 | borders[0][3] = null; |
||
354 | |||
355 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1] |
356 | .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1] |
||
357 | .getMinY()); |
||
358 | 21790 | dguerrero | if (inputExtents[0].intersectsLine(border)) |
359 | borders[1][0] = border; |
||
360 | else
|
||
361 | borders[1][0] = null; |
||
362 | |||
363 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1] |
364 | .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1] |
||
365 | .getMinY()); |
||
366 | 21790 | dguerrero | if (inputExtents[0].intersectsLine(border)) |
367 | borders[1][1] = border; |
||
368 | else
|
||
369 | borders[1][1] = null; |
||
370 | |||
371 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1] |
372 | .getMinY(), inputExtents[1].getMinX(), inputExtents[1] |
||
373 | .getMinY()); |
||
374 | 21790 | dguerrero | if (inputExtents[0].intersectsLine(border)) |
375 | borders[1][2] = border; |
||
376 | else
|
||
377 | borders[1][2] = null; |
||
378 | |||
379 | 21794 | dguerrero | border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1] |
380 | .getMinY(), inputExtents[1].getMinX(), inputExtents[1] |
||
381 | .getMaxY()); |
||
382 | 21790 | dguerrero | if (inputExtents[0].intersectsLine(border)) |
383 | borders[1][3] = border; |
||
384 | else
|
||
385 | borders[1][3] = null; |
||
386 | } |
||
387 | 21794 | dguerrero | |
388 | private Point2D rasterToWorld(int col, int row) { |
||
389 | double worldX = resultGridExtent.getMin().getX() + (col + 0.5) |
||
390 | * resultGridExtent.getCellSizeX(); |
||
391 | double worldY = resultGridExtent.getMax().getY() + (row + 0.5) |
||
392 | * resultGridExtent.getCellSizeY(); |
||
393 | return new Point2D.Double(worldX, worldY); |
||
394 | 21790 | dguerrero | } |
395 | } |