Statistics
| Revision:

root / trunk / extensions / extGeoreferencing / src / com / iver / cit / gvsig / fmap / tools / Behavior / GeoRedimBehavior.java @ 2977

History | View | Annotate | Download (15.5 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.Cursor;
45
import java.awt.Graphics;
46
import java.awt.Image;
47
import java.awt.Point;
48
import java.awt.Rectangle;
49
import java.awt.Toolkit;
50
import java.awt.event.MouseEvent;
51
import java.awt.geom.Point2D;
52
import java.awt.geom.Rectangle2D;
53
import java.awt.image.BufferedImage;
54

    
55
import javax.swing.ImageIcon;
56

    
57
import org.cresques.px.Extent;
58

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

    
71

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

    
134
        /**
135
         * Funci?n que carga la capa si todav?a no lo est?.
136
         */
137
        private void loadLayer(){
138
                //Cargamos la capa si esta es null
139
                if(this.lyrGeoRaster == null){
140
                        View theView = (View) PluginServices.getMDIManager().getActiveView();
141
                        for(int i=0;i<theView.getMapControl().getMapContext().getLayers().getLayersCount();i++){
142
                                FLayer lyr = theView.getMapControl().getMapContext().getLayers().getLayer(i);
143
                                if(lyr instanceof FLyrGeoRaster)
144
                                        this.lyrGeoRaster = (FLyrGeoRaster)lyr;
145
                        }
146
                }
147
        }
148
        
149
        /**
150
         * Cuando se produce un evento de pintado dibujamos el marco de la imagen para
151
         * que el usuario pueda seleccionar y redimensionar.
152
         */
153
        public void paintComponent(Graphics g) {
154
                
155
                BufferedImage img = getMapControl().getImage();
156
                g.drawImage(img, 0, 0, null);
157
                g.setColor(Color.red);
158
                ViewPort vp = getMapControl().getMapContext().getViewPort();
159
                loadLayer();
160
                Rectangle r = new Rectangle();
161
                
162
                if(tmpLr == null || tmpUl == null){
163
                        ul = vp.fromMapPoint(lyrGeoRaster.getAssignExtent().getMin().getX(), lyrGeoRaster.getAssignExtent().getMin().getY());
164
                        lr = vp.fromMapPoint(lyrGeoRaster.getAssignExtent().getMax().getX(), lyrGeoRaster.getAssignExtent().getMax().getY());
165
                        r.setFrameFromDiagonal(ul, lr);
166
                }else
167
                        r.setFrameFromDiagonal(tmpUl, tmpLr);
168
                        
169
                        g.drawRect(r.x, r.y, r.width, r.height);
170
                
171
        }
172

    
173
        /**
174
         * Reimplementaci?n del m?todo mousePressed de Behavior. Cuando se pulsa
175
         * estando sobre el marco de la imagen activamos la posibilidad de arrastrar
176
         * para redimensionar la imagen.
177
         *
178
         * @param e MouseEvent
179
         */
180
        public void mousePressed(MouseEvent e) {
181
                if (e.getButton() == MouseEvent.BUTTON1) {
182
                        
183
                        loadLayer();
184
                        tmpUl = ul;
185
                        tmpLr = lr;
186
                        
187
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
188
                        double wcX = vp.toMapPoint(e.getX(), e.getY()).getX();
189
                        double wcY = vp.toMapPoint(e.getX(), e.getY()).getY();
190
                        
191
                        double minX = lyrGeoRaster.getAssignExtent().getMin().getX();
192
                        double minY = lyrGeoRaster.getAssignExtent().getMin().getY();
193
                        double maxX = lyrGeoRaster.getAssignExtent().getMax().getX();
194
                        double maxY = lyrGeoRaster.getAssignExtent().getMax().getY();
195
                        
196
                        
197
                        if(iconActive[0]){//Estirar en horizontal activado
198
                                if(wcX > (maxX - WIDTH_BORDER) && wcX < maxX)
199
                                        redimActive[0] = true;
200
                                if(wcX < (minX + WIDTH_BORDER) && wcX > minX)
201
                                        redimActive[1] = true;
202
                        }
203
                        if(iconActive[1]){//Estirar en vertical activado
204
                                if(wcY > (maxY - WIDTH_BORDER) && wcY < maxY)
205
                                        redimActive[3] = true;
206
                                if(wcY < (minY + WIDTH_BORDER) && wcY > minY)
207
                                        redimActive[2] = true;
208
                        }
209
                        if(iconActive[2] || iconActive[3]){ //Estirar en oblicuo activado
210
                                redimActive[4] = true;
211
                                pointInit = e.getPoint();
212
                                rectInit =  new Rectangle2D.Double(tmpUl.getX(), tmpUl.getY(), tmpLr.getX() - tmpUl.getX(), tmpLr.getY() - tmpUl.getY());
213
                        }
214
                        
215
                }
216

    
217
                if (listener.cancelDrawing()) {
218
                        getMapControl().cancelDrawing();
219
                }
220

    
221
                getMapControl().repaint();
222
        }
223

    
224
        /**
225
         * Reimplementaci?n del m?todo mouseReleased de Behavior. Desactivamos
226
         * los flags de redimensionado y a partir de la selecci?n del usuario 
227
         * creamos un nuevo extent para la imagen. Con este extent creamos una nueva
228
         * capa que sustituir? a la anterior.
229
         *
230
         * @param e MouseEvent
231
         *
232
         * @throws BehaviorException Excepci?n lanzada cuando el Behavior.
233
         */
234
        public void mouseReleased(MouseEvent e) throws BehaviorException {
235
                if (e.getButton() == MouseEvent.BUTTON1) {
236
                        //Desactivamos los flags de redimensionado
237
                        for(int i=0;i<redimActive.length;i++)
238
                                redimActive[i] = false;
239
                        //Asignamos el nuevo extent a la imagen
240
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
241
                        Extent ext = new Extent(vp.toMapPoint((int)tmpUl.getX(), (int)tmpUl.getY()).getX(),
242
                                                                        vp.toMapPoint((int)tmpUl.getX(), (int)tmpUl.getY()).getY(),
243
                                                                        vp.toMapPoint((int)tmpLr.getX(), (int)tmpLr.getY()).getX(),
244
                                                                        vp.toMapPoint((int)tmpLr.getX(), (int)tmpLr.getY()).getY());
245
                        if(this.lyrGeoRaster != null){
246
                                ((FLyrGeoRaster)getMapControl().getMapContext().getLayers().getLayer(lyrGeoRaster.getName())).setAssignExtent(ext);
247
                                getMapControl().getMapContext().invalidate();
248
                                tmpUl = null;
249
                                tmpLr = null;
250
                        }
251
                }
252
        }
253

    
254
        /**
255
         * Al arrastrar cuando se ha pulsado sobre el marco de la imagen recalculamos
256
         * el marco de la imagen 
257
         *
258
         * @param e MouseEvent
259
         */
260
        public void mouseDragged(MouseEvent e) {
261
                double longLadoLargo = Math.abs(tmpLr.getX() - tmpUl.getX());
262
                double longLadoCorto = Math.abs(tmpLr.getY() - tmpUl.getY());
263
                
264
                if(redimActive[0]){//vertical derecha
265
                        double newLadoLargo = (e.getX() - tmpUl.getX());
266
                        double newLadoCorto = (newLadoLargo * longLadoCorto) / longLadoLargo;
267
                        double coordCentro = tmpLr.getY() + (Math.abs(tmpLr.getY() - tmpUl.getY()) / 2);
268
                        tmpUl = new Point2D.Double(tmpUl.getX(), coordCentro + (newLadoCorto/2));
269
                        tmpLr = new Point2D.Double(e.getX(), coordCentro - (newLadoCorto/2));
270
                        //System.out.println("Vertical derecha "+e.getPoint()+" newladoLargo="+newLadoLargo+" newladoCorto="+newLadoCorto+" centro="+coordCentro);
271
                        //System.out.println("................  longLadoLargo="+longLadoLargo+" longLadoCorto="+longLadoCorto);
272
                }
273
                if(redimActive[1]){//vertical izquierda
274
                        double newLadoLargo = (e.getX() - tmpLr.getX());
275
                        double newLadoCorto = (newLadoLargo * longLadoCorto) / longLadoLargo;
276
                        double coordCentro = tmpLr.getY() + (Math.abs(tmpLr.getY() - tmpUl.getY()) / 2);
277
                        tmpLr = new Point2D.Double(tmpLr.getX(), coordCentro + (newLadoCorto/2));
278
                        tmpUl = new Point2D.Double(e.getX(), coordCentro - (newLadoCorto/2));
279
                }
280
                if(redimActive[2]){//horizontal abajo
281
                        double newLadoCorto = (e.getY() - tmpLr.getY());
282
                        double newLadoLargo = (newLadoCorto * longLadoLargo) / longLadoCorto;
283
                        double coordCentro = tmpLr.getX() - (Math.abs(tmpLr.getX() - tmpUl.getX()) / 2);
284
                        tmpLr = new Point2D.Double(coordCentro + (newLadoLargo/2), tmpLr.getY());
285
                        tmpUl = new Point2D.Double(coordCentro - (newLadoLargo/2), e.getY());
286
                }
287
                if(redimActive[3]){//horizontal arriba
288
                        double newLadoCorto = (e.getY() - tmpUl.getY());
289
                        double newLadoLargo = (newLadoCorto * longLadoLargo) / longLadoCorto;
290
                        double coordCentro = tmpLr.getX() - (Math.abs(tmpLr.getX() - tmpUl.getX()) / 2);
291
                        tmpUl = new Point2D.Double(coordCentro + (newLadoLargo/2), tmpUl.getY());
292
                        tmpLr = new Point2D.Double(coordCentro - (newLadoLargo/2), e.getY());
293
                }
294
                if(redimActive[4]){//inclinado
295
                        double distX = (e.getX() - pointInit.getX());
296
                        double distY = (e.getY() - pointInit.getY());
297
                        double incrLadoLargo = 0D, incrLadoCorto = 0D;
298
                        incrLadoLargo = distX;
299
                        //Calculamos la distancia que incrementaremos al lado corto
300
                        boolean ejeXLargo = true; 
301
                        if(longLadoCorto > longLadoLargo){
302
                                double tmp = longLadoLargo;
303
                                longLadoLargo = longLadoCorto;
304
                                longLadoCorto = tmp;
305
                                ejeXLargo = false;
306
                        }        
307
                        
308
                        incrLadoCorto = (incrLadoLargo * longLadoCorto) / longLadoLargo;
309
                        Point2D antUl = tmpUl;
310
                        Point2D antLr = tmpLr;
311
                        if(distX > 0 && e.getX() > lr.getX()){
312
                                tmpUl = new Point2D.Double(rectInit.getMinX() - Math.abs(incrLadoLargo), rectInit.getMinY() + Math.abs(incrLadoCorto));
313
                                tmpLr = new Point2D.Double(rectInit.getMaxX() + Math.abs(incrLadoLargo), rectInit.getMaxY() - Math.abs(incrLadoCorto));
314
                        }else if(distX < 0 && e.getX() < ul.getX()){
315
                                tmpUl = new Point2D.Double(rectInit.getMinX() - Math.abs(incrLadoLargo), rectInit.getMinY() + Math.abs(incrLadoCorto));
316
                                tmpLr = new Point2D.Double(rectInit.getMaxX() + Math.abs(incrLadoLargo), rectInit.getMaxY() - Math.abs(incrLadoCorto));
317
                        }else if(distX > 0 && e.getX() < lr.getX() && e.getX() > ul.getX()){
318
                                tmpUl = new Point2D.Double(rectInit.getMinX() + Math.abs(incrLadoLargo), rectInit.getMinY() - Math.abs(incrLadoCorto));
319
                                tmpLr = new Point2D.Double(rectInit.getMaxX() - Math.abs(incrLadoLargo), rectInit.getMaxY() + Math.abs(incrLadoCorto));
320
                        }else if(distX < 0 && e.getX() < lr.getX() && e.getX() > ul.getX()){
321
                                tmpUl = new Point2D.Double(rectInit.getMinX() + Math.abs(incrLadoLargo), rectInit.getMinY() - Math.abs(incrLadoCorto));
322
                                tmpLr = new Point2D.Double(rectInit.getMaxX() - Math.abs(incrLadoLargo), rectInit.getMaxY() + Math.abs(incrLadoCorto));
323
                        }
324
                        //A partir de un tama?o m?nimo no reducimos m?s
325
                        if((tmpLr.getX() - tmpUl.getX()) < 100 || (tmpUl.getY() - tmpLr.getY()) < 100){
326
                                tmpUl = antUl;
327
                                tmpLr = antLr;
328
                        }
329
                                
330
                }
331
                
332
                getMapControl().repaint();
333
        }
334

    
335
        /**
336
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#setListener(com.iver.cit.gvsig.fmap.tools.ToolListener)
337
         */
338
        public void setListener(ToolListener listener) {
339
                this.listener = (RectangleListener) listener;
340
        }
341

    
342
        /**
343
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#getListener()
344
         */
345
        public ToolListener getListener() {
346
                return listener;
347
        }
348
        
349
        /**
350
         * Cuando movemos el rat?n detecta si estamos en el marco de la 
351
         * imagen y pone el icono del cursor del rat?n adecuado.
352
         */
353
        public void mouseMoved(MouseEvent e) throws BehaviorException {
354
                ViewPort vp = getMapControl().getMapContext().getViewPort();
355
                
356
                loadLayer();
357
                
358
                double wcX = vp.toMapPoint(e.getX(), e.getY()).getX();
359
                double wcY = vp.toMapPoint(e.getX(), e.getY()).getY();
360
                
361
                double minX = lyrGeoRaster.getAssignExtent().getMin().getX();
362
                double minY = lyrGeoRaster.getAssignExtent().getMin().getY();
363
                double maxX = lyrGeoRaster.getAssignExtent().getMax().getX();
364
                double maxY = lyrGeoRaster.getAssignExtent().getMax().getY();
365
                
366
                //Calculamos el borde sobre el cual cambiar? el puntero del rat?n y la longitud de la esquina
367
                
368
                WIDTH_BORDER = (int)Math.round((maxX - minX) * 0.02);
369
                LONG_CORNER = (int)Math.round((maxX - minX) * 0.03);
370
                if(WIDTH_BORDER < 15)
371
                        WIDTH_BORDER = 15;
372
                if(LONG_CORNER < 20)
373
                        LONG_CORNER = 20;
374
                                
375
                int iconPosActive = -1;
376
                
377
                //Flecha horizontal
378
                if(        ((wcX > minX && wcX < minX + WIDTH_BORDER) ||
379
                         (wcX < maxX && wcX > maxX - WIDTH_BORDER )) &&
380
                        (wcY < (maxY - LONG_CORNER)) &&
381
                        (wcY > (minY + LONG_CORNER))){        
382
                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconHoriz,
383
                                        new Point(16, 16), ""));
384
                        iconPosActive = 0;
385
                                                
386
                }else{
387
                        //Flecha Vertical
388
                        if(        ((wcY > minY && wcY < minY + WIDTH_BORDER) ||
389
                                 (wcY < maxY && wcY > maxY - WIDTH_BORDER )) &&
390
                                (wcX < (maxX - LONG_CORNER)) &&
391
                                (wcX > (minX + LONG_CORNER))){        
392
                                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconVert,
393
                                                        new Point(16, 16), ""));
