Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoreferencing / src / com / iver / cit / gvsig / fmap / tools / Behavior / GeoRedimBehavior.java @ 3102

History | View | Annotate | Download (16.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. 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 Ib??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
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.tools.Behavior;
42

    
43
import java.awt.Color;
44
import java.awt.Component;
45
import java.awt.Cursor;
46
import java.awt.Graphics;
47
import java.awt.Image;
48
import java.awt.Point;
49
import java.awt.Rectangle;
50
import java.awt.Toolkit;
51
import java.awt.event.MouseEvent;
52
import java.awt.geom.Point2D;
53
import java.awt.geom.Rectangle2D;
54
import java.awt.image.BufferedImage;
55

    
56
import javax.swing.ImageIcon;
57
import javax.swing.JOptionPane;
58

    
59
import org.cresques.px.Extent;
60

    
61
import com.iver.andami.PluginServices;
62
import com.iver.cit.gvsig.fmap.MapControl;
63
import com.iver.cit.gvsig.fmap.ViewPort;
64
import com.iver.cit.gvsig.fmap.layers.FLayer;
65
import com.iver.cit.gvsig.fmap.layers.FLyrGeoRaster;
66
import com.iver.cit.gvsig.fmap.layers.FLyrRaster;
67
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
68
import com.iver.cit.gvsig.fmap.tools.Listeners.RectangleListener;
69
import com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener;
70
import com.iver.cit.gvsig.gui.View;
71
import com.iver.cit.gvsig.gui.Dialogs.GeoreferencingDialog;
72

    
73

    
74
/**
75
 * Behaviour que espera un listener de tipo RedimListener.
76
 * Nacho Brodin (brodin_ign@gva.es)
77
 *
78
 */
79
public class GeoRedimBehavior extends Behavior {
80
        private RectangleListener listener;
81
        private Cursor cur = null;
82
        
83
        private final Image iconHoriz = new ImageIcon(MapControl.class.getResource(
84
        "images/FlechaHorizCursor.gif")).getImage();
85
        private final Image iconVert = new ImageIcon(MapControl.class.getResource(
86
        "images/FlechaVertCursor.gif")).getImage();
87
        private final Image iconInclDer = new ImageIcon(MapControl.class.getResource(
88
        "images/FlechaInclDerCursor.gif")).getImage();
89
        private final Image iconInclIzq = new ImageIcon(MapControl.class.getResource(
90
        "images/FlechaInclIzqCursor.gif")).getImage();
91
        private final Image defaultCursor = new ImageIcon(MapControl.class.getResource(
92
        "images/ZoomInCursor.gif")).getImage();
93
        
94
        private int WIDTH_BORDER = 25; 
95
        private int LONG_CORNER = 35;
96
        
97
        /**
98
         * Cada elemento del vector corresponde a un tipo de icono que
99
         * estar? a true si est? activo y a false si no lo est?.
100
         * horizontal, vertical, inclinado derecha, inclinado izquierda
101
         */
102
        private boolean[] iconActive = {false, false, false, false};
103
                
104
        private Point2D ul = null;
105
        private Point2D lr = null;
106
        private Point2D tmpUl = null;
107
        private Point2D tmpLr = null;
108
        
109
        /**
110
         * Cada elemento corresponde a la acivaci?n de redimensionado en una
111
         * direcci?n que estar? activa a true.
112
         * vertical derecha, vertical izquierda, horizontal arriba, horizontal abajo,
113
         * inclinado
114
         */
115
        private boolean[] redimActive = new boolean[5];
116
        
117
        private Point2D pointInit = null;
118
        private Rectangle2D rectInit = null;
119
        
120
        private FLyrGeoRaster lyrGeoRaster = null;
121
                
122
        private GeoreferencingDialog parent = null;
123
                
124
        /**
125
         * Crea un nuevo RectangleBehavior.
126
         *
127
         * @param zili listener.
128
         */
129
        public GeoRedimBehavior(RectangleListener zili, GeoreferencingDialog p) {
130
                listener = zili;
131
                parent = p;
132
                for(int i=0; i<redimActive.length;i++)
133
                        redimActive[i] = false;
134
        }
135

    
136
        /**
137
         * Funci?n que carga la capa si todav?a no lo est?.
138
         */
139
        private void loadLayer() throws InstantiationException, ClassCastException{
140
                //Cargamos la capa
141
                
142
                View theView = (View) PluginServices.getMDIManager().getActiveView();
143
                for(int i=0;i<theView.getMapControl().getMapContext().getLayers().getLayersCount();i++){
144
                        FLayer lyr = theView.getMapControl().getMapContext().getLayers().getLayer(i);
145
                        if(        lyr instanceof FLyrGeoRaster && 
146
                                lyr.getName().startsWith("*") &&
147
                                lyr.isActive())
148
                                this.lyrGeoRaster = (FLyrGeoRaster)lyr;
149
                }
150
                if(lyrGeoRaster == null)
151
                        throw new InstantiationException("No se ha podido cargar la capa de georreferenciaci?n");
152
        }
153

    
154
        
155
        /**
156
         * Cuando se produce un evento de pintado dibujamos el marco de la imagen para
157
         * que el usuario pueda seleccionar y redimensionar.
158
         */
159
        public void paintComponent(Graphics g) {
160
                
161
                BufferedImage img = getMapControl().getImage();
162
                g.drawImage(img, 0, 0, null);
163
                g.setColor(Color.red);
164
                ViewPort vp = getMapControl().getMapContext().getViewPort();
165
                try{
166
                        loadLayer();
167
                        Rectangle r = new Rectangle();
168
                        
169
                        if(tmpLr == null || tmpUl == null){
170
                                ul = vp.fromMapPoint(lyrGeoRaster.getAssignExtent().getMin().getX(), lyrGeoRaster.getAssignExtent().getMin().getY());
171
                                lr = vp.fromMapPoint(lyrGeoRaster.getAssignExtent().getMax().getX(), lyrGeoRaster.getAssignExtent().getMax().getY());
172
                                r.setFrameFromDiagonal(ul, lr);
173
                        }else
174
                                r.setFrameFromDiagonal(tmpUl, tmpLr);
175
                                
176
                                g.drawRect(r.x, r.y, r.width, r.height);
177
                }catch(InstantiationException exc){
178
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
179
                                        PluginServices.getText(this, "error_capa_puntos"));
180
                }catch(ClassCastException exc){
181
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
182
                                        PluginServices.getText(this, "error_capa_puntos"));
183
                }
184
                
185
        }
