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 / fframes / FFrameView.java @ 72

History | View | Annotate | Download (40.4 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.fframes;
23

    
24
import java.awt.Color;
25
import java.awt.Dimension;
26
import java.awt.Graphics;
27
import java.awt.Graphics2D;
28
import java.awt.Image;
29
import java.awt.Point;
30
import java.awt.Rectangle;
31
import java.awt.geom.AffineTransform;
32
import java.awt.geom.Point2D;
33
import java.awt.geom.Rectangle2D;
34
import java.awt.image.BufferedImage;
35

    
36
import javax.swing.SwingUtilities;
37

    
38
import org.cresques.cts.IProjection;
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

    
42
import org.gvsig.andami.PluginServices;
43
import org.gvsig.andami.messages.NotificationManager;
44
import org.gvsig.app.project.Project;
45
import org.gvsig.app.project.documents.layout.DefaultLayoutNotification;
46
import org.gvsig.app.project.documents.layout.FLayoutUtilities;
47
import org.gvsig.app.project.documents.layout.LayoutNotification;
48
import org.gvsig.app.project.documents.view.DefaultViewDocument;
49
import org.gvsig.app.project.documents.view.ViewDocument;
50
import org.gvsig.compat.print.PrintAttributes;
51
import org.gvsig.fmap.dal.exception.ReadException;
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
54
import org.gvsig.fmap.geom.GeometryLocator;
55
import org.gvsig.fmap.geom.GeometryManager;
56
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
57
import org.gvsig.fmap.geom.primitive.Envelope;
58
import org.gvsig.fmap.mapcontext.MapContext;
59
import org.gvsig.fmap.mapcontext.MapContextException;
60
import org.gvsig.fmap.mapcontext.ViewPort;
61
import org.gvsig.fmap.mapcontext.events.ColorEvent;
62
import org.gvsig.fmap.mapcontext.events.ExtentEvent;
63
import org.gvsig.fmap.mapcontext.events.ProjectionEvent;
64
import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener;
65
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
66
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
67
import org.gvsig.tools.ToolsLocator;
68
import org.gvsig.tools.dynobject.DynStruct;
69
import org.gvsig.tools.persistence.PersistenceManager;
70
import org.gvsig.tools.persistence.PersistentState;
71
import org.gvsig.tools.persistence.exception.PersistenceException;
72

    
73
/**
74
 * FFrame para introducir una vista en el Layout.
75
 * 
76
 * @author Vicente Caballero Navarro
77
 */
78
public class FFrameView extends FFrame implements ViewPortListener,
79
    LegendListener, IFFrameUseProject, IFFrameUseFMap {
80

    
81
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameView";
82

    
83
    private static final String MODE_FIELD = "mode";
84
    private static final String TYPESCALE_FIELD = "typeScale";
85
    private static final String EXTENSION_FIELD = "extension";
86
    private static final String QUALITY_FIELD = "quality";
87
    private static final String VIEWING_FIELD = "viewing";
88
    private static final String BLINKED_FIELD = "bLinked";
89
    private static final String MAPUNITS_FIELD = "mapUnits";
90
    private static final String SCALE_FIELD = "scale";
91
    private static final String VIEW_FIELD = "view";
92
    private static final String ENVELOPE_FIELD = "envelope";
93
    private static final String SHOWGRID_FIELD = "showGrid";
94
    private static final String GRID_FIELD = "gridview";
95
    private static final String MAPCONTEXT_FIELD = "mapContext";
96

    
97
    private static final GeometryManager geomManager = GeometryLocator
98
        .getGeometryManager();
99
    private static final Logger logger = LoggerFactory
100
        .getLogger(FFrameView.class);
101
    public static final int PRESENTATION = 0;
102
    public static final int DRAFT = 1;
103
    protected int mode;
104
    protected int typeScale = AUTOMATICO;
105
    protected int extension = 0;
106
    protected int quality = PRESENTATION;
107
    protected int viewing = 0;
108
    protected boolean linked = true;
109
    protected ViewDocument viewDocument = null;
110
    protected MapContext mapContext = null;
111
    protected double mapScale = 0;
112
    protected int mapUnits = 1; // Meters.
113

    
114
    protected BufferedImage m_image = null;
115
    protected AffineTransform at = null;
116
    protected Project project = null;
117
    protected double scaleAnt;
118
    protected boolean refresh = false;
119
    protected Point origin;
120
    protected Point2D p1;
121
    protected Point2D p2;
122
    protected IFFrame grid;
123
    protected boolean showGrid = false;
124

    
125
    /**
126
     * Creates a new FFrameView object.
127
     */
128
    public FFrameView() {
129
        num++;
130
    }
131

    
132
    /**
133
     * Devuelve una descripci?n del FFrameView.
134
     * 
135
     * @return Descripci?n.
136
     */
137
    public String toString() {
138
        if (getView() == null) {
139
            return "FFrameView " + num + ": " + "Vacio";
140
        }
141

    
142
        return "FFrameView " + num + ": " + getView().getName();
143
    }
144

    
145
    /**
146
     * Rellena la escala de la vista que contiene el fframe.
147
     * 
148
     * @param d
149
     *            escala de la vista.
150
     */
151
    public void setScale(double d) {
152
        mapScale = d;
153
    }
154

    
155
    /**
156
     * Inserta el nuevo extent a la FFrameView.
157
     * 
158
     * @param r
159
     *            Rect?ngulo a ocupar por el FFrameView.
160
     */
161
    public void setNewEnvelope(Envelope r) {
162
        getMapContext().getViewPort().setEnvelope(r);
163
        refresh = true;
164
        mapScale =
165
            FLayoutUtilities.getScaleView(getMapContext().getViewPort(),
166
                getBoundBox().width, getBoundingBox(null).width
167
                    / getBoundBox().width);
168
    }
169

    
170
    /**
171
     * Devuelve el FMap de la vista o una clonaci?n de este si se utiliza una
172
     * escala fija.
173
     * 
174
     * @return FMap.
175
     */
176
    public MapContext getMapContext() {
177
        return mapContext;
178
    }
179

    
180
    /**
181
     * Rellena la calidad que se quiere aplicar.
182
     * 
183
     * @param q
184
     *            entero que representa la calidad a aplicar.
185
     */
186
    public void setQuality(int q) {
187
        quality = q;
188
    }
189

    
190
    /**
191
     * Devuelve un entero que representa la calidad que est? seleccionada.
192
     * 
193
     * @return tipo de calidad selccionada.
194
     */
195
    public int getQuality() {
196
        return quality;
197
    }
198

    
199
    /**
200
     * Devuelve un entero que representa la forma en que se actualiza la vista.
201
     * 
202
     * @return forma que se actualiza la vista.
203
     */
204
    public int getViewing() {
205
        return viewing;
206
    }
207

    
208
    /**
209
     * Rellena la forma de actualizar la vista(cuando activo o siempre). De
210
     * momento esta opci?n esta deshabilitada.
211
     * 
212
     * @param v
213
     *            entero que representa la forma de actualizar la vista.
214
     */
215
    public void setViewing(int v) {
216
        viewing = v;
217
    }
218

    
219
    /**
220
     * Inserta el ProjectView de donde obtener las propiedades de la vista a
221
     * mostrar.
222
     * 
223
     * @param v
224
     *            Modelo de la vista.
225
     */
226
    public void setView(ViewDocument dvd) {
227
        
228
        viewDocument = dvd;
229
        MapContext mctxt = dvd.getMapContext();
230
        
231
        ViewPort vp = null;
232
        if (getMapContext() != null) {
233
            vp = getMapContext().getViewPort();
234
        }else{
235
            try {
236
                vp = (ViewPort) mctxt.getViewPort().clone();
237
            } catch (CloneNotSupportedException e1) {
238
                NotificationManager.addError("Excepci?n :", e1);
239
            }
240

    
241
        }
242
        vp.setImageSize(new Dimension((int) getBoundingBox(null).width,
243
            (int) getBoundingBox(null).height));
244

    
245
        if (linked){
246
            if (getTypeScale() == AUTOMATICO) {
247
                try {
248
                    mapContext =
249
                        mctxt.createNewFMap(
250
                            (ViewPort) mctxt.getViewPort().clone());
251
                } catch (CloneNotSupportedException e1) {
252
                    NotificationManager.addError("Excepci?n :", e1);
253
                }
254

    
255
                mapContext.getViewPort().setImageSize(
256
                    new Dimension((int) getBoundingBox(null).width,
257
                        (int) getBoundingBox(null).height));
258
                mctxt.getViewPort().addViewPortListener(this);
259
                mctxt.addLayerListener(this);
260
            }else{
261
                if (getTypeScale() == CONSTANTE) {
262
                    mapContext = mctxt.createNewFMap(vp);
263
                    vp.setEnvelope(getNewEnvelope(getScale()));
264
                    mctxt.getViewPort().addViewPortListener(this);
265
                    mctxt.addLayerListener(this);
266
                }else{
267
                    if (getTypeScale() == MANUAL) {
268
                        mapContext = mctxt.createNewFMap(vp);
269
                        vp.setEnvelope(getNewEnvelope(getScale()));
270
                        mctxt.getViewPort()
271
                            .addViewPortListener(this);
272
                        mctxt.addLayerListener(this);
273
                    }
274
                }
275
            }
276
        }else{
277
            if (!linked) {
278

    
279
                if (getTypeScale() == AUTOMATICO) {
280
                    mapContext = mctxt.cloneFMap();
281
                    // (v.getMapContext().getViewPort().cloneViewPort());
282
                    try {
283
                        mapContext.setViewPort((ViewPort) mctxt
284
                            .getViewPort().clone());
285
                    } catch (CloneNotSupportedException e1) {
286
                        NotificationManager.addError("Excepci?n :", e1);
287
                    }
288
                    mapContext.getViewPort().setImageSize(
289
                        new Dimension((int) getBoundingBox(null).width,
290
                            (int) getBoundingBox(null).height));
291
                    mctxt.getViewPort().addViewPortListener(this);
292
                }else{
293
                    if (getTypeScale() == CONSTANTE) {
294
                        mapContext = mctxt.cloneFMap();
295
                        vp.setEnvelope(getNewEnvelope(getScale()));
296
                        mapContext.setViewPort(vp);
297
                        mctxt.getViewPort().addViewPortListener(this);
298
                    }else{
299
                        if (getTypeScale() == MANUAL) {
300
                            mapContext = mctxt.cloneFMap();
301
                            vp.setEnvelope(getNewEnvelope(getScale()));
302
                            mapContext.setViewPort(vp);
303
                            mctxt.getViewPort()
304
                                .addViewPortListener(this);
305
                        }
306
                    }
307
                }               
308
            }
309
        }
310
    }
311

    
312
    /**
313
     * Devuelve el modelo de la vista.
314
     * 
315
     * @return Modelo de la vista.
316
     */
317
    public ViewDocument getView() {
318
        return viewDocument;
319
    }
320

    
321
    /**
322
     * Devuelve un Rect?ngulo que representa el extent de la vista que se
323
     * requiere a partir de una escala.
324
     * 
325
     * @param scale
326
     *            Escala a mostrar.
327
     * 
328
     * @return Rect?ngulo.
329
     */
330
    protected Envelope getNewEnvelope(long scale) {
331
        double hview = getBoundBox().getHeight();
332
        double wview = getBoundBox().getWidth();
333
        double hextent = (scale * hview) / 100.0;
334
        double wextent = (scale * wview) / 100.0;
335

    
336
        if (mapContext.getViewPort().getEnvelope() == null) {
337
            try {
338
                return geomManager.createEnvelope(0, 0, 0, 0, SUBTYPES.GEOM2D);
339
            } catch (CreateEnvelopeException e) {
340
                logger.error("Error creating the envelope", e);
341
                return null;
342
            }
343
        }
344
        double newx =
345
            mapContext.getViewPort().getEnvelope().getCenter(Geometry.DIMENSIONS.X)
346
                - (wextent / 2.0);
347
        double newy =
348
            mapContext.getViewPort().getEnvelope().getCenter(Geometry.DIMENSIONS.Y)
349
                - (hextent / 2.0);
350
        IProjection proj = mapContext.getViewPort().getProjection();
351
        Envelope r = null;
352
        try {
353
            r =
354
                geomManager.createEnvelope(newx, newy, newx + wextent, newy
355
                    + hextent, SUBTYPES.GEOM2D);
356
        } catch (CreateEnvelopeException e) {
357
            logger.error("Error creating the envelope", e);
358
        }
359
        if (!proj.isProjected()) {
360
            Rectangle2D auxR =
361
                new Rectangle2D.Double(newx, newy, wextent, hextent);
362
            Rectangle2D aux =
363
                mapContext.getViewPort().getProjection()
364
                    .getExtent(auxR, scale, wview, hview, 1, 100, 2.54);
365
            try {
366
                r =
367
                    geomManager.createEnvelope(aux.getX(), aux.getY(),
368
                        aux.getMaxX(), aux.getMaxY(), SUBTYPES.GEOM2D);
369
            } catch (CreateEnvelopeException e) {
370
                logger.error("Error creating the envelope", e);
371
            }
372
        }
373
        return r;
374
    }
375

    
376
    /**
377
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
378
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
379
     * de dibujar.
380
     * 
381
     * @param g
382
     *            Graphics2D
383
     * @param at
384
     *            Transformada af?n.
385
     * @param rectangleView
386
     *            rect?ngulo sobre el que hacer un clip.
387
     * @param imgBase
388
     *            Imagen para acelerar el dibujado.
389
     */
390
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rectangleView, BufferedImage imgBase) {
391
        Rectangle2D.Double rectangleLayout = getBoundingBox(at);  
392
        Rectangle originalClip = preDraw(g, rectangleLayout);    
393
        if (intersects(rectangleView, rectangleLayout)) {
394
            if (getMapContext() == null) {
395
                drawEmpty(g);
396
            } else {      
397
                if (getQuality() == PRESENTATION) {
398
                    drawPresentation(g, at, rectangleLayout, rectangleView, imgBase);
399
                } else {
400
                    drawDraft(g);
401
                }               
402
            }
403
        }
404
        postDraw(g, rectangleLayout, rectangleView, imgBase, originalClip, at); 
405
        if (showGrid && grid != null) {           
406
            grid.draw(g, at, rectangleView, imgBase);
407
        }    
408
    }
409
    
410
    protected void drawPresentation(Graphics2D g, AffineTransform affineTransform, Rectangle2D.Double rectangleLayout, Rectangle2D rectangleView, BufferedImage imgBase){
411
        Point mapOrigin = new Point((int)rectangleView.getMinX(), (int)rectangleView.getMaxY());
412

    
413
        ViewPort viewPort = this.getMapContext().getViewPort();
414
        Color theBackColor = viewPort.getBackColor();
415

    
416
        //If the image has to be created...
417
        if (!(origin != null
418
            && origin.equals(mapOrigin)
419
            && affineTransform.getScaleX() == scaleAnt
420
            && m_image != null
421
            && !refresh
422
            && !(rectangleLayout.getWidth() > rectangleView.getWidth() || rectangleLayout.getHeight() > rectangleView.getHeight()))) {
423

    
424
            double scale1_1 = MapContext.getScreenDPI() / 2.54;
425
            /*
426
             * This is the ratio between the size assumed by the
427
             * mapcontext drawer and the true size on screen
428
             */
429
            double visible_factor = affineTransform.getScaleX() / scale1_1;
430
            int draw_w = (int) (1d * rectangleLayout.width / visible_factor);
431
            int draw_h = (int) (1d * rectangleLayout.height / visible_factor);
432

    
433
            viewPort.setImageSize(new Dimension(draw_w, draw_h));
434
            viewPort.refreshExtent();
435

    
436
            /*
437
            viewPort.setOffset(new Point2D.Double(rectangleLayout.x, rectangleLayout.y));
438
            */
439

    
440
            m_image =
441
                new BufferedImage(
442
                    draw_w, //(int) rectangleLayout.getWidth(),
443
                    draw_h, //(int) rectangleLayout.getHeight(),
444
                    BufferedImage.TYPE_INT_ARGB);
445

    
446
            Graphics2D gimg = (Graphics2D) m_image.createGraphics();
447
            
448
            /*
449
            gimg.translate(-((int) rectangleLayout.getX()),
450
                -((int) rectangleLayout.getY()));
451
            */
452
            
453
            try {
454
                getMapContext().draw(m_image, gimg, getScale());
455
                gimg.dispose();
456
            } catch (ReadException e) {
457
                logger.error("Error reading the provider" , e);
458
            } catch (MapContextException mpex) {
459
                logger.error("Error reading the provider" , mpex);
460
            }
461
            /*
462
            gimg.translate(((int) rectangleLayout.getX()),
463
                ((int) rectangleLayout.getY()));
464
                */
465
            refresh = false;    
466
        } 
467

    
468
        //Draw the created image
469
        if (theBackColor != null) {
470
            g.setColor(theBackColor);
471
            g.fillRect((int) rectangleLayout.x, (int) rectangleLayout.y,
472
                viewPort.getImageWidth(),
473
                viewPort.getImageHeight());
474
        }
475
        
476
        m_image = copyForcingImageSize(
477
            m_image,
478
            (int) rectangleLayout.getWidth(),
479
            (int) rectangleLayout.getHeight());
480

    
481
        g.drawImage(m_image,
482
            (int) rectangleLayout.getX(),
483
            (int) rectangleLayout.getY(), null);
484
        
485
        scaleAnt = affineTransform.getScaleX();
486
        origin = mapOrigin;             
487
    }
488
    
489
    /**
490
     * @param m_image2
491
     * @param width
492
     * @param height
493
     * @return
494
     */
495
    protected BufferedImage copyForcingImageSize(
496
        BufferedImage disp_img, int w, int h) {
497
        
498
        Graphics rg = null;
499
        
500
        try {
501
            if (disp_img == null || w < 1 || h < 1) {
502
                return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
503
            }
504
            int from_w = disp_img.getWidth(null);
505
            int from_h = disp_img.getHeight(null);
506
            if (from_w < 1 || from_h < 1) {
507
                return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
508
            }
509
            
510
            BufferedImage resp =
511
                new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
512
            rg = resp.createGraphics();
513
            
514
            double rat_w = (1d*w) / (1d*from_w);
515
            double rat_h = (1d*h) / (1d*from_h);
516
            int offset_w = 0;
517
            int offset_h = 0;
518
            Image aux = null;
519

    
520
            if (rat_w <= rat_h) {
521
                // apply resize of width
522
                int target_h = Math.max(1, (int) (from_h * rat_w));
523
                // w, target_h
524
                offset_w = 0;
525
                offset_h = (h - target_h) / 2;
526
                aux = disp_img.getScaledInstance(w, target_h, Image.SCALE_FAST);
527
                rg.drawImage(aux, offset_w, offset_h, null);
528

    
529
            } else {
530
                // apply resize from height
531
                int target_w = Math.max(1, (int) (from_w * rat_h));
532
                // target_w, h
533
                offset_w = (w - target_w) / 2;
534
                offset_h = 0;
535
                aux = disp_img.getScaledInstance(target_w, h, Image.SCALE_FAST);
536
                rg.drawImage(aux, offset_w, offset_h, null);
537
            }
538
            
539
            aux = null;
540
            resp.flush();
541
            rg.dispose();
542
            return resp;
543
        } catch (Throwable th) {
544
            logger.info("While resizing image.", th);
545
            if (rg != null) {
546
                rg.dispose();
547
            }
548
            return null;
549
        }
550
        
551
    }
552

    
553
    protected Rectangle preDraw(Graphics2D g, Rectangle2D.Double rectangleLayout){
554
        Rectangle originalClip = null;
555
        if (g.getClipBounds() != null) {
556
            originalClip = (Rectangle) g.getClipBounds().clone();
557
        }
558
        if (getRotation() != 0) {
559
            g.rotate(Math.toRadians(getRotation()), rectangleLayout.getCenterX(), rectangleLayout.getCenterY()
560
                + (rectangleLayout.height / 2));
561
        }       
562
        g.clipRect((int) rectangleLayout.getMinX(), (int) rectangleLayout.getMinY(),
563
            (int) rectangleLayout.getWidth(), (int) rectangleLayout.getHeight());
564
        return originalClip;
565
    }
566
    
567
    protected void postDraw(Graphics2D g, Rectangle2D.Double rectangleLayout, Rectangle2D rectangleView, BufferedImage imgBase, 
568
        Rectangle originalClip, AffineTransform at){
569
        if (getRotation() != 0) {
570
            g.rotate(Math.toRadians(-getRotation()), rectangleLayout.getCenterX(), rectangleLayout.getCenterY());
571
        }
572
        if (getMapContext() != null) {
573
            setATMap(getMapContext().getViewPort().getAffineTransform());
574
        }
575
        if (originalClip != null) {
576
            g.setClip(originalClip.x, originalClip.y, originalClip.width, originalClip.height);
577
        }            
578
    }
579

    
580
    private Envelope calculateEnvelope() {
581
        if (p1 == null || p2 == null) {
582
            try {
583
                return geomManager.createEnvelope(0, 0, 0, 0, SUBTYPES.GEOM2D);
584
            } catch (CreateEnvelopeException e) {
585
                logger.error("Error creating the envelope", e);
586
            }
587
        }
588
        Envelope r = null;
589
        try {
590
            r =
591
                geomManager.createEnvelope(p1.getX(), p1.getY(), p2.getX(),
592
                    p2.getY(), SUBTYPES.GEOM2D);
593
        } catch (CreateEnvelopeException e) {
594
            logger.error("Error creating the envelope", e);
595
        }
596
        return r;
597
    }
598

    
599
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
600
        PrintAttributes printAttributes) {
601
        Rectangle2D.Double rectangleLayout = getBoundingBox(at);  
602
        
603
        Rectangle originalClip = preDraw(g, rectangleLayout);
604
        print(g, at, printAttributes);
605
        postDraw(g, rectangleLayout, null, null, originalClip, at);
606
        if (showGrid && grid != null) {
607
            grid.print(g, at, geom, printAttributes);
608
        }    
609
    }
