Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.app / org.gvsig.raster.tools.app.basic / src / main / java / org / gvsig / raster / tools / app / basic / tool / clip / ui / listener / ClippingPanelListener.java @ 1864

History | View | Annotate | Download (34.5 KB)

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.tools.app.basic.tool.clip.ui.listener;
23

    
24
import java.awt.Component;
25
import java.awt.Cursor;
26
import java.awt.Dimension;
27
import java.awt.Image;
28
import java.awt.event.ActionEvent;
29
import java.awt.event.ActionListener;
30
import java.awt.geom.AffineTransform;
31
import java.awt.geom.NoninvertibleTransformException;
32
import java.awt.geom.Point2D;
33
import java.io.File;
34
import java.util.EventObject;
35
import java.util.List;
36

    
37
import javax.swing.JOptionPane;
38

    
39
import org.gvsig.andami.PluginServices;
40
import org.gvsig.andami.Utilities;
41
import org.gvsig.andami.ui.mdiManager.IWindow;
42
import org.gvsig.app.project.documents.view.gui.AbstractViewPanel;
43
import org.gvsig.app.project.documents.view.toolListeners.StatusBarListener;
44
import org.gvsig.fmap.dal.coverage.RasterLocator;
45
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
46
import org.gvsig.fmap.dal.coverage.exception.ROIException;
47
import org.gvsig.fmap.dal.coverage.grid.ROI;
48
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
49
import org.gvsig.fmap.geom.primitive.Envelope;
50
import org.gvsig.fmap.mapcontrol.MapControl;
51
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
52
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
53
import org.gvsig.fmap.mapcontrol.tools.Behavior.MouseMovementBehavior;
54
import org.gvsig.fmap.mapcontrol.tools.Behavior.RectangleBehavior;
55
import org.gvsig.fmap.mapcontrol.tools.Events.EnvelopeEvent;
56
import org.gvsig.fmap.mapcontrol.tools.Listeners.RectangleListener;
57
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
58
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelEvent;
59
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelListener;
60
import org.gvsig.gui.beans.coordinatespanel.CoordinatesEvent;
61
import org.gvsig.gui.beans.coordinatespanel.CoordinatesListener;
62
import org.gvsig.gui.beans.coordinatespanel.CoordinatesPanel;
63
import org.gvsig.gui.beans.datainput.DataInputContainerListener;
64
import org.gvsig.gui.beans.table.models.CheckBoxModel;
65
import org.gvsig.i18n.Messages;
66
import org.gvsig.raster.fmap.layers.FLyrRaster;
67
import org.gvsig.raster.tools.app.basic.RasterToolsUtil;
68
import org.gvsig.raster.tools.app.basic.raster.bean.endinfo.EndInfoDialog;
69
import org.gvsig.raster.tools.app.basic.raster.process.ClippingProcess;
70
import org.gvsig.raster.tools.app.basic.raster.process.IProcessActions;
71
import org.gvsig.raster.tools.app.basic.raster.process.RasterProcess;
72
import org.gvsig.raster.tools.app.basic.tool.clip.ClippingData;
73
import org.gvsig.raster.tools.app.basic.tool.clip.ui.ClippingPanel;
74
import org.gvsig.raster.tools.app.basic.tool.clip.ui.panel.ClippingCoordinatesPanel;
75
import org.gvsig.raster.tools.app.basic.tool.clip.ui.panel.ClippingOptionsPanel;
76
import org.gvsig.raster.tools.app.basic.tool.clip.ui.panel.ClippingResolutionPanel;
77
import org.gvsig.raster.tools.app.basic.tool.clip.ui.panel.ClippingSelectionPanel;
78

    
79
/**
80
 * <code>ClippingPanelListener</code> es una clase donde se recoger?n y
81
 * tratar?n todos los eventos del panel de recorte
82
 *
83
 * @version 19/04/2007
84
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
85
 */
86
public class ClippingPanelListener implements ActionListener, RectangleListener, ButtonsPanelListener, CoordinatesListener, DataInputContainerListener, IProcessActions {
87
        private Dimension             dim                     = new Dimension();
88
        private AffineTransform       at                      = null;
89
        private ClippingPanel         clippingPanel           = null;
90
        private ClippingData          data                    = null;
91
        private boolean               enableValueChangedEvent = true;
92
        private FLyrRaster            fLayer                  = null;
93
        private MapControl            mapControl              = null;
94
        /**
95
         * Herramienta seleccionada en el momento de la apertura del dialogo
96
         */
97
        private String                 lastTool                = null;
98
        private String                 viewName                = null;
99
        private static ClippingData    lastDataSaved           = null;
100

    
101
        /**
102
         * Crea un nuevo <code>ClippingPanelListener</code> con el
103
         * <code>ClippingPanelListener</code> asociado
104
         * @param panel
105
         */
106
        public ClippingPanelListener(ClippingPanel clippingPanel) {
107
                this.clippingPanel = clippingPanel;
108
        }
109

    
110
        /**
111
         * Asigna el modelo de datos
112
         * @param data
113
         */
114
        public void setData(ClippingData data) {
115
                this.data = data;
116
                if(fLayer != null) {
117
                        data.setPxWidth((int)fLayer.getDataStore().getWidth());
118
                        data.setPxHeight((int)fLayer.getDataStore().getHeight());
119
                }
120
        }
121

    
122
        /**
123
         * Asigna la matriz de transformaci?n entre puntos en coordenadas del raster y
124
         * puntos en coordenadas reales.
125
         * @param AffineTransform
126
         */
127
        private void setAffineTransform(AffineTransform at) {
128
                this.at = at;
129
        }
130

    
131
        /**
132
         * Asigna la dimensi?n del raster
133
         * @param dim
134
         */
135
        public void setDimension(Dimension dim) {
136
                this.dim = dim;
137
        }
138

    
139
        /**
140
         * M?todo que se invoca cuando se disparan los eventos de los botones de
141
         * extensi?n completa o de seleccion de extensi?n con el rat?n
142
         */
143
        public void actionPerformed(ActionEvent e) {
144
                // Bot?n de selecci?n del extent completo
145
                // Modificamos las coordenadas reales y recalculamos las coordenadas pixel
146
                if (e.getSource() == getResolutionPanel().getButtonRestore()) {
147
                        getClippingPanel().restoreStatus(data);
148
                }
149

    
150
                //Load parameters
151
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(0)) {
152
                        if(lastDataSaved != null) {
153
                                data = (ClippingData)lastDataSaved.clone();
154
                                data.addObserver(getClippingPanel());
155
                                data.updateObservers();
156
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_APPLY).setEnabled(true);
157
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT).setEnabled(true);
158
                        } else