186

    
187
        /**
188
         * Reimplementaci?n del m?todo mousePressed de Behavior. Cuando se pulsa
189
         * estando sobre el marco de la imagen activamos la posibilidad de arrastrar
190
         * para redimensionar la imagen.
191
         *
192
         * @param e MouseEvent
193
         */
194
        public void mousePressed(MouseEvent e) {
195
                if (e.getButton() == MouseEvent.BUTTON1) {
196
                        
197
                        try{
198
                                loadLayer();
199
                        }catch(InstantiationException exc){
200
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
201
                                                PluginServices.getText(this, "error_capa_puntos"));
202
                                return;
203
                        }catch(ClassCastException exc){
204
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
205
                                                PluginServices.getText(this, "error_capa_puntos"));
206
                                return;
207
                        }
208
                        
209
                        tmpUl = ul;
210
                        tmpLr = lr;
211
                        
212
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
213
                        double wcX = vp.toMapPoint(e.getX(), e.getY()).getX();
214
                        double wcY = vp.toMapPoint(e.getX(), e.getY()).getY();
215
                        
216
                        double minX = lyrGeoRaster.getAssignExtent().getMin().getX();
217
                        double minY = lyrGeoRaster.getAssignExtent().getMin().getY();
218
                        double maxX = lyrGeoRaster.getAssignExtent().getMax().getX();
219
                        double maxY = lyrGeoRaster.getAssignExtent().getMax().getY();
220
                        
221
                        
222
                        if(iconActive[0]){//Estirar en horizontal activado
223
                                if(wcX > (maxX - WIDTH_BORDER) && wcX < maxX)
224
                                        redimActive[0] = true;
225
                                if(wcX < (minX + WIDTH_BORDER) && wcX > minX)
226
                                        redimActive[1] = true;
227
                        }
228
                        if(iconActive[1]){//Estirar en vertical activado
229
                                if(wcY > (maxY - WIDTH_BORDER) && wcY < maxY)
230
                                        redimActive[3] = true;
231
                                if(wcY < (minY + WIDTH_BORDER) && wcY > minY)
232
                                        redimActive[2] = true;
233
                        }