610

    
611
    protected void print(Graphics2D g, AffineTransform at, PrintAttributes printAttributes) {
612
        Rectangle2D.Double layoutRectangle = getBoundingBox(at);
613
              
614
        ViewPort viewPort = this.getMapContext().getViewPort();
615
        
616
        Point2D old_offset = viewPort.getOffset();
617
        Dimension old_imgsize = viewPort.getImageSize();
618
        
619
        viewPort.setOffset(new Point2D.Double(layoutRectangle.x, layoutRectangle.y));
620
        viewPort.setImageSize(new Dimension((int) layoutRectangle.width, (int) layoutRectangle.height));
621

    
622
        //Draw the backgroung color of the map
623
        Color theBackColor = viewPort.getBackColor();
624
        if (theBackColor != null) {
625
            g.setColor(theBackColor);
626
            g.fillRect((int) layoutRectangle.x, (int) layoutRectangle.y, viewPort
627
                    .getImageWidth(), viewPort
628
                    .getImageHeight());
629
        }        
630
        
631
        //Print the map
632
        try {
633
            this.getMapContext().print(g, getScale(), printAttributes);
634
        } catch (ReadException e) {
635
            NotificationManager.addError(e.getMessage(), e);
636
        } catch (MapContextException e) {
637
            NotificationManager.addError(e.getMessage(), e);
638
        }      
639
        
640
        // Restore offset, imgsize
641
        viewPort.setOffset(old_offset);
642
        viewPort.setImageSize(old_imgsize);
643
    }