159
                                RasterToolsUtil.messageBoxError(RasterToolsUtil.getText(this, "no_data_saved"), null);
160
                }
161

    
162
                //Save parameters
163
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(1)) {
164
                        lastDataSaved = (ClippingData)data.clone();
165
                }
166
                
167
                //Redondear las coordenadas p?xel
168
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(2)) {
169
                        roundPixels();
170
                        return;
171
                }
172

    
173
                //Bot?n de selecci?n del ?rea m?xima asociada a los ROIs
174
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(3)) {
175
                        try {
176
                                List<ROI> roiList = getFLayer().getRois();
177
                                if(roiList != null && roiList.size() > 0) {
178
                                        Extent ext = RasterLocator.getManager().getRasterUtils().getROIsMaximunExtent(roiList);
179
                                        assignROISExtent(ext, getFLayer());
180
                                } else
181
                                        assignFullExtent();
182
                        } catch (ROIException e1) {
183
                                RasterToolsUtil.messageBoxError(Messages.getText("problems_loading_rois"), null);
184
                        }
185
                        
186
                        return;
187
                }
188

    
189
                // Bot?n de selecci?n del extent completo
190
                // Modificamos las coordenadas reales y recalculamos las coordenadas pixel
191
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(4)) {
192
                        assignFullExtent();
193
                        return;
194
                }
195

    
196
                // Bot?n de selecci?n de la herramienta de seleccionar desde la vista
197
                if (e.getSource() == getCoordinatesPanel().getButtonBarContainer().getButton(5)) {
198
                        selectToolButton();
199
                        return;
200
                }
201

    
202
        }
203
        
204
        /**
205
         * Round off the pixels value
206
         */
207
        private void roundPixels() {
208
                data.setUlxPx((int)(data.getUlxPx()));
209
                data.setUlyPx((int)(data.getUlyPx()));
210
                data.setLrxPx((int)(data.getLrxPx()));
211
                data.setLryPx((int)(data.getLryPx()));
212
                data.setUrxPx((int)(data.getUrxPx()));
213
                data.setUryPx((int)(data.getUryPx()));
214
                data.setLlxPx((int)(data.getLlxPx()));
215
                data.setLlyPx((int)(data.getLlyPx()));
216
                
217
                Point2D ulWc = new Point2D.Double();
218
                Point2D lrWc = new Point2D.Double();
219
                Point2D llWc = new Point2D.Double();
220
                Point2D urWc = new Point2D.Double();
221
                
222
                at.transform(new Point2D.Double(data.getUlxPx(), data.getUlyPx()), ulWc);
223
                at.transform(new Point2D.Double(data.getLrxPx() + 1, data.getLryPx() + 1), lrWc);
224
                at.transform(new Point2D.Double(data.getLlxPx(), data.getLlyPx() + 1), llWc);
225
                at.transform(new Point2D.Double(data.getUrxPx() + 1, data.getUryPx()), urWc);
226

    
227
                data.setCoorReal(ulWc, lrWc, llWc, urWc);
228
                data.setAffineTransform(at);
229
                data.initSize();
230
                data.updateObservers();
231
        }
232

    
233
        /**
234
         * Asigna el extent completo a los cuadros de texto donde se introducen las coordenadas
235
         * reales y p?xel.
236
         */
237
        private void assignROISExtent(Extent ext, FLyrRaster layer) {
238
                AffineTransform at = layer.getAffineTransform();
239
                Point2D ulWc = new Point2D.Double(ext.minX(), ext.maxY());
240
                Point2D lrWc = new Point2D.Double(ext.maxX(), ext.minY());
241
                Point2D llWc = new Point2D.Double(ext.minX(), ext.minY());
242
                Point2D urWc = new Point2D.Double(ext.maxX(), ext.maxY());
243

    
244
                ulWc = getFLayer().adjustWorldRequest(ulWc);
245
                lrWc = getFLayer().adjustWorldRequest(lrWc);
246
                llWc = getFLayer().adjustWorldRequest(llWc);
247
                urWc = getFLayer().adjustWorldRequest(urWc);
248

    
249
                Point2D ulPx = new Point2D.Double();
250
                Point2D lrPx = new Point2D.Double();
251
                Point2D llPx = new Point2D.Double();
252
                Point2D urPx = new Point2D.Double();
253

    
254
                try {
255
                        at.inverseTransform(ulWc, ulPx);
256
                        at.inverseTransform(lrWc, lrPx);
257
                        at.inverseTransform(ulWc, llPx);
258
                        at.inverseTransform(lrWc, urPx);
259
                } catch (NoninvertibleTransformException e) {
260
                        JOptionPane.showMessageDialog((Component) PluginServices.getMainFrame(), Messages.getText("coordenadas_erroneas"));
261
                        return;
262
                }
263

    
264
                data.setCoorPixel(ulPx, lrPx, llPx, urPx);
265
                data.setCoorReal(ulWc, lrWc, llWc, urWc);
266
                data.setAffineTransform(at);
267
                data.initSize();
268
                getClippingPanel().saveStatus(data);
269

    
270
                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_APPLY).setEnabled(true);
