Statistics
| Revision:

svn-document-layout / trunk / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / FLayoutZooms.java @ 134

History | View | Annotate | Download (20.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.app.project.documents.layout;
23

    
24
import java.awt.Dimension;
25
import java.awt.Point;
26
import java.awt.Toolkit;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.Point2D;
29
import java.awt.geom.Rectangle2D;
30
import java.util.prefs.Preferences;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
import org.gvsig.app.project.documents.layout.fframes.IFFrame;
35
import org.gvsig.app.project.documents.layout.fframes.IFFrameUseFMap;
36
import org.gvsig.app.project.documents.layout.gui.LayoutPanel;
37
import org.gvsig.compat.CompatLocator;
38
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
42
import org.gvsig.fmap.mapcontext.MapContext;
43
import org.gvsig.tools.observer.Observable;
44
import org.gvsig.tools.observer.ObservableHelper;
45
import org.gvsig.tools.observer.Observer;
46

    
47
/**
48
 * Clase encargada de realizar los zooms al Layout.
49
 * 
50
 * @author Vicente Caballero Navarro
51
 */
52
public class FLayoutZooms implements Observable{
53

    
54
    private static final GeometryManager geomManager = GeometryLocator
55
        .getGeometryManager();
56
    private static final Logger logger = LoggerFactory
57
        .getLogger(FLayoutZooms.class);
58
    private LayoutPanel layout = null;
59
    private ObservableHelper observers;
60
    
61
    public FLayoutZooms(LayoutPanel layoutPanel) {
62
        layout = layoutPanel;
63
        observers = new ObservableHelper();
64
        observers.addObserver(layoutPanel.getLayoutControl());
65
    }
66

    
67
    /**
68
     * Realiza un zoom por rect?ngulo o por punto con un escalado por defecto
69
     * sobre el Layout que se le pasa como par?metro.
70
     * 
71
     * @param p1
72
     *            punto de inicio del rect?ngulo.
73
     * @param p2
74
     *            punto final del rec?ngulo.
75
     */
76
    public void setZoomIn(Point p1, Point p2) {
77
        if (java.lang.Math.abs(layout.getLayoutControl().getFirstPoint().x
78
            - p2.x) < 4) {
79
            double difw = 2;
80
            setZoom(difw, p2);
81
        } else {
82
            if (p1.getX() > p2.getX()) {
83
                int aux = p2.x;
84
                p2.x = p1.x;
85
                p1.x = aux;
86
            }
87

    
88
            if (p1.getY() > p2.getY()) {
89
                int aux = p2.y;
90
                p2.y = p1.y;
91
                p1.y = aux;
92
            }
93

    
94
            Point2D.Double pSheet1 =
95
                FLayoutUtilities.toSheetPoint(
96
                    new Point2D.Double(p1.getX(), p1.getY()), layout
97
                        .getLayoutControl().getAT());
98
            Point2D.Double pSheet2 =
99
                FLayoutUtilities.toSheetPoint(
100
                    new Point2D.Double(p2.getX(), p2.getY()), layout
101
                        .getLayoutControl().getAT());
102

    
103
            double xmin;
104
            double xmax;
105
            double ymin;
106
            double ymax = 0;
107

    
108
            if (pSheet1.x > pSheet2.x) {
109
                xmin = pSheet2.x;
110
                xmax = pSheet1.x;
111
            } else {
112
                xmin = pSheet1.x;
113
                xmax = pSheet2.x;
114
            }
115

    
116
            if (pSheet1.y > pSheet2.y) {
117
                ymin = pSheet2.y;
118
                ymax = pSheet1.y;
119
            } else {
120
                ymin = pSheet1.y;
121
                ymax = pSheet2.y;
122
            }
123

    
124
            Rectangle2D.Double rScreen = new Rectangle2D.Double();
125
            Rectangle2D.Double rSheet = new Rectangle2D.Double();
126
            double x =
127
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
128
                    .getRect().getX(), layout.getLayoutControl().getAT());
129
            double y =
130
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
131
                    .getRect().getY(), layout.getLayoutControl().getAT());
132
            double w =
133
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
134
                    .getRect().getWidth(), layout.getLayoutControl().getAT());
135
            double h =
136
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
137
                    .getRect().getHeight(), layout.getLayoutControl().getAT());
