Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / FeatherProcess.java @ 31496

History | View | Annotate | Download (13.2 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.File;
48
import java.io.IOException;
49

    
50
import org.gvsig.andami.PluginServices;
51
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
52
import org.gvsig.fmap.geom.primitive.Envelope;
53
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
54
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
55
import org.gvsig.raster.RasterProcess;
56
import org.gvsig.raster.buffer.RasterBufferInvalidException;
57
import org.gvsig.raster.buffer.WriterBufferServer;
58
import org.gvsig.raster.dataset.GeoRasterWriter;
59
import org.gvsig.raster.dataset.IBuffer;
60
import org.gvsig.raster.dataset.NotSupportedExtensionException;
61
import org.gvsig.raster.dataset.RasterDriverException;
62
import org.gvsig.raster.datastruct.Extent;
63
import org.gvsig.raster.grid.Grid;
64
import org.gvsig.raster.grid.GridException;
65
import org.gvsig.raster.grid.GridExtent;
66
import org.gvsig.raster.grid.GridInterpolated;
67
import org.gvsig.raster.grid.OutOfGridException;
68
import org.gvsig.raster.util.RasterToolsUtil;
69

    
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 FeatherProcess extends RasterProcess {
79

    
80
        private FLyrRasterSE inputRasterLayers[] = null;
81
        private Grid inputGrids[] = null;
82
        private FLyrRasterSE outputRasterLayer = null;
83

    
84
        private Line2D borders[][] = null;
85

    
86
        private Rectangle2D inputExtents[] = null;
87
        private Rectangle2D intersection = null;
88

    
89
        private Grid resultGrid = null;
90
        private GridExtent resultGridExtent = null;
91
        private int resultPxWidth, resultPxHeight= 0;
92
        private int resultbandCount = 0;
93
        private int resultNodataValue = 0;
94

    
95
        private WriterBufferServer writerBufferServer = null;
96
        private String fileName = null;
97
        private DefaultViewPanel view                = null;
98

    
99
        int percent = 0;
100

    
101
        //Variables auxiliares:
102
        private double distances[] = null;
103
        private double cellValue = 0;
104
        private double totalDistance = 0;
105
        private double resultCellVale[] =null;
106
        private GeoRasterWriter grw = null;;
107

    
108

    
109
        public void init() {
110

    
111
                // Obtener las capas que intervienen en el mosaico.
112
                inputRasterLayers = (FLyrRasterSE[]) getParam("inputRasterLayers");
113
                view = (DefaultViewPanel) getParam("view");
114
                inputExtents = new Rectangle2D.Double[inputRasterLayers.length];
115
                for (int i = 0; i<inputRasterLayers.length;i++){
116
                        Envelope env=inputRasterLayers[i].getFullEnvelope();
117
                        inputExtents[i] = new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env.getLength(0), env.getLength(1));
118
                }
119

    
120
                intersection = new Rectangle2D.Double();
121
                Rectangle2D.intersect(inputExtents[0], inputExtents[1], intersection);
122

    
123
                Rectangle2D resultExtent = new Rectangle2D.Double();
124
                Rectangle2D.union(inputExtents[0], inputExtents[1], resultExtent);
125

    
126
                double cellSizeX = inputRasterLayers[0].getAffineTransform().getScaleX();
127
                double cellSizeY = inputRasterLayers[0].getAffineTransform().getScaleY();
128

    
129
                // TODO: Contemplar el caso de capas con distinto tama?o de celda.
130
                for (int i = 1; i< inputRasterLayers.length; i++)
131
                {
132
                        if (Math.abs(cellSizeX) > Math.abs(inputRasterLayers[i].getAffineTransform().getScaleX()))
133
                                cellSizeX = inputRasterLayers[i].getAffineTransform().getScaleX();
134
                        if (Math.abs(cellSizeY) > Math.abs(inputRasterLayers[i].getAffineTransform().getScaleY()))
135
                                cellSizeY = inputRasterLayers[i].getAffineTransform().getScaleY();
136
                }
137

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

    
143
                // Grid Resultante
144
                try {
145
                        // TODO: Determiar el tipo de dato y n?mero de bandas.
146
                        resultGrid = new Grid(resultGridExtent, resultGridExtent,
147
                                        IBuffer.TYPE_BYTE, new int[] { 0, 1, 2 });
148
                        resultGrid.setNoDataValue(0);
149

    
150
                        resultbandCount = resultGrid.getBandCount();
151
                        resultCellVale = new double[resultbandCount];
152
                } catch (RasterBufferInvalidException e) {
153
                        RasterToolsUtil.messageBoxError("buffer_incorrecto", this, e);
154
                }
155
                fileName = getStringParam("filename");
156

    
157
        }
158

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

    
164
                // Construccion de los grid de entrada:
165
                inputGrids = new Grid[inputRasterLayers.length];
166
                for (int l = 0; l < inputRasterLayers.length; l++) {
167
                        try {
168
                                inputGrids[l] = new Grid(inputRasterLayers[l].getDataSource(), new int[] { 0, 1, 2 }, resultGridExtent);
169
                                inputGrids[l].setInterpolationMethod(GridInterpolated.INTERPOLATION_NearestNeighbour);
170
                        } catch (RasterBufferInvalidException e) {
171
                                // TODO Auto-generated catch block
172
                                e.printStackTrace();
173
                        }
174
                }
175

    
176
                // Recorrido del grid resultante
177
                for (int col = 0; col < resultPxWidth; col++){
178
                        percent = col*100/resultPxWidth;
179
                        System.out.println("------------- "+percent+" %"); /////////DEBUG***********
180
                        for (int row = 0; row < resultPxHeight;row++) {
181
                                try {
182
                                        setValue(col, row);
183
                                } catch (OutOfGridException e) {
184
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(
185
                                                        this, "bad_access_grid"), this, e);
186
                                }
187
                        }
188
                }