271
                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT).setEnabled(true);
272
        }
273

    
274
        /**
275
         * Asigna el extent completo a los cuadros de texto donde se introducen las coordenadas
276
         * reales y p?xel.
277
         */
278
        private void assignFullExtent() {
279
                Point2D ulPx = new Point2D.Double(0, 0);
280
                Point2D lrPx = new Point2D.Double(dim.width, dim.height);
281
                Point2D urPx = new Point2D.Double(dim.width, 0);
282
                Point2D llPx = new Point2D.Double(0, dim.height);
283

    
284
                //Convertimos nuevamente a coordenadas reales
285
                Point2D ulWc = new Point2D.Double();
286
                Point2D lrWc = new Point2D.Double();
287
                Point2D urWc = new Point2D.Double();
288
                Point2D llWc = new Point2D.Double();
289
                at.transform(ulPx, ulWc);
290
                at.transform(lrPx, lrWc);
291
                at.transform(urPx, urWc);
292
                at.transform(llPx, llWc);
293

    
294
                ulPx = new Point2D.Double(0, 0);
295
                lrPx = new Point2D.Double(dim.width - 1, dim.height - 1);
296
                urPx = new Point2D.Double(dim.width - 1, 0);
297
                llPx = new Point2D.Double(0, dim.height - 1);
298

    
299
                data.setCoorPixel(ulPx, lrPx, llPx, urPx);
300
                data.setCoorReal(ulWc, lrWc, llWc, urWc);
301
                data.setAffineTransform(at);
302
                data.initSize();
303

    
304
                getClippingPanel().saveStatus(data);
305
                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_APPLY).setEnabled(true);
306
                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT).setEnabled(true);
307
        }
308

    
309
        /**
310
         * Al producirse un evento de perdida de foco o pulsaci?n de "enter" en un campo de texto de coordenadas
311
         * hay que asignar el nuevo valor introducido.
312
         * @param obj
313
         */
314
        private void eventJTextField(CoordinatesEvent e) {
315
                try {
316
                        if (e.getSource() == getCoordinatesPanel().getPixelCoordinates()) {
317
                                if (e.getName().equals("11")) {
318
                                        data.setUlxPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue11()).doubleValue());
319
                                        data.setLlxPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue11()).doubleValue());
320
                                }
321
                                if (e.getName().equals("12")) {
322
                                        data.setUlyPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue12()).doubleValue());
323
                                        data.setUryPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue12()).doubleValue());
324
                                }
325
                                if (e.getName().equals("21")) {
326
                                        data.setLrxPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue21()).doubleValue());
327
                                        data.setUrxPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue21()).doubleValue());
328
                                }
329
                                if (e.getName().equals("22")) {
330
                                        data.setLryPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue22()).doubleValue());
331
                                        data.setLlyPx(Double.valueOf(getCoordinatesPanel().getPixelCoordinates().getValue22()).doubleValue());
332
                                }
333
                                data.updateObservers();
334
                        }
335

    
336
                        if (e.getSource() == getCoordinatesPanel().getRealCoordinates()) {
337
                                if (e.getName().equals("11")) {
338
                                        data.setUlxWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue11()).doubleValue());
339
                                        data.setLlxWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue11()).doubleValue());
340
                                }
341
                                if (e.getName().equals("12")) {
342
                                        data.setUlyWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue12()).doubleValue());
343
                                        data.setUryWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue12()).doubleValue());
344
                                }
345
                                if (e.getName().equals("21")) {
346
                                        data.setLrxWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue21()).doubleValue());
347
                                        data.setUrxWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue21()).doubleValue());
348
                                }
349
                                if (e.getName().equals("22")) {
350
                                        data.setLryWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue22()).doubleValue());
351
                                        data.setLlyWc(Double.valueOf(getCoordinatesPanel().getRealCoordinates().getValue22()).doubleValue());
352
                                }
353
                                data.updateObservers();
354
                        }
355
                } catch (NumberFormatException ex1) {
356
                        // No hay valores parseables a decimal en las cajas de texto. No hacemos nada
357
                }
358
        }
359

    
360
        
361
        /**
362
         * Recalcula el valor de los campos de coordenadas reales y pixel. Cuando modificamos alg?n campo
363
         * de las coordenadas reales se modifican los pixeles y viceversa.
364
         * @param modifyPx true si se ha modificado alg?n campo de coordenadas pixel y false si se ha modificado
365
         * alg?n campo de las coordenadas reales.
366
         */
