root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / tasseledcap / TasseledCapProcess.java @ 13820
History | View | Annotate | Download (12.2 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2006 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 |
|
42 |
package org.gvsig.remotesensing.tasseledcap; |
43 |
|
44 |
import java.awt.Component; |
45 |
import java.awt.geom.AffineTransform; |
46 |
import java.io.File; |
47 |
import java.io.IOException; |
48 |
|
49 |
import javax.swing.JOptionPane; |
50 |
import javax.swing.JPopupMenu.Separator; |
51 |
|
52 |
|
53 |
import org.gvsig.fmap.raster.layers.FLyrRasterSE; |
54 |
import org.gvsig.gui.beans.incrementabletask.IIncrementable; |
55 |
import org.gvsig.gui.beans.incrementabletask.IncrementableEvent; |
56 |
import org.gvsig.gui.beans.incrementabletask.IncrementableListener; |
57 |
import org.gvsig.gui.beans.incrementabletask.IncrementableTask; |
58 |
import org.gvsig.raster.buffer.RasterBuffer; |
59 |
import org.gvsig.raster.buffer.RasterBufferInvalidAccessException; |
60 |
import org.gvsig.raster.buffer.RasterBufferInvalidException; |
61 |
import org.gvsig.rastertools.cutting.WriterBufferServer; |
62 |
import org.gvsig.raster.dataset.GeoRasterWriter; |
63 |
import org.gvsig.raster.dataset.IBuffer; |
64 |
import org.gvsig.raster.dataset.NotSupportedExtensionException; |
65 |
import org.gvsig.raster.dataset.RasterDriverException; |
66 |
import org.gvsig.raster.grid.Grid; |
67 |
import org.gvsig.raster.grid.GridExtent; |
68 |
import org.gvsig.raster.grid.OutOfGridException; |
69 |
import org.gvsig.raster.process.CancelEvent; |
70 |
import org.gvsig.raster.process.RasterTask; |
71 |
import org.gvsig.raster.process.RasterTaskQueue; |
72 |
|
73 |
import com.iver.andami.PluginServices; |
74 |
import com.iver.andami.Utilities; |
75 |
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException; |
76 |
import com.iver.cit.gvsig.fmap.MapContext; |
77 |
import com.iver.cit.gvsig.fmap.layers.FLayer; |
78 |
|
79 |
|
80 |
/**
|
81 |
* Implementaci?n de la transformaci?n Tasseled Cap. La Trasformaci?n es aplicable a imagenes
|
82 |
* LandSat MS, LandSatTM y LandSantETM
|
83 |
*
|
84 |
* @author Alejandro Mu?oz
|
85 |
*
|
86 |
*/
|
87 |
public class TasseledCapProcess implements Runnable, IIncrementable, IncrementableListener{ |
88 |
|
89 |
private Grid grid = null; |
90 |
private IncrementableTask incrementableTask = null; |
91 |
private int percent = 0; |
92 |
private boolean cancel = false; |
93 |
private MapContext mapContext = null; |
94 |
private int type = 0; |
95 |
private String layerName = null; |
96 |
private Thread blinker = null; |
97 |
private WriterBufferServer writerBufferServer = null; |
98 |
private Grid resultGrid = null; |
99 |
private AffineTransform atransform = null; |
100 |
private RasterTask rasterTask = new RasterTask(this); |
101 |
/**
|
102 |
* Constructor.
|
103 |
*
|
104 |
* @param grid Grid sobre el que se aplica la transformaci?n
|
105 |
* @param mapContext
|
106 |
* @param type tipo de imagen: <code>1</code> LandSat MS, <code>2</code> LandSat TM, <code>3</code> LandSat ETM+
|
107 |
* @param layerName nombre de la capa generada
|
108 |
* @param atransform matriz de transformacion de capa generada
|
109 |
*/
|
110 |
public TasseledCapProcess(Grid grid,MapContext mapContext,int type, String layerName, AffineTransform aTransform) { |
111 |
this.grid = grid;
|
112 |
this.mapContext = mapContext;
|
113 |
this.type = type;
|
114 |
this.layerName = layerName;
|
115 |
this.atransform= aTransform;
|
116 |
} |
117 |
|
118 |
/**
|
119 |
* Lanza el proceso.
|
120 |
*
|
121 |
*/
|
122 |
public void start() { |
123 |
cancel = false;
|
124 |
blinker = new Thread(this); |
125 |
blinker.start(); |
126 |
} |
127 |
|
128 |
/**
|
129 |
* Proceso.
|
130 |
*/
|
131 |
public void run() { |
132 |
RasterTaskQueue.register(rasterTask); //Registro de la tarea
|
133 |
double matrixParams[][]= null; |
134 |
// Sensor LandSat
|
135 |
switch (type){
|
136 |
|
137 |
case 0: |
138 |
// MATRIZ COEFICIENTES IMAGEN LANDSAT MS
|
139 |
double LandSatMS[][]= |
140 |
{ |
141 |
/* Brillo de suelo */ {0.433, 0.632, 0.586, 0.264}, |
142 |
/* Indice de Verdor */ {-0.290, -0.562, 0.600, 0.491}, |
143 |
/* Indice de Senescencia*/{-0.829, 0.522, -0.039, 0.194}, |
144 |
/* Cuarta */ {0.223, 0.012, -0.543, 0.810} |
145 |
}; |
146 |
|
147 |
matrixParams=LandSatMS; |
148 |
break;
|
149 |
|
150 |
case 1: |
151 |
// MATRIZ COEFICIENTES IMAGEN LANDSAT TM
|
152 |
|
153 |
double LandSatTM[][]={ |
154 |
|
155 |
/* Brillo */ {0.33183, 0.33121, 0.55177, 0.42514, 0.48087, 0.25252 }, |
156 |
/* Verdor */ {-0.24717, -0.16263, -0.40639, 0.85468, 0.05493, -0.11749 }, |
157 |
/* Tercera */ {0.13929, 0.22490, 0.40359, 0.25178, -0.70133, -0.45732 }, |
158 |
|
159 |
}; |
160 |
|
161 |
matrixParams= LandSatTM; |
162 |
break;
|
163 |
|
164 |
|
165 |
case 2: |
166 |
// MATRIZ COEFICIENTES IMAGEN LANDSAT ETM
|
167 |
double LandSatETM[][]={ |
168 |
|
169 |
/* Brightness */ {0.3561, 0.3972, 0.3904, 0.6966, 0.2286, 0.1596 }, |
170 |
/* Greenness */ {-0.3344, -0.3544, -0.4556, 0.6966, -0.0242, -0.2630}, |
171 |
/* Vetness */ {0.2626, 0.2141, 0.0926, 0.0656, -0.7629, -0.5388 }, |
172 |
/* Fourth */ {0.0805, -0.0498, 0.1950, -0.1327, 0.5752, -0.7775 }, |
173 |
/* Fifth */ {-0.7252, -0.0202, 0.6683, 0.0631, -0.1494, -0.0274 }, |
174 |
/* Sixth */ {0.4000, -0.8172, 0.3832, 0.0602, -0.1095, -0.0985 } |
175 |
}; |
176 |
|
177 |
matrixParams= LandSatETM; |
178 |
break;
|
179 |
|
180 |
} |
181 |
|
182 |
GridExtent layerExtent = null;
|
183 |
layerExtent= grid.getGridExtent(); |
184 |
|
185 |
|
186 |
// Grid para escrituta
|
187 |
int bands[]= new int [matrixParams.length]; |
188 |
for(int i=0;i<matrixParams.length; i++) |
189 |
bands[i]=i; |
190 |
|
191 |
try {
|
192 |
resultGrid = new Grid(layerExtent, layerExtent, IBuffer.TYPE_DOUBLE, bands);
|
193 |
} catch (RasterBufferInvalidException e1) {
|
194 |
e1.printStackTrace(); |
195 |
} |
196 |
|
197 |
// Algoritmo TasseledCap. Trasformacion
|
198 |
|
199 |
double valor=0; |
200 |
// Buffer de tipo Byte
|
201 |
int iNX=layerExtent.getNX();
|
202 |
int iNY=layerExtent.getNY();
|
203 |
|
204 |
try{
|
205 |
|
206 |
if (grid.getRasterBuf().getDataType()== RasterBuffer.TYPE_BYTE){
|
207 |
for(int i=0; i<iNX;i++ ) { |
208 |
if (cancel)
|
209 |
return;
|
210 |
for (int j=0; j<iNY;j++){ |
211 |
for (int k=0; k<matrixParams.length; k++){ |
212 |
for(int s=0;s<matrixParams[0].length;s++) |
213 |
{ grid.setBandToOperate(s); |
214 |
valor+=(double)grid.getCellValueAsByte(i,j)*matrixParams[k][s];
|
215 |
} |
216 |
resultGrid.setBandToOperate(k); |
217 |
resultGrid.setCellValue(i, j, valor); |
218 |
valor=0;
|
219 |
percent = i*100/grid.getNX();
|
220 |
} |
221 |
} |
222 |
} |
223 |
} // Fin RasterBuffer.TYPE_BYTE
|
224 |
|
225 |
// El buffer es de tipo short
|
226 |
if (grid.getRasterBuf().getDataType()== RasterBuffer.TYPE_SHORT){
|
227 |
|
228 |
for(int i=0; i<layerExtent.getNX();i++ ) { |
229 |
if (cancel)
|
230 |
return;
|
231 |
for (int j=0; j<layerExtent.getNY();j++){ |
232 |
for (int k=0; k<matrixParams.length ; k++){ |
233 |
for(int s=0;s<matrixParams[0].length;s++) |
234 |
{ grid.setBandToOperate(s); |
235 |
valor+=(double)grid.getCellValueAsShort(i,j)*matrixParams[k][s];
|
236 |
} |
237 |
resultGrid.setBandToOperate(k); |
238 |
resultGrid.setCellValue(i, j, valor); |
239 |
valor=0;
|
240 |
percent = i*100/grid.getNX();
|
241 |
} |
242 |
} |
243 |
} |
244 |
} // Fin RasterBuffer.TYPE_SHORT
|
245 |
|
246 |
// El buffer es de tipo entero
|
247 |
if (grid.getRasterBuf().getDataType()== RasterBuffer.TYPE_INT){
|
248 |
|
249 |
for(int i=0; i<layerExtent.getNX();i++ ) { |
250 |
if (cancel)
|
251 |
return;
|
252 |
for (int j=0; j<layerExtent.getNY();j++){ |
253 |
for (int k=0; k<matrixParams.length ; k++){ |
254 |
for(int s=0;s<matrixParams[0].length;s++) |
255 |
{ |
256 |
grid.setBandToOperate(s); |
257 |
valor+=(double)grid.getCellValueAsInt(i,j)*matrixParams[k][s];
|
258 |
} |
259 |
resultGrid.setBandToOperate(k); |
260 |
resultGrid.setCellValue(i, j, valor); |
261 |
valor=0;
|
262 |
percent = i*100/grid.getNX();
|
263 |
} |
264 |
} |
265 |
} |
266 |
} // Fin RasterBuffer.TYPE_INT
|
267 |
|
268 |
// El buffer es de tipo float
|
269 |
if (grid.getRasterBuf().getDataType()== RasterBuffer.TYPE_FLOAT){
|
270 |
|
271 |
for(int i=0; i<layerExtent.getNX();i++ ) { |
272 |
if (cancel)
|
273 |
return;
|
274 |
for (int j=0; j<layerExtent.getNY();j++){ |
275 |
for (int k=0; k<matrixParams.length ; k++){ |
276 |
for(int s=0;s<matrixParams[0].length;s++) |
277 |
{ |
278 |
grid.setBandToOperate(s); |
279 |
valor+=(double)grid.getCellValueAsFloat(i,j)*matrixParams[k][s];
|
280 |
} |
281 |
|
282 |
resultGrid.setBandToOperate(k); |
283 |
resultGrid.setCellValue(i, j, valor); |
284 |
valor=0;
|
285 |
percent = i*100/grid.getNX();
|
286 |
} |
287 |
} |
288 |
} |
289 |
} // Fin RasterBuffer.TYPE_FLOAT
|
290 |
|
291 |
// El buffer es de tipo double
|
292 |
if (grid.getRasterBuf().getDataType()== RasterBuffer.TYPE_FLOAT){
|
293 |
|
294 |
for(int i=0; i<layerExtent.getNX();i++ ) { |
295 |
if (cancel)
|
296 |
return;
|
297 |
for (int j=0; j<layerExtent.getNY();j++){ |
298 |
for (int k=0; k<matrixParams.length ; k++){ |
299 |
for(int s=0;s<matrixParams[0].length;s++) |
300 |
{ |
301 |
grid.setBandToOperate(s); |
302 |
valor+=(double)grid.getCellValueAsDouble(i,j)*matrixParams[k][s];
|
303 |
} |
304 |
resultGrid.setBandToOperate(k); |
305 |
resultGrid.setCellValue(i, j, valor); |
306 |
valor=0;
|
307 |
|
308 |
percent = i*100/grid.getNX();
|
309 |
} |
310 |
} |
311 |
} |
312 |
} // Fin RasterBuffer.TYPE_DOUBLE
|
313 |
|
314 |
// Escritura del resultado en fichero
|
315 |
if(mapContext!=null) |
316 |
writeToFile(); |
317 |
|
318 |
}catch (OutOfGridException e) {
|
319 |
e.printStackTrace(); |
320 |
} catch (RasterBufferInvalidAccessException e) {
|
321 |
e.printStackTrace(); |
322 |
} finally {
|
323 |
RasterTaskQueue.remove(rasterTask); |
324 |
if (incrementableTask != null) |
325 |
incrementableTask.processFinalize(); |
326 |
} |
327 |
RasterTaskQueue.remove(rasterTask); |
328 |
} // Fin run()
|
329 |
|
330 |
|
331 |
|
332 |
public void writeToFile(){ |
333 |
|
334 |
String fileName=layerName;
|
335 |
int endIndex = fileName.lastIndexOf("."); |
336 |
if (endIndex < 0) |
337 |
endIndex = fileName.length(); |
338 |
|
339 |
// Escritura de los datos a disco
|
340 |
IBuffer buffer = resultGrid.getRasterBuf(); |
341 |
writerBufferServer = new WriterBufferServer(buffer);
|
342 |
|
343 |
try{
|
344 |
GeoRasterWriter grw = GeoRasterWriter.getWriter(writerBufferServer, fileName, buffer.getBandCount(), atransform, buffer.getWidth(), buffer.getHeight(),buffer.getDataType(), GeoRasterWriter.getWriter(fileName).getParams(),null);
|
345 |
grw.dataWrite(); |
346 |
grw.writeClose(); |
347 |
mapContext.beginAtomicEvent(); |
348 |
FLayer lyr = null;
|
349 |
lyr = FLyrRasterSE.createLayer(layerName.substring( |
350 |
layerName.lastIndexOf(File.separator) + 1, endIndex),new File(layerName), mapContext.getProjection()); |
351 |
mapContext.getLayers().addLayer(lyr); |
352 |
mapContext.endAtomicEvent(); |
353 |
mapContext.invalidate(); |
354 |
} catch (NotSupportedExtensionException e) {
|
355 |
e.printStackTrace(); |
356 |
} catch (RasterDriverException e) {
|
357 |
e.printStackTrace(); |
358 |
} catch (IOException e) { |
359 |
e.printStackTrace(); |
360 |
} catch (InterruptedException e) { |
361 |
Thread.currentThread().interrupt();
|
362 |
} catch (LoadLayerException e) {
|
363 |
JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), |
364 |
PluginServices.getText(this, "error_cargar_capa")); |
365 |
} |
366 |
|
367 |
} // Fin writeToFile
|
368 |
|
369 |
|
370 |
|
371 |
public Grid getGridResult(){
|
372 |
return resultGrid;
|
373 |
} |
374 |
|
375 |
public String getLabel() { |
376 |
return PluginServices.getText(this,"procesando"); |
377 |
} |
378 |
|
379 |
public String getLog() { |
380 |
if (writerBufferServer==null) |
381 |
return PluginServices.getText(this,"calculando_tasseled_cap")+"..."; |
382 |
else
|
383 |
return PluginServices.getText(this,"escribiendo_resultado")+"..."; |
384 |
} |
385 |
|
386 |
public int getPercent() { |
387 |
if (writerBufferServer==null) |
388 |
return percent;
|
389 |
else
|
390 |
return writerBufferServer.getPercent();
|
391 |
} |
392 |
|
393 |
public String getTitle() { |
394 |
return PluginServices.getText(this,"tasseled_cap"); |
395 |
} |
396 |
|
397 |
public void actionCanceled(IncrementableEvent e) { |
398 |
rasterTask.setEvent(new CancelEvent(this)); |
399 |
} |
400 |
|
401 |
public void actionResumed(IncrementableEvent e) { |
402 |
|
403 |
} |
404 |
|
405 |
public void actionSuspended(IncrementableEvent e) { |
406 |
} |
407 |
|
408 |
public void setIncrementableTask(IncrementableTask incrementableTask) { |
409 |
this.incrementableTask = incrementableTask;
|
410 |
this.incrementableTask.addIncrementableListener(this); |
411 |
} |
412 |
|
413 |
} |