Statistics
| Revision:

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

History | View | Annotate | Download (14.4 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.RasterBufferInvalidException;
53
import org.gvsig.raster.buffer.WriterBufferServer;
54
import org.gvsig.raster.dataset.FileNotOpenException;
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.OutOfGridException;
65
import org.gvsig.raster.grid.filter.RasterFilter;
66
import org.gvsig.raster.grid.filter.enhancement.LinearEnhancementFilter;
67
import org.gvsig.raster.grid.filter.enhancement.LinearStretchEnhancementByteFilter;
68
import org.gvsig.raster.grid.filter.enhancement.LinearStretchEnhancementFilter;
69
import org.gvsig.raster.grid.filter.enhancement.LinearStretchParams;
70
import org.gvsig.raster.util.RasterToolsUtil;
71

    
72
import com.iver.andami.PluginServices;
73
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
74

    
75
/**
76
 * Proceso para la obtenci?n de una imagen mosaico a partir de un conjunto de
77
 * im?genes por el metodo de degradado (Feathering).
78
 * 
79
 * @params
80
 * <LI>FLyrRasterSE[] "inputRasterLayers": Capas raster de entrada</LI>
81
 * <LI>String "outputPath": Ruta completa al fichero de salida del proceso</LI>
82
 * 
83
 * @result
84
 * <LI>FLyrRasterSE: Capa raster con el resultado del mosaico</LI>
85
 *
86
 * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
87
 * 
88
 */
89
public class FeatherProcessBuff extends RasterProcess {
90

    
91
        private FLyrRasterSE inputRasterLayers[] = null;
92
        private IBuffer inputBuffers[] = null;
93

    
94
        private FLyrRasterSE outputRasterLayer = null;
95

    
96
        private Line2D borders[][] = null;
97

    
98
        private Rectangle2D inputExtents[] = null;
99
        private Rectangle2D intersection = null;
100

    
101
        private Grid resultGrid = null;
102
        private GridExtent resultGridExtent = null;
103
        private int resultPxWidth, resultPxHeight= 0;
104
        private int resultbandCount = 0;
105

    
106
        private WriterBufferServer writerBufferServer = null;
107
        private String fileName = null;
108
        int percent = 0;
109

    
110
        //Variables auxiliares:
111
        private double distances[] = null;
112
        private byte values[] = null;
113
        private double totalD = 0;
114
        private double result[] = null;
115
        
116
        private GeoRasterWriter grw;
117

    
118
        public void init() {
119

    
120
                insertLineLog(PluginServices.getText(this, "preparando_entrada")+"...");
121
                // Obtener las capas que intervienen en el mosaico.
122
                inputRasterLayers = (FLyrRasterSE[]) getParam("inputRasterLayers");
123

    
124
                inputExtents = new Rectangle2D.Double[inputRasterLayers.length];
125
                for (int i = 0; i < inputRasterLayers.length; i++)
126
                        inputExtents[i] = inputRasterLayers[i].getFullExtent();
127

    
128
                intersection = new Rectangle2D.Double();
129
                Rectangle2D.intersect(inputExtents[0], inputExtents[1], intersection);
130

    
131
                Rectangle2D resultExtent = new Rectangle2D.Double();
132
                Rectangle2D.union(inputExtents[0], inputExtents[1], resultExtent);
133

    
134
                // TODO: Contemplar el caso de capas con distinto tama?o de celda.
135
                double cellSizeX = inputRasterLayers[0].getAffineTransform()
136
                                .getScaleX();
137
                double cellSizeY = inputRasterLayers[0].getAffineTransform()
138
                                .getScaleY();
139

    
140
                resultGridExtent = new GridExtent(new Extent(resultExtent), cellSizeX,
141
                                cellSizeY);
142
                
143
                resultPxWidth = resultGridExtent.getNX();
144
                resultPxHeight = resultGridExtent.getNY();
145

    
146
                // Grid Resultante
147
                try {
148
                        // TODO: Determiar el tipo de dato y n?mero de bandas.
149
                        resultGrid = new Grid(resultGridExtent, resultGridExtent,
150
                                        IBuffer.TYPE_BYTE, new int[] { 0, 1, 2 });
151
                        resultGrid.setNoDataValue(0);
152
                        resultbandCount = resultGrid.getBandCount();
153
                } catch (RasterBufferInvalidException e) {
154
                        RasterToolsUtil.messageBoxError("error_datos_entrada", this, e);
155
                }
156
                fileName = getStringParam("outputPath");
157
                values = new byte[resultbandCount];
158
                result = new double[resultbandCount];
159

    
160
        }
161

    
162
        public void process() throws InterruptedException {
163
                // Calcular las lineas de borde (entre 0, 3 o 4 lineas)
164
                calculateBorders();
165
                distances = new double[borders.length];
166

    
167
                // Construccion de los buffers de entrada:
168
                IRasterDataSource dsetCopy = null;
169

    
170
                inputBuffers = new IBuffer[inputRasterLayers.length];
171
                for (int l = 0; l < inputRasterLayers.length; l++) {
172
                        dsetCopy = inputRasterLayers[l].getDataSource().newDataset();
173
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
174
                        bufferFactory.setAdjustToExtent(false);
175
                        bufferFactory.setNoDataToFill(resultGrid.getNoDataValue());
176
                        bufferFactory.setDrawableBands(inputRasterLayers[l].getRenderBands());
177

    
178
                        try {
179
                                bufferFactory.setReadOnly(true);
180

    
181
                                bufferFactory.setAreaOfInterest(resultGridExtent.getMin().getX(), resultGridExtent.getMax().getY(), 
182
                                                resultGridExtent.getMax().getX(), resultGridExtent.getMin().getY(), resultGridExtent.getNX(),resultGridExtent.getNY());
183
                                
184
                        } catch (InvalidSetViewException e) {
185
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_datos_entrada"), this, e);        
186
                        } catch (RasterDriverException e) {
187
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_datos_entrada"), this, e);        
188
                        }
189
                        /*
190
                        //Aplicar filtro de realce si es necesario:
191
                        LinearStretchParams leParams = null;
192
                        try {
193
                                leParams = LinearStretchParams.createStandardParam(inputRasterLayers[l].getRenderBands(), 0.0, bufferFactory.getDataSource().getStatistics(), false);
194
                        } catch (FileNotOpenException e) {
195
                                // TODO Auto-generated catch block
196
                                e.printStackTrace();
197
                        } catch (RasterDriverException e) {
198
                                // TODO Auto-generated catch block
199
                                e.printStackTrace();
200
                        }
201
                        RasterFilter linearStretchEnhancementFilter = new LinearStretchEnhancementFilter();
202
                        linearStretchEnhancementFilter.addParam("raster", bufferFactory.getRasterBuf());
203
                        linearStretchEnhancementFilter.addParam("stats", bufferFactory.getDataSource().getStatistics());
204
                        linearStretchEnhancementFilter.addParam("renderBands",inputRasterLayers[l].getRenderBands());
205
                        linearStretchEnhancementFilter.addParam("remove",new Boolean(false));
206
                        linearStretchEnhancementFilter.addParam("stretchs", leParams);
207
                        linearStretchEnhancementFilter.execute();
208
                        
209
                        inputBuffers[l] = (IBuffer)linearStretchEnhancementFilter.getResult("raster");*/
210
                        
211
                        inputBuffers[l] = bufferFactory.getRasterBuf();
212
                }
213

    
214
                // Recorrido del grid resultante
215
                insertLineLog(PluginServices.getText(this, "realizando_degradado")+"...");
216
                for (int col = 0; col < resultPxWidth; col++) {
217
                        percent = col*100/resultPxWidth; 
218
                        for (int row = 0; row < resultPxHeight; row++) {
219
                                try {
220
                                        setValue(col, row);
221
                                } catch (OutOfGridException e) {
222
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(
223
                                                        this, "bad_access_grid"), this, e);
224
                                }
225
                        }
226
                }
227
                
228
                // Se liberan los buffers
229
                for(int i=0; i<inputRasterLayers.length;i++)
230
                        inputBuffers[i].free();
231
                
232
                createLayer();
233
                if (externalActions != null)
234
                        externalActions.end(outputRasterLayer);
235
        }
236

    
237
        private void createLayer() {
238
                insertLineLog(PluginServices.getText(this, "escribiendo_resultado")+"...");
239
                
240
                writerBufferServer = new WriterBufferServer(resultGrid.getRasterBuf());
241
                AffineTransform aTransform = new AffineTransform(resultGridExtent
242
                                .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(),
243
                                resultGridExtent.getMin().getX(), resultGridExtent.getMax()
244
                                                .getY());
245
                try {
246
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileName,
247
                                        resultGrid.getBandCount(), aTransform, resultGridExtent
248
                                                        .getNX(), resultGridExtent.getNY(), resultGrid
249
                                                        .getDataType(), GeoRasterWriter.getWriter(fileName)
250
                                                        .getParams(), inputRasterLayers[0].getProjection());
251
                        grw.dataWrite();
252
                        grw.writeClose();
253
                        resultGrid.getRasterBuf().free();
254
                        outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
255
                                        fileName, inputRasterLayers[0].getProjection());
256
                                
257
                } catch (NotSupportedExtensionException e) {
258
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
259
                                        "error_writer_notsupportedextension"), this, e);