138

    
139
            double wv =
140
                FLayoutUtilities.toSheetDistance(layout.getVisibleRect()
141
                    .getWidth(), layout.getLayoutControl().getAT());
142
            double hv =
143
                FLayoutUtilities.toSheetDistance(layout.getVisibleRect()
144
                    .getHeight(), layout.getLayoutControl().getAT());
145
            double mw = xmax - xmin;
146
            double mh = ymax - ymin;
147
            double difw = wv / mw;
148
            double difh = hv / mh;
149

    
150
            if (difw < difh) {
151
                rSheet.x =
152
                    (-xmin * difw)
153
                        - x
154
                        + ((wv - ((pSheet2.getX() - pSheet1.getX()) * difw)) / 2);
155
                rSheet.y =
156
                    (-ymin * difw)
157
                        - y
158
                        + ((hv - ((pSheet2.getY() - pSheet1.getY()) * difw)) / 2);
159

    
160
                rSheet.width = w * difw;
161
                rSheet.height = h * difw;
162
            } else {
163
                rSheet.x =
164
                    (-xmin * difh)
165
                        - x
166
                        + ((wv - ((pSheet2.getX() - pSheet1.getX()) * difh)) / 2);
167
                rSheet.y =
168
                    (-ymin * difh)
169
                        - y
170
                        + ((hv - ((pSheet2.getY() - pSheet1.getY()) * difh)) / 2);
171

    
172
                rSheet.width = w * difh;
173
                rSheet.height = h * difh;
174
            }
175
            setPointsToZoom(p1, p2);
176
            rScreen.setRect(FLayoutUtilities.fromSheetRect(rSheet, layout
177
                .getLayoutControl().getAT()));
178
            if (FLayoutUtilities.isPosible(rScreen)) {
179
                layout.getLayoutControl().getRect().setRect(rScreen);
180
            }
181
        }
182
    }
183

    
184
    /**
185
     * Realiza un zoom out sobre el Layout que se le pasa como par?metro.
186
     * 
187
     * @param p2
188
     *            punto central del rect?ngulo.
189
     */
190
    public void setZoomOut(Point p2) {
191
        double difw = 0.5;
192
        setZoom(difw, p2);
193
    }
194

    
195
    /**
196
     * Realiza un zoom out sobre el Layout que se le pasa como par?metro.
197
     * 
198
     * @param dif
199
     *            factor.
200
     * @param p2
201
     *            punto final del rec?ngulo.
202
     */
203
    public void setZoom(double dif, Point p2) {
204
        Point2D.Double pSheet2 =
205
            FLayoutUtilities.toSheetPoint(
206
                new Point2D.Double(p2.getX(), p2.getY()), layout
207
                    .getLayoutControl().getAT());
208
        Rectangle2D.Double rScreen = new Rectangle2D.Double();
209
        Rectangle2D.Double rSheet = new Rectangle2D.Double();
210

    
211
        double difw = dif;
212

    
213
        rSheet.x =
214
            (-pSheet2.getX() * difw)
215
                - FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
216
                    .getRect().getX(), layout.getLayoutControl().getAT())
217
                + FLayoutUtilities.toSheetDistance(layout.getWidth() / 2,
218
                    layout.getLayoutControl().getAT());
219
        rSheet.y =
220
            (-pSheet2.getY() * difw)
221
                - FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
222
                    .getRect().getY(), layout.getLayoutControl().getAT())
223
                + FLayoutUtilities.toSheetDistance(layout.getHeight() / 2,
224
                    layout.getLayoutControl().getAT());
225

    
226
        rSheet.width =
227
            FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
228
                .getRect().getWidth(), layout.getLayoutControl().getAT())
229
                * difw;
230
        rSheet.height =
231
            FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
232
                .getRect().getHeight(), layout.getLayoutControl().getAT())
233
                * difw;
