Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_912 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / ViewPort.java @ 11422

History | View | Annotate | Download (23.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap;
42

    
43
import java.awt.Color;
44
import java.awt.Dimension;
45
import java.awt.Point;
46
import java.awt.geom.AffineTransform;
47
import java.awt.geom.NoninvertibleTransformException;
48
import java.awt.geom.Point2D;
49
import java.awt.geom.Rectangle2D;
50
import java.util.ArrayList;
51

    
52
import org.cresques.cts.GeoCalc;
53
import org.cresques.cts.IProjection;
54
import org.cresques.cts.gt2.CSUTM;
55

    
56
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
57
import com.iver.utiles.StringUtilities;
58
import com.iver.utiles.XMLEntity;
59

    
60

    
61
/**
62
 * Clase con atributos de la vista.
63
 * 050211, jmorell: A?ado los Grados como unidad de mapa.
64
 *
65
 * @author Vicente Caballero Navarro
66
 */
67
public class ViewPort {
68
        public static int KILOMETROS = 0;
69
        public static int METROS = 1;
70
        public static int CENTIMETRO = 2;
71
        public static int MILIMETRO = 3;
72
        public static int MILLAS = 4;
73
        public static int YARDAS = 5;
74
        public static int PIES = 6;
75
        public static int PULGADAS = 7;
76
        public static int GRADOS = 8;
77

    
78
        /**
79
         * Resoluci?n (Puntos por pulgada) de la vista actual. Se necesita para los
80
         * c?lculos de escala geogr?fica.
81
         */
82
        private static int dpi = java.awt.Toolkit.getDefaultToolkit()
83
                                                                                         .getScreenResolution();
84
        private Rectangle2D extent;
85
        private Rectangle2D adjustedExtent;
86
        private ExtentHistory extents = new ExtentHistory();
87
        private Dimension imageSize;
88
        private AffineTransform trans = new AffineTransform();
89
        private int distanceUnits = METROS;
90
        private int mapUnits = METROS;
91
        private ArrayList listeners = new ArrayList();
92
        private Point2D offset = new Point2D.Double(0, 0);
93
        private Rectangle2D clip;
94
        private Color backColor = null; //Color.WHITE;
95
        private IProjection proj;
96
        private double dist1pixel;
97
        private double dist3pixel;
98
        private double scale;
99
        private Rectangle2D cliprect;
100
        private boolean adjustableExtent=true;
101

    
102
        /**
103
         * Crea un nuevo ViewPort.
104
         *
105
         * @param proj Proyecci?n.
106
         */
107
        public ViewPort(IProjection proj) {
108
                // Por defecto
109
                this.proj = proj;
110
        }
111

    
112
        /**
113
         * Sets the adjustable option, so the extent is automatically adjusted to view aspect.
114
         *
115
         * @param boolean Adjustable.
116
         */
117
        public void setAdjustable(boolean adjustable) {
118
                adjustableExtent = adjustable;
119
        }
120

    
121
        /**
122
         * A?ade un ViewPortListener al extentListener.
123
         *
124
         * @param arg0 ViewPortListener.
125
         *
126
         * @return True si ha sido a?adida correctamente.
127
         */
128
        public boolean addViewPortListener(ViewPortListener arg0) {
129
                if (!listeners.contains(arg0))
130
                        return listeners.add(arg0);
131
                return false;
132
        }
133

    
134

    
135
        /**
136
         * Borra el ViewPortListener que se pasa como par?metro delos
137
         * extentListener.
138
         *
139
         * @param arg0 ViewPortListener.
140
         *
141
         * @return True si ha sido borrado correctamente.
142
         */
143
        public boolean removeViewPortListener(ViewPortListener arg0) {
144
                return listeners.remove(arg0);
145
        }
146

    
147
        /**
148
         * Devuelve la distancia en pixels a partir de una distancia real.
149
         *
150
         * @param d Distancia real.
151
         *
152
         * @return Distancia en pixels.
153
         */
154
        public int fromMapDistance(double d) {
155
                Point2D.Double pWorld = new Point2D.Double(1, 1);
156
                Point2D.Double pScreen = new Point2D.Double();
157

    
158
                try {
159
                        trans.deltaTransform(pWorld, pScreen);
160
                } catch (Exception e) {
161
                        System.err.print(e.getMessage());
162
                }
163

    
164
                return (int) (d * pScreen.x);
165
        }
166

    
167
        /**
168
         * Devuelve un punto en pixels a partir de una coordenada X e Y real.
169
         *
170
         * @param x Coordenada X real.
171
         * @param y Coordenada Y real.
172
         *
173
         * @return Punto en pixels.
174
         */
175
        public Point2D fromMapPoint(double x, double y) {
176
                Point2D.Double pWorld = new Point2D.Double(x, y);
177
                Point2D.Double pScreen = new Point2D.Double();
178

    
179
                try {
180
                        trans.transform(pWorld, pScreen);
181
                } catch (Exception e) {
182
                        System.err.print(e.getMessage());
183
                }
184

    
185
                return pScreen;
186
        }
187

    
188
        /**
189
         * Devuelve el punto en pixels a partir de un punto real.
190
         *
191
         * @param point Punto real.
192
         *
193
         * @return Punto en pixels.
194
         */
195
        public Point2D fromMapPoint(Point2D point) {
196
                return fromMapPoint(point.getX(), point.getY());
197
        }
198

    
199
        /**
200
         * Devuelve un punto real a partir de una coordenada X e Y en pixels.
201
         *
202
         * @param x Coordenada X en pixels.
203
         * @param y Coordenada Y en pixels.
204
         *
205
         * @return Punto real.
206
         */
207
        public Point2D toMapPoint(int x, int y) {
208
                Point pScreen = new Point(x, y);
209

    
210
                return toMapPoint(pScreen);
211
        }
212

    
213
        public Rectangle2D toMapRectangle(Rectangle2D r){
214
                double w=toMapDistance((int)r.getWidth());
215
                double h=toMapDistance((int)r.getHeight());
216
                Point2D p1=toMapPoint((int)r.getX(),(int)r.getY());
217
                return new Rectangle2D.Double(p1.getX(),p1.getY(),w,h);
218
        }
219
        /**
220
         * Devuelve la distancia real a partir de la distancia en pixels.
221
         *
222
         * @param d Distancia en pixels.
223
         *
224
         * @return Distancia real.
225
         */
226
        public double toMapDistance(int d) {
227
                double dist = d / trans.getScaleX();
228

    
229
                return dist;
230
        }
231

    
232
        /**
233
         * Devuelve un punto real a partir de un punto en pixels.
234
         *
235
         * @param pScreen Punto en pixels.
236
         *
237
         * @return Punto real.
238
         *
239
         * @throws RuntimeException
240
         */
241
        public Point2D toMapPoint(Point2D pScreen) {
242
                Point2D.Double pWorld = new Point2D.Double();
243
                AffineTransform at;
244

    
245
                try {
246
                        at = trans.createInverse();
247
                        at.transform(pScreen, pWorld);
248
                } catch (NoninvertibleTransformException e) {
249
                        throw new RuntimeException(e);
250
                }
251

    
252
                return pWorld;
253
        }
254

    
255
        /**
256
         * Calcula la distancia entre dos puntos en unidades de usuario. Los puntos
257
         * est?n en unidades de usuario. Se tiene en cuenta la proyecci?n, con lo
258
         * que es INDISPENSABLE que la variable proj contenga el valor correcto de
259
         * la proyecci?n.
260
         *
261
         * @param pt1
262
         * @param pt2
263
         *
264
         * @return distancia real.
265
         */
266
        public double distanceWorld(Point2D pt1, Point2D pt2) {
267
                double dist = -1;
268
                dist = pt1.distance(pt2);
269

    
270
                if ((proj != null) && !(proj instanceof CSUTM)) {
271
                        dist = new GeoCalc(proj).distanceVincenty(proj.toGeo(pt1),
272
                                        proj.toGeo(pt2));
273
                }
274

    
275
                return dist*MapContext.CHANGEM[getMapUnits()];
276
        }
277

    
278
        /**
279
         * Rellena el extent anterior como actual.
280
         */
281
        public void setPreviousExtent() {
282
                extent = extents.removePrev();
283

    
284
                //Calcula la transformaci?n af?n
285
                calculateAffineTransform();
286

    
287
                // Lanzamos los eventos de extent cambiado
288
                callExtentChanged(getAdjustedExtent());
289
        }
290

    
291
        /**
292
         * <p>
293
         * When the zoom changes (for instance when using the zoom in or zoom out tools,
294
         * but also zooming to a selected feature or shape) the extent that covers that
295
         * area is the value returned by this method. It is not the actual area shown
296
         * in the view because it does not care about the aspect ratio. However, any
297
         * part of the real world contained in this extent is shown in the view.<br>
298
         * </p>
299
         * <p>
300
         * Probably <b>this is not what you are looking for</b>. If you are looking for
301
         * the complete extent currently shown, you must use getAdjustedExtent() method
302
         * which returns the extent that contains this one but regarding the current
303
         * view's aspect ratio.
304
         * </p>
305
         * @return Extent.
306
         */
307
        public Rectangle2D getExtent() {
308
                return extent;
309
        }
310

    
311
        /**
312
         * Inserta el extent.
313
         *
314
         * @param r Extent.
315
         */
316
        public void setExtent(Rectangle2D r) {
317
                if (extent != null) {
318
                        extents.put(extent);
319
                }
320

    
321
                //Esto comprueba que el extent no es de anchura o altura = "0"
322
                //y si es as? lo redimensiona.
323
                if (r!=null &&((r.getWidth() == 0) || (r.getHeight() == 0))) {
324
                        extent = new Rectangle2D.Double(r.getMinX() - 0.1,
325
                                        r.getMinY() - 0.1, r.getWidth() + 0.2, r.getHeight() + 0.2);
326
                } else {
327
                        extent = r;
328
                }
329

    
330
                //Calcula la transformaci?n af?n
331
                calculateAffineTransform();
332

    
333
                // Lanzamos los eventos de extent cambiado
334
                callExtentChanged(getAdjustedExtent());
335
        }
336

    
337
        /**
338
         * Refresca el extent.
339
     *
340
         */
341
        public void refreshExtent() {
342
                //this.scale = scale;
343

    
344
                //Calcula la transformaci?n af?n
345
                calculateAffineTransform();
346

    
347
                // Lanzamos los eventos de extent cambiado
348
                callExtentChanged(getAdjustedExtent());
349
        }
350

    
351
        /**
352
         * Devuelve la escala. Debe estar siempre actualizada y no calcularse nunca
353
         * aqu? pues se utiliza en el dibujado para cada geometr?a
354
         *
355
         * @return Escala.
356
         */
357
        public double getScale() {
358
                return proj.getScale(extent.getMinX(), extent.getMaxX(),
359
                        imageSize.getWidth(), dpi);
360
        }
361

    
362
        /**
363
         * Devuelve la matriz de transformaci?n.
364
         *
365
         * @return Matriz de transformaci?n.
366
         */
367
        public AffineTransform getAffineTransform() {
368
                return trans;
369
        }
370

    
371
        /**
372
         * Devuelve las dimensiones de la imagen.
373
         *
374
         * @return Returns the imageSize.
375
         */
376
        public Dimension getImageSize() {
377
                return imageSize;
378
        }
379

    
380
        /**
381
         * Inserta las dimensiones de la imagen.
382
         *
383
         * @param imageSize The imageSize to set.
384
         */
385
        public void setImageSize(Dimension imageSize) {
386
                this.imageSize = imageSize;
387
                calculateAffineTransform();
388
        }
389

    
390
        /**
391
         * Llamada a los listeners tras el cambio de extent.
392
         *
393
         * @param newRect Extent.
394
         */
395
        private void callExtentChanged(Rectangle2D newRect) {
396
                ExtentEvent ev = ExtentEvent.createExtentEvent(newRect);
397

    
398
                for (int i = 0; i < listeners.size(); i++) {
399
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
400
                        listener.extentChanged(ev);
401
                }
402
        }
403

    
404
        /**
405
         * Llamada a los listeners tras el cambio de color.
406
         *
407
         * @param c Color.
408
         */
409
        private void callColorChanged(Color c) {
410
                ColorEvent ce = ColorEvent.createColorEvent(c);
411

    
412
                for (int i = 0; i < listeners.size(); i++) {
413
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
414
                        listener.backColorChanged(ce);
415
                }
416
        }
417
        /**
418
         * Llamada a los listeners tras el cambio de extent.
419
         *
420
         * @param newRect Extent.
421
         */
422
        private void callProjectionChanged(IProjection projection) {
423
                ProjectionEvent ev = ProjectionEvent.createProjectionEvent(projection);
424

    
425
                for (int i = 0; i < listeners.size(); i++) {
426
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
427
                        listener.projectionChanged(ev);
428
                }
429
        }
430

    
431

    
432
        /**
433
         * C?lculo de la matriz de transformaci?n.
434
         *
435
         * @throws RuntimeException
436
         */
437
        private void calculateAffineTransform() {
438
                if ((imageSize == null) || (extent == null) ||
439
                                (imageSize.getWidth() <= 0) || (imageSize.getHeight() <= 0)) {
440
                        return;
441
                }
442

    
443
                AffineTransform escalado = new AffineTransform();
444
                AffineTransform translacion = new AffineTransform();
445

    
446
                double escalaX;
447
                double escalaY;
448

    
449
                escalaX = imageSize.getWidth() / extent.getWidth();
450
                escalaY = imageSize.getHeight() / extent.getHeight();
451

    
452
                double xCenter = extent.getCenterX();
453
                double yCenter = extent.getCenterY();
454
                double newHeight;
455
                double newWidth;
456

    
457
                adjustedExtent = new Rectangle2D.Double();
458

    
459
                if (adjustableExtent) {
460
                        if (escalaX < escalaY) {
461
                                scale = escalaX;
462
                                newHeight = imageSize.getHeight() / scale;
463
                                adjustedExtent.setRect(xCenter - (extent.getWidth() / 2.0),
464
                                        yCenter - (newHeight / 2.0), extent.getWidth(), newHeight);
465
                        } else {
466
                                scale = escalaY;
467
                                newWidth = imageSize.getWidth() / scale;
468
                                adjustedExtent.setRect(xCenter - (newWidth / 2.0),
469
                                        yCenter - (extent.getHeight() / 2.0), newWidth,
470
                                        extent.getHeight());
471
                        }
472
                        escalado.setToScale(scale, -scale);
473
                }
474
                else { // adjusted is same as extent
475
                        scale = escalaX;
476
                        adjustedExtent.setFrame(extent);
477
                        escalado.setToScale(escalaX, -escalaY);
478
                }
479

    
480
                translacion.setToTranslation(-getAdjustedExtent().getX(),
481
                        -getAdjustedExtent().getY() - getAdjustedExtent().getHeight());
482

    
483
                AffineTransform offsetTrans = new AffineTransform();
484
                offsetTrans.setToTranslation(offset.getX(), offset.getY());
485

    
486
                trans.setToIdentity();
487
                trans.concatenate(offsetTrans);
488
                trans.concatenate(escalado);
489

    
490
                trans.concatenate(translacion);
491

    
492
                // Calculamos las distancias de 1 pixel y 3 pixel con esa transformaci?n
493
                // de coordenadas, de forma que est?n precalculadas para cuando las necesitemos
494
                AffineTransform at;
495

    
496
                try {
497
                        at = trans.createInverse();
498

    
499
                        java.awt.Point pPixel = new java.awt.Point(1, 1);
500
                        Point2D.Float pProv = new Point2D.Float();
501
                        at.deltaTransform(pPixel, pProv);
502

    
503
                        dist1pixel = pProv.x;
504
                        dist3pixel = 3 * pProv.x;
505
                } catch (NoninvertibleTransformException e) {
506
                        System.err.println("transformada afin = " + trans.toString());
507
                        System.err.println("extent = " + extent.toString() +
508
                                " imageSize= " + imageSize.toString());
509
                        throw new RuntimeException(e);
510
                }
511
        }
512

    
513
        /**
514
         * Inserta la desviaci?n.
515
         *
516
         * @param p Punto.
517
         */
518
        public void setOffset(Point2D p) {
519
                offset = p;
520
        }
521
        /**
522
         * The offset is the position where to start drawing. The offset of a View is
523
         * always (0, 0) because the drawing area fits with the full window area. But in
524
         * a Layout it is up to the place where the FFrameView is located.
525
         *
526
         * @param p Point, in pixels, where the map starts.
527
         */
528
        public Point2D getOffset() {
529
                return offset;
530
        }
531
        /**
532
         * Inserta el color de fondo.
533
         *
534
         * @param c Color de fondo.
535
         */
536
        public void setBackColor(Color c) {
537
                backColor = c;
538
                callColorChanged(backColor);
539
        }
540

    
541
        /**
542
         * Devuelve el color de fondo.
543
         *
544
         * @return Color de fondo.
545
         */
546
        public Color getBackColor() {
547
                return backColor;
548
        }
549

    
550
        /**
551
         * Returns the extent currently covered by the view.
552
         *
553
         * @return Returns the adjustedExtent.
554
         */
555
        public Rectangle2D getAdjustedExtent() {
556
                if (cliprect!=null){
557
                        return adjustedExtent.createIntersection(cliprect);
558
                }
559
                return adjustedExtent;
560
        }
561

    
562
        /**
563
         * Devuelve la unidad de medida en la que queremos realizar nuestras mediciones y
564
         * en la que se nos mostrar? toda la informaci?n.
565
         *
566
         * @return Returns the distanceUnits.
567
         */
568
        public int getDistanceUnits() {
569
                return distanceUnits;
570
        }
571

    
572
        /**
573
         * Inserta la unidad de medida en la que queremos realizar nuestras mediciones y
574
         * en la que se nos mostrar? toda la informaci?n.
575
         *
576
         * @param distanceUnits The distanceUnits to set.
577
         */
578
        public void setDistanceUnits(int distanceUnits) {
579
                this.distanceUnits = distanceUnits;
580
        }
581

    
582
        /**
583
         * Devuelve la unidad de medida del mapa, es la unidad de medida en la que est? la cartogr?fia que cargamos,
584
         * normalmente en metros.
585
         *
586
         * @return Returns the mapUnits.
587
         */
588
        public int getMapUnits() {
589
                return mapUnits;
590
        }
591

    
592
        /**
593
         * Inserta la unidad de medida del mapa, es la unidad de medida en la que est? la cartogr?fia que cargamos,
594
         * normalmente en metros.
595
         *
596
         * @param mapUnits The mapUnits to set.
597
         */
598
        public void setMapUnits(int mapUnits) {
599
                this.mapUnits = mapUnits;
600
        }
601

    
602
        /**
603
         * Devuelve la anchura de la imagen.
604
         *
605
         * @return anchura en pixels de la imagen.
606
         */
607
        public int getImageWidth() {
608
                return imageSize.width;
609
        }
610

    
611
        /**
612
         * Devuelve la altura de la imagen.
613
         *
614
         * @return altura de la imagen.
615
         */
616
        public int getImageHeight() {
617
                return imageSize.height;
618
        }
619

    
620
        /**
621
         * Devuelve la distancia real de un pixel.
622
         *
623
         * @return Distancia real de un pixel.
624
         */
625
        public double getDist1pixel() {
626
                return dist1pixel;
627
        }
628

    
629
        /**
630
         * Inserta la distancia real de un pixel.
631
         *
632
         * @param dist1pixel Distancia real de un pixel.
633
         */
634
        public void setDist1pixel(double dist1pixel) {
635
                this.dist1pixel = dist1pixel;
636
        }
637

    
638
        /**
639
         * Devuelve la distancia real de tres pixel.
640
         *
641
         * @return Distancia real de tres pixel.
642
         */
643
        public double getDist3pixel() {
644
                return dist3pixel;
645
        }
646

    
647
        /**
648
         * Inserta la distancia real de tres pixels.
649
         *
650
         * @param dist3pixel Distancia real de tres pixels.
651
         */
652
        public void setDist3pixel(double dist3pixel) {
653
                this.dist3pixel = dist3pixel;
654
        }
655

    
656
        /**
657
         * Devuelve los Extents anteriores almacenados.
658
         *
659
         * @return Returns the extents.
660
         */
661
        public ExtentHistory getExtents() {
662
                return extents;
663
        }
664

    
665
        /**
666
         * Devuelve la proyecci?n.
667
         *
668
         * @return Returns the proj.
669
         */
670
        public IProjection getProjection() {
671
                return proj;
672
        }
673

    
674
        /**
675
         * Inserta la proyecci?n.
676
         *
677
         * @param proj The proj to set.
678
         */
679
        public void setProjection(IProjection proj) {
680
                if(this.proj == null || !this.proj.getAbrev().equals(proj.getAbrev())) {
681
                        this.proj = proj;
682
                        callProjectionChanged(proj);
683
                }
684
        }
685

    
686
        /**
687
         * M?todo que solo lo utilizamos a la hora de imprimir. NO lanza
688
         * un calculateAffineTransform, ni recalcula el adjustedExtent.
689
         * TODO: Para evitar este m?todo, habr?a que redefinir el interfaz
690
         * RasterAdapter, y que recibiera un ViewPortData.
691
         * @param at
692
         */
693
        public void setAffineTransform(AffineTransform at)
694
        {
695
            this.trans = at;
696
        }
697

    
698
        /**
699
         * Devuelve el XMLEntity.
700
         *
701
         * @return XMLEntity.
702
         */
703
        public XMLEntity getXMLEntity() {
704
                XMLEntity xml = new XMLEntity();
705
                xml.putProperty("className",this.getClass().getName());
706

    
707
                if (adjustedExtent != null) {
708
                        xml.putProperty("adjustedExtentX", adjustedExtent.getX());
709
                        xml.putProperty("adjustedExtentY", adjustedExtent.getY());
710
                        xml.putProperty("adjustedExtentW", adjustedExtent.getWidth());
711
                        xml.putProperty("adjustedExtentH", adjustedExtent.getHeight());
712
                }
713

    
714
                if (backColor != null)
715
                    xml.putProperty("backColor", StringUtilities.color2String(backColor));
716

    
717
                if (clip != null) {
718
                        xml.putProperty("clipX", clip.getX());
719
                        xml.putProperty("clipY", clip.getY());
720
                        xml.putProperty("clipW", clip.getWidth());
721
                        xml.putProperty("clipH", clip.getHeight());
722
                }
723

    
724
                xml.putProperty("dist1pixel", dist1pixel);
725
                xml.putProperty("dist3pixel", dist3pixel);
726
                xml.putProperty("distanceUnits", distanceUnits);
727

    
728
                if (extent != null) {
729
                        xml.putProperty("extentX", extent.getX());
730
                        xml.putProperty("extentY", extent.getY());
731
                        xml.putProperty("extentW", extent.getWidth());
732
                        xml.putProperty("extentH", extent.getHeight());
733
                }
734

    
735
                xml.addChild(extents.getXMLEntity());
736
                xml.putProperty("mapUnits", mapUnits);
737
                xml.putProperty("offsetX", offset.getX());
738
                xml.putProperty("offsetY", offset.getY());
739

    
740
                if (proj != null) {
741
                        xml.putProperty("proj", proj.getAbrev());
742
                }
743

    
744
                xml.putProperty("scale", scale);
745

    
746
                return xml;
747
        }
748

    
749
        /**
750
         * Crea un nuevo ViewPort a partir del XMLEntity.
751
         *
752
         * @param xml XMLEntity.
753
         *
754
         * @return Nuevo ViewPort.
755
         */
756
        public static ViewPort createFromXML03(XMLEntity xml) {
757
                ViewPort vp = new ViewPort(null);
758

    
759
                if (xml.contains("adjustedExtentX")) {
760
                        vp.adjustedExtent = new Rectangle2D.Double(xml.getDoubleProperty(
761
                                                "adjustedExtentX"),
762
                                        xml.getDoubleProperty("adjustedExtentY"),
763
                                        xml.getDoubleProperty("adjustedExtentW"),
764
                                        xml.getDoubleProperty("adjustedExtentH"));
765
                }
766

    
767
                if (xml.contains("backColor")) {
768
                        vp.setBackColor(StringUtilities.string2Color(xml.getStringProperty(
769
                                                "backColor")));
770
                }
771

    
772
                if (xml.contains("clipX")) {
773
                        vp.clip = new Rectangle2D.Double(xml.getDoubleProperty("clipX"),
774
                                        xml.getDoubleProperty("clipY"),
775
                                        xml.getDoubleProperty("clipW"),
776
                                        xml.getDoubleProperty("clipH"));
777
                }
778

    
779
                vp.setDist1pixel(xml.getDoubleProperty("dist1pixel"));
780
                vp.setDist3pixel(xml.getDoubleProperty("dist3pixel"));
781
                vp.setDistanceUnits(xml.getIntProperty("distanceUnits"));
782
                vp.extents = ExtentHistory.createFromXML03(xml.getChild(0));
783

    
784
                if (xml.contains("extentX")) {
785
                        vp.setExtent(new Rectangle2D.Double(xml.getDoubleProperty("extentX"),
786
                                        xml.getDoubleProperty("extentY"),
787
                                        xml.getDoubleProperty("extentW"),
788
                                        xml.getDoubleProperty("extentH")));
789

    
790
                        //Calcula la transformaci?n af?n
791
                        vp.calculateAffineTransform();
792

    
793
                        // Lanzamos los eventos de extent cambiado
794
                        // vp.callExtentListeners(vp.adjustedExtent);
795
                }
796

    
797
                vp.setMapUnits(xml.getIntProperty("mapUnits"));
798
                vp.setOffset(new Point2D.Double(xml.getDoubleProperty("offsetX"),
799
                                xml.getDoubleProperty("offsetY")));
800

    
801
                if (xml.contains("proj")) {
802
                        vp.proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
803
                }
804

    
805
                //vp.setScale(xml.getDoubleProperty("scale"));
806
                vp.refreshExtent();
807
                return vp;
808
        }
809

    
810
        /**
811
         * Crea un nuevo ViewPort a partir del XMLEntity.
812
         *
813
         * @param xml XMLEntity.
814
         *
815
         * @return Nuevo ViewPort.
816
         */
817
        public static ViewPort createFromXML(XMLEntity xml) {
818
                ViewPort vp = new ViewPort(null);
819

    
820
                if (xml.contains("adjustedExtentX")) {
821
                        vp.adjustedExtent = new Rectangle2D.Double(xml.getDoubleProperty(
822
                                                "adjustedExtentX"),
823
                                        xml.getDoubleProperty("adjustedExtentY"),
824
                                        xml.getDoubleProperty("adjustedExtentW"),
825
                                        xml.getDoubleProperty("adjustedExtentH"));
826
                }
827

    
828
                if (xml.contains("backColor")) {
829
                        vp.setBackColor(StringUtilities.string2Color(xml.getStringProperty(
830
                                                "backColor")));
831
                }else {
832
                        vp.setBackColor(Color.white);
833
                }
834

    
835
                if (xml.contains("clipX")) {
836
                        vp.clip = new Rectangle2D.Double(xml.getDoubleProperty("clipX"),
837
                                        xml.getDoubleProperty("clipY"),
838
                                        xml.getDoubleProperty("clipW"),
839
                                        xml.getDoubleProperty("clipH"));
840
                }
841

    
842
                vp.setDist1pixel(xml.getDoubleProperty("dist1pixel"));
843
                vp.setDist3pixel(xml.getDoubleProperty("dist3pixel"));
844
                vp.setDistanceUnits(xml.getIntProperty("distanceUnits"));
845
                vp.extents = ExtentHistory.createFromXML(xml.getChild(0));
846

    
847
                if (xml.contains("extentX")) {
848
                        vp.setExtent(new Rectangle2D.Double(xml.getDoubleProperty("extentX"),
849
                                        xml.getDoubleProperty("extentY"),
850
                                        xml.getDoubleProperty("extentW"),
851
                                        xml.getDoubleProperty("extentH")));
852

    
853
                        //Calcula la transformaci?n af?n
854
                        vp.calculateAffineTransform();
855

    
856
                        // Lanzamos los eventos de extent cambiado
857
                        // vp.callExtentListeners(vp.adjustedExtent);
858
                }
859

    
860
                vp.setMapUnits(xml.getIntProperty("mapUnits"));
861
                vp.setOffset(new Point2D.Double(xml.getDoubleProperty("offsetX"),
862
                                xml.getDoubleProperty("offsetY")));
863

    
864
                if (xml.contains("proj")) {
865
                        vp.proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
866
                }
867

    
868
                //vp.setScale(xml.getDoubleProperty("scale"));
869
                vp.refreshExtent();
870
                return vp;
871
        }
872

    
873
        /**
874
         * Clona el ViewPort.
875
         *
876
         * @return ViewPort clonado.
877
         */
878
        public ViewPort cloneViewPort() {
879
                return createFromXML(getXMLEntity());
880
        }
881

    
882
        /**
883
         * Devuelve el String con datos del ViewPort.
884
         *
885
         * @return Cadena con datos del ViewPort.
886
         */
887
        public String toString() {
888
                String str;
889
                str = "Datos del viewPort:\nExtent=" + extent + "\nadjustedExtent=" +
890
                        adjustedExtent + "\nimageSize=" + imageSize + "\nescale=" + scale +
891
                        "\ntrans=" + trans;
892

    
893
                return str;
894
        }
895

    
896
        public void setClipRect(Rectangle2D rectView) {
897
                cliprect=rectView;
898

    
899
        }
900

    
901
        public Rectangle2D fromMapRectangle(Rectangle2D r) {
902
                double w=fromMapDistance((int)r.getWidth());
903
                double h=fromMapDistance((int)r.getHeight());
904
                Point2D p1=fromMapPoint((int)r.getX(),(int)r.getY());
905
                return new Rectangle2D.Double(p1.getX(),p1.getY(),w,h);
906
        }
907
        public void setScale(long s){
908
                double x=extent.getX();
909
                double y=extent.getY();
910
                double escalaX = imageSize.getWidth() / extent.getWidth();
911
                double w=imageSize.getWidth() / s;
912
                double h=imageSize.getHeight() / s;
913
                double difw = escalaX/s;
914

    
915
                double x1 = (-x * difw) -
916
            x+
917
            extent.getWidth()/2;
918
        double y1 = (-y * difw) -
919
            y +
920
            extent.getHeight()/2;
921
        double w1=extent.getWidth()*difw;
922
        double h1=extent.getHeight()*difw;
923
                extent.setRect(-x1,-y1,w1,h1);
924
        }
925

    
926
}