Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / FLayoutZooms.java @ 36648

History | View | Annotate | Download (18.9 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.Point;
25
import java.awt.Toolkit;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.Point2D;
28
import java.awt.geom.Rectangle2D;
29
import java.util.prefs.Preferences;
30

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
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.fmap.geom.Geometry.SUBTYPES;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
41
import org.gvsig.fmap.mapcontext.MapContext;
42

    
43
/**
44
 * Clase encargada de realizar los zooms al Layout.
45
 * 
46
 * @author Vicente Caballero Navarro
47
 */
48
public class FLayoutZooms {
49

    
50
    private static final GeometryManager geomManager = GeometryLocator
51
        .getGeometryManager();
52
    private static final Logger logger = LoggerFactory
53
        .getLogger(FLayoutZooms.class);
54
    private LayoutPanel layout = null;
55

    
56
    public FLayoutZooms(LayoutPanel l) {
57
        layout = l;
58
    }
59

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

    
81
            if (p1.getY() > p2.getY()) {
82
                int aux = p2.y;
83
                p2.y = p1.y;
84
                p1.y = aux;
85
            }
86

    
87
            Point2D.Double pSheet1 =
88
                FLayoutUtilities.toSheetPoint(
89
                    new Point2D.Double(p1.getX(), p1.getY()), layout
90
                        .getLayoutControl().getAT());
91
            Point2D.Double pSheet2 =
92
                FLayoutUtilities.toSheetPoint(
93
                    new Point2D.Double(p2.getX(), p2.getY()), layout
94
                        .getLayoutControl().getAT());
95

    
96
            double xmin;
97
            double xmax;
98
            double ymin;
99
            double ymax = 0;
100

    
101
            if (pSheet1.x > pSheet2.x) {
102
                xmin = pSheet2.x;
103
                xmax = pSheet1.x;
104
            } else {
105
                xmin = pSheet1.x;
106
                xmax = pSheet2.x;
107
            }
108

    
109
            if (pSheet1.y > pSheet2.y) {
110
                ymin = pSheet2.y;
111
                ymax = pSheet1.y;
112
            } else {
113
                ymin = pSheet1.y;
114
                ymax = pSheet2.y;
115
            }
116

    
117
            Rectangle2D.Double rScreen = new Rectangle2D.Double();
118
            Rectangle2D.Double rSheet = new Rectangle2D.Double();
119
            double x =
120
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
121
                    .getRect().getX(), layout.getLayoutControl().getAT());
122
            double y =
123
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
124
                    .getRect().getY(), layout.getLayoutControl().getAT());
125
            double w =
126
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
127
                    .getRect().getWidth(), layout.getLayoutControl().getAT());
128
            double h =
129
                FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
130
                    .getRect().getHeight(), layout.getLayoutControl().getAT());
131

    
132
            double wv =
133
                FLayoutUtilities.toSheetDistance(layout.getVisibleRect()
134
                    .getWidth(), layout.getLayoutControl().getAT());
135
            double hv =
136
                FLayoutUtilities.toSheetDistance(layout.getVisibleRect()
137
                    .getHeight(), layout.getLayoutControl().getAT());
138
            double mw = xmax - xmin;
139
            double mh = ymax - ymin;
140
            double difw = wv / mw;
141
            double difh = hv / mh;
142

    
143
            if (difw < difh) {
144
                rSheet.x =
145
                    (-xmin * difw)
146
                        - x
147
                        + ((wv - ((pSheet2.getX() - pSheet1.getX()) * difw)) / 2);
148
                rSheet.y =
149
                    (-ymin * difw)
150
                        - y
151
                        + ((hv - ((pSheet2.getY() - pSheet1.getY()) * difw)) / 2);
152

    
153
                rSheet.width = w * difw;
154
                rSheet.height = h * difw;
155
            } else {
156
                rSheet.x =
157
                    (-xmin * difh)
158
                        - x
159
                        + ((wv - ((pSheet2.getX() - pSheet1.getX()) * difh)) / 2);
160
                rSheet.y =
161
                    (-ymin * difh)
162
                        - y
163
                        + ((hv - ((pSheet2.getY() - pSheet1.getY()) * difh)) / 2);
164

    
165
                rSheet.width = w * difh;
166
                rSheet.height = h * difh;
167
            }
168
            setPointsToZoom(p1, p2);
