Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / FeatherProcessBuff.java @ 29641

History | View | Annotate | Download (16.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.awt.image.DataBuffer;
48
import java.io.IOException;
49

    
50
import org.gvsig.andami.PluginServices;
51
import org.gvsig.fmap.geom.primitive.Envelope;
52
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
53
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
54
import org.gvsig.raster.RasterProcess;
55
import org.gvsig.raster.buffer.BufferFactory;
56
import org.gvsig.raster.buffer.BufferInterpolation;
57
import org.gvsig.raster.buffer.RasterBuffer;
58
import org.gvsig.raster.buffer.RasterBufferInvalidException;
59
import org.gvsig.raster.buffer.WriterBufferServer;
60
import org.gvsig.raster.dataset.FileNotOpenException;
61
import org.gvsig.raster.dataset.GeoRasterWriter;
62
import org.gvsig.raster.dataset.IBuffer;
63
import org.gvsig.raster.dataset.IRasterDataSource;
64
import org.gvsig.raster.dataset.InvalidSetViewException;
65
import org.gvsig.raster.dataset.NotSupportedExtensionException;
66
import org.gvsig.raster.dataset.RasterDriverException;
67
import org.gvsig.raster.datastruct.Extent;
68
import org.gvsig.raster.grid.Grid;
69
import org.gvsig.raster.grid.GridExtent;
70
import org.gvsig.raster.grid.OutOfGridException;
71
import org.gvsig.raster.grid.filter.RasterFilter;
72
import org.gvsig.raster.grid.filter.enhancement.EnhancementStretchListManager;
73
import org.gvsig.raster.grid.filter.enhancement.LinearStretchParams;
74
import org.gvsig.raster.util.RasterToolsUtil;
75
import org.gvsig.remotesensing.RemoteSensingUtils;
76

    
77

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

    
94
        private FLyrRasterSE inputRasterLayers[] = null;
95
        private IBuffer inputBuffers[] = null;
96

    
97
        private FLyrRasterSE outputRasterLayer = null;
98

    
99
        private Line2D borders[][] = null;
100

    
101
        private Rectangle2D inputExtents[] = null;
102
        private Rectangle2D intersection = null;
103

    
104
        private Grid resultGrid = null;
105
        private GridExtent resultGridExtent = null;
106
        private int resultPxWidth, resultPxHeight= 0;
107
        private int resultbandCount = 0;
108

    
109
        private WriterBufferServer writerBufferServer = null;
110
        private String fileName = null;
111
        int percent = 0;
112

    
113
        //Variables auxiliares:
114
        private double distances[] = null;
115
        private byte values[] = null;
116
        double value = 0;
117
        private double totalD = 0;
118
        private int bandCount = 0;
119
        private double noDataValue = 0;
120
        private double result[] = null;
121

    
122
        private GeoRasterWriter grw;
123

    
124
        public void init() {
125

    
126
                insertLineLog(PluginServices.getText(this, "preparando_entrada")+"...");
127
                // Obtener las capas que intervienen en el mosaico.
128
                inputRasterLayers = (FLyrRasterSE[]) getParam("inputRasterLayers");
129

    
130
                inputExtents = new Rectangle2D.Double[inputRasterLayers.length];
131
                for (int i = 0; i < inputRasterLayers.length; i++){
132
                        Envelope env=inputRasterLayers[i].getFullEnvelope();
133
                        inputExtents[i] = new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env.getLength(0), env.getLength(1));
134
                }
135
                intersection = new Rectangle2D.Double();
136
                Rectangle2D.intersect(inputExtents[0], inputExtents[1], intersection);
137

    
138
                Rectangle2D resultExtent = new Rectangle2D.Double();
139
                Rectangle2D.union(inputExtents[0], inputExtents[1], resultExtent);
140

    
141
                /*
142
                // TODO: Contemplar el caso de capas con distinto tama?o de celda.
143
                double cellSizeX = inputRasterLayers[0].getAffineTransform()
144
                                .getScaleX();
145
                double cellSizeY = inputRasterLayers[0].getAffineTransform()
146
                                .getScaleY();
147
                */
148
                double cellSizeX = getMinCellSize()[0];
149
                double cellSizeY = getMinCellSize()[1];
150

    
151
                resultGridExtent = new GridExtent(new Extent(resultExtent), cellSizeX,
152
                                cellSizeY);
153

    
154
                resultPxWidth = resultGridExtent.getNX();
155
                resultPxHeight = resultGridExtent.getNY();
156

    
157
                // Grid Resultante
158
                try {
159
                        resultGrid = new Grid(resultGridExtent, resultGridExtent,
160
                                        IBuffer.TYPE_BYTE, new int[] { 0, 1, 2 });
161
                        //resultGrid.setNoDataValue(0);
162
                        resultbandCount = resultGrid.getBandCount();
163
                } catch (RasterBufferInvalidException e) {
164
                        RasterToolsUtil.messageBoxError("error_datos_entrada", this, e);
165
                }
166
                fileName = getStringParam("outputPath");
167
                values = new byte[resultbandCount];
168
                result = new double[resultbandCount];
169

    
170
        }