189
                createLayer();
190
                if (externalActions != null)
191
                        externalActions.end(outputRasterLayer);
192
        }
193

    
194
        private void createLayer() {
195
                writerBufferServer = new WriterBufferServer(resultGrid.getRasterBuf());
196
                AffineTransform aTransform = new AffineTransform(resultGridExtent
197
                                .getCellSizeX(), 0.0, 0.0, resultGridExtent.getCellSizeY(),
198
                                resultGridExtent.getMin().getX(), resultGridExtent.getMax()
199
                                                .getY());
200
                try {
201
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileName,
202
                                        resultGrid.getBandCount(), aTransform, resultGridExtent
203
                                                        .getNX(), resultGridExtent.getNY(), resultGrid
204
                                                        .getDataType(), GeoRasterWriter.getWriter(fileName)
205
                                                        .getParams(), null);
206
                        grw.dataWrite();
207
                        grw.getPercent();
208
                        grw.writeClose();
209

    
210
                        int endIndex = fileName.lastIndexOf(".");
211
                        if (endIndex < 0)
212
                                endIndex = fileName.length();
213
                        outputRasterLayer = FLyrRasterSE.createLayer(fileName.substring(fileName.lastIndexOf(File.separator) + 1, endIndex),
214
                                        fileName, null);
215
                        if(view==null)
216
                                return;
217
                        view.getModel().getMapContext().getLayers().addLayer(outputRasterLayer);
218
                } catch (NotSupportedExtensionException e) {
219
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
220
                                        "error_writer_notsupportedextension"), this, e);
221
                } catch (RasterDriverException e) {
222
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
223
                                        "raster_buffer_invalid_extension"), this, e);
224
                } catch (IOException e) {
225
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this,
226
                                        "error_writer"), this, e);
227
                } catch (InterruptedException e) {
228
                        Thread.currentThread().interrupt();
229
                } catch (LoadLayerException e) {
230
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
231
                }
232
        }
233

    
234

    
235
        private void setValue(int col, int row) throws OutOfGridException {
236
                //?Est? el punto en la intersecci?n?
237
                Point2D  worldCoords = rasterToWorld(col, row);
238
                if (intersection.contains(worldCoords)){   //////**************************************************
239
                        setFeatherValue(col, row);
240
                        return;
241
                }
242

    
243
                for (int g = 0; g < inputGrids.length; g++) {
244
                        if (inputExtents[g].contains(worldCoords)){ //////**************************************************
245
                                try {
246

    
247
                                        for (int band = 0; band < resultbandCount; band++){
248
                                                inputGrids[g].setBandToOperate(band);
249
                                                resultGrid.setBandToOperate(band);
250
                                                cellValue = inputGrids[g].getCellValueAsByte(col, row) & 0xff;
251
                                                if(!inputGrids[g].isNoDataValue(cellValue)){
252
                                                        resultGrid.setCellValue(col, row, (byte)cellValue);
253
                                                }
254
                                                else{
255
                                                        resultGrid.setCellValue(col, row,(byte) resultNodataValue);
256
                                                }
257
                                        }
258
                                } catch (GridException e) {
259
                                        // TODO Auto-generated catch block
260
                                        e.printStackTrace();
261
                                }
262
                                return;
263
                        }
264
                }
265
        }