234
                        if(iconActive[2] || iconActive[3]){ //Estirar en oblicuo activado
235
                                redimActive[4] = true;
236
                                pointInit = e.getPoint();
237
                                rectInit =  new Rectangle2D.Double(tmpUl.getX(), tmpUl.getY(), tmpLr.getX() - tmpUl.getX(), tmpLr.getY() - tmpUl.getY());
238
                        }
239
                        
240
                }
241

    
242
                if (listener.cancelDrawing()) {
243
                        getMapControl().cancelDrawing();
244
                }
245

    
246
                getMapControl().repaint();
247
        }
248

    
249
        /**
250
         * Reimplementaci?n del m?todo mouseReleased de Behavior. Desactivamos
251
         * los flags de redimensionado y a partir de la selecci?n del usuario 
252
         * creamos un nuevo extent para la imagen. Con este extent creamos una nueva
253
         * capa que sustituir? a la anterior.
254
         *
255
         * @param e MouseEvent
256
         *
257
         * @throws BehaviorException Excepci?n lanzada cuando el Behavior.
258
         */
259
        public void mouseReleased(MouseEvent e) throws BehaviorException {
260
                if (e.getButton() == MouseEvent.BUTTON1) {
261
                        //Desactivamos los flags de redimensionado
262
                        for(int i=0;i<redimActive.length;i++)
263
                                redimActive[i] = false;
264
                        //Asignamos el nuevo extent a la imagen
265
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
266
                        Extent ext = new Extent(vp.toMapPoint((int)tmpUl.getX(), (int)tmpUl.getY()).getX(),
267
                                                                        vp.toMapPoint((int)tmpUl.getX(), (int)tmpUl.getY()).getY(),
268
                                                                        vp.toMapPoint((int)tmpLr.getX(), (int)tmpLr.getY()).getX(),
269
                                                                        vp.toMapPoint((int)tmpLr.getX(), (int)tmpLr.getY()).getY());
270
                        if(this.lyrGeoRaster != null){
271
                                ((FLyrGeoRaster)getMapControl().getMapContext().getLayers().getLayer(lyrGeoRaster.getName())).setAssignExtent(ext);
272
                                getMapControl().getMapContext().invalidate();
273
                                tmpUl = null;
274
                                tmpLr = null;
275
                        }
276
                }
277
        }
278

    
279
        /**
280
         * Al arrastrar cuando se ha pulsado sobre el marco de la imagen recalculamos
281
         * el marco de la imagen 
282
         *
283
         * @param e MouseEvent
284
         */