171

    
172
        private double[] getMinCellSize() {
173
                double minCellSize[] = new double[2];
174
                minCellSize[0]=Double.MAX_VALUE;
175
                minCellSize[1]=Double.MAX_VALUE;
176
                for (int i = 0; i< inputRasterLayers.length; i++) {
177
                        if(Math.abs(inputRasterLayers[i].getAffineTransform().getScaleX())<Math.abs(minCellSize[0]))
178
                                minCellSize[0]=inputRasterLayers[i].getAffineTransform().getScaleX();
179
                        if(Math.abs(inputRasterLayers[i].getAffineTransform().getScaleY())<Math.abs(minCellSize[1]))
180
                                minCellSize[1]=inputRasterLayers[i].getAffineTransform().getScaleY();
181
                }
182
                return minCellSize;
183
        }
184

    
185
        public void process() throws InterruptedException {
186
                // Calcular las lineas de borde (entre 0, 3 o 4 lineas)
187
                calculateBorders();
188
                distances = new double[borders.length];
189

    
190
                // Construccion de los buffers de entrada:
191
                IRasterDataSource dsetCopy = null;
192

    
193
                inputBuffers = new IBuffer[inputRasterLayers.length];
194
                for (int l = 0; l < inputRasterLayers.length; l++) {
195

    
196
                        dsetCopy = inputRasterLayers[l].getDataSource().newDataset();
197
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
198
                        GridExtent gridExtent = new GridExtent(resultGridExtent.getMin().getX(),
199
                                        resultGridExtent.getMin().getY(),
200
                                        resultGridExtent.getMax().getX(),
201
                                        resultGridExtent.getMax().getY(),
202
                                         inputRasterLayers[l].getAffineTransform().getScaleX(),
203
                                         inputRasterLayers[l].getAffineTransform().getScaleY());
204
                        try {
205
                                bufferFactory.setAdjustToExtent(false);
206
                                //bufferFactory.setNoDataToFill(resultGrid.getNoDataValue());
207
                                bufferFactory.setNoDataToFill(inputRasterLayers[l].getNoDataValue());
208
                                bufferFactory.setReadOnly(true);
209
                                bufferFactory.setDrawableBands(inputRasterLayers[l].getRenderBands());
210
                                /*bufferFactory.setAreaOfInterest(resultGridExtent.getMin().getX(), resultGridExtent.getMax().getY(),
211
                                                resultGridExtent.getMax().getX(), resultGridExtent.getMin().getY(), resultGridExtent.getNX(),resultGridExtent.getNY());*/
212
                                bufferFactory.setAreaOfInterest(gridExtent.getMin().getX(), gridExtent.getMax().getY(),
213
                                                gridExtent.getMax().getX(), gridExtent.getMin().getY(), gridExtent.getNX(),gridExtent.getNY());
214

    
215
                        } catch (InvalidSetViewException e) {
216
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_datos_entrada"), this, e);
217
                        } catch (RasterDriverException e) {
218
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_datos_entrada"), this, e);
219
                        }
220

    
221
                        //Obtenere el burffer interpolado:
222
                        inputBuffers[l] = bufferFactory.getRasterBuf();
223
                        inputBuffers[l] = ((RasterBuffer)inputBuffers[l]).getAdjustedWindow(resultGridExtent.getNX(), resultGridExtent.getNY(), BufferInterpolation.INTERPOLATION_Bilinear);
224

    
225
                        //Aplicar filtro de realce si es necesario:
226

    
227
                        if(inputBuffers[l].getDataType()!=DataBuffer.TYPE_BYTE){
228
                                LinearStretchParams leParams = null;
229
                                try {
230
                                        leParams = LinearStretchParams.createStandardParam(inputRasterLayers[l].getRenderBands(), 0.0, bufferFactory.getDataSource().getStatistics(), false);
231
                                } catch (FileNotOpenException e) {
232
                                        // TODO Auto-generated catch block
233
                                        e.printStackTrace();
234
                                } catch (RasterDriverException e) {
235
                                        // TODO Auto-generated catch block
236
                                        e.printStackTrace();
237
                                }
238

    
239
                                RasterFilter linearStretchEnhancementFilter = EnhancementStretchListManager.createEnhancedFilter(leParams, bufferFactory.getDataSource().getStatistics(),
240
                                                inputRasterLayers[l].getRenderBands(), false);
241
                                linearStretchEnhancementFilter.addParam("raster", inputBuffers[l]);
242
                                linearStretchEnhancementFilter.execute();
243

    
244
                                inputBuffers[l] = (IBuffer)linearStretchEnhancementFilter.getResult("raster");
245
                        }
246
                }
247

    
248
                // Recorrido del grid resultante
249
                insertLineLog(PluginServices.getText(this, "realizando_degradado")+"...");
250
                for (int col = 0; col < resultPxWidth; col++) {
251
                        percent = col*100/resultPxWidth;
252
                        for (int row = 0; row < resultPxHeight; row++) {
253
                                try {
254
                                        setValue(col, row);
255
                                } catch (OutOfGridException e) {
256
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(
257
                                                        this, "bad_access_grid"), this, e);
258
                                }
259
                        }
260
                }
