Statistics
| Revision:

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

History | View | Annotate | Download (12.9 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.setDrawableBands(drawableBands);
153

    
154
                        try {
155
                                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
                                        bufferFactory.setReadOnly(true);
162

    
163
                                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
                        } 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
                        inputBuffers[l] = ((RasterBuffer) inputBuffers[l])
181
                                        .getAdjustedWindow(xResolution, yResolution,
182
                                                        GridInterpolated.INTERPOLATION_NearestNeighbour);
183
                }
184

    
185
                // Recorrido del grid resultante
186
                // 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
                                }
200
                        }
201
                }
202
                // }
203
                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
                // ?Est? el punto en la intersecci?n?
244
                Point2D worldCoords = rasterToWorld(col, row);
245
                if (intersection.contains(worldCoords)) {
246
                        setFeatherValue(col, row);
247
                        /*
248
                         * for (int band = 0; band<resultbandCount; band++){
249
                         * resultGrid.setBandToOperate(band); resultGrid.setCellValue(col,
250
                         * row, (byte)255); }
251
                         */
252
                        return;
253
                }
254

    
255
                byte values[] = new byte[resultbandCount];
256
                for (int g = 0; g < inputBuffers.length; g++) {
257
                        inputBuffers[g].getElemByte(row, col, values);
258
                        for (int band = 0; band < resultbandCount; band++) {
259
                                resultGrid.setBandToOperate(band);
260
                                if (inputBuffers[g].getNoDataValue() != values[band]) {
261
                                        resultGrid.setCellValue(col, row, values[band]);
262
                                } else {
263
                                        resultGrid.setCellValue(col, row, (byte) resultGrid
264
                                                        .getNoDataValue());
265
                                }
266
                        }
267
                        return;
268
                }
269
        }
270

    
271
        private void setFeatherValue(int col, int row) throws OutOfGridException {
272
                Point2D worldPoint = rasterToWorld(col, row);
273

    
274
                double distances[] = new double[borders.length];
275
                byte values[] = new byte[resultbandCount];
276
                double totalD = 0;
277
                double result[] = new double[resultbandCount];
278

    
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
                                        double newDistance = borders[i][j].ptLineDist(worldPoint);
286
                                        if (distances[i] > newDistance)
287
                                                distances[i] = newDistance;
288
                                }
289
                        totalD = totalD + distances[i];
290

    
291
                        inputBuffers[i].getElemByte(row, col, values);
292
                        for (int band = 0; band < resultbandCount; band++) {
293
                                result[band] = result[band] + values[band] * distances[i];
294
                        }
295
                }
296

    
297
                // Escribir el resultado de cada banda.
298
                for (int band = 0; band < resultbandCount; band++) {
299
                        result[band] = result[band] / totalD;
300
                        resultGrid.setBandToOperate(band);
301
                        resultGrid.setCellValue(col, row, (byte) result[band]);
302
                        result[band] = 0;
303
                }
304
        }
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

    
321
                borders = new Line2D.Double[2][4];
322

    
323
                Line2D.Double border = new Line2D.Double(inputExtents[0].getMinX(),
324
                                inputExtents[0].getMaxY(), inputExtents[0].getMaxX(),
325
                                inputExtents[0].getMaxY());
326
                if (inputExtents[1].intersectsLine(border))
327
                        borders[0][0] = border;
328
                else
329
                        borders[0][0] = null;
330

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

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

    
347
                border = new Line2D.Double(inputExtents[0].getMinX(), inputExtents[0]
348
                                .getMinY(), inputExtents[0].getMinX(), inputExtents[0]
349
                                .getMaxY());
350
                if (inputExtents[1].intersectsLine(border))
351
                        borders[0][3] = border;
352
                else
353
                        borders[0][3] = null;
354

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

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

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

    
379
                border = new Line2D.Double(inputExtents[1].getMinX(), inputExtents[1]
380
                                .getMinY(), inputExtents[1].getMinX(), inputExtents[1]
381
                                .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)
390
                                * resultGridExtent.getCellSizeX();
391
                double worldY = resultGridExtent.getMax().getY() + (row + 0.5)
392
                                * resultGridExtent.getCellSizeY();
393
                return new Point2D.Double(worldX, worldY);
394
        }
395
}