394
                                        iconPosActive = 1;
395
                        }else{
396
                                //Flecha oblicua derecha
397
                                if((wcX > (maxX - LONG_CORNER) && wcX < maxX &&
398
                                        wcY < (minY + LONG_CORNER) && wcY > minY) ||
399
                                   (wcX > minX && wcX < (minX + LONG_CORNER) &&
400
                                        wcY < maxY && wcY > (maxY - LONG_CORNER))){
401
                                        getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconInclIzq,
402
                                                        new Point(16, 16), ""));
403
                                        iconPosActive = 2;
404
                                }else{
405
                                        //Flecha oblicua izquierda
406
                                        if((wcX > minX && wcX < (minX + LONG_CORNER) &&
407
                                                wcY < (minY + LONG_CORNER) && wcY > minY) ||
408
                                           (wcX > (maxX - LONG_CORNER) && wcX < maxX &&
409
                                                wcY > (maxY - LONG_CORNER) && wcY < maxY)){
410
                                                getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(iconInclDer,
411
                                                                        new Point(16, 16), ""));
412
                                                iconPosActive = 3;
413
                                        }else{
414
                                                getMapControl().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(defaultCursor,
415
                                                                new Point(16, 16), ""));
416
                                                iconPosActive = -1;
417
                                        }
418
                                }
419
                        }
420
                }
421
                
422
                //Ponemos a true el incono activado y a false el resto
423
                for(int i=0;i<iconActive.length;i++){
424
                        if(i==iconPosActive)
425
                                iconActive[i] = true;
426
                        else
427
                                iconActive[i] = false;
428
                }                        
429
                getMapControl().repaint();        
430
        }
431

    
432
}