261

    
262
                // Se liberan los buffers
263
                for(int i=0; i<inputRasterLayers.length;i++)
264
                        inputBuffers[i].free();
265

    
266
                createLayer();
267
                if (externalActions != null)
268
                        externalActions.end(outputRasterLayer);
269
        }
270

    
271
        private void createLayer() {
272
                insertLineLog(PluginServices.getText(this, "escribiendo_resultado")+"...");
273

    
274
                writerBufferServer = new WriterBufferServer(resultGrid.getRasterBuf());
275
                AffineTransform aTransform = new AffineTransform(resultGridExtent
276
                                .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(),
277
                                resultGridExtent.getMin().getX(), resultGridExtent.getMax()
278
                                                .getY());
279
                try {
280
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileName,
281
                                        resultGrid.getBandCount(), aTransform, resultGridExtent
282
                                                        .getNX(), resultGridExtent.getNY(), resultGrid
283
                                                        .getDataType(), GeoRasterWriter.getWriter(fileName)
284
                                                        .getParams(), inputRasterLayers[0].getProjection());
285
                        grw.dataWrite();
286
                        grw.writeClose();
287
                        resultGrid.getRasterBuf().free();
288
                        outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
289
                                        fileName, inputRasterLayers[0].getProjection());
290

    
291
                } catch (NotSupportedExtensionException e) {
292
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
293
                                        "error_writer_notsupportedextension"), this, e);
294
                } catch (RasterDriverException e) {
295
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
296
                                        "raster_buffer_invalid_extension"), this, e);
297
                } catch (IOException e) {
298
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
299
                                        "error_writer"), this, e);
300
                } catch (InterruptedException e) {
301
                        Thread.currentThread().interrupt();
302
                } catch (LoadLayerException e) {
303
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
304
                }
305
        }
306

    
307
        private void setValue(int col, int row) throws OutOfGridException {
308
                // ?Est? el punto en la intersecci?n?
309
                Point2D worldCoords = rasterToWorld(col, row);
310
                if (intersection.contains(worldCoords)) {
311
                        setFeatherValue(col, row);
312
                        return;
313
                }
314
                byte value = 0;
315
                for (int g = 0; g < inputBuffers.length; g++) {
316
                        if (inputExtents[g].contains(worldCoords)){
317
                                for (int band = 0; band < inputBuffers[g].getBandCount(); band++) {
318
                                        value = (byte)RemoteSensingUtils.getCellValueInLayerCoords(inputBuffers[g], col, row, band);
319
                                        resultGrid.setBandToOperate(band);
320
                                        if ((byte)inputBuffers[g].getNoDataValue() != value) {
321
                                                resultGrid.setCellValue(col, row, value);
322
                                        } else {
323
                                                resultGrid.setCellValue(col, row, (byte) resultGrid
324
                                                                .getNoDataValue());
325
                                        }
326
                                }
327
                                return;
328
                        }
329
                }
330
        }