367
        private void recalcCoordFields(boolean modifyPx) {
368
                try {
369
                        Point2D ulPx = new Point2D.Double(data.getUlxPx(), data.getUlyPx());
370
                        Point2D lrPx = new Point2D.Double(data.getLrxPx(), data.getLryPx());
371
                        Point2D llPx = new Point2D.Double(data.getLlxPx(), data.getLlyPx());
372
                        Point2D urPx = new Point2D.Double(data.getUrxPx(), data.getUryPx());
373
                        
374
                        Point2D ulWc = new Point2D.Double(data.getUlxWc(), data.getUlyWc());
375
                        Point2D lrWc = new Point2D.Double(data.getLrxWc(), data.getLryWc());
376
                        Point2D llWc = new Point2D.Double(data.getLlxWc(), data.getLlyWc());
377
                        Point2D urWc = new Point2D.Double(data.getUrxWc(), data.getUryWc());
378
                        
379
                        if (modifyPx) {
380
                                at.transform(new Point2D.Double(ulPx.getX(), ulPx.getY()), ulWc);
381
                                at.transform(new Point2D.Double(lrPx.getX() + 1, lrPx.getY() + 1), lrWc);
382
                                at.transform(new Point2D.Double(llPx.getX(), llPx.getY() + 1), llWc);
383
                                at.transform(new Point2D.Double(urPx.getX() + 1, urPx.getY()), urWc);
384

    
385
                                data.setCoorReal(ulWc, lrWc, llWc, urWc);
386
                                data.setAffineTransform(at);
387
                                data.initSize();
388

    
389
                                getClippingPanel().saveStatus(data);
390
                        } else {
391
                                try {
392
                                        at.inverseTransform(ulWc, ulPx);
393
                                        at.inverseTransform(lrWc, lrPx);
394
                                        at.inverseTransform(llWc, llPx);
395
                                        at.inverseTransform(urWc, urPx);
396
                                } catch (NoninvertibleTransformException e) {
397
                                        JOptionPane.showMessageDialog((Component) PluginServices.getMainFrame(), PluginServices.getText(this, "coordenadas_erroneas"));
398
                                        return;
399
                                }
400

    
401
                                //adjustPoints(ulPx, lrPx);
402
                                //adjustPoints(llPx, urPx);
403
                                lrPx = new Point2D.Double(lrPx.getX() - 1, lrPx.getY() - 1);
404
                                llPx = new Point2D.Double(llPx.getX(), llPx.getY() - 1);
405
                                urPx = new Point2D.Double(urPx.getX() - 1, urPx.getY());
406
                                data.setCoorPixel(ulPx, lrPx, llPx, urPx);
407
                                data.setAffineTransform(at);
408
                                data.initSize();
409
                                getClippingPanel().saveStatus(data);
410
                        }
411
                        
412
                        //Condiciones para activar botones. 
413
                        if(activeButtons(ulPx, lrPx, ulWc, lrWc)) {
414
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_APPLY).setEnabled(true);
415
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT).setEnabled(true);
416
                        } else {
417
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_APPLY).setEnabled(false);
418
                                getClippingPanel().getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT).setEnabled(false);
419
                        }
420
                        
421
                } catch (NumberFormatException ex) {
422
                        return;
423
                }
424

    
425
        }
426
        
427
        public boolean activeButtons(Point2D ulPx, Point2D lrPx, Point2D ulWc, Point2D lrWc) {
428
                if(ulPx.getX() < lrPx.getX() && ulPx.getY() < lrPx.getY() &&
429
                        ulWc.getX() < lrWc.getX() && ulWc.getY() > lrWc.getY() &&
430
                        (lrPx.getX() - ulPx.getX()) >= 2 && (lrPx.getY() - ulPx.getY()) >= 2 &&
431
                        ulPx.getX() >= 0 && ulPx.getY() >= 0 && 
432
                        lrPx.getX() <= (fLayer.getDataStore().getWidth() - 1) &&
433
                        lrPx.getY() <= (fLayer.getDataStore().getHeight() - 1)) {
434
                        return true;
435
                }
436
                return false;
437
        }
438
        
439
        /**
440
         * Turns world coordinates into entire numbers to avoid rounds errors 
441
         * @param ul
442
         *        Upper left coordinate
443
         * @param lr
444
         *        Lower right coordinate
445
         */
446
        @SuppressWarnings("unused")