266

    
267
        private void setFeatherValue(int col, int row) throws OutOfGridException {
268
                Point2D worldPoint = rasterToWorld(col, row);
269

    
270
                totalDistance = 0;
271
                double newDistance = 0;
272

    
273
                try {
274
                        for (int i = 0; i<borders.length;i++){
275

    
276
                                //C?lculo de la distancia m?nima a los bordes de cada imagen
277
                                distances[i]= Double.POSITIVE_INFINITY;
278
                                for(int j = 0; j<borders[0].length;j++)
279
                                        if (borders[i][j] != null){
280
                                                newDistance = borders[i][j].ptLineDist(worldPoint); ///////*****************************
281
                                                if(distances[i]>newDistance)
282
                                                        distances[i]=newDistance;
283
                                        }
284
                                totalDistance = totalDistance + distances[i];
285

    
286
                                for (int band = 0; band<resultbandCount;band++){
287
                                        inputGrids[i].setBandToOperate(band);
288
                                        cellValue = inputGrids[i].getCellValueAsByte(col, row) & 0xff;
289
                                        resultCellVale[band] = resultCellVale[band] + cellValue*distances[i];
290
                                }
291
                        }
292

    
293
                        //Escribir el resultado de cada banda.
294
                        for (int band = 0; band<resultbandCount;band++){
295
                                resultCellVale[band] = resultCellVale[band]/totalDistance;
296
                                resultGrid.setBandToOperate(band);
297
                                resultGrid.setCellValue(col, row, (byte)resultCellVale[band]);
298
                                resultCellVale[band]=0;
299
                        }
300
                } catch (GridException e) {
301
                        // TODO Auto-generated catch block
302
                        e.printStackTrace();
303
                }
304
        }
305

    
306
        public int getPercent() {
307
                if (grw != null)
308
                        return grw.getPercent();
309

    
310
                return percent;
311
        }
312

    
313
        public String getTitle() {
314
                if (percent == 0)
315
                        return PluginServices.getText(this, "iniciando_proceso");
316

    
317
                if (grw != null)
318
                        return PluginServices.getText(this, "escribiendo_resultado");
319

    
320
                return PluginServices.getText(this, "calculando_feather");
321
        }
322

    
323
        /**
324
         * Calcula los bordes que interesan para la obtenci?n de distancias en el
325
         * proceso.
326
         */
327
        private void calculateBorders() {
328

    
329
                borders = new Line2D.Double[2][4];
330

    
331
                Line2D.Double border = new Line2D.Double(inputExtents[0].getMinX(), inputExtents[0]
332
                                .getMaxY(), inputExtents[0].getMaxX(), inputExtents[0].getMaxY());
333
                if (inputExtents[1].intersectsLine(border))
334
                        borders[0][0] = border;
335
                else
336
                        borders[0][0] = null;
337

    
338
                border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0].getMaxY(),
339
                                inputExtents[0].getMaxX(), inputExtents[0].getMinY());
340
                if (inputExtents[1].intersectsLine(border))
341
                        borders[0][1] = border;
342
                else
343
                        borders[0][1] = null;
344

    
345
                border = new Line2D.Double(inputExtents[0].getMaxX(), inputExtents[0].getMinY(),
346
                                inputExtents[0].getMinX(), inputExtents[0].getMinY());
347
                if (inputExtents[1].intersectsLine(border))
348
                        borders[0][2] = border;
349
                else
350
                        borders[0][2] = null;
351

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

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

    
366
                border = new Line2D.Double(inputExtents[1].getMaxX(), inputExtents[1].getMaxY(),
367
                                inputExtents[1].getMaxX(), inputExtents[1].getMinY());
368
                if (inputExtents[0].intersectsLine(border))
369
                        borders[1][1] = border;
370
                else
371
                        borders[1][1] = null;
372

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

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

    
388
        private Point2D rasterToWorld (int col, int row){
389
                double worldX = resultGridExtent.getMin().getX()+(col+0.5)*resultGridExtent.getCellSizeX();
390
                double worldY = resultGridExtent.getMax().getY()+(row+0.5)*resultGridExtent.getCellSizeY();
391
                return new Point2D.Double(worldX,worldY);
392
        }
393
}