Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / FeatherProcessBuff.java @ 22012

History | View | Annotate | Download (14.1 KB)

1
/* 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

    
84
        private FLyrRasterSE outputRasterLayer = null;
85

    
86
        private Line2D borders[][] = null;
87

    
88
        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

    
95
        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
                for (int i = 0; i < inputRasterLayers.length; i++)
106
                        inputExtents[i] = inputRasterLayers[i].getFullExtent();
107

    
108
                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

    
146
                inputBuffers = new IBuffer[inputRasterLayers.length];
147
                int drawableBands[] = { 0, 1, 2 };
148
                for (int l = 0; l < inputRasterLayers.length; l++) {
149
                        dsetCopy = inputRasterLayers[l].getDataSource().newDataset();
150
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
151
                        bufferFactory.setAdjustToExtent(false);
152
                        bufferFactory.setNoDataToFill(resultGrid.getNoDataValue());
153
                        bufferFactory.setDrawableBands(drawableBands);
154

    
155
                        try {
156
                                if (RasterBuffer.isBufferTooBig(new double[] {
157
                                                resultGridExtent.getMin().getX(),
158
                                                resultGridExtent.getMin().getY(),
159
                                                resultGridExtent.getMax().getX(),
160
                                                resultGridExtent.getMax().getY() },
161
                                                drawableBands.length))
162
                                        bufferFactory.setReadOnly(true);
163

    
164
                                bufferFactory.setAreaOfInterest(inputExtents[l].getMinX(), inputExtents[l].getMaxY(), 
165
                                                inputExtents[l].getMaxX(), inputExtents[l].getMinY(),resultGridExtent.getNX(),resultGridExtent.getNY());
166
                                
167
                                /*
168
                                bufferFactory.setAreaOfInterest(inputExtents[l].getMinX(), inputExtents[l].getMaxY(), 
169
                                                inputExtents[l].getMaxX()- inputExtents[l].getMinX(), inputExtents[l].getMaxY() - inputExtents[l].getMinY());
170
                                                */
171
                        } catch (InvalidSetViewException e) {
172
                                // TODO Auto-generated catch block
173
                                e.printStackTrace();
174
                        } catch (RasterDriverException e) {
175
                                // TODO Auto-generated catch block
176
                                e.printStackTrace();
177
                        }
178
                        inputBuffers[l] = bufferFactory.getRasterBuf();
179

    
180
                        insertLineLog(RasterToolsUtil.getText(this, "interpolando"));
181

    
182
                        inputBuffers[l] = ((RasterBuffer) inputBuffers[l])
183
                                        .getAdjustedWindow(xResolution, yResolution,
184
                                                        GridInterpolated.INTERPOLATION_NearestNeighbour);
185
                        
186
                }
187

    
188
                // Recorrido del grid resultante
189
                // for (int band = 0; band < resultGrid.getBandCount(); band++){
190
                // resultGrid.setBandToOperate(band);
191
                for (int col = 0; col < resultGrid.getNX(); col++) {
192
                        // percent =
193
                        // col*resultGrid.getBandCount()*100/resultGrid.getNX()*resultGrid.getBandCount();
194
                        for (int row = 0; row < resultGrid.getNY(); row++) {
195
                                try {
196
                                        setValue(col, row);
197
                                        // resultGrid.setCellValue(col, row, getValue(col, row,
198
                                        // band));
199
                                } catch (OutOfGridException e) {
200
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(
201
                                                        this, "bad_access_grid"), this, e);
202
                                }
203
                        }
204
                }
205
                // }
206
                createLayer();
207
                if (externalActions != null)
208
                        externalActions.end(outputRasterLayer);
209
        }
210

    
211
        private void createLayer() {
212
                writerBufferServer = new WriterBufferServer(resultGrid.getRasterBuf());
213
                AffineTransform aTransform = new AffineTransform(resultGridExtent
214
                                .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(),
215
                                resultGridExtent.getMin().getX(), resultGridExtent.getMax()
216
                                                .getY());
217
                GeoRasterWriter grw;
218
                try {
219
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileName,
220
                                        resultGrid.getBandCount(), aTransform, resultGridExtent
221
                                                        .getNX(), resultGridExtent.getNY(), resultGrid
222
                                                        .getDataType(), GeoRasterWriter.getWriter(fileName)
223
                                                        .getParams(), null);
224
                        grw.dataWrite();
225
                        grw.writeClose();
226

    
227
                        outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
228
                                        fileName, null);