644

    
645
    /**
646
     * Rellena la unidad de medida en la que est? la vista.
647
     * 
648
     * @param i
649
     *            entero que representa la unidad de medida de la vista.
650
     */
651
    public void setMapUnits(int i) {
652
        mapUnits = i;
653
    }
654

    
655
    /**
656
     * Obtiene la unidad de medida en la que est? la vista.
657
     * 
658
     * @return Unidad de medida.
659
     */
660
    public int getMapUnits() {
661
        return mapUnits;
662
    }
663

    
664
    /**
665
     * Devuelve la escala seg?n el tipo de escala que se haya seleccionado al
666
     * a?adida la vista.
667
     * 
668
     * @return escala.
669
     */
670
    public long getScale() {
671
        /*
672
         * if (m_bLinked){
673
         * return getScaleView1(METROS);
674
         * }
675
         */
676
        if (getMapContext() == null) {
677
            return 0;
678
        }
679
        if (getTypeScale() == AUTOMATICO) {
680
            return FLayoutUtilities.getScaleView(getMapContext().getViewPort(),
681
                getBoundBox().width, getBoundingBox(null).width);
682
        } else
683
            if (getTypeScale() == CONSTANTE) {
684
                return (long) mapScale;
685
            } else
686
                if (getTypeScale() == MANUAL) {
687
                    return (long) mapScale;
688
                }
689

    
690
        return (long) mapScale;
691
    }