285
        public void mouseDragged(MouseEvent e) {
286
                double longLadoLargo = Math.abs(tmpLr.getX() - tmpUl.getX());
287
                double longLadoCorto = Math.abs(tmpLr.getY() - tmpUl.getY());
288
                
289
                if(redimActive[0]){//vertical derecha
290
                        double newLadoLargo = (e.getX() - tmpUl.getX());
291
                        double newLadoCorto = (newLadoLargo * longLadoCorto) / longLadoLargo;
292
                        double coordCentro = tmpLr.getY() + (Math.abs(tmpLr.getY() - tmpUl.getY()) / 2);
293
                        tmpUl = new Point2D.Double(tmpUl.getX(), coordCentro + (newLadoCorto/2));
294
                        tmpLr = new Point2D.Double(e.getX(), coordCentro - (newLadoCorto/2));
295
                        //System.out.println("Vertical derecha "+e.getPoint()+" newladoLargo="+newLadoLargo+" newladoCorto="+newLadoCorto+" centro="+coordCentro);
296
                        //System.out.println("................  longLadoLargo="+longLadoLargo+" longLadoCorto="+longLadoCorto);
297
                }
298
                if(redimActive[1]){//vertical izquierda
299
                        double newLadoLargo = (e.getX() - tmpLr.getX());
300
                        double newLadoCorto = (newLadoLargo * longLadoCorto) / longLadoLargo;
301
                        double coordCentro = tmpLr.getY() + (Math.abs(tmpLr.getY() - tmpUl.getY()) / 2);
302
                        tmpLr = new Point2D.Double(tmpLr.getX(), coordCentro + (newLadoCorto/2));
303
                        tmpUl = new Point2D.Double(e.getX(), coordCentro - (newLadoCorto/2));
304
                }
305
                if(redimActive[2]){//horizontal abajo
306
                        double newLadoCorto = (e.getY() - tmpLr.getY());
307
                        double newLadoLargo = (newLadoCorto * longLadoLargo) / longLadoCorto;
308
                        double coordCentro = tmpLr.getX() - (Math.abs(tmpLr.getX() - tmpUl.getX()) / 2);
309
                        tmpLr = new Point2D.Double(coordCentro + (newLadoLargo/2), tmpLr.getY());
310
                        tmpUl = new Point2D.Double(coordCentro - (newLadoLargo/2), e.getY());
311
                }
312
                if(redimActive[3]){//horizontal arriba
313
                        double newLadoCorto = (e.getY() - tmpUl.getY());
314
                        double newLadoLargo = (newLadoCorto * longLadoLargo) / longLadoCorto;
315
                        double coordCentro = tmpLr.getX() - (Math.abs(tmpLr.getX() - tmpUl.getX()) / 2);
316
                        tmpUl = new Point2D.Double(coordCentro + (newLadoLargo/2), tmpUl.getY());
317
                        tmpLr = new Point2D.Double(coordCentro - (newLadoLargo/2), e.getY());
318
                }
319
                if(redimActive[4]){//inclinado
320
                        double distX = (e.getX() - pointInit.getX());
321
                        double distY = (e.getY() - pointInit.getY());
322
                        double incrLadoLargo = 0D, incrLadoCorto = 0D;
323
                        incrLadoLargo = distX;
324
                        //Calculamos la distancia que incrementaremos al lado corto
325
                        boolean ejeXLargo = true; 
326
                        if(longLadoCorto > longLadoLargo){
327
                                double tmp = longLadoLargo;
328
                                longLadoLargo = longLadoCorto;
329
                                longLadoCorto = tmp;
330
                                ejeXLargo = false;
331
                        }        
332
                        
333
                        incrLadoCorto = (incrLadoLargo * longLadoCorto) / longLadoLargo;
334
                        Point2D antUl = tmpUl;
335
                        Point2D antLr = tmpLr;
336
                        if(distX > 0 && e.getX() > lr.getX()){
337
                                tmpUl = new Point2D.Double(rectInit.getMinX() - Math.abs(incrLadoLargo), rectInit.getMinY() + Math.abs(incrLadoCorto));
338
                                tmpLr = new Point2D.Double(rectInit.getMaxX() + Math.abs(incrLadoLargo), rectInit.getMaxY() - Math.abs(incrLadoCorto));
339
                        }else if(distX < 0 && e.getX() < ul.getX()){
340
                                tmpUl = new Point2D.Double(rectInit.getMinX() - Math.abs(incrLadoLargo), rectInit.getMinY() + Math.abs(incrLadoCorto));
341
                                tmpLr = new Point2D.Double(rectInit.getMaxX() + Math.abs(incrLadoLargo), rectInit.getMaxY() - Math.abs(incrLadoCorto));
342
                        }else if(distX > 0 && e.getX() < lr.getX() && e.getX() > ul.getX()){
343
                                tmpUl = new Point2D.Double(rectInit.getMinX() + Math.abs(incrLadoLargo), rectInit.getMinY() - Math.abs(incrLadoCorto));
344
                                tmpLr = new Point2D.Double(rectInit.getMaxX() - Math.abs(incrLadoLargo), rectInit.getMaxY() + Math.abs(incrLadoCorto));
345
                        }else if(distX < 0 && e.getX() < lr.getX() && e.getX() > ul.getX()){
346
                                tmpUl = new Point2D.Double(rectInit.getMinX() + Math.abs(incrLadoLargo), rectInit.getMinY() - Math.abs(incrLadoCorto));
347
                                tmpLr = new Point2D.Double(rectInit.getMaxX() - Math.abs(incrLadoLargo), rectInit.getMaxY() + Math.abs(incrLadoCorto));
348
                        }
349
                        //A partir de un tama?o m?nimo no reducimos m?s
350
                        if((tmpLr.getX() - tmpUl.getX()) < 100 || (tmpUl.getY() - tmpLr.getY()) < 100){
351
                                tmpUl = antUl;
352
                                tmpLr = antLr;
353
                        }
354
                                
355
                }
356
                
357
                getMapControl().repaint();
358
        }
359

    
360
        /**
361
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#setListener(com.iver.cit.gvsig.fmap.tools.ToolListener)
362
         */
363
        public void setListener(ToolListener listener) {
364
                this.listener = (RectangleListener) listener;
365
        }
366

    
367
        /**
368
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#getListener()
369
         */