229
                        
230
                        
231
                        /*
232
                         * DEBUG: Escritura de los buffers interpolados de las im?genes de entrada 
233
                         */
234
                        
235
                        for(int i=0; i<inputBuffers.length; i++){
236
                                writerBufferServer = new WriterBufferServer(inputBuffers[i]);
237
                                aTransform = new AffineTransform(resultGridExtent
238
                                                .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(),
239
                                                resultGridExtent.getMin().getX(), resultGridExtent.getMax()
240
                                                                .getY());
241
                                grw = GeoRasterWriter.getWriter(writerBufferServer, fileName.replaceFirst(".tif", "Inpu"+i+".tif"),
242
                                                resultGrid.getBandCount(), aTransform, resultGridExtent
243
                                                                .getNX(), resultGridExtent.getNY(), resultGrid
244
                                                                .getDataType(), GeoRasterWriter.getWriter(fileName.replaceFirst(".tif", "Inpu"+i+".tif"))
245
                                                                .getParams(), null);
246
                                grw.dataWrite();
247
                                grw.writeClose();
248

    
249
                                outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
250
                                                fileName.replaceFirst(".tif", "Inpu"+i+".tif"), null);
251
                        }
252
                        /*
253
                         * DEBUG: End **************************************************************
254
                         */
255
                                
256
                } catch (NotSupportedExtensionException e) {
257
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
258
                                        "error_writer_notsupportedextension"), this, e);
259
                } catch (RasterDriverException e) {
260
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
261
                                        "raster_buffer_invalid_extension"), this, e);
262
                } catch (IOException e) {
263
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
264
                                        "error_writer"), this, e);
265
                } catch (InterruptedException e) {
266
                        Thread.currentThread().interrupt();
267
                } catch (LoadLayerException e) {
268
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
269
                }
270
        }
271

    
272
        private void setValue(int col, int row) throws OutOfGridException {
273
                // ?Est? el punto en la intersecci?n?
274
                Point2D worldCoords = rasterToWorld(col, row);
275
                if (intersection.contains(worldCoords)) {
276
                        setFeatherValue(col, row);
277
                        /*
278
                         * for (int band = 0; band<resultbandCount; band++){
279
                         * resultGrid.setBandToOperate(band); resultGrid.setCellValue(col,
280
                         * row, (byte)255); }
281
                         */
282
                        return;
283
                }
284

    
285
                byte values[] = new byte[resultbandCount];
286
                for (int g = 0; g < inputBuffers.length; g++) {
287
                        inputBuffers[g].getElemByte(row, col, values);
288
                        for (int band = 0; band < resultbandCount; band++) {
289
                                resultGrid.setBandToOperate(band);
290
                                if (inputBuffers[g].getNoDataValue() != values[band]) {
291
                                        resultGrid.setCellValue(col, row, values[band]);
292
                                } else {
293
                                        resultGrid.setCellValue(col, row, (byte) resultGrid
294
                                                        .getNoDataValue());
295
                                }
296
                        }
297
                        return;
298
                }
299
        }