692

    
693
    /**
694
     * Seleccionar si la vista esta relacionada o no con la original.
695
     * 
696
     * @param b
697
     *            true si est? ligada y false si no lo est?.
698
     */
699
    public void setLinked(boolean b) {
700
        linked = b;
701
    }
702

    
703
    /**
704
     * Devuelve si est? ligada o no el FFrameView con la vista.
705
     * 
706
     * @return True si la vista est? ligada.
707
     */
708
    public boolean getLinked() {
709
        return linked;
710
    }
711

    
712
    /**
713
     * Devuelve la opci?n seleccionada:Rellenar marco de la vista o recorte a
714
     * la vista.
715
     * 
716
     * @return entero que representa la opci?n elegida.
717
     */
718
    public int getExtension() {
719
        return extension;
720
    }
721

    
722
    /**
723
     * Devuelve el tipo de escala que est? seleccionada AUTOMATICO,CONSTANTE o
724
     * MANUAL.
725
     * 
726
     * @return entero que representa el tipo seleccionado.
727
     */
728
    public int getTypeScale() {
729
        return typeScale;
730
    }
731

    
732
    /**
733
     * Rellenar si se quiere:Rellenar marco de la vista o recorte a la vista.
734
     * 
735
     * @param i
736
     *            entero que representa la opci?n elegida.
737
     */