234

    
235
        rScreen.setRect(FLayoutUtilities.fromSheetRect(rSheet, layout
236
            .getLayoutControl().getAT()));
237

    
238
        if (FLayoutUtilities.isPosible(rScreen)) {
239
            layout.getLayoutControl().getRect().setRect(rScreen);
240
        }
241

    
242
        // Para realizar el zoom a partir de un punto.
243
        Point p1 =
244
            new Point((int) (p2.getX() - (layout.getWidth() / (difw * 2))),
245
                (int) (p2.getY() - (layout.getHeight() / (difw * 2))));
246
        p2 =
247
            new Point((int) (p2.getX() + (layout.getWidth() / (difw * 2))),
248
                (int) (p2.getY() + (layout.getHeight() / (difw * 2))));
249
        setPointsToZoom(p1, p2);
250
    }
251

    
252
    /**
253
     * Introduce los puntos de control para controlar el zoom del Layout.
254
     */
255
    private void setPointsToZoom(Point p1, Point p2) {
256
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
257

    
258
        for (int i = 0; i < fframes.length; i++) {
259
            if (fframes[i] instanceof IFFrameUseFMap) {
260
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
261
                if (fframe.getATMap() != null) {
262
                    
263
                    Point2D vppo1 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
264
                        p1, fframes[i]);
265
                    Point2D vppo2 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
266
                        p2, fframes[i]);
267
                    
268
                    Point2D px1 =
269
                        FLayoutFunctions.toMapPoint(vppo1, fframe.getATMap());
270
                    Point2D px2 =
271
                        FLayoutFunctions.toMapPoint(vppo2, fframe.getATMap());
272
                    fframe.setPointsToZoom(px1, px2);
273
                }
274
            }
275
        }
276
    }
277

    
278
    /**
279
     * Aplica el zoom real teniendo en cuenta la resoluci?n de pantalla.
280
     */
281
    public void realZoom() {
282
        double cm =
283
            layout.getLayoutContext().getAttributes()
284
                .getPixXCm(layout.getLayoutControl().getRect());
285
        double dpi = CompatLocator.getGraphicsUtils().getScreenDPI();
286
        double dif = (cm * Attributes.PULGADA) / dpi;
287
        setZoom(1 / dif, new Point(layout.getWidth() / 2,
288
            layout.getHeight() / 2));
289
        layout.getLayoutControl().refresh();
290
    }
291

    
292
    /**
293
     * Realiza un zoom in a partir del zoom actual de la vista.
294
     */
295
    public void zoomIn() {
296
        setZoom(2, new Point(layout.getWidth() / 2, layout.getHeight() / 2));
297
        layout.getLayoutControl().refresh();
298
    }
299

    
300
    /**
301
     * Realiza un zoom out a partir del zoom actual de la vista.
302
     */
303
    public void zoomOut() {
304
        setZoom(0.5, new Point(layout.getWidth() / 2, layout.getHeight() / 2));
305
        layout.getLayoutControl().refresh();
306
    }
307

    
308
    /**
309
     * Realiza un zoom a los elementos que esten seleccionados, si no hay
310
     * ning?n elemento seleccionado no realiza ning?n zoom
311
     */
312
    public void zoomSelect() {
313
        Rectangle2D.Double recaux = null;
314
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
315
        for (int i = 0; i < fframes.length; i++) {
316
            if (fframes[i].getSelected() != IFFrame.NOSELECT) {
317
                if (recaux == null) {
318
                    recaux =
319
                        fframes[i].getBoundingBox(layout.getLayoutControl()
320
                            .getAT());
321
                } else {
322
                    recaux.add(fframes[i].getBoundingBox(layout
323
                        .getLayoutControl().getAT()));
324
                }
325
            }
326
        }
327

    
328
        if (recaux != null) {
329
            Point p1 = new Point((int) recaux.x, (int) recaux.y);
330
            Point p2 =
331
                new Point((int) recaux.getMaxX(), (int) recaux.getMaxY());
332
            setZoomIn(p1, p2);
333
            layout.getLayoutControl().refresh();
334
        }
335
    }