169
            rScreen.setRect(FLayoutUtilities.fromSheetRect(rSheet, layout
170
                .getLayoutControl().getAT()));
171
            if (FLayoutUtilities.isPosible(rScreen)) {
172
                layout.getLayoutControl().getRect().setRect(rScreen);
173
            }
174
        }
175
    }
176

    
177
    /**
178
     * Realiza un zoom out sobre el Layout que se le pasa como par?metro.
179
     * 
180
     * @param p2
181
     *            punto central del rect?ngulo.
182
     */
183
    public void setZoomOut(Point p2) {
184
        double difw = 0.5;
185
        setZoom(difw, p2);
186
    }
187

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

    
204
        double difw = dif;
205

    
206
        rSheet.x =
207
            (-pSheet2.getX() * difw)
208
                - FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
209
                    .getRect().getX(), layout.getLayoutControl().getAT())
210
                + FLayoutUtilities.toSheetDistance(layout.getWidth() / 2,
211
                    layout.getLayoutControl().getAT());
212
        rSheet.y =
213
            (-pSheet2.getY() * difw)
214
                - FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
215
                    .getRect().getY(), layout.getLayoutControl().getAT())
216
                + FLayoutUtilities.toSheetDistance(layout.getHeight() / 2,
217
                    layout.getLayoutControl().getAT());
218

    
219
        rSheet.width =
220
            FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
221
                .getRect().getWidth(), layout.getLayoutControl().getAT())
222
                * difw;
223
        rSheet.height =
224
            FLayoutUtilities.toSheetDistance(layout.getLayoutControl()
225
                .getRect().getHeight(), layout.getLayoutControl().getAT())
226
                * difw;
227

    
228
        rScreen.setRect(FLayoutUtilities.fromSheetRect(rSheet, layout
229
            .getLayoutControl().getAT()));
230

    
231
        if (FLayoutUtilities.isPosible(rScreen)) {
232
            layout.getLayoutControl().getRect().setRect(rScreen);
233
        }
234

    
235
        // Para realizar el zoom a partir de un punto.
236
        Point p1 =
237
            new Point((int) (p2.getX() - (layout.getWidth() / (difw * 2))),
238
                (int) (p2.getY() - (layout.getHeight() / (difw * 2))));
239
        p2 =
240
            new Point((int) (p2.getX() + (layout.getWidth() / (difw * 2))),
241
                (int) (p2.getY() + (layout.getHeight() / (difw * 2))));
242
        setPointsToZoom(p1, p2);
243
    }
244

    
245
    /**
246
     * Introduce los puntos de control para controlar el zoom del Layout.
247
     */
248
    private void setPointsToZoom(Point p1, Point p2) {
249
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
250

    
251
        for (int i = 0; i < fframes.length; i++) {
252
            if (fframes[i] instanceof IFFrameUseFMap) {
253
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
254
                if (fframe.getATMap() != null) {
255
                    Point2D px1 =
256
                        FLayoutFunctions.toMapPoint(p1, fframe.getATMap());
257
                    Point2D px2 =
258
                        FLayoutFunctions.toMapPoint(p2, fframe.getATMap());
259
                    fframe.setPointsToZoom(px1, px2);
260
                }
261
            }
262
        }
263
    }
264

    
265
    /**
266
     * Aplica el zoom real teniendo en cuenta la resoluci?n de pantalla.
267
     */
268
    public void realZoom() {
269
        Preferences prefsResolution =
270
            Preferences.userRoot().node("gvsig.configuration.screen");
271
        double cm =
272
            layout.getLayoutContext().getAttributes()
273
                .getPixXCm(layout.getLayoutControl().getRect());
274
        Toolkit kit = Toolkit.getDefaultToolkit();
275
        double dpi = prefsResolution.getInt("dpi", kit.getScreenResolution());
276
        double dif = (cm * Attributes.PULGADA) / dpi;
277
        setZoom(1 / dif, new Point(layout.getWidth() / 2,
278
            layout.getHeight() / 2));
279
        layout.getLayoutControl().refresh();
280
    }
281

    
282
    /**
283
     * Realiza un zoom in a partir del zoom actual de la vista.
284
     */
285
    public void zoomIn() {
286
        setZoom(2, new Point(layout.getWidth() / 2, layout.getHeight() / 2));
287
        layout.getLayoutControl().refresh();
288
    }