738
    public void setExtension(int i) {
739
        extension = i;
740
    }
741

    
742
    /**
743
     * Rellenar el tipo de escala que se desea.
744
     * 
745
     * @param i
746
     *            entero que representa el tipo de escala.
747
     */
748
    public void setTypeScale(int i) {
749
        typeScale = i;
750
    }
751

    
752
    /**
753
     * Inserta la imagen para repintar el FFrameView.
754
     * 
755
     * @param bi
756
     *            Imagen para repintar.
757
     */
758
    public void setBufferedImage(BufferedImage bi) {
759
        m_image = bi;
760
    }
761

    
762
    /**
763
     * Devuelve la imagen para repintar.
764
     * 
765
     * @return Imagen para repintar.
766
     */
767
    public BufferedImage getBufferedImage() {
768
        return m_image;
769
    }
770

    
771
    /**
772
     * Devuelve la MAtriz de transformaci?n utilizada por la FFrameView.
773
     * 
774
     * @return MAtriz de transformaci?n.
775
     */
776
    public AffineTransform getATMap() {
777
        return at;
778
    }
779

    
780
    /**
781
     * Inserta la matriz de transformaci?n.
782
     * 
783
     * @param transform
784
     *            Matriz de transformaci?n.
785
     */
786
    public void setATMap(AffineTransform transform) {
787
        at = transform;
788
    }