336

    
337
    /**
338
     * Realiza un zoom a todos los elementos del layout.
339
     */
340
    public void zoomAllFrames() {
341
        Rectangle2D.Double recaux = null;
342
        IFFrame[] fframes =
343
            layout.getLayoutControl().getLayoutContext().getFFrames();
344
        for (int i = 0; i < fframes.length; i++) {
345
            if (recaux == null) {
346
                recaux =
347
                    fframes[i]
348
                        .getBoundingBox(layout.getLayoutControl().getAT());
349
            } else {
350
                recaux.add(fframes[i].getBoundingBox(layout.getLayoutControl()
351
                    .getAT()));
352
            }
353
        }
354

    
355
        if (recaux != null) {
356
            Point p1 = new Point((int) recaux.x, (int) recaux.y);
357
            Point p2 =
358
                new Point((int) recaux.getMaxX(), (int) recaux.getMaxY());
359
            setZoomIn(p1, p2);
360
            layout.getLayoutControl().refresh();
361
        }
362
    }
363

    
364
    /**
365
     * Realiza un zoom in a las vista a?adidas al Layout que esten seleccionadas
366
     * 
367
     * @param p1
368
     *            Punto inicial del rect?ngulo
369
     * @param p2
370
     *            Punto final del rect?ngulo
371
     */
372
    public void setViewZoomIn(Point2D poi1, Point2D poi2) {
373
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
374
        for (int i = 0; i < fframes.length; i++) {
375
            if (fframes[i] instanceof IFFrameUseFMap) {
376
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
377

    
378
                if (((IFFrame) fframe).getSelected() != IFFrame.NOSELECT) {
379
                    
380
                    Point2D vppo1 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
381
                        poi1, fframes[i]);
382
                    Point2D vppo2 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
383
                        poi2, fframes[i]);
384
                    
385
                    Point2D.Double mapp1 = FLayoutFunctions.toMapPoint(vppo1, fframe.getATMap());
386
                    Point2D.Double mapp2 = FLayoutFunctions.toMapPoint(vppo2, fframe.getATMap());
387

    
388
                    // Borramos el anterior
389
                    observers.notifyObservers(this, 
390
                        new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));
391
                    Rectangle2D.Double r = new Rectangle2D.Double();
392

    
393
                    if (java.lang.Math.abs(poi1.getX() - poi2.getX()) <= 3) {
394
                        double nuevoX;
395
                        double nuevoY;
396
                        double cX;
397
                        double cY;
398

    
399
                        cX = mapp2.getX();
400
                        cY = mapp2.getY();
401

    
402
                        double factor = 1 / MapContext.ZOOMINFACTOR;
403

    
404
                        Rectangle2D extent =
405
                            fframe.getMapContext().getViewPort().getExtent();
406
                        if (extent != null) {
407
                            nuevoX = cX - ((extent.getWidth() * factor) / 2.0);
408
                            nuevoY = cY - ((extent.getHeight() * factor) / 2.0);
409
                            r.x = nuevoX;
410
                            r.y = nuevoY;
411
                            r.width = extent.getWidth() * factor;
412
                            r.height = extent.getHeight() * factor;
413
                        }
414

    
415
                        // fframeAux.setNewExtent(r);
416
                    } else {
417
                        // Fijamos el nuevo extent
418

    
419
                        r.setFrameFromDiagonal(mapp1, mapp2);
420

    
421
                        // fframeAux.setNewExtent(r);
422
                    }
423

    
424
                    /*
425
                     * if (fframe.getTypeScale()!=IFFrameUseFMap.AUTOMATICO) {
426
                     * fframeAux.setNewExtent(r);
427
                     * fframeAux.refresh();
428
                     * layout.getEFS().modifyFFrame((IFFrame)fframe,(IFFrame)
429
                     * fframeAux);
430
                     * ((IFFrame)fframeAux).getBoundingBox(layout.getAT());
431
                     * layout.updateFFrames();
432
                     * layout.setIsReSel(true);
433
                     * }else {
434
                     */
435
                    try {
436
                        fframe.setNewEnvelope(geomManager.createEnvelope(
437
                            r.getX(), r.getY(), r.getMaxX(), r.getMaxY(),
438
                            SUBTYPES.GEOM2D));
439
                    } catch (CreateEnvelopeException e) {
440
                        logger.error("Error creating the envelope", e);
441
                    }
442
                    fframe.refresh();
443
                    if (fframe.getLinked()) {
444
                        fframe.refreshOriginalExtent();
445
                    }
446
                    // /}
447
                    // Fin del else
448
                    // layout.repaint();
449
                }