260
                } catch (RasterDriverException e) {
261
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
262
                                        "raster_buffer_invalid_extension"), this, e);
263
                } catch (IOException e) {
264
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
265
                                        "error_writer"), this, e);
266
                } catch (InterruptedException e) {
267
                        Thread.currentThread().interrupt();
268
                } catch (LoadLayerException e) {
269
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
270
                }
271
        }
272

    
273
        private void setValue(int col, int row) throws OutOfGridException {
274
                // ?Est? el punto en la intersecci?n?
275
                Point2D worldCoords = rasterToWorld(col, row);
276
                if (intersection.contains(worldCoords)) {
277
                        setFeatherValue(col, row);
278
                        return;
279
                }
280

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

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

    
302
                totalD = 0;
303

    
304
                for (int i = 0; i < borders.length; i++) {
305

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

    
316
                        inputBuffers[i].getElemByte(row, col, values);
317
                        for (int band = 0; band < resultbandCount; band++) {
318
                                result[band] = result[band] + (values[band] & 0xff) * distances[i];
319
                        }
320
                }
321

    
322
                // Escribir el resultado de cada banda.
323
                for (int band = 0; band < resultbandCount; band++) {
324
                        result[band] = result[band] / totalD;
325
                        resultGrid.setBandToOperate(band);
326
                        resultGrid.setCellValue(col, row, (byte) result[band]);
327
                        result[band] = 0;
328
                }
329
        }
330
        
331
        public Object getResult() {
332
                return outputRasterLayer;
333
        }
334

    
335
        public int getPercent() {
336
                if (grw != null)
337
                        return grw.getPercent();
338
                
339
                return percent;
340
        }
341

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

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

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

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

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

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

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

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

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

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

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

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