Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / ViewPort.java @ 980

History | View | Annotate | Download (14.4 KB)

1
/* Generated by Together */
2
package com.iver.cit.gvsig.fmap;
3

    
4
import com.iver.utiles.StringUtilities;
5
import com.iver.utiles.XMLEntity;
6

    
7
import org.cresques.cts.IProjection;
8
import org.cresques.cts.ProjectionPool;
9

    
10
import java.awt.Color;
11
import java.awt.Dimension;
12
import java.awt.Point;
13
import java.awt.geom.AffineTransform;
14
import java.awt.geom.NoninvertibleTransformException;
15
import java.awt.geom.Point2D;
16
import java.awt.geom.Rectangle2D;
17

    
18
import java.util.ArrayList;
19

    
20

    
21
/**
22
 * DOCUMENT ME!
23
 *
24
 * @author Vicente Caballero Navarro
25
 */
26
public class ViewPort {
27
        public static int KILOMETROS = 0;
28
        public static int METROS = 1;
29
        public static int CENTIMETRO = 2;
30
        public static int MILIMETRO = 3;
31
        public static int MILLAS = 4;
32
        public static int YARDAS = 5;
33
        public static int PIES = 6;
34
        public static int PULGADAS = 7;
35

    
36
        /**
37
         * Resoluci?n (Puntos por pulgada) de la vista actual. Se necesita para los
38
         * c?lculos de escala geogr?fica.
39
         */
40
        private static int dpi = java.awt.Toolkit.getDefaultToolkit()
41
                                                                                         .getScreenResolution();
42
        private Rectangle2D extent;
43
        private Rectangle2D adjustedExtent;
44
        private ExtentHistory extents = new ExtentHistory();
45
        private Dimension imageSize;
46
        private AffineTransform trans = new AffineTransform();
47
        private int distanceUnits = METROS;
48
        private int mapUnits = METROS;
49
        private ArrayList extentListeners = new ArrayList();
50
        private ArrayList colorListeners = new ArrayList();
51
        private Point2D offset = new Point2D.Double(0, 0);
52
        private Rectangle2D clip;
53
        private Color backColor = null; //Color.WHITE;
54
        private IProjection proj;
55
        private double dist1pixel;
56
        private double dist3pixel;
57
        private double scale;
58

    
59
        /**
60
         * Crea un nuevo ViewPort.
61
         *
62
         * @param proj DOCUMENT ME!
63
         */
64
        public ViewPort(IProjection proj) {
65
                // Por defecto
66
                this.proj = proj;
67
        }
68

    
69
        /**
70
         * DOCUMENT ME!
71
         *
72
         * @param arg0 DOCUMENT ME!
73
         *
74
         * @return DOCUMENT ME!
75
         */
76
        public boolean addExtentListener(ViewPortListener arg0) {
77
                return extentListeners.add(arg0);
78
        }
79

    
80
        /**
81
         * DOCUMENT ME!
82
         *
83
         * @param arg0 DOCUMENT ME!
84
         *
85
         * @return DOCUMENT ME!
86
         */
87
        public boolean addColorListener(ViewPortListener arg0) {
88
                return colorListeners.add(arg0);
89
        }
90

    
91
        /**
92
         * DOCUMENT ME!
93
         *
94
         * @param arg0 DOCUMENT ME!
95
         *
96
         * @return DOCUMENT ME!
97
         */
98
        public boolean removeExtentListener(ViewPortListener arg0) {
99
                return extentListeners.remove(arg0);
100
        }
101

    
102
        /**
103
         * DOCUMENT ME!
104
         *
105
         * @param arg0 DOCUMENT ME!
106
         *
107
         * @return DOCUMENT ME!
108
         */
109
        public boolean removeColorListener(ViewPortListener arg0) {
110
                return colorListeners.remove(arg0);
111
        }
112

    
113
        /**
114
         * DOCUMENT ME!
115
         *
116
         * @param d DOCUMENT ME!
117
         *
118
         * @return DOCUMENT ME!
119
         */
120
        public int fromMapDistance(double d) {
121
                Point2D.Double pWorld = new Point2D.Double(1, 1);
122
                Point2D.Double pScreen = new Point2D.Double();
123

    
124
                double nuevoX;
125
                double nuevoY;
126
                double cX;
127
                double cY;
128

    
129
                try {
130
                        trans.deltaTransform(pWorld, pScreen);
131
                } catch (Exception e) {
132
                        System.err.print(e.getMessage());
133
                }
134

    
135
                return (int) (d * pScreen.x);
136
        }
137

    
138
        /**
139
         * DOCUMENT ME!
140
         *
141
         * @param x DOCUMENT ME!
142
         * @param y DOCUMENT ME!
143
         *
144
         * @return DOCUMENT ME!
145
         */
146
        public Point2D fromMapPoint(double x, double y) {
147
                Point2D.Double pWorld = new Point2D.Double(x, y);
148
                Point2D.Double pScreen = new Point2D.Double();
149

    
150
                double nuevoX;
151
                double nuevoY;
152
                double cX;
153
                double cY;
154

    
155
                try {
156
                        trans.transform(pWorld, pScreen);
157
                } catch (Exception e) {
158
                        System.err.print(e.getMessage());
159
                }
160

    
161
                return pScreen;
162
        }
163

    
164
        /**
165
         * DOCUMENT ME!
166
         *
167
         * @param x DOCUMENT ME!
168
         * @param y DOCUMENT ME!
169
         *
170
         * @return DOCUMENT ME!
171
         */
172
        public Point2D toMapPoint(int x, int y) {
173
                Point pScreen = new Point(x, y);
174

    
175
                return toMapPoint(pScreen);
176
        }
177

    
178
        /**
179
         * DOCUMENT ME!
180
         *
181
         * @param d DOCUMENT ME!
182
         *
183
         * @return DOCUMENT ME!
184
         */
185
        public double toMapDistance(int d) {
186
                double dist = d / trans.getScaleX();
187

    
188
                return dist;
189
        }
190

    
191
        /**
192
         * DOCUMENT ME!
193
         *
194
         * @param pScreen DOCUMENT ME!
195
         *
196
         * @return DOCUMENT ME!
197
         *
198
         * @throws RuntimeException DOCUMENT ME!
199
         */
200
        public Point2D toMapPoint(Point2D pScreen) {
201
                Point2D.Double pWorld = new Point2D.Double();
202
                AffineTransform at;
203

    
204
                try {
205
                        at = trans.createInverse();
206
                        at.transform(pScreen, pWorld);
207
                } catch (NoninvertibleTransformException e) {
208
                        throw new RuntimeException(e);
209
                }
210

    
211
                return pWorld;
212
        }
213

    
214
        /**
215
         * DOCUMENT ME!
216
         */
217
        public void setPreviousExtent() {
218
                extent = extents.removePrev();
219

    
220
                //Calcula la transformaci?n af?n
221
                calculateAffineTransform();
222

    
223
                // Lanzamos los eventos de extent cambiado
224
                callExtentListeners(adjustedExtent);
225
        }
226

    
227
        /**
228
         * DOCUMENT ME!
229
         *
230
         * @return DOCUMENT ME!
231
         */
232
        public Rectangle2D getExtent() {
233
                return extent;
234
        }
235

    
236
        /**
237
         * DOCUMENT ME!
238
         *
239
         * @param r DOCUMENT ME!
240
         */
241
        public void setExtent(Rectangle2D r) {
242
                if (extent != null) {
243
                        extents.put(extent);
244
                }
245

    
246
                //Esto comprueba que el extent no es de anchura o altura = "0" 
247
                //y si es as? lo redimensiona.
248
                if ((r.getWidth() == 0) || (r.getHeight() == 0)) {
249
                        extent = new Rectangle2D.Double(r.getMinX() - 0.1,
250
                                        r.getMinY() - 0.1, r.getWidth() + 0.2, r.getHeight() + 0.2);
251
                } else {
252
                        extent = r;
253
                }
254

    
255
                //Calcula la transformaci?n af?n
256
                calculateAffineTransform();
257

    
258
                // Lanzamos los eventos de extent cambiado
259
                callExtentListeners(adjustedExtent);
260
        }
261

    
262
        /**
263
         * DOCUMENT ME!
264
         *
265
         * @param scale DOCUMENT ME!
266
         */
267
        public void setScale(double scale) {
268
                this.scale = scale;
269

    
270
                //Calcula la transformaci?n af?n
271
                calculateAffineTransform();
272

    
273
                // Lanzamos los eventos de extent cambiado
274
                callExtentListeners(adjustedExtent);
275
        }
276

    
277
        /**
278
         * Devuelve la escala. Debe estar siempre actualizada y no calcularse nunca
279
         * aqu? pues se utiliza en el dibujado para cada geometr?a
280
         *
281
         * @return
282
         */
283
        public double getScale() {
284
                return proj.getScale(extent.getMinX(), extent.getMaxX(),
285
                        imageSize.getWidth(), dpi);
286
        }
287

    
288
        /**
289
         * DOCUMENT ME!
290
         *
291
         * @return
292
         */
293
        public AffineTransform getAffineTransform() {
294
                return trans;
295
        }
296

    
297
        /**
298
         * DOCUMENT ME!
299
         *
300
         * @return Returns the imageSize.
301
         */
302
        public Dimension getImageSize() {
303
                return imageSize;
304
        }
305

    
306
        /**
307
         * DOCUMENT ME!
308
         *
309
         * @param imageSize The imageSize to set.
310
         */
311
        public void setImageSize(Dimension imageSize) {
312
                this.imageSize = imageSize;
313
                calculateAffineTransform();
314
        }
315

    
316
        /**
317
         * DOCUMENT ME!
318
         *
319
         * @param newRect DOCUMENT ME!
320
         */
321
        private void callExtentListeners(Rectangle2D newRect) {
322
                ExtentEvent ev = new ExtentEvent(newRect);
323

    
324
                for (int i = 0; i < extentListeners.size(); i++) {
325
                        ViewPortListener listener = (ViewPortListener) extentListeners.get(i);
326
                        listener.extentChanged(ev);
327
                }
328
        }
329

    
330
        /**
331
         * DOCUMENT ME!
332
         *
333
         * @param c DOCUMENT ME!
334
         */
335
        private void callColorListeners(Color c) {
336
                ColorEvent ce = new ColorEvent(c);
337

    
338
                for (int i = 0; i < colorListeners.size(); i++) {
339
                        ViewPortListener listener = (ViewPortListener) colorListeners.get(i);
340
                        listener.backColorChanged(ce);
341
                }
342
        }
343

    
344
        /**
345
         *
346
         */
347
        private void calculateAffineTransform() {
348
                if ((imageSize == null) || (extent == null) ||
349
                                (imageSize.getWidth() <= 0) || (imageSize.getHeight() <= 0)) {
350
                        return;
351
                }
352

    
353
                AffineTransform escalado = new AffineTransform();
354
                AffineTransform translacion = new AffineTransform();
355

    
356
                double escalaX;
357
                double escalaY;
358

    
359
                escalaX = imageSize.getWidth() / extent.getWidth();
360
                escalaY = imageSize.getHeight() / extent.getHeight();
361

    
362
                double xCenter = extent.getCenterX();
363
                double yCenter = extent.getCenterY();
364
                double newHeight;
365
                double newWidth;
366

    
367
                adjustedExtent = new Rectangle2D.Double();
368

    
369
                if (escalaX < escalaY) {
370
                        scale = escalaX;
371
                        newHeight = imageSize.getHeight() / scale;
372
                        adjustedExtent.setRect(xCenter - (extent.getWidth() / 2.0),
373
                                yCenter - (newHeight / 2.0), extent.getWidth(), newHeight);
374
                } else {
375
                        scale = escalaY;
376
                        newWidth = imageSize.getWidth() / scale;
377
                        adjustedExtent.setRect(xCenter - (newWidth / 2.0),
378
                                yCenter - (extent.getHeight() / 2.0), newWidth,
379
                                extent.getHeight());
380
                }
381

    
382
                translacion.setToTranslation(-adjustedExtent.getX(),
383
                        -adjustedExtent.getY() - adjustedExtent.getHeight());
384
                escalado.setToScale(scale, -scale);
385

    
386
                AffineTransform offsetTrans = new AffineTransform();
387
                offsetTrans.setToTranslation(offset.getX(), offset.getY());
388

    
389
                trans.setToIdentity();
390
                trans.concatenate(offsetTrans);
391
                trans.concatenate(escalado);
392

    
393
                trans.concatenate(translacion);
394

    
395
                // Calculamos las distancias de 1 pixel y 3 pixel con esa transformaci?n 
396
                // de coordenadas, de forma que est?n precalculadas para cuando las necesitemos
397
                AffineTransform at;
398

    
399
                try {
400
                        at = trans.createInverse();
401

    
402
                        java.awt.Point pPixel = new java.awt.Point(1, 1);
403
                        Point2D.Float pProv = new Point2D.Float();
404
                        at.deltaTransform(pPixel, pProv);
405

    
406
                        dist1pixel = pProv.x;
407
                        dist3pixel = 3 * pProv.x;
408
                } catch (NoninvertibleTransformException e) {
409
                        System.err.println("transformada afin = " + trans.toString());
410
                        System.err.println("extent = " + extent.toString() +
411
                                " imageSize= " + imageSize.toString());
412
                        throw new RuntimeException(e);
413
                }
414
        }
415

    
416
        /**
417
         * DOCUMENT ME!
418
         *
419
         * @param p DOCUMENT ME!
420
         */
421
        public void setOffset(Point2D p) {
422
                offset = p;
423
        }
424

    
425
        /**
426
         * DOCUMENT ME!
427
         *
428
         * @param c DOCUMENT ME!
429
         */
430
        public void setBackColor(Color c) {
431
                backColor = c;
432
                callColorListeners(backColor);
433
        }
434

    
435
        /**
436
         * DOCUMENT ME!
437
         *
438
         * @return DOCUMENT ME!
439
         */
440
        public Color getBackColor() {
441
                return backColor;
442
        }
443

    
444
        /**
445
         * DOCUMENT ME!
446
         *
447
         * @return Returns the adjustedExtent.
448
         */
449
        public Rectangle2D getAdjustedExtent() {
450
                return adjustedExtent;
451
        }
452

    
453
        /**
454
         * DOCUMENT ME!
455
         *
456
         * @return Returns the distanceUnits.
457
         */
458
        public int getDistanceUnits() {
459
                return distanceUnits;
460
        }
461

    
462
        /**
463
         * DOCUMENT ME!
464
         *
465
         * @param distanceUnits The distanceUnits to set.
466
         */
467
        public void setDistanceUnits(int distanceUnits) {
468
                this.distanceUnits = distanceUnits;
469
        }
470

    
471
        /**
472
         * DOCUMENT ME!
473
         *
474
         * @return Returns the mapUnits.
475
         */
476
        public int getMapUnits() {
477
                return mapUnits;
478
        }
479

    
480
        /**
481
         * DOCUMENT ME!
482
         *
483
         * @param mapUnits The mapUnits to set.
484
         */
485
        public void setMapUnits(int mapUnits) {
486
                this.mapUnits = mapUnits;
487
        }
488

    
489
        /**
490
         * DOCUMENT ME!
491
         *
492
         * @return DOCUMENT ME!
493
         */
494
        public int getImageWidth() {
495
                return imageSize.width;
496
        }
497

    
498
        /**
499
         * DOCUMENT ME!
500
         *
501
         * @return DOCUMENT ME!
502
         */
503
        public int getImageHeight() {
504
                return imageSize.height;
505
        }
506

    
507
        /**
508
         * DOCUMENT ME!
509
         *
510
         * @return DOCUMENT ME!
511
         */
512
        public double getDist1pixel() {
513
                return dist1pixel;
514
        }
515

    
516
        /**
517
         * DOCUMENT ME!
518
         *
519
         * @param dist1pixel DOCUMENT ME!
520
         */
521
        public void setDist1pixel(double dist1pixel) {
522
                this.dist1pixel = dist1pixel;
523
        }
524

    
525
        /**
526
         * DOCUMENT ME!
527
         *
528
         * @return DOCUMENT ME!
529
         */
530
        public double getDist3pixel() {
531
                return dist3pixel;
532
        }
533

    
534
        /**
535
         * DOCUMENT ME!
536
         *
537
         * @param dist3pixel DOCUMENT ME!
538
         */
539
        public void setDist3pixel(double dist3pixel) {
540
                this.dist3pixel = dist3pixel;
541
        }
542

    
543
        /**
544
         * DOCUMENT ME!
545
         *
546
         * @return Returns the extents.
547
         */
548
        public ExtentHistory getExtents() {
549
                return extents;
550
        }
551

    
552
        /**
553
         * DOCUMENT ME!
554
         *
555
         * @return Returns the proj.
556
         */
557
        public IProjection getProjection() {
558
                return proj;
559
        }
560

    
561
        /**
562
         * DOCUMENT ME!
563
         *
564
         * @param proj The proj to set.
565
         */
566
        public void setProjection(IProjection proj) {
567
                this.proj = proj;
568
        }
569

    
570
        /**
571
         * DOCUMENT ME!
572
         *
573
         * @return DOCUMENT ME!
574
         */
575
        public XMLEntity getXMLEntity() {
576
                XMLEntity xml = new XMLEntity();
577

    
578
                if (adjustedExtent != null) {
579
                        xml.putProperty("adjustedExtentX", adjustedExtent.getX());
580
                        xml.putProperty("adjustedExtentY", adjustedExtent.getY());
581
                        xml.putProperty("adjustedExtentW", adjustedExtent.getWidth());
582
                        xml.putProperty("adjustedExtentH", adjustedExtent.getHeight());
583
                }
584

    
585
                xml.putProperty("backColor", StringUtilities.color2String(backColor));
586

    
587
                if (clip != null) {
588
                        xml.putProperty("clipX", clip.getX());
589
                        xml.putProperty("clipY", clip.getY());
590
                        xml.putProperty("clipW", clip.getWidth());
591
                        xml.putProperty("clipH", clip.getHeight());
592
                }
593

    
594
                xml.putProperty("dist1pixel", dist1pixel);
595
                xml.putProperty("dist3pixel", dist3pixel);
596
                xml.putProperty("distanceUnits", distanceUnits);
597

    
598
                if (extent != null) {
599
                        xml.putProperty("extentX", extent.getX());
600
                        xml.putProperty("extentY", extent.getY());
601
                        xml.putProperty("extentW", extent.getWidth());
602
                        xml.putProperty("extentH", extent.getHeight());
603
                }
604

    
605
                xml.addChild(extents.getXMLEntity());
606
                xml.putProperty("mapUnits", mapUnits);
607
                xml.putProperty("offsetX", offset.getX());
608
                xml.putProperty("offsetY", offset.getY());
609

    
610
                if (proj != null) {
611
                        xml.putProperty("proj", proj.getAbrev());
612
                }
613

    
614
                xml.putProperty("scale", scale);
615

    
616
                return xml;
617
        }
618

    
619
        /**
620
         * DOCUMENT ME!
621
         *
622
         * @param xml DOCUMENT ME!
623
         *
624
         * @return DOCUMENT ME!
625
         */
626
        public static ViewPort createFromXML(XMLEntity xml) {
627
                ViewPort vp = new ViewPort(null);
628

    
629
                if (xml.contains("adjustedExtentX")) {
630
                        vp.adjustedExtent = new Rectangle2D.Double(xml.getDoubleProperty(
631
                                                "adjustedExtentX"),
632
                                        xml.getDoubleProperty("adjustedExtentY"),
633
                                        xml.getDoubleProperty("adjustedExtentW"),
634
                                        xml.getDoubleProperty("adjustedExtentH"));
635
                }
636

    
637
                if (xml.contains("backColor")) {
638
                        vp.setBackColor(StringUtilities.string2Color(xml.getStringProperty(
639
                                                "backColor")));
640
                }
641

    
642
                if (xml.contains("clipX")) {
643
                        vp.clip = new Rectangle2D.Double(xml.getDoubleProperty("clipX"),
644
                                        xml.getDoubleProperty("clipY"),
645
                                        xml.getDoubleProperty("clipW"),
646
                                        xml.getDoubleProperty("clipH"));
647
                }
648

    
649
                vp.setDist1pixel(xml.getDoubleProperty("dist1pixel"));
650
                vp.setDist3pixel(xml.getDoubleProperty("dist3pixel"));
651
                vp.setDistanceUnits(xml.getIntProperty("distanceUnits"));
652
                vp.extents = ExtentHistory.createFromXML(xml.getChild(0));
653

    
654
                if (xml.contains("extentX")) {
655
                        vp.setExtent(new Rectangle2D.Double(xml.getDoubleProperty("extentX"),
656
                                        xml.getDoubleProperty("extentY"),
657
                                        xml.getDoubleProperty("extentW"),
658
                                        xml.getDoubleProperty("extentH")));
659

    
660
                        //Calcula la transformaci?n af?n
661
                        vp.calculateAffineTransform();
662

    
663
                        // Lanzamos los eventos de extent cambiado
664
                        vp.callExtentListeners(vp.adjustedExtent);
665
                }
666

    
667
                vp.setMapUnits(xml.getIntProperty("mapUnits"));
668
                vp.setOffset(new Point2D.Double(xml.getDoubleProperty("offsetX"),
669
                                xml.getDoubleProperty("offsetY")));
670

    
671
                if (xml.contains("proj")) {
672
                        vp.proj = ProjectionPool.get(xml.getStringProperty("proj"));
673
                }
674

    
675
                vp.setScale(xml.getDoubleProperty("scale"));
676

    
677
                return vp;
678
        }
679

    
680
        /**
681
         * DOCUMENT ME!
682
         *
683
         * @return DOCUMENT ME!
684
         */
685
        public ViewPort cloneViewPort() {
686
                return createFromXML(getXMLEntity());
687
        }
688

    
689
        /**
690
         * DOCUMENT ME!
691
         *
692
         * @return DOCUMENT ME!
693
         */
694
        public String toString() {
695
                String str;
696
                str = "Datos del viewPort:\nExtent=" + extent + "\nadjustedExtent=" +
697
                        adjustedExtent + "\nimageSize=" + imageSize + "\nescale=" + scale +
698
                        "\ntrans=" + trans;
699

    
700
                return str;
701
        }
702
}