450
            }
451
        }
452
    }
453

    
454
    /**
455
     * Realiza un zoom out a las vistas a?adidas al Layout y que est?n
456
     * seleccionadas
457
     * 
458
     * @param p2
459
     *            Punto central
460
     */
461
    public void setViewZoomOut(Point p2) {
462
        Point2D.Double pWorld;
463
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
464
        for (int i = 0; i < fframes.length; i++) {
465
            if (fframes[i] instanceof IFFrameUseFMap) {
466
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
467

    
468
                if (((IFFrame) fframe).getSelected() != IFFrame.NOSELECT) {
469

    
470
                    double nuevoX;
471
                    double nuevoY;
472
                    double cX;
473
                    double cY;
474
                    Point pScreen = new Point((int) p2.getX(), (int) p2.getY());
475
                    
476
                    Point2D vppo1 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
477
                        pScreen, fframes[i]);
478
                    
479
                    pWorld = FLayoutFunctions.toMapPoint(vppo1, fframe.getATMap());
480

    
481
                    cX = pWorld.getX();
482
                    cY = pWorld.getY();
483

    
484
                    double factor = 1 / MapContext.ZOOMOUTFACTOR;
485
                    Rectangle2D extent =
486
                        fframe.getMapContext().getViewPort().getExtent();
487
                    if (extent != null) {
488
                        nuevoX = cX - ((extent.getWidth() * factor) / 2.0);
489
                        nuevoY = cY - ((extent.getHeight() * factor) / 2.0);
490
                        double x = nuevoX;
491
                        double y = nuevoY;
492
                        double width = extent.getWidth() * factor;
493
                        double height = extent.getHeight() * factor;
494
                        try {
495
                            fframe.setNewEnvelope(geomManager.createEnvelope(x,
496
                                y, x + width, y + height, SUBTYPES.GEOM2D));
497
                        } catch (CreateEnvelopeException e) {
498
                            logger.error("Error creating the envelope", e);
499
                        }
500
                        fframe.refresh();
501
                        if (fframe.getLinked()) {
502
                            fframe.refreshOriginalExtent();
503
                        }
504
                    }
505
                }
506
            }
507
        }
508
    }
509

    
510
    /**
511
     * Modifica los puntos de control para generar el zoom del Layout
512
     * 
513
     * @param p1
514
     *            Punto inicial
515
     * @param p2
516
     *            Punto final
517
     */
518
    public void setPan(Point p1, Point p2) {
519
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
520

    
521
        for (int i = 0; i < fframes.length; i++) {
522
            if (fframes[i] instanceof IFFrameUseFMap) {
523
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
524
                AffineTransform at = fframe.getATMap();
525
                if (at != null) {
526
                    
527
                    Point2D vppo1 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
528
                        p1, fframes[i]);
529
                    Point2D vppo2 = FLayoutUtilities.screenCoordinatesToViewportImageCoordinates(
530
                        p2, fframes[i]);
531

    
532
                    Point2D px1 = FLayoutFunctions.toMapPoint(vppo1, at);
533
                    Point2D px2 = FLayoutFunctions.toMapPoint(vppo2, at);
534
                    fframe.movePoints(px1, px2);
535
                }
536
            }
537
        }
538
    }
539

    
540
    public void addObserver(Observer o) {
541
        observers.addObserver(o);        
542
    }
543

    
544
    public void deleteObserver(Observer o) {
545
      observers.deleteObserver(o);        
546
    }
547

    
548
    public void deleteObservers() {
549
       observers.deleteObservers();        
550
    }
551
}