370
        public ToolListener getListener() {
371
                return listener;
372
        }
373
        
374
        /**
375
         * Cuando movemos el rat?n detecta si estamos en el marco de la 
376
         * imagen y pone el icono del cursor del rat?n adecuado.
377
         */
378
        public void mouseMoved(MouseEvent e) throws BehaviorException {
379
                ViewPort vp = getMapControl().getMapContext().getViewPort();
380
                
381
                try{
382
                        loadLayer();
383
                }catch(InstantiationException exc){
384
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
385
                                        PluginServices.getText(this, "error_capa_puntos"));
386
                        return;
387
                }catch(ClassCastException exc){
388
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
389
                                        PluginServices.getText(this, "error_capa_puntos"));
390
                        return;
391
                }
392
                
393
                double wcX = vp.toMapPoint(e.getX(), e.getY()).getX();
394
                double wcY = vp.toMapPoint(e.getX(), e.getY()).getY();
395
                
396
                double minX = lyrGeoRaster.getAssignExtent().getMin().getX();
397
                double minY = lyrGeoRaster.getAssignExtent().getMin().getY();
398
                double maxX = lyrGeoRaster.getAssignExtent().getMax().getX();
399
                double maxY = lyrGeoRaster.getAssignExtent().getMax().getY();
400
                
401
                //Calculamos el borde sobre el cual cambiar? el puntero del rat?n y la longitud de la esquina
402
                
403
                WIDTH_BORDER = (int)Math.round((maxX - minX) * 0.02);
404
                LONG_CORNER = (int)Math.round((maxX - minX) * 0.03);
405
                if(WIDTH_BORDER < 15)
406
                        WIDTH_BORDER = 15;
407
                if(LONG_CORNER < 20)
408
                        LONG_CORNER = 20;
409
                                
410
                int iconPosActive = -1;
411
                
412
                //Flecha horizontal
413
                if(        ((wcX > minX && wcX < minX + WIDTH_BORDER) ||
414
                         (wcX < maxX && wcX > maxX - WIDTH_BORDER )) &&
415
                        (wcY < (maxY - LONG_CORNER)) &&
416
                        (wcY > (minY + LONG_CORNER))){        
417
                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconHoriz,
418
                                        new Point(16, 16), ""));
419
                        iconPosActive = 0;
420
                                                
421
                }else{
422
                        //Flecha Vertical
423
                        if(        ((wcY > minY && wcY < minY + WIDTH_BORDER) ||
424
                                 (wcY < maxY && wcY > maxY - WIDTH_BORDER )) &&
425
                                (wcX < (maxX - LONG_CORNER)) &&
426
                                (wcX > (minX + LONG_CORNER))){        
427
                                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconVert,
428
                                                        new Point(16, 16), ""));
429
                                        iconPosActive = 1;
430
                        }else{
431
                                //Flecha oblicua derecha
432
                                if((wcX > (maxX - LONG_CORNER) && wcX < maxX &&
433
                                        wcY < (minY + LONG_CORNER) && wcY > minY) ||
434
                                   (wcX > minX && wcX < (minX + LONG_CORNER) &&
435
                                        wcY < maxY && wcY > (maxY - LONG_CORNER))){
436
                                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconInclIzq,
437
                                                        new Point(16, 16), ""));
438
                                        iconPosActive = 2;
439
                                }else{
440
                                        //Flecha oblicua izquierda
441
                                        if((wcX > minX && wcX < (minX + LONG_CORNER) &&
442
                                                wcY < (minY + LONG_CORNER) && wcY > minY) ||
443
                                           (wcX > (maxX - LONG_CORNER) && wcX < maxX &&
444
                                                wcY > (maxY - LONG_CORNER) && wcY < maxY)){
445
                                                getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconInclDer,
446
                                                                        new Point(16, 16), ""));
447
                                                iconPosActive = 3;
448
                                        }else{
449
                                                getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(defaultCursor,
450
                                                                new Point(16, 16), ""));
451
                                                iconPosActive = -1;
452
                                        }
453
                                }
454
                        }
455
                }
456
                
457
                //Ponemos a true el incono activado y a false el resto
458
                for(int i=0;i<iconActive.length;i++){
459
                        if(i==iconPosActive)
460
                                iconActive[i] = true;
461
                        else
462
                                iconActive[i] = false;
463
                }                        
464
                getMapControl().repaint();        
465
        }
466

    
467
}