Revision 2175

View differences:

org.gvsig.raster.multifile/trunk/org.gvsig.raster.multifile/org.gvsig.raster.multifile.app.multifileclient/src/main/java/org/gvsig/raster/multifile/app/panel/BandSelectorListener.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
package org.gvsig.raster.multifile.app.panel;
23

  
24
import java.awt.event.ActionEvent;
25
import java.awt.event.ActionListener;
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.io.File;
29
import java.io.IOException;
30
import java.util.ArrayList;
31
import java.util.List;
32

  
33
import javax.swing.JOptionPane;
34

  
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.ui.mdiManager.WindowInfo;
37
import org.gvsig.fmap.dal.DALLocator;
38
import org.gvsig.fmap.dal.DataServerExplorer;
39
import org.gvsig.fmap.dal.DataServerExplorerParameters;
40
import org.gvsig.fmap.dal.coverage.RasterLocator;
41
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
42
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
43
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
44
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
45
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
46
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
47
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
48
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
49
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
50
import org.gvsig.fmap.dal.coverage.util.ProviderServices;
51
import org.gvsig.fmap.dal.exception.CloseException;
52
import org.gvsig.fmap.dal.raster.spi.CoverageStoreProvider;
53
import org.gvsig.fmap.dal.serverexplorer.filesystem.swing.FilesystemExplorerWizardPanel;
54
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
55
import org.gvsig.fmap.dal.spi.DataStoreProvider;
56
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
57
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelEvent;
58
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelListener;
59
import org.gvsig.gui.beans.swing.JFileChooser;
60
import org.gvsig.gui.beans.table.exceptions.NotInitializeException;
61
import org.gvsig.i18n.Messages;
62
import org.gvsig.raster.fmap.layers.DefaultFLyrRaster;
63
import org.gvsig.raster.fmap.layers.FLyrRaster;
64
import org.gvsig.raster.mainplugin.RasterMainPluginUtils;
65
import org.gvsig.raster.mainplugin.config.Configuration;
66
import org.gvsig.raster.multifile.io.MultiFileDataParameters;
67
import org.gvsig.raster.multifile.io.MultiFileFormat;
68
import org.gvsig.raster.multifile.io.MultiFileProvider;
69
import org.gvsig.raster.swing.RasterSwingLibrary;
70
import org.gvsig.tools.locator.LocatorException;
71
import org.slf4j.Logger;
72
import org.slf4j.LoggerFactory;
73

  
74
/**
75
 * Clase que maneja los eventos del panel BandSetupPanel. Gestiona el a?adir o
76
 * eliminar ficheros de la lista y contiene las acciones a realizar cuando en
77
 * panel registrable se pulsa aceptar, aplicar o cancelar.
78
 *
79
 * @author Nacho Brodin (brodin_ign@gva.es)
80
 */