300

    
301
        private void setFeatherValue(int col, int row) throws OutOfGridException {
302
                Point2D worldPoint = rasterToWorld(col, row);
303

    
304
                double distances[] = new double[borders.length];
305
                byte values[] = new byte[resultbandCount];
306
                double totalD = 0;
307
                double result[] = new double[resultbandCount];
308

    
309
                for (int i = 0; i < borders.length; i++) {
310

    
311
                        // C?lculo de la distancia m?nima a los bordes de cada imagen
312
                        distances[i] = Double.POSITIVE_INFINITY;
313
                        for (int j = 0; j < borders[0].length; j++)
314
                                if (borders[i][j] != null) {
315
                                        double newDistance = borders[i][j].ptLineDist(worldPoint);
316
                                        if (distances[i] > newDistance)
317
                                                distances[i] = newDistance;
318
                                }
319
                        totalD = totalD + distances[i];
320

    
321
                        inputBuffers[i].getElemByte(row, col, values);
322
                        for (int band = 0; band < resultbandCount; band++) {
323
                                result[band] = result[band] + values[band] * distances[i];
324
                        }
325
                }
326

    
327
                // Escribir el resultado de cada banda.
328
                for (int band = 0; band < resultbandCount; band++) {
329
                        result[band] = result[band] / totalD;
330
                        resultGrid.setBandToOperate(band);
331
                        resultGrid.setCellValue(col, row, (byte) result[band]);
332
                        result[band] = 0;
333
                }
334
        }
335

    
336
        public int getPercent() {
337
                // TODO Auto-generated method stub
338
                return 0;
339
        }
340

    
341
        public String getTitle() {
342
                return PluginServices.getText(this, "calculando_feather");
343
        }
344

    
345
        /**
346
         * Calcula los bordes que interesan para la obtenci?n de distancias en el
347
         * proceso.
348
         */
349
        private void calculateBorders() {
350

    
351
                borders = new Line2D.Double[2][4];
352

    
353
                Line2D.Double border = new Line2D.Double(inputExtents[0].getMinX(),
354
                                inputExtents[0].getMaxY(), inputExtents[0].getMaxX(),
355
                                inputExtents[0].getMaxY());
356
                if (inputExtents[1].intersectsLine(border))
357
                        borders[0][0] = border;
358
                else
359
                        borders[0][0] = null;
360

    
361
                border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0]
362
                                .getMaxY(), inputExtents[0].getMaxX(), inputExtents[0]
363
                                .getMinY());
364
                if (inputExtents[1].intersectsLine(border))
365
                        borders[0][1] = border;
366
                else
367
                        borders[0][1] = null;
368

    
369
                border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0]
370
                                .getMinY(), inputExtents[0].getMinX(), inputExtents[0]
371
                                .getMinY());
372
                if (inputExtents[1].intersectsLine(border))
373
                        borders[0][2] = border;
374
                else
375
                        borders[0][2] = null;
376

    
377
                border = new Line2D.Double(inputExtents[0].getMinX(), inputExtents[0]
378
                                .getMinY(), inputExtents[0].getMinX(), inputExtents[0]
379
                                .getMaxY());
380
                if (inputExtents[1].intersectsLine(border))
381
                        borders[0][3] = border;
382
                else
383
                        borders[0][3] = null;
384

    
385
                border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1]
386
                                .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1]
387
                                .getMinY());
388
                if (inputExtents[0].intersectsLine(border))
389
                        borders[1][0] = border;
390
                else
391
                        borders[1][0] = null;
392

    
393
                border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1]
394
                                .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1]
395
                                .getMinY());
396
                if (inputExtents[0].intersectsLine(border))
397
                        borders[1][1] = border;
398
                else
399
                        borders[1][1] = null;
400

    
401
                border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1]
402
                                .getMinY(), inputExtents[1].getMinX(), inputExtents[1]
403
                                .getMinY());
404
                if (inputExtents[0].intersectsLine(border))
405
                        borders[1][2] = border;
406
                else
407
                        borders[1][2] = null;
408

    
409
                border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1]
410
                                .getMinY(), inputExtents[1].getMinX(), inputExtents[1]
411
                                .getMaxY());
412
                if (inputExtents[0].intersectsLine(border))
413
                        borders[1][3] = border;
414
                else
415
                        borders[1][3] = null;
416
        }
417

    
418
        private Point2D rasterToWorld(int col, int row) {
419
                double worldX = resultGridExtent.getMin().getX() + (col + 0.5)
420
                                * resultGridExtent.getCellSizeX();
421
                double worldY = resultGridExtent.getMax().getY() + (row + 0.5)
422
                                * resultGridExtent.getCellSizeY();
423
                return new Point2D.Double(worldX, worldY);
424
        }
425
}