447
        private void adjustPoints(Point2D ul, Point2D lr) {
448
                double a = (ul.getX() - (int)ul.getX());
449
                double b = (ul.getY() - (int)ul.getY());
450
                double c = (lr.getX() - (int)lr.getX());
451
                double d = (lr.getY() - (int)lr.getY());
452
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
453
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
454
                lr.setLocation(        (c > 0.95 || c < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
455
                                                (d > 0.95 || d < 0.05) ? Math.round(lr.getY()) : lr.getY());
456
        }
457

    
458
        /**
459
         * Ajusta las coordenadas especificadas en los par?metros al ?rea m?xima
460
         * del raster en p?xeles
461
         * @param req
462
         */
463
        @SuppressWarnings("unused")
464
        private Point2D adjustPixelRequest(Point2D req) {
465
                req.setLocation(Math.max(0, req.getX()), Math.max(0, req.getY()));
466
                req.setLocation(Math.min(dim.width - 1, req.getX()), Math.min(dim.height - 1, req.getY()));
467
                return req;
468
        }
469

    
470
        /**
471
         * Invocaci?n de los eventos de la ventana de <code>DefaultButtonsPanel</code>
472
         */
473
        public void actionButtonPressed(ButtonsPanelEvent e) {
474
                // Bot?n de Aceptar
475
                if (e.getButton() == ButtonsPanel.BUTTON_ACCEPT) {
476
                        accept();
477
                        close();
478
                }
479

    
480
                // Bot?n de Aplicar
481
                if (e.getButton() == ButtonsPanel.BUTTON_APPLY)
482
                        accept();
483

    
484
                // Bot?n de Cerrar
485
                if (e.getButton() == ButtonsPanel.BUTTON_CANCEL)
486
                        close();
487

    
488
                getFLayer().getMapContext().invalidate();
489
        }
490

    
491
        /**
492
         * Cerrar la ventana del recorte
493
         */
494
        private void close() {
495
                try {
496
                        if (getLastTool() != null)
497
                                getMapControl().setTool(getLastTool());
498
                        PluginServices.getMDIManager().closeWindow(getClippingPanel().getClippingDialog());
499
                } catch (ArrayIndexOutOfBoundsException ex) {
500
                        // Si la ventana no se puede eliminar no hacemos nada
501
                }
502
        }
503

    
504
        /**
505
         * Obtener el <code>ClippingPanel</code> asociado
506
         * @return ClippingPanel
507
         */
508
        private ClippingPanel getClippingPanel() {
509
                return clippingPanel;
510
        }
511

    
512
        private ClippingCoordinatesPanel getCoordinatesPanel() {
513
                return getClippingPanel().getCoordinatesPanel();
514
        }
515

    
516
        private ClippingResolutionPanel getResolutionPanel() {
517
                return getClippingPanel().getResolutionPanel();
518
        }
519

    
520
        private ClippingOptionsPanel getOptionsPanel() {
521
                return getClippingPanel().getOptionsPanel();
522
        }
523

    
524
        private ClippingSelectionPanel getSelectionPanel() {
525
                return getClippingPanel().getSelectionPanel();
526
        }
527

    
528
        /**
529
         * Acciones realizadas cuando se acepta en el dialogo. Se obtendr?n los datos
530
         * de recorte desde el dialogo, crearemos el objeto ClippingProcess que
531
         * gestiona el recortado, ajustamos el tama?o del grid de salida y procesamos.
532
         */
533
        private void accept() {
534
                if(data.getPxHeight() == 0 || data.getPxWidth() == 0) {
535
                        RasterToolsUtil.messageBoxError(RasterToolsUtil.getText(this, "wrong_resolution"), null);
536
                        return;
537
                }
538
                
539
                // Controlamos las coordenadas del recorte que no se salgan de la imagen.
540
                // De ser as? mostramos un error
541
                CoordinatesPanel coordinatesReales = getCoordinatesPanel().getRealCoordinates();
542
                double ulx = 0;
543
                double lrx = 0;
544
                double lry = 0;
545
                double uly = 0;
546
                try {
547
                        ulx = Double.parseDouble(coordinatesReales.getValue11());
548
                        lry = Double.parseDouble(coordinatesReales.getValue22());
549
                        lrx = Double.parseDouble(coordinatesReales.getValue21());
550
                        uly = Double.parseDouble(coordinatesReales.getValue12());
551
                        Envelope ext = getFLayer().getFullEnvelope();
552
                        if (((int) ulx) > ((int) ext.getMaximum(0)) || ((int) lrx) < ((int) ext.getMinimum(0)) || ((int) uly) > ((int) ext.getMaximum(1)) || ((int) lry) < ((int) ext.getMinimum(1))) {
553
                                RasterToolsUtil.messageBoxError(RasterToolsUtil.getText(this, "coordenadas_erroneas"), null);
554
                                return;
555
                        }
556
                } catch (NumberFormatException e) {
557
                        RasterToolsUtil.messageBoxError(RasterToolsUtil.getText(this, "coordenadas_erroneas"), null);
558
                        return;
559
                }
560

    
561
                double[] wcValues = data.getWcCoordinatesToClip();
562
                double[] pxValues = data.getPxCoordinatesToClip();
563
                boolean pxRound = arePixelsRound(pxValues);
564

    
565
                // Seleccionamos las bandas que se usaran en el recorte a partir de la tabla
566
                int countBands = 0;
567
                int rowCount = ((CheckBoxModel) getSelectionPanel().getTableContainer().getModel()).getRowCount();
568
                for (int iRow = 0; iRow < rowCount; iRow++)
569
                        if ((((Boolean) ((CheckBoxModel) getSelectionPanel().getTableContainer().getModel()).getValueAt(iRow, 0))).booleanValue())
570
                                countBands++;
571

    
572
                int[] drawableBands = new int[countBands];
573
                int i = 0;
574
                for (int iRow = 0; iRow < rowCount; iRow++) {
575
                        if ((((Boolean) ((CheckBoxModel) getSelectionPanel().getTableContainer().getModel()).getValueAt(iRow, 0))).booleanValue()) {
576
                                int row = ((Integer) ((CheckBoxModel) getSelectionPanel().getTableContainer().getModel()).getValueAt(iRow, 2)).intValue();
577
                                drawableBands[i++] = row;
578
                        }
579
                }
580

    
581
                /**
582
                 * Donde se va a guardar el fichero
583
                 */
584
                String path;
585
                if (getOptionsPanel().getCbSaveFile().isSelected()) {
586
                        path = getOptionsPanel().getDirectoryTextField().getText();
587
                        File f = new File(path);
588
                        if(!f.exists() || !f.canWrite()) {
589
                                RasterToolsUtil.messageBoxError(RasterToolsUtil.getText(this, "path_not_valid"), null);
590
                                return;
591
                        }
592
                } else
593
                        path = Utilities.createTempDirectory();
594

    
595
                String file = getOptionsPanel().getFilenameTextField().getText();
596
                if (file.compareTo(RasterLocator.getManager().getFileUtils().getOnlyLayerName()) == 0)
597
                        RasterLocator.getManager().getFileUtils().usesOnlyLayerName();
598

    
599
                if (file == "")
600
                        file = "cutlayer";
601

    
602
                String filename = path + File.separator + file;
603

    
604
                if (new File(filename + ".tif").exists())
605
                        if (!RasterToolsUtil.messageBoxYesOrNot("raster_error_file_exists", getOptionsPanel()))
606
                                return;
607

    
608
                /**
609
                 * Preparacion para la generacion del proceso del recorte
610
                 */
611
                if (getFLayer() == null)
612
                        return;
613

    
614
                AffineTransform transf = null;
615
                if(pxRound && 
616
                   ((pxValues[2] - pxValues[0]) == data.getPxWidth()) && 
617
                   ((pxValues[3] - pxValues[1]) == data.getPxHeight()))
618
                        transf = new AffineTransform(at.getScaleX(), at.getShearY(), at.getShearX(), at.getScaleY(), wcValues[0], wcValues[1]);
619
                else
620
                        transf = calcAffineTransform(wcValues[0], wcValues[1], wcValues[2], wcValues[3],
621
                                                                                Math.round(data.getPxWidth()), Math.round(data.getPxHeight()), at);
622
                
623

    
624
                int interpMethod = getResolutionPanel().getSelectedInterpolationMethod();
625

    
626
                // Creamos la interpretaci?n de color para el caso de que la salida tenga
627
                // m?s de una banda por fichero. Siempre creamos RED, GREEN y BLUE
628
                String[] ci = new String[drawableBands.length];
629
                for (int j = 0; j < ci.length; j++) {
630
                        switch (j) {
631
                                case 0:
632
                                        if (ci.length >= 3)
633
                                                ci[j] = ColorInterpretation.RED_BAND;
634
                                        else
635
                                                ci[j] = ColorInterpretation.GRAY_BAND;
636
                                        break;
637
                                case 1:
638
                                        if (ci.length >= 3)
639
                                                ci[j] = ColorInterpretation.GREEN_BAND;
640
                                        else
641
                                                ci[j] = ColorInterpretation.UNDEF_BAND;
642
                                        break;
643
                                case 2:
644
                                        ci[j] = ColorInterpretation.BLUE_BAND;
645
                                        break;
646
                                default:
647
                                        ci[j] = ColorInterpretation.UNDEF_BAND;
648
                                        break;
649
                        }
650
                }
651

    
652
                RasterProcess clippingProcess = new ClippingProcess();
653
                clippingProcess.setActions(this);
654
                clippingProcess.addParam("viewname", getViewName());
655
                if(pxRound)
656
                        clippingProcess.addParam("pixelcoordinates", pxValues);
657
                else
658
                        clippingProcess.addParam("realcoordinates", wcValues);
659
                clippingProcess.addParam("suffix", ".tif");
660
                clippingProcess.addParam("filename", filename);
661
                clippingProcess.addParam("layer", getFLayer());
662
                clippingProcess.addParam("drawablebands", drawableBands);
663
                clippingProcess.addParam("onelayerperband", new Boolean(getOptionsPanel().getCbOneLyrPerBand().isSelected()));
664
                clippingProcess.addParam("interpolationmethod", new Integer(interpMethod));
665
                clippingProcess.addParam("affinetransform", transf);
666
                clippingProcess.addParam("colorInterpretation",  RasterLocator.getManager().getDataStructFactory().createColorInterpretation(ci));
667
                clippingProcess.addParam("resolution", new int[]{(int) Math.round(data.getPxWidth()),
668
                                                                                                                 (int) Math.round(data.getPxHeight())});
669
                clippingProcess.start();
670
        }
671

    
672
        /**
673
         * Calcula la matriz de transformaci?n que se usar? para el nuevo raster generado.
674
         * @param ulx Coordenada X real de la esquina superior izquierda
675
         * @param uly Coordenada Y real de la esquina superior izquierda
676
         * @param lrx Coordenada X real de la esquina inferior derecha
677
         * @param lry Coordenada Y real de la esquina inferior derecha
678
         * @param width Ancho en p?xeles del nuevo raster
679
         * @param height Alto en p?xeles del nuevo raster
680
         * @param trans Matriz de transformaci?n de la nueva capa
681
         * @return Matriz de transformaci?n para el nuevo raster
682
         */
683
        private AffineTransform calcAffineTransform(double ulx, double uly, double lrx, double lry,
684
                                                                                                double width, double height, AffineTransform trans) {
685
                Point2D ul = new Point2D.Double(ulx, uly);
686
                Point2D lr = new Point2D.Double(lrx, lry);
687
                try {
688
                        trans.inverseTransform(ul, ul);
689
                        trans.inverseTransform(lr, lr);
690
                } catch (NoninvertibleTransformException e) {
691
                        JOptionPane.showMessageDialog(null, RasterToolsUtil.getText(this, "coordenadas_erroneas"));
692
                        return new AffineTransform();
693
                }
694
                double w = Math.abs(lr.getX() - ul.getX());
695

    
696
                Point2D ur = new Point2D.Double(ul.getX() + w, ul.getY());
697
                Point2D ll = new Point2D.Double(lr.getX() - w, lr.getY() );
698

    
699
                //Obtenemos la georreferenciaci?n de las cuatro esquinas del nuevo raster
700
                trans.transform(ul, ul);
701
                trans.transform(ur, ur);
702
                trans.transform(lr, lr);
703
                trans.transform(ll, ll);
704

    
705
                double pixelSizeX = (lrx - ulx) / width;
706
                double pixelSizeY = (lry - uly) / height;
707
                double rotX = trans.getShearX();
708
                double rotY = trans.getShearY();
709
                return new AffineTransform(pixelSizeX, rotY, rotX, pixelSizeY, ulx, uly);
710
        }
711
        
712
        /**
713
         * Returns true if the pixels are round
714
         * @param pxValues
715
         * @return
716
         */
717
        private boolean arePixelsRound(double[] pxValues) {
718
                if((((int)pxValues[0]) - pxValues[0]) == 0 &&
719
                   (((int)pxValues[1]) - pxValues[1]) == 0 &&
720
                   (((int)pxValues[2]) - pxValues[2]) == 0 &&
721
                   (((int)pxValues[3]) - pxValues[3]) == 0) {
722
                        return true;
723
                }
724
                return false;
725
        }
726

    
727
        /*
728
         * (non-Javadoc)
729
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
730
         */
731
        public boolean cancelDrawing() {
732
                return false;
733
        }
734

    
735
        /*
736
         * (non-Javadoc)
737
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#getCursor()
738
         */
739
        public Cursor getCursor() {
740
                return null;
741
        }
742

    
743
        /*
744
         * (non-Javadoc)
745
         * @see org.gvsig.gui.beans.coordinatespanel.CoordinatesListener#actionValueChanged(org.gvsig.gui.beans.coordinatespanel.CoordinatesEvent)
746
         */
747
        public void actionValueChanged(CoordinatesEvent e) {
748
                if (e.getSource() == getCoordinatesPanel().getPixelCoordinates()) {
749
                        eventJTextField(e);
750
                        if (e.getName().equals("11") || 
751
                                e.getName().equals("12") || 
752
                                e.getName().equals("21") ||
753
                                e.getName().equals("22"))
754
                                recalcCoordFields(true);
755
                        
756
                }
757
                if (e.getSource() == getCoordinatesPanel().getRealCoordinates()) {
758
                        eventJTextField(e);
759
                        if (e.getName().equals("11") || 
760
                                e.getName().equals("12") || 
761
                                e.getName().equals("21") || 
762
                                e.getName().equals("22"))
763
                                recalcCoordFields(false);
764
                }
765
        }
766

    
767
        /*
768
         * (non-Javadoc)
769
         * @see org.gvsig.gui.beans.datainput.DataInputContainerListener#actionValueChanged(java.util.EventObject)
770
         */
771
        public void actionValueChanged(EventObject e) {
772
                if(!enableValueChangedEvent)
773
                        return;
774

    
775
                enableValueChangedEvent = false; //Desactivamos el evento de cambio de valor de las cajas de texto para que no se bucle
776

    
777
                if (e.getSource() == getResolutionPanel().getCCellSize().getDataInputField()) {
778
                        // Cambiamos PS ==> wPx=wWC/PS & hPx=wPx/rel
779
                        double ps = 0;
780
                        try {
781
                                ps = Double.parseDouble(getResolutionPanel().getCCellSize().getValue());
782
                        } catch (NumberFormatException ex) {
783
                                return;
784
                        }
785
                        data.setPxWidth(data.getWcWidth() / ps);
786
                        data.setPxHeight(data.getWcHeight() / ps);
787
                        data.updateObservers();
788
                } else if (e.getSource() == getResolutionPanel().getCWidth().getDataInputField()) {
789
                        // Cambiamos wPx ==> hPx=wPx/rel & PS=wWC/wPx
790
                        double wPx = 0;
791
                        try {
792
                                wPx = Double.parseDouble(getResolutionPanel().getCWidth().getValue());
793
                        } catch (NumberFormatException ex) {
794
                                return;
795
                        }
796
                        data.setPxWidth(wPx);
797
                        data.setPxHeight(Math.round(wPx / data.getRatio()));
798
                        data.updateObservers();
799
                } else if (e.getSource() == getResolutionPanel().getCHeight().getDataInputField()) {
800
                        // Cambiamos hPx ==> wPx=rel*wPx & PS=hWC/hPx
801
                        double hPx = 0;
802
                        try {
803
                                hPx = Double.parseDouble(getResolutionPanel().getCHeight().getValue());
804
                        } catch (NumberFormatException ex) {
805
                                return;
806
                        }
807
                        data.setPxHeight(hPx);
808
                        data.setPxWidth(Math.round(Math.round(hPx * data.getRatio())));
809
                        data.updateObservers();
810
                }
811
                enableValueChangedEvent = true;
812
        }
813

    
814
        /**
815
         * Asigna el valor para la activaci?n y desactivaci?n del evento de cambio de valor en
816
         * las cajas de texto.
817
         * @param enableValueChangedEvent
818
         */
819
        public void setEnableValueChangedEvent(boolean enableValueChangedEvent) {
820
                this.enableValueChangedEvent = enableValueChangedEvent;
821
        }
822

    
823
        /*
824
         * (non-Javadoc)
825
         * @see org.gvsig.raster.IProcessActions#end(java.lang.Object)
826
         */
827
        public void end(Object params) {
828
                if(        params instanceof Object[] &&
829
                        ((Object[])params).length == 2 &&
830
                        ((Object[])params)[0] instanceof String &&
831
                        ((Object[])params)[1] instanceof Long) {
832

    
833
                        String fName = (String)((Object[])params)[0];
834
                        long milis = ((Long)((Object[])params)[1]).longValue();
835

    
836
                        EndInfoDialog.show(fName, milis);
837
                }
838
        }
839

    
840
        /**
841
         * Obtener la capa de un raster.
842
         * @return
843
         */
844
        public FLyrRaster getFLayer() {
845
                return fLayer;
846
        }
847

    
848
        /**
849
         * Obtiene la ultima herramienta seleccionada antes de cargar el recorte
850
         * @return
851
         */
852
        public String getLastTool() {
853
                return lastTool;
854
        }
855

    
856
        /**
857
         * Obtiene el nombre de la vista
858
         * @return
859
         */
860
        public String getViewName() {
861
                return viewName;
862
        }
863

    
864
        /**
865
         * Establecer la capa para usarla en el recorte
866
         * @param fLayer
867
         */
868
        public void setLayer(FLyrRaster fLayer) {
869
                this.fLayer = fLayer;
870
                AbstractViewPanel view = (AbstractViewPanel) PluginServices.getMDIManager().getActiveWindow();
871
                viewName = PluginServices.getMDIManager().getWindowInfo(view).getTitle();
872
                mapControl = view.getMapControl();
873

    
874
                lastTool = mapControl.getCurrentTool();
875

    
876
                // Listener de eventos de movimiento que pone las coordenadas del rat?n en
877
                // la barra de estado
878
                StatusBarListener sbl = new StatusBarListener(mapControl);
879

    
880
                // Cortar Raster
881
                ClippingMouseViewListener clippingMouseViewListener = new ClippingMouseViewListener(mapControl, getClippingPanel(), data, fLayer);
882
                mapControl.addBehavior("cutRaster", new Behavior[] {
883
                                new RectangleBehavior(clippingMouseViewListener), new MouseMovementBehavior(sbl)
884
                        }
885
                );
886

    
887
                getSelectionPanel().setLayer(fLayer);
888

    
889
                // Obtener la extension completa de la capa
890

    
891
                setAffineTransform(fLayer.getAffineTransform());
892
                setDimension(new Dimension((int)fLayer.getDataStore().getWidth(), (int)fLayer.getDataStore().getHeight()));
893
                
894
                //Limitaciones del recorte para un servicio remoto
895
                //1-Interpolaci?n deshabilitada. Se hace la petici?n al servidor de los pixeles que queramos
896
                //2-No se pueden intercambiar bandas. Puede hacerse a posteriori cuando ya est? en disco
897
                //3-No se puede seleccionar por coordenadas pixel. Si la fuente es WebMapService puede no tener resoluci?n 
898
                //en pixeles por lo que puede no tener sentido este tipo de selecci?n
899
                if(getFLayer().isRemote()) {
900
                        getResolutionPanel().getComboInterpolation().setEnabled(false);
901
                        getClippingPanel().removeTab(getSelectionPanel());
902
                        getCoordinatesPanel().getPixelCoordinates().setVisible(false);
903
                }
904
        }
905

    
906
        /**
907
         * Acciones que se realizan para seleccionar la tool CutRaster
908
         */
909
        public void selectToolButton() {
910
                // seleccionamos la vista de gvSIG
911
                org.gvsig.app.project.documents.view.gui.AbstractViewPanel theView = null;
912
                try {
913
                        IWindow[] allViews = PluginServices.getMDIManager().getAllWindows();
914
                        for (int i = 0; i < allViews.length; i++) {
915
                                if (allViews[i] instanceof org.gvsig.app.project.documents.view.gui.AbstractViewPanel
916
                                                && PluginServices.getMDIManager().getWindowInfo((AbstractViewPanel) allViews[i])
917
                                                                .getTitle().equals(viewName))
918
                                        theView = (org.gvsig.app.project.documents.view.gui.AbstractViewPanel) allViews[i];
919
                        }
920
                        if (theView == null)
921
                                return;
922
                } catch (ClassCastException ex) {
923
                        // RasterToolsUtil.messageBoxError("cant_get_view "), this, ex);
924
                        return;
925
                }
926
                MapControl m_MapControl = theView.getMapControl();
927

    
928
                // Listener de eventos de movimiento que pone las coordenadas del rat?n en
929
                // la barra de estado
930
                //StatusBarListener sbl = new StatusBarListener(m_MapControl);
931

    
932
                // Cortar Raster
933
                /*ClippingMouseViewListener clippingMouseViewListener = new ClippingMouseViewListener(m_MapControl, getClippingPanel(), data, getFLayer());
934
                m_MapControl.addMapTool("cutRaster", new Behavior[] {
935
                                new RectangleBehavior(clippingMouseViewListener), new MouseMovementBehavior(sbl)
936
                                }
937
                );*/
938

    
939
                m_MapControl.setTool("clipRaster");
940
        }
941

    
942
        /**
943
         * Obtiene el <code>MapControl</code> de gvSIG
944
         * @return <code>MapControl</code>
945
         */
946
        public MapControl getMapControl() {
947
                return mapControl;
948
        }
949

    
950

    
951
        public void rectangle(EnvelopeEvent event) throws BehaviorException {}
952
        public void interrupted() {}
953

    
954
        /*
955
         * (non-Javadoc)
956
         * @see org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener#getImageCursor()
957
         */
958
        public Image getImageCursor() {
959
                return null;
960
        }
961
}