81
public class BandSelectorListener implements ActionListener, ButtonsPanelListener {
82
	private Logger                log            = LoggerFactory.getLogger(BandSelectorListener.class);
83
	private BandSelectorPanel     bandSetupPanel = null;
84
	private JFileChooser          fileChooser    = null;
85
	private FLyrRaster            fLayer         = null;
86
	private boolean               enabled        = true;
87
	private List<File>            fileList       = null;
88

  
89
	/**
90
	 * Constructor
91
	 * @param bs Panel del selector de bandas
92
	 * @param lyr Capa raster
93
	 */
94
	public BandSelectorListener(BandSelectorPanel bs) {
95
		this.bandSetupPanel = bs;
96
		bs.getFileList().getJButtonAdd().addActionListener(this);
97
		bs.getFileList().getJButtonRemove().addActionListener(this);
98
		bs.getNumBandSelectorCombo().addActionListener(this);
99
	}
100

  
101
	/**
102
	 * Comprobar si la asignacion de color es correcta para las 4 bandas. No puede
103
	 * existir una banda con distintas interpretaciones de color. Se comprueban dos
104
	 * casos, asignaciones en escala de grises o en RGB.
105
	 * @param r
106
	 * @param g
107
	 * @param b
108
	 * @param a
109
	 * @return
110
	 */
111
	private boolean isCorrectAssignedBand(int r, int g, int b, int a) {
112
		// Si es gris es correcta la asignacion
113
		if ((r == g) && (r == b) && (r >= 0)) {
114
			// Si el alpha esta asignado a la misma banda es incorrecto
115
			if (r == a)
116
				return false;
117
			// En caso contrario es correcto
118
			return true;
119
		}
120

  
121
		// Si dos bandas coinciden, se dice que no es correcta la asignacion
122
		int list[] = { r, g, b, a };
123
		for (int i = 0; i <= 3; i++)
124
			for (int j = 0; j <= 3; j++)
125
				if ((i != j) && (list[i] == list[j]) && (list[i] > -1))
126
					return false;
127

  
128
		return true;
129
	}
130

  
131
	/**
132
	 * Constructor
133
	 * @param bs Panel del selector de bandas
134
	 * @param lyr Capa raster
135
	 */
136
	public void init(FLyrRaster lyr) {
137
		fLayer = lyr;
138
	}
139

  
140
	/**
141
	 * Listener para la gesti?n de los botones de a?adir, eliminar fichero y
142
	 * el combo de selecci?n de bandas.
143
	 */
144
	public void actionPerformed(ActionEvent e) {
145

  
146
		if (e.getSource().equals(bandSetupPanel.getFileList().getJButtonAdd()))
147
			addFileBand();
148

  
149
		if (e.getSource().equals(bandSetupPanel.getFileList().getJButtonRemove()))
150
			delFileBand();
151

  
152
		if (e.getSource().equals(bandSetupPanel.getNumBandSelectorCombo())) {
153
			String vBands = (String) bandSetupPanel.getNumBandSelectorCombo().getSelectedItem();
154
			if (vBands != null) {
155
				if (vBands.compareTo("3") == 0)
156
					bandSetupPanel.resetMode(3);
157

  
158
				if (vBands.compareTo("2") == 0)
159
					bandSetupPanel.resetMode(2);
160

  
161
				if (vBands.compareTo("1") == 0)
162
					bandSetupPanel.resetMode(1);
163
			}
164
		}
165

  
166
		if (e.getSource().equals(bandSetupPanel.getSaveButton())) {
167
			int rBand = bandSetupPanel.getAssignedBand(RasterDataStore.RED_BAND);
168
			int gBand = bandSetupPanel.getAssignedBand(RasterDataStore.GREEN_BAND);
169
			int bBand = bandSetupPanel.getAssignedBand(RasterDataStore.BLUE_BAND);
170
			int aBand = bandSetupPanel.getAssignedBand(RasterDataStore.ALPHA_BAND);
171

  
172
			if (!isCorrectAssignedBand(rBand, gBand, bBand, aBand)) {
173
				RasterSwingLibrary.messageBoxError(Messages.getText("combinacion_no_asignable"), bandSetupPanel);
174
				return;
175
			}
176

  
177
			RasterSwingLibrary.messageBoxYesOrNot(Messages.getText("color_interpretation_continue"), this);
178
			RasterDataStore dataSource = fLayer.getDataStore();
179
			if(dataSource == null) {
180
				RasterSwingLibrary.messageBoxError(Messages.getText("error_carga_capa"), bandSetupPanel);
181
				return;
182
			}
183

  
184
			ColorInterpretation ci = dataSource.getColorInterpretation();
185
			try {
186
				// Combinaci?n GRAY
187
				if ((rBand == gBand) && (rBand == bBand) && (rBand >= 0)) {
188
					for (int iBand = 0; iBand < bandSetupPanel.getARGBTable().getRowCount(); iBand++) {
189
						ci.setColorInterpValue(iBand, ColorInterpretation.UNDEF_BAND);
190
					}
191
					ci.setColorInterpValue(rBand, ColorInterpretation.GRAY_BAND);
192
					ci.setColorInterpValue(aBand, ColorInterpretation.ALPHA_BAND);
193
				} else {
194
					// Combinaci?n RGB
195
					for (int iBand = 0; iBand < bandSetupPanel.getARGBTable().getRowCount(); iBand++)
196
						ci.setColorInterpValue(iBand, bandSetupPanel.getColorInterpretationByBand(iBand));
197
				}
198
				String fileName = fLayer.getDataStore().getName();
199
				RasterLocator.getManager().getProviderServices().saveObjectToRmfFile(fileName, ci);
200
			} catch (RmfSerializerException exc) {
201
				RasterSwingLibrary.messageBoxError(Messages.getText("error_salvando_rmf"), bandSetupPanel, exc);
202
			} catch (NotInitializeException exc) {
203
				RasterSwingLibrary.messageBoxError(Messages.getText("table_not_initialize"), bandSetupPanel, exc);
204
			}
205
		}
206

  
207
		boolean autoRefreshView = Configuration.getValue("general_auto_preview", Boolean.TRUE).booleanValue();
208
		
209
		if (!autoRefreshView)
210
			return;
211

  
212
		bandSetupPanel.onlyApply();
213
	}
214

  
215
	/**
216
	 * Checks if the new file is compatible with the old one
217
	 * @param file
218
	 * @return
219
	 * @throws LocatorException
220
	 * @throws NotSupportedExtensionException
221
	 * @throws RasterDriverException
222
	 * @throws CloseException
223
	 */
224
	private boolean checkNewFile(String file) throws LocatorException, NotSupportedExtensionException, RasterDriverException, CloseException {
225
		Rectangle2D extentOrigin = fLayer.getFullRasterExtent().toRectangle2D();
226
		
227
		ProviderServices provServ = RasterLocator.getManager().getProviderServices();
228
		RasterDataParameters storeParameters = provServ.createParameters(file);
229
		storeParameters.setSRS(fLayer.getDataStore().getProjection());
230
		RasterDataStore dataStore = RasterLocator.getManager().getProviderServices().open(storeParameters);
231
		
232
		Extent extentNewFile = dataStore.getExtent();
233

  
234
		// Comprobamos que el extent y tama?o del fichero a?adido sea igual al
235
		// fichero original. Si no es as? no abrimos la capa y mostramos un aviso
236

  
237
		double widthNewFile = (extentNewFile.getMax().getX() - extentNewFile.getMin().getX());
238
		double heightNewFile = (extentNewFile.getMax().getY() - extentNewFile.getMin().getY());
239

  
240
		if ((widthNewFile - extentOrigin.getWidth()) > 1.0 || (widthNewFile - extentOrigin.getWidth()) < -1.0 || (heightNewFile - extentOrigin.getHeight()) > 1.0
241
				|| (heightNewFile - extentOrigin.getHeight()) < -1.0) {
242
			return false;
243
		}
244

  
245
		if ((extentNewFile.getMax().getX() - extentNewFile.getMin().getX()) != extentOrigin.getWidth()
246
				|| (extentNewFile.getMax().getY() - extentNewFile.getMin().getY()) != extentOrigin.getHeight()) {
247
			return false;
248
		}
249

  
250
		dataStore.close();
251
		return true;
252
	}
253
	
254
	/**
255
	 * A?ade una banda al raster
256
	 * @param e
257
	 */
258
	private void addFileBand() {
259
		// String[] driverNames = null;
260

  
261
		// Creaci?n del dialogo para selecci?n de ficheros
262
		
263
		fileChooser = new JFileChooser(
264
				FilesystemExplorerWizardPanel.OPEN_LAYER_FILE_CHOOSER_ID,
265
				JFileChooser.getLastPath(FilesystemExplorerWizardPanel.OPEN_LAYER_FILE_CHOOSER_ID, null));
266
		fileChooser.setMultiSelectionEnabled(true);
267
		fileChooser.setAcceptAllFileFilterUsed(false);
268

  
269
		fileChooser.addChoosableFileFilter(new DriverFileFilter());
270

  
271
		int result = fileChooser.showOpenDialog(bandSetupPanel);
272

  
273
		if (result == JFileChooser.APPROVE_OPTION) {
274
			RasterDataStore dataStore = fLayer.getDataStore();
275
			File[] files = fileChooser.getSelectedFiles();
276

  
277
			JFileChooser.setLastPath(FilesystemExplorerWizardPanel.OPEN_LAYER_FILE_CHOOSER_ID, files[0]);
278
			
279
			fileList = new ArrayList<File>();
280
			
281
			for (int i = 0; i < files.length; i++) {
282
				//Checks that the file does not exist
283
				String[] uris = dataStore.getURIByProvider();
284
				boolean exists = false;
285
				for (int j = 0; j < uris.length; j++) {
286
					if (uris[j].endsWith(files[i].getName())) {
287
						RasterSwingLibrary.messageBoxError( Messages.getText("fichero_existe") + ": " + files[i].getAbsolutePath(), bandSetupPanel);
288
						exists = true;
289
						break;
290
					}
291
				}
292
				if(!exists)
293
					fileList.add(files[i]);
294
			}
295
			
296
			for (int i = fileList.size() - 1; i >= 0; i--) {
297
				//Checks extents
298
				try {
299
					if(!checkNewFile(fileList.get(i).getAbsolutePath())) {
300
						JOptionPane.showMessageDialog(null, Messages.getText("extents_no_coincidentes") +  " " + files[i].getAbsolutePath(), "", JOptionPane.ERROR_MESSAGE);
301
						fileList.remove(i);
302
					}
303
				} catch (Exception e) {
304
					log.debug("Problems check the bounding boxes", e);
305
				}
306
			}
307
			
308
			if(dataStore.isTiled()) {
309
				if(!RasterSwingLibrary.messageBoxYesOrNot(Messages.getText("store_tiled"), this)) {
310
					return;
311
				}
312
			}
313
			
314
			if(dataStore.isMultiFile()) {
315
				for (int i = 0; i < fileList.size(); i++) {
316
					try {
317
						dataStore.addFile(fileList.get(i).getAbsolutePath());
318
					} catch (InvalidSourceException e) {
319
						RasterSwingLibrary.messageBoxError(Messages.getText("addband_error"), bandSetupPanel, e);
320
					}
321
				}
322
				
323
				dataStore.setProvider(dataStore.getProvider());
324
				
325
				//It shows the files and bands in the panel
326
				try {
327
					bandSetupPanel.addFiles(dataStore);
328
				} catch (NotInitializeException e) {
329
					RasterSwingLibrary.messageBoxError("table_not_initialize", this, e);
330
				}
331
			} else {
332
				//New layer name
333
				WindowInfo wi = PluginServices.getMDIManager().getActiveWindow().getWindowInfo();
334
				LayerNameDialog dialog = new LayerNameDialog(new Point2D.Double(wi.getX(), wi.getY()), 300, 80, this);
335
				RasterMainPluginUtils.addWindow(dialog);
336
			}
337
		}
338
	}
339
	
340
	/**
341
	 * Catchs the events from LayerNameDialog to get the name of the new layer
342
	 */
343
	public void actionButtonPressed(ButtonsPanelEvent e) {
344
		String layerName = (String)e.getSource();
345
	
346
		RasterDataStore dataStore = fLayer.getDataStore();
347
		RasterDataParameters paramFirstFile = (RasterDataParameters)dataStore.getParameters();//(RasterDataParameters)((RasterProvider)dataStore.getProvider()).getDataParameters();
348
		
349
		ProviderServices provServ = RasterLocator.getManager().getProviderServices();
350
		DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
351

  
352
		try {
353
			//It creates the new Multifile provider
354
			DataServerExplorerParameters explParams = dataManager.createServerExplorerParameters(MultiFileProvider.NAME);
355
			DataServerExplorer explorer = dataManager.openServerExplorer(MultiFileProvider.NAME, explParams);
356
			MultiFileDataParameters newParamsMultifile = (MultiFileDataParameters)dataManager.createStoreParameters(explorer.getProviderName());
357
			String path = paramFirstFile.getURI().substring(0, paramFirstFile.getURI().lastIndexOf(File.separator) + 1);
358
			String fileURI = path + layerName + ".mff";
359
			String rmfURI = path + layerName + ".rmf";
360
			int counter = 0;
361
			while(new File(fileURI).exists() || new File(rmfURI).exists()) {
362
				fileURI = path + layerName + "_" + counter + ".mff";
363
				rmfURI = path + layerName + "_" + counter + ".rmf";
364
				counter ++;
365
			}
366
			if(counter > 0)
367
				layerName += "_" + counter;
368
			
369
			newParamsMultifile.setURI(fileURI);
370
			newParamsMultifile.addProvider(dataStore);
371
			DataStoreProvider provMultifile = dataManager.createProvider((DataStoreProviderServices)dataStore, newParamsMultifile);
372

  
373
			//And now it creates and adds the new ones
374
			for (int i = 0; i < fileList.size(); i++) {
375
				ArrayList<RasterDataParameters> storeParametersList = provServ.createParametersList(fileList.get(i).getAbsolutePath());
376
				for (int j = 0; j < storeParametersList.size(); j++) {
377
					DataStoreProvider newFileProv = dataManager.createProvider((DataStoreProviderServices)dataStore, storeParametersList.get(j));
378
					newParamsMultifile.addProviderNotTiled(newFileProv);
379
				}
380
			}
381

  
382
			((DefaultFLyrRaster)fLayer).setName(layerName);
383
			//Assigns the MultifileProvider to the store
384
			dataStore.setProvider((CoverageStoreProvider)provMultifile);
385

  
386
			//It shows the files and bands in the panel
387
			try {
388
				bandSetupPanel.addFiles(dataStore);
389
			} catch (NotInitializeException ex) {
390
				RasterSwingLibrary.messageBoxError(Messages.getText("table_not_initialize"), this, ex);
391
			}
392
			
393
			ArrayList<File> uriList = new ArrayList<File>();
394
			uriList.add(new File(paramFirstFile.getURI()));
395
			for (int i = 0; i < fileList.size(); i++) {
396
				uriList.add(fileList.get(i));
397
			}
398
			saveMultiFileLayer(layerName, paramFirstFile.getURI(), uriList);
399

  
400
		} catch (Exception exc) {
401
			RasterSwingLibrary.messageBoxError(Messages.getText("addband_error"), bandSetupPanel, exc);
402
		}
403
	}
404
	
405
	/**
406
	 * Saves the new layer in disk
407
	 * @param layerName
408
	 * @param file
409
	 * @param uriList
410
	 * @throws IOException
411
	 */
412
	private String saveMultiFileLayer(String layerName, String file, ArrayList<File> uriList) throws IOException {
413
		String path = file.substring(0, file.lastIndexOf(File.separator) + 1);
414
		path = path + layerName + ".mff";
415
		
416
		/*File filePath = new File(path);
417
		if(filePath.exists()) {
418
			RasterToolsUtil.messageBoxInfo("file_exists_rename", bandSetupPanel);
419
			filePath.renameTo(new File(path + "~"));
420
		}*/
421
		
422
		MultiFileFormat format = new MultiFileFormat();
423
		for (int i = 0; i < uriList.size(); i++) {
424
			format.addFile(uriList.get(i));
425
		}
426
		format.setName(layerName);
427
		
428
		format.write(path);
429
		return path;
430
	}
431

  
432
	/**
433
	 * Elimina una banda del raster. Si queda solo un fichero o no se ha
434
	 * seleccionado ninguna banda no hace nada.
435
	 *
436
	 * @param e
437
	 */
438
	private void delFileBand() {
439
		Object[] objects = bandSetupPanel.getFileList().getJList().getSelectedValues();
440
		RasterDataStore dataStore = fLayer.getDataStore();
441
		
442
		for (int i = objects.length - 1; i >= 0; i--) {
443
			if (bandSetupPanel.getFileList().getNFiles() > 1) {
444
				String pathName = objects[i].toString();
445
				dataStore.removeFile(pathName);
446

  
447
				String file = pathName.substring(pathName.lastIndexOf(File.separator) + 1);
448
				file = file.substring(file.lastIndexOf("\\") + 1);
449
				bandSetupPanel.removeFile(file);
450
			}
451
		}
452
		
453
		setNewBandsPositionInRendering();
454
	}
455

  
456
	/**
457
	 * Acciones a ejecutar cuando se aplica
458
	 */
459
	public void apply() {
460
		if (enabled)
461
			setNewBandsPositionInRendering();
462
	}
463

  
464
	/**
465
	 * Asigna la posici?n de las bandas en el rederizado basandose en la selecci?n
466
	 * hecho en la tabla de bandas.
467
	 */
468
	public void setNewBandsPositionInRendering() {
469
		if (fLayer != null && fLayer.getRender() != null) {
470
			fLayer.getRender().setRenderBands(new int[]{bandSetupPanel.getAssignedBand(RasterDataStore.RED_BAND),
471
					bandSetupPanel.getAssignedBand(RasterDataStore.GREEN_BAND),
472
					bandSetupPanel.getAssignedBand(RasterDataStore.BLUE_BAND)});
473
			int alphaBand = bandSetupPanel.getAssignedBand(RasterDataStore.ALPHA_BAND);
474
			// Ultima transparencia aplicada en el renderizador
475
			Transparency gt = fLayer.getRender().getLastTransparency();
476
			if(gt != null)
477
				gt.setTransparencyBand(alphaBand);
478

  
479
			// Transparencia del dataset
480
			/*if(fLayer.getDataStore() != null) {
481
				Transparency t = fLayer.getDataStore().getTransparency();
482
				if(t != null)
483
					t.setTransparencyBand(alphaBand);
484
			}*/
485
			fLayer.getMapContext().invalidate();
486
		}
487
	}
488

  
489
	/**
490
	 * Activa o desactiva la acci?n del panel
491
	 * @param enabled true para activa y false para desactivar.
492
	 */
493
	public void setEnabledPanelAction(boolean enabled) {
494
		this.enabled = enabled;
495
	}
496

  
497
}

Also available in: Unified diff