789

    
790
    /**
791
     * Inserta el proyecto.
792
     * 
793
     * @param p
794
     *            Proyecto.
795
     */
796
    public void setProject(Project p) {
797
        project = p;
798
    }
799

    
800
    /**
801
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
802
     */
803
    public String getNameFFrame() {
804
        return PluginServices.getText(this, "Vista") + num;
805
    }
806

    
807
    public String getName() {
808
        return PERSISTENCE_DEFINITION_NAME;
809
    }
810

    
811
    /**
812
     * @see com.iver.cit.gvsig.fmap.ExtentListener#extentChanged(org.gvsig.fmap.mapcontext.events.ExtentEvent)
813
     */
814
    public void extentChanged(ExtentEvent e) {
815
        if (linked){
816
            if (getTypeScale() == AUTOMATICO) {
817
                mapContext.getViewPort().setEnvelope(e.getNewExtent());
818
                observers.notifyObservers(this, 
819
                    new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
820
            } else
821
                if (getTypeScale() == MANUAL) {
822
                    Envelope oldExtent = mapContext.getViewPort().getEnvelope();
823
                    Envelope newExtent = e.getNewExtent();
824
                    double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
825
                    double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
826
                    try {
827
                        mapContext.getViewPort().setEnvelope(
828
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
829
                                + xDif, oldExtent.getMinimum(1) + yDif,
830
                                oldExtent.getMaximum(0) + xDif,
831
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
832
                    } catch (CreateEnvelopeException e1) {
833
                        e1.printStackTrace();
834
                    }
835
                   
836
                    observers.notifyObservers(this, 
837
                        new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));           
838
                  
839
                }
840
            refresh = true;
841
        }
842
    }
843

    
844
    /**
845
     * @see org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener#backColorChanged(org.gvsig.fmap.mapcontext.events.ColorEvent)
846
     */
847
    public void backColorChanged(ColorEvent e) {
848
        if (getLinked()) {
849
            mapContext.getViewPort().setBackColor(e.getNewColor());
850
            observers.notifyObservers(this, 
851
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));          
852
        }
853
    }
854

    
855
    /**
856
     * @see org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener#projectionChanged(org.gvsig.fmap.mapcontext.events.ProjectionEvent)
857
     */