289

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

    
298
    /**
299
     * Realiza un zoom a los elementos que esten seleccionados, si no hay
300
     * ning?n elemento seleccionado no realiza ning?n zoom
301
     */
302
    public void zoomSelect() {
303
        Rectangle2D.Double recaux = null;
304
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
305
        for (int i = 0; i < fframes.length; i++) {
306
            if (fframes[i].getSelected() != IFFrame.NOSELECT) {
307
                if (recaux == null) {
308
                    recaux =
309
                        fframes[i].getBoundingBox(layout.getLayoutControl()
310
                            .getAT());
311
                } else {
312
                    recaux.add(fframes[i].getBoundingBox(layout
313
                        .getLayoutControl().getAT()));
314
                }
315
            }
316
        }
317

    
318
        if (recaux != null) {
319
            Point p1 = new Point((int) recaux.x, (int) recaux.y);
320
            Point p2 =
321
                new Point((int) recaux.getMaxX(), (int) recaux.getMaxY());
322
            setZoomIn(p1, p2);
323
            layout.getLayoutControl().refresh();
324
        }
325
    }
326

    
327
    /**
328
     * Realiza un zoom a todos los elementos del layout.
329
     */
330
    public void zoomAllFrames() {
331
        Rectangle2D.Double recaux = null;
332
        IFFrame[] fframes =
333
            layout.getLayoutControl().getLayoutContext().getFFrames();
334
        for (int i = 0; i < fframes.length; i++) {
335
            if (recaux == null) {
336
                recaux =
337
                    fframes[i]
338
                        .getBoundingBox(layout.getLayoutControl().getAT());
339
            } else {
340
                recaux.add(fframes[i].getBoundingBox(layout.getLayoutControl()
341
                    .getAT()));
342
            }
343
        }
344

    
345
        if (recaux != null) {
346
            Point p1 = new Point((int) recaux.x, (int) recaux.y);
347
            Point p2 =
348
                new Point((int) recaux.getMaxX(), (int) recaux.getMaxY());
349
            setZoomIn(p1, p2);
350
            layout.getLayoutControl().refresh();
351
        }
352
    }
353

    
354
    /**
355
     * Realiza un zoom in a las vista a?adidas al Layout que esten seleccionadas
356
     * 
357
     * @param p1
358
     *            Punto inicial del rect?ngulo
359
     * @param p2
360
     *            Punto final del rect?ngulo
361
     */
362
    public void setViewZoomIn(Point2D p1, Point2D p2) {
363
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
364
        for (int i = 0; i < fframes.length; i++) {
365
            if (fframes[i] instanceof IFFrameUseFMap) {
366
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
367

    
368
                if (((IFFrame) fframe).getSelected() != IFFrame.NOSELECT) {
369
                    // IFFrameUseFMap
370
                    // fframeAux=(IFFrameUseFMap)((IFFrame)fframe).cloneFFrame(layout);
371
                    p1 = FLayoutFunctions.toMapPoint(p1, fframe.getATMap());
372
                    p2 = FLayoutFunctions.toMapPoint(p2, fframe.getATMap());
373

    
374
                    // Borramos el anterior
375
                    layout.getLayoutControl().setStatus(
376
                        LayoutControl.DESACTUALIZADO);
377
                    Rectangle2D.Double r = new Rectangle2D.Double();
378

    
379
                    if (java.lang.Math.abs(p1.getX() - p2.getX()) <= 3) {
380
                        double nuevoX;
381
                        double nuevoY;
382
                        double cX;
383
                        double cY;
384

    
385
                        cX = p2.getX();
386
                        cY = p2.getY();
387

    
388
                        double factor = 1 / MapContext.ZOOMINFACTOR;
389

    
390
                        Rectangle2D extent =
391
                            fframe.getMapContext().getViewPort().getExtent();
392
                        if (extent != null) {
393
                            nuevoX = cX - ((extent.getWidth() * factor) / 2.0);
394
                            nuevoY = cY - ((extent.getHeight() * factor) / 2.0);
395
                            r.x = nuevoX;
396
                            r.y = nuevoY;
397
                            r.width = extent.getWidth() * factor;
398
                            r.height = extent.getHeight() * factor;
399
                        }
400

    
401
                        // fframeAux.setNewExtent(r);
402
                    } else {
403
                        // Fijamos el nuevo extent
404

    
405
                        r.setFrameFromDiagonal(p1, p2);
406

    
407
                        // fframeAux.setNewExtent(r);
408
                    }
409

    
410
                    /*
411
                     * if (fframe.getTypeScale()!=IFFrameUseFMap.AUTOMATICO) {
412
                     * fframeAux.setNewExtent(r);
413
                     * fframeAux.refresh();
414
                     * layout.getEFS().modifyFFrame((IFFrame)fframe,(IFFrame)
415
                     * fframeAux);
416
                     * ((IFFrame)fframeAux).getBoundingBox(layout.getAT());
417
                     * layout.updateFFrames();
418
                     * layout.setIsReSel(true);
419
                     * }else {
420
                     */
421
                    try {
422
                        fframe.setNewEnvelope(geomManager.createEnvelope(
423
                            r.getX(), r.getY(), r.getMaxX(), r.getMaxY(),
424
                            SUBTYPES.GEOM2D));
425
                    } catch (CreateEnvelopeException e) {
426
                        logger.error("Error creating the envelope", e);
427
                    }
428
                    fframe.refresh();
429
                    fframe.refreshOriginalExtent();
430
                    // /}
431
                    // Fin del else
432
                    // layout.repaint();
433
                }
434
            }
435
        }
436
    }
437

    
438
    /**
439
     * Realiza un zoom out a las vistas a?adidas al Layout y que est?n
440
     * seleccionadas
441
     * 
442
     * @param p2
443
     *            Punto central
444
     */
445
    public void setViewZoomOut(Point p2) {
446
        Point2D.Double pWorld;
447
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
448
        for (int i = 0; i < fframes.length; i++) {
449
            if (fframes[i] instanceof IFFrameUseFMap) {
450
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
451

    
452
                if (((IFFrame) fframe).getSelected() != IFFrame.NOSELECT) {
453
                    // IFFrameUseFMap
454
                    // fframeAux=(IFFrameUseFMap)((IFFrame)fframe).cloneFFrame(layout);
455
                    double nuevoX;
456
                    double nuevoY;
457
                    double cX;
458
                    double cY;
459
                    Point pScreen = new Point((int) p2.getX(), (int) p2.getY());
460
                    pWorld =
461
                        FLayoutFunctions.toMapPoint(pScreen, fframe.getATMap());
462

    
463
                    cX = pWorld.getX();
464
                    cY = pWorld.getY();
465

    
466
                    double factor = 1 / MapContext.ZOOMOUTFACTOR;
467
                    Rectangle2D extent =
468
                        fframe.getMapContext().getViewPort().getExtent();
469
                    if (extent != null) {
470
                        nuevoX = cX - ((extent.getWidth() * factor) / 2.0);
471
                        nuevoY = cY - ((extent.getHeight() * factor) / 2.0);
472
                        double x = nuevoX;
473
                        double y = nuevoY;
474
                        double width = extent.getWidth() * factor;
475
                        double height = extent.getHeight() * factor;
476
                        try {
477
                            fframe.setNewEnvelope(geomManager.createEnvelope(x,
478
                                y, x + width, y + height, SUBTYPES.GEOM2D));
479
                        } catch (CreateEnvelopeException e) {
480
                            logger.error("Error creating the envelope", e);
481
                        }
482
                        fframe.refresh();
483
                        fframe.refreshOriginalExtent();
484
                    }
485
                }
486
            }
487
        }
488
    }
489

    
490
    /**
491
     * Modifica los puntos de control para generar el zoom del Layout
492
     * 
493
     * @param p1
494
     *            Punto inicial
495
     * @param p2
496
     *            Punto final
497
     */
498
    public void setPan(Point p1, Point p2) {
499
        IFFrame[] fframes = layout.getLayoutContext().getFFrames();
500

    
501
        for (int i = 0; i < fframes.length; i++) {
502
            if (fframes[i] instanceof IFFrameUseFMap) {
503
                IFFrameUseFMap fframe = (IFFrameUseFMap) fframes[i];
504
                AffineTransform at = fframe.getATMap();
505
                if (at != null) {
506
                    Point2D px1 = FLayoutFunctions.toMapPoint(p1, at);
507
                    Point2D px2 = FLayoutFunctions.toMapPoint(p2, at);
508
                    fframe.movePoints(px1, px2);
509
                }
510
            }
511
        }
512
    }
513
}