331

    
332
        private void setFeatherValue(int col, int row) throws OutOfGridException {
333
                Point2D worldPoint = rasterToWorld(col, row);
334

    
335
                totalD = 0;
336

    
337
                for (int i = 0; i < borders.length; i++) {
338

    
339
                        // C?lculo de la distancia m?nima a los bordes de cada imagen
340
                        distances[i] = Double.POSITIVE_INFINITY;
341
                        for (int j = 0; j < borders[0].length; j++)
342
                                if (borders[i][j] != null) {
343
                                        double newDistance = borders[i][j].ptLineDist(worldPoint);
344
                                        if (distances[i] > newDistance)
345
                                                distances[i] = newDistance;
346
                                }
347
                        totalD = totalD + distances[i];
348

    
349
                        value = 0;
350
                        bandCount = inputBuffers[i].getBandCount();
351
                        noDataValue = (byte)inputBuffers[i].getNoDataValue();
352
                        for (int band = 0; band < resultbandCount; band++) {
353
                                        if (band < bandCount){
354
                                                value = RemoteSensingUtils.getCellValueInLayerCoords(inputBuffers[i], col,row, band);
355
                                                if (noDataValue!=value)
356
                                                        result[band] = result[band] + value * distances[i];
357
                                        }
358
                        }
359
                }
360

    
361
                // Escribir el resultado de cada banda.
362
                for (int band = 0; band < resultbandCount; band++) {
363
                        result[band] = result[band] / totalD;
364
                        resultGrid.setBandToOperate(band);
365
                        resultGrid.setCellValue(col, row, (byte) result[band]);
366
                        result[band] = 0;
367
                }
368
        }
369

    
370
        public Object getResult() {
371
                return outputRasterLayer;
372
        }
373

    
374
        public int getPercent() {
375
                if (grw != null)
376
                        return grw.getPercent();
377

    
378
                return percent;
379
        }
380

    
381
        public String getTitle() {
382
                return PluginServices.getText(this, "calculando_feather");
383
        }
384

    
385
        /**
386
         * Calcula los bordes que interesan para la obtenci?n de distancias en el
387
         * proceso.
388
         */
389
        private void calculateBorders() {
390

    
391
                borders = new Line2D.Double[2][4];
392

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

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

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

    
417
                border = new Line2D.Double(inputExtents[0].getMinX(), inputExtents[0]
418
                                .getMinY(), inputExtents[0].getMinX(), inputExtents[0]
419
                                .getMaxY());
420
                if (inputExtents[1].intersectsLine(border))
421
                        borders[0][3] = border;
422
                else
423
                        borders[0][3] = null;
424

    
425
                border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1]
426
                                .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1]
427
                                .getMinY());
428
                if (inputExtents[0].intersectsLine(border))
429
                        borders[1][0] = border;
430
                else
431
                        borders[1][0] = null;
432

    
433
                border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1]
434
                                .getMaxY(), inputExtents[1].getMaxX(), inputExtents[1]
435
                                .getMinY());
436
                if (inputExtents[0].intersectsLine(border))
437
                        borders[1][1] = border;
438
                else
439
                        borders[1][1] = null;
440

    
441
                border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1]
442
                                .getMinY(), inputExtents[1].getMinX(), inputExtents[1]
443
                                .getMinY());
444
                if (inputExtents[0].intersectsLine(border))
445
                        borders[1][2] = border;
446
                else
447
                        borders[1][2] = null;
448

    
449
                border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1]
450
                                .getMinY(), inputExtents[1].getMinX(), inputExtents[1]
451
                                .getMaxY());
452
                if (inputExtents[0].intersectsLine(border))
453
                        borders[1][3] = border;
454
                else
455
                        borders[1][3] = null;
456
        }
457

    
458
        private Point2D rasterToWorld(int col, int row) {
459
                double worldX = resultGridExtent.getMin().getX() + (col + 0.5)
460
                                * resultGridExtent.getCellSizeX();
461
                double worldY = resultGridExtent.getMax().getY() + (row + 0.5)
462
                                * resultGridExtent.getCellSizeY();
463
                return new Point2D.Double(worldX, worldY);
464
        }
465
}