858
    public void projectionChanged(ProjectionEvent e) {
859
        if (getTypeScale() == AUTOMATICO) {
860
            mapContext.getViewPort().setProjection(e.getNewProjection());
861
            observers.notifyObservers(this, 
862
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
863
        }
864
    }
865

    
866
    /**
867
     * DOCUMENT ME!
868
     * 
869
     * @param e
870
     *            DOCUMENT ME!
871
     */
872
    public void legendChanged(final LegendChangedEvent e) {
873
        if (!SwingUtilities.isEventDispatchThread()) {
874
            SwingUtilities.invokeLater(new Runnable() {
875

    
876
                public void run() {
877
                    legendChanged(e);
878
                }
879
            });
880
            return;
881
        }
882
        if (getLinked()) {
883
            observers.notifyObservers(this, 
884
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
885
            refresh = true;
886
        }
887
    }
888

    
889
    /**
890
     * DOCUMENT ME!
891
     * 
892
     * @param arg0
893
     *            DOCUMENT ME!
894
     * 
895
     * @return DOCUMENT ME!
896
     */
897
    public boolean compare(Object arg0) {
898
        if (!(arg0 instanceof FFrameView)) {
899
            return false;
900
        }
901

    
902
        if (!this.getName().equals(((FFrameView) arg0).getName())) {
903
            return false;
904
        }
905

    
906
        if (Math.abs(this.getBoundBox().getWidth()
907
            - (((FFrameView) arg0).getBoundBox().getWidth())) > 0.05) {
908
            return false;
909
        }
910
        if (Math.abs(this.getBoundBox().getHeight()
911
            - (((FFrameView) arg0).getBoundBox().getHeight())) > 0.05) {
912
            return false;
913
        }
914

    
915
        if (!this.toString().equals(((FFrameView) arg0).toString())) {
916
            return false;
917
        }
918

    
919
        if (this.getMapContext() != null
920
            && !this.getMapContext()
921
                .equals(((FFrameView) arg0).getMapContext())) {
922
            return false;
923
        }
924

    
925
        if (this.getRotation() != ((FFrameView) arg0).getRotation()) {
926
            return false;
927
        }
928
        return true;
929
    }
930

    
931
    /*
932
     * This was causing issues with the notifications
933
     * because different instances were considered the same
934
     * after cloning a frame (the frame is cloned for example
935
     * when the user changes size of frame)
936
     * 
937
    public boolean equals(Object arg0) {
938
        return this.compare(arg0);
939
    }
940
    */
941

    
942
    public void refresh() {
943
        if (viewDocument != null
944
            && (getTypeScale() == MANUAL || getTypeScale() == CONSTANTE)) {
945
            getMapContext().getViewPort().setEnvelope(
946
                getNewEnvelope(getScale()));
947
        }
948
        refresh = true;
949
    }
950

    
951
    public void fullExtent() throws ReadException {
952
        setNewEnvelope(getMapContext().getFullEnvelope());
953
    }
954

    
955
    public void setPointsToZoom(Point2D px1, Point2D px2) {
956
        p1 = px1;
957
        p2 = px2;
958
    }
959

    
960
    public void movePoints(Point2D px1, Point2D px2) {
961
        double difX = -px2.getX() + px1.getX();
962
        double difY = -px2.getY() + px1.getY();
963
        if (p1 != null) {
964
            p1.setLocation(p1.getX() + difX, p1.getY() + difY);
965
            p2.setLocation(p2.getX() + difX, p2.getY() + difY);
966
        }
967
    }
968

    
969
    /**
970
     * This method deals with places where this fframeview and the cloned
971
     * fframeview (frame) are registered as listeners. The goal should be
972
     * leaving the cloned instance (frame) as listener in the same way
973
     * that 'this' instance is doing.
974
     */
975
    protected void cloneActions(FFrameView frame) {
976
        if (viewDocument == null || viewDocument.getMapContext() == null) {
977
            return;
978
        }
979
        
980
        frame.setTypeScale(this.getTypeScale());
981
        frame.setLinked(linked);
982
        
983
        if (linked) {
984
            if (getTypeScale() == AUTOMATICO) {
985
                frame.viewDocument.getMapContext().getViewPort().addViewPortListener(frame);
986
                frame.viewDocument.getMapContext().addLayerListener(frame);
987
            } else
988
                if (getTypeScale() == CONSTANTE) {
989
                    frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
990
                    frame.viewDocument.getMapContext().addLayerListener(frame);
991
                } else
992
                    if (getTypeScale() == MANUAL) {
993
                        frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
994
                        frame.viewDocument.getMapContext().addLayerListener(frame);
995
                    }
996
        } else
997
            if (!linked) {
998
                if (getTypeScale() == AUTOMATICO) {
999
                    frame.viewDocument.getMapContext().getViewPort().addViewPortListener(frame);
1000
                } else
1001
                    if (getTypeScale() == CONSTANTE) {
1002
                        frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
1003
                    } else
1004
                        if (getTypeScale() == MANUAL) {
1005
                            frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
1006
                        }
1007
            }
1008
        /*
1009
        ((FFrameView) frame).viewDocument.getMapContext().removeLayerListener(
1010
            (FFrameView) frame);
1011
        ((FFrameView) frame).viewDocument.getMapContext().getViewPort()
1012
            .removeViewPortListener((FFrameView) frame);
1013
        */
1014
    }
1015

    
1016
    public Object clone() throws CloneNotSupportedException {
1017
        FFrameView frame = (FFrameView) super.clone();
1018

    
1019
        frame.setSelected(this.getSelected() != IFFrame.NOSELECT);
1020

    
1021
        if (grid != null) {
1022
            FFrameGrid newGrid = (FFrameGrid) this.grid.clone();
1023
            newGrid.setFFrameDependence(frame);
1024
            frame.setGrid(newGrid);
1025
        }
1026
        cloneActions(frame);
1027
        return frame;
1028
    }
1029

    
1030
    public void setGrid(IFFrame grid) {
1031
        this.grid = grid;
1032
        this.grid.setRotation(this.getRotation());
1033
    }
1034

    
1035
    public IFFrame getGrid() {
1036
        return this.grid;
1037
    }
1038

    
1039
    public void setRotation(double rotation) {
1040
        super.setRotation(rotation);
1041
        if (grid != null) {
1042
            grid.setRotation(rotation);
1043
        }
1044
    }
1045

    
1046
    public void showGrid(boolean b) {
1047
        showGrid = b;
1048
    }
1049

    
1050
    public boolean isShowGrid() {
1051
        return showGrid;
1052
    }
1053

    
1054
    public void refreshOriginalExtent() {
1055
        if (getTypeScale() == AUTOMATICO) {
1056
            viewDocument.getMapContext().getViewPort()
1057
                .setEnvelope(getMapContext().getViewPort().getEnvelope());
1058
            viewDocument.getMapContext().getViewPort().refreshExtent();
1059
        } else
1060
            if (getTypeScale() == MANUAL) {
1061
                Envelope oldExtent =
1062
                    viewDocument.getMapContext().getViewPort().getEnvelope();
1063
                Envelope newExtent =
1064
                    getMapContext().getViewPort().getEnvelope();
1065
                double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
1066
                double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
1067
                try {
1068
                    viewDocument.getMapContext()
1069
                        .getViewPort()
1070
                        .setEnvelope(
1071
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
1072
                                + xDif, oldExtent.getMinimum(1) + yDif,
1073
                                oldExtent.getMaximum(0) + xDif,
1074
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
1075
                } catch (CreateEnvelopeException e) {
1076
                    e.printStackTrace();
1077
                }
1078
                viewDocument.getMapContext().getViewPort().refreshExtent();
1079
            }
1080
    }
1081

    
1082
    public static void registerPersistent() {
1083
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1084
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
1085
            DynStruct definition =
1086
                manager.addDefinition(FFrameView.class,
1087
                    PERSISTENCE_DEFINITION_NAME,
1088
                    "FFrameView persistence definition", null, null);
1089

    
1090
            definition.extend(manager
1091
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
1092

    
1093
            definition.addDynFieldInt(MODE_FIELD).setMandatory(true);
1094
            definition.addDynFieldInt(TYPESCALE_FIELD).setMandatory(true);
1095
            definition.addDynFieldInt(EXTENSION_FIELD).setMandatory(true);
1096
            definition.addDynFieldInt(QUALITY_FIELD).setMandatory(true);
1097
            definition.addDynFieldInt(VIEWING_FIELD).setMandatory(true);
1098
            definition.addDynFieldBoolean(BLINKED_FIELD).setMandatory(true);
1099
            definition.addDynFieldInt(MAPUNITS_FIELD).setMandatory(true);
1100
            definition.addDynFieldDouble(SCALE_FIELD).setMandatory(true);
1101
            definition.addDynFieldObject(VIEW_FIELD)
1102
                .setClassOfValue(ViewDocument.class).setMandatory(false);
1103
            definition.addDynFieldObject(ENVELOPE_FIELD)
1104
                .setClassOfValue(Envelope.class).setMandatory(false);
1105
            definition.addDynFieldBoolean(SHOWGRID_FIELD).setMandatory(true);
1106
            definition.addDynFieldObject(GRID_FIELD)
1107
                .setClassOfValue(IFFrame.class).setMandatory(false);
1108
            definition.addDynFieldObject(MAPCONTEXT_FIELD)
1109
                .setClassOfValue(MapContext.class).setMandatory(false);
1110
        }
1111
    }
1112

    
1113
    @Override
1114
    public void loadFromState(PersistentState state)
1115
        throws PersistenceException {
1116
        super.loadFromState(state);
1117
        mode = state.getInt(MODE_FIELD);
1118
        typeScale = state.getInt(TYPESCALE_FIELD);
1119
        extension = state.getInt(EXTENSION_FIELD);
1120
        quality = state.getInt(QUALITY_FIELD);
1121
        viewing = state.getInt(VIEWING_FIELD);
1122
        linked = state.getBoolean(BLINKED_FIELD);
1123
        mapUnits = state.getInt(MAPUNITS_FIELD);
1124
        mapScale = state.getDouble(SCALE_FIELD);
1125
        viewDocument = (ViewDocument) state.get(VIEW_FIELD);
1126

    
1127
        if (state.hasValue(MAPCONTEXT_FIELD)) {
1128
            mapContext = (MapContext) state.get(MAPCONTEXT_FIELD);
1129
            mapContext.getViewPort().setEnvelope(
1130
                (Envelope) state.get(ENVELOPE_FIELD));
1131
        }
1132

    
1133
        showGrid = state.getBoolean(SHOWGRID_FIELD);
1134
        grid = (IFFrame) state.get(GRID_FIELD);
1135
    }
1136

    
1137
    @Override
1138
    public void saveToState(PersistentState state) throws PersistenceException {
1139
        super.saveToState(state);
1140
        state.set(MODE_FIELD, mode);
1141
        state.set(TYPESCALE_FIELD, typeScale);
1142
        state.set(EXTENSION_FIELD, extension);
1143
        state.set(QUALITY_FIELD, quality);
1144
        state.set(VIEWING_FIELD, viewing);
1145
        state.set(BLINKED_FIELD, linked);
1146
        state.set(MAPUNITS_FIELD, mapUnits);
1147
        state.set(SCALE_FIELD, mapScale);
1148
        state.set(VIEW_FIELD, viewDocument);
1149

    
1150
        if (getMapContext() != null
1151
            && getMapContext().getViewPort().getEnvelope() != null) {
1152
            state.set(ENVELOPE_FIELD, getMapContext().getViewPort()
1153
                .getEnvelope());
1154
            state.set(MAPCONTEXT_FIELD, mapContext);
1155
        }
1156

    
1157
        state.set(SHOWGRID_FIELD, showGrid);
1158
        state.set(GRID_FIELD, grid);
1159
    }
1160
    
1161
    @Override
1162
    public void setBoundBox(Rectangle2D r) {      
1163
        super.setBoundBox(r);
1164
        refresh();
1165
    }   
1166

    
1167
    /**
1168
     * getRotation returns rotation of the frame
1169
     * getMapRotation returns rotation of the map
1170
     * 
1171
     * @return in degrees
1172
     */
1173
    public double getMapRotation() {
1174
        return 0;
1175
    }
1176
}