Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / ViewPort.java @ 29519

History | View | Annotate | Download (51.4 KB)

1 29506 jtorres
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2 21200 vcaballero
 *
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 29506 jtorres
 *   Av. Blasco Ib��ez, 50
24 21200 vcaballero
 *   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 org.gvsig.fmap.mapcontext;
42
43
import java.awt.Color;
44
import java.awt.Dimension;
45
import java.awt.Point;
46 26225 jmvivo
import java.awt.Toolkit;
47 21200 vcaballero
import java.awt.geom.AffineTransform;
48
import java.awt.geom.NoninvertibleTransformException;
49
import java.awt.geom.Point2D;
50
import java.awt.geom.Rectangle2D;
51
import java.util.ArrayList;
52
53
import org.cresques.cts.GeoCalc;
54
import org.cresques.cts.IProjection;
55 27514 cmartinez
import org.cresques.cts.UTM;
56 21200 vcaballero
import org.gvsig.fmap.crs.CRSFactory;
57 27414 jpiera
import org.gvsig.fmap.geom.GeometryLocator;
58
import org.gvsig.fmap.geom.GeometryManager;
59
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
60
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
61 21426 vcaballero
import org.gvsig.fmap.geom.primitive.Envelope;
62 27019 jpiera
import org.gvsig.fmap.geom.util.UtilFunctions;
63 21200 vcaballero
import org.gvsig.fmap.mapcontext.events.ColorEvent;
64
import org.gvsig.fmap.mapcontext.events.ExtentEvent;
65
import org.gvsig.fmap.mapcontext.events.ProjectionEvent;
66
import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener;
67 27414 jpiera
import org.slf4j.Logger;
68
import org.slf4j.LoggerFactory;
69 21200 vcaballero
70
import com.iver.utiles.StringUtilities;
71
import com.iver.utiles.XMLEntity;
72
73
/**
74 29519 jtorres
 * <p>
75
 * <code>ViewPort</code> class represents the logic needed to transform a
76
 * rectangular area of a map to the available area in screen to display it.
77
 * </p>
78
 *
79
 * <p>
80
 * Includes an affine transformation, between the rectangular area selected of
81
 * the external map, in its own <i>map coordinates</i>, to the rectangular area
82
 * available of a view in <i>screen coordinates</i>.
83
 * </p>
84
 *
85
 * <p>
86
 * Elements:
87 21200 vcaballero
 * <ul>
88
 * <li><i>extent</i>: the area selected of the map, in <i>map coordinates</i>.
89 29519 jtorres
 * <li><i>imageSize</i>: width and height in pixels (<i>screen coordinates</i>)
90
 * of the area available in screen to display the area selected of the map.
91
 * <li><i>adjustedExtent</i>: the area selected must be an scale of
92
 * <i>imageSize</i>.<br>
93
 * This implies adapt the extent, preserving and centering it, and adding around
94
 * the needed area to fill all the image size. That added area will be extracted
95
 * from the original map, wherever exists, and filled with the background color
96
 * wherever not.
97 21200 vcaballero
 * <li><i>scale</i>: the scale between the adjusted extent and the image size.
98 29519 jtorres
 * <li><i>backColor</i>: the default background color in the view, if there is
99
 * no map.
100 21200 vcaballero
 * <li><i>trans</i>: the affine transformation.
101
 * <li><i>proj</i>: map projection used in this view.
102
 * <li><i>distanceUnits</i>: distance measurement units, of data in screen.
103
 * <li><i>mapUnits</i>: measurement units, of data in map.
104 29519 jtorres
 * <li><i>extents</i>: an {@link ExtentHistory ExtentHistory} with the last
105
 * previous extents.
106
 * <li><i>offset</i>: position in pixels of the available rectangular area,
107
 * where start drawing the map.
108
 * <li><i>dist1pixel</i>: the distance in <i>world coordinates</i> equivalent to
109
 * 1 pixel in the view with the current extent.
110
 * <li><i>dist3pixel</i>: the distance in <i>world coordinates</i> equivalent to
111
 * 3 pixels in the view with the current extent.
112
 * <li><i>listeners</i>: list with the {@link ViewPortListener ViewPortListener}
113
 * registered.
114 21200 vcaballero
 * </ul>
115
 * </p>
116 29519 jtorres
 *
117 21200 vcaballero
 * @author Vicente Caballero Navarro
118
 */
119
public class ViewPort {
120 29519 jtorres
        // /**
121
        // * <p>Metric unit or length equal to 1000 meters.</p>
122
        // */
123
        // public static int KILOMETROS = 0;
124
        //
125
        // /**
126
        // * <p>The base unit of length in the International System of Units that is
127
        // equal to the distance
128
        // * traveled by light in a vacuum in {frac;1;299,792,458} second or to
129
        // about 39.37 inches.</p>
130
        // */
131
        // public static int METROS = 1;
132
        //
133
        // /**
134
        // * <p>Metric unit or length equal to 0'01 meters.</p>
135
        // */
136
        // public static int CENTIMETRO = 2;
137
        //
138
        // /**
139
        // * <p>Metric unit or length equal to 0'001 meters.</p>
140
        // */
141
        // public static int MILIMETRO = 3;
142
        //
143
        // /**
144
        // * <p>The international statute mile by international agreement. It is
145
        // defined to be precisely
146
        // * 1,760 international yards (by definition, 0.9144 m each) and is
147
        // therefore exactly 1,609.344
148
        // * metres (1.609344 km).</p>
149
        // */
150
        // public static int MILLAS = 4;
151
        //
152
        // /**
153
        // * <p>Unit of length equal in the United States to 0.9144 meter.</p>
154
        // */
155
        // public static int YARDAS = 5;
156
        //
157
        // /**
158
        // * <p>Any of various units of length based on the length of the human
159
        // foot; especially :
160
        // * a unit equal to 1/3 yard and comprising 12 inches.</p>
161
        // */
162
        // public static int PIES = 6;
163
        //
164
        // /**
165
        // * <p>Unit of length equal to 1/36 yard.</p>
166
        // */
167
        // public static int PULGADAS = 7;
168
        //
169
        // /**
170
        // * <p>Grades according the current projection.</p>
171
        // */
172
        // public static int GRADOS = 8;
173
        private static final GeometryManager geomManager = GeometryLocator
174
                        .getGeometryManager();
175
        private static final Logger logger = LoggerFactory
176
                        .getLogger(GeometryManager.class);
177
178 21200 vcaballero
        /**
179 29519 jtorres
         * <p>
180
         * Screen resolution in <i>dots-per-inch</i>. Useful to calculate the
181
         * geographic scale of the view.
182
         * </p>
183
         *
184 21200 vcaballero
         * @see Toolkit#getScreenResolution()
185
         * @see #getScale()
186
         */
187
        private static int dpi = java.awt.Toolkit.getDefaultToolkit()
188 29519 jtorres
                        .getScreenResolution();
189 21200 vcaballero
190
        /**
191 29519 jtorres
         * <p>
192
         * Area selected by user using some tool.
193 21200 vcaballero
         * </p>
194 29519 jtorres
         *
195 21200 vcaballero
         * <p>
196 29519 jtorres
         * When the zoom changes (for instance when using the zoom in or zoom out
197
         * tools, but also zooming to a selected feature or shape) the extent that
198
         * covers that area is the value returned by this method. It is not the
199
         * actual area shown in the view because it does not care about the aspect
200
         * ratio of the available area. However, any part of the real world
201
         * contained in this extent is shown in the view.
202 21200 vcaballero
         * </p>
203 29519 jtorres
         * <p>
204
         * Probably this is not what you are looking for. If you are looking for the
205
         * complete extent currently shown, you must use
206
         * {@linkplain #getAdjustedExtent()} method which returns the extent that
207
         * contains this one but regarding the current view's aspect ratio.
208
         * </p>
209
         *
210 21200 vcaballero
         * @see #getExtent()
211 21426 vcaballero
         * @see #setEnvelope(Envelope)
212 21200 vcaballero
         */
213
        protected Rectangle2D extent;
214
215
        /**
216 29519 jtorres
         * <p>
217
         * Location and dimensions of the extent adjusted to the image size.
218
         * </p>
219
         *
220 21200 vcaballero
         * @see #getAdjustedExtent()
221
         */
222
        protected Rectangle2D adjustedExtent;
223
224
        /**
225 29519 jtorres
         * Draw version of the context. It's used for know when de componend has
226
         * changed any visualization property
227
         *
228
         * @see getDrawVersion
229
         * @see updateDrawVersion
230
         */
231
        private long drawVersion = 0L;
232
233
        /**
234
         * <p>
235
         * History with the last extents of the view.
236
         * </p>
237
         *
238 21200 vcaballero
         * @see #setPreviousExtent()
239
         * @see #getExtents()
240
         */
241
        protected ExtentHistory extents = new ExtentHistory();
242
243
        /**
244 29519 jtorres
         * <p>
245
         * Size in <i>screen coordinates</i> of the rectangle where the image is
246
         * displayed.
247
         * </p>
248
         * <p>
249
         * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
250
         *
251 21200 vcaballero
         * <ul>
252
         * <li>The new {@link #scale scale} .
253
         * <li>The new {@link #adjustedExtent adjustableExtent} .
254
         * <li>The new {@link #trans trans} .
255 29519 jtorres
         * <li>The new real world coordinates equivalent to 1 pixel (
256
         * {@link #dist1pixel dist1pixel}) .
257
         * <li>The new real world coordinates equivalent to 3 pixels (
258
         * {@link #dist3pixel dist3pixel}) .
259 21200 vcaballero
         * </ul>
260
         * </p>
261 29519 jtorres
         *
262 21200 vcaballero
         * @see #getImageSize()
263
         * @see #getImageHeight()
264
         * @see #getImageWidth()
265
         * @see #setImageSize(Dimension)
266
         */
267
        private Dimension imageSize;
268
269
        /**
270 29519 jtorres
         * <p>
271
         * the affine transformation between the {@link #extent extent} in <i>map 2D
272
         * coordinates</i> to the image area in the screen, in <i>screen 2D
273
         * coordinates</i> (pixels).
274
         * </p>
275
         *
276 21200 vcaballero
         * @see AffineTransform
277 29519 jtorres
         *
278 21200 vcaballero
         * @see #getAffineTransform()
279
         * @see #setAffineTransform(AffineTransform)
280
         * @see #calculateAffineTransform()
281
         */
282
        private AffineTransform trans = new AffineTransform();
283
284
        /**
285 29519 jtorres
         * <p>
286
         * Measurement unit used for measuring distances and displaying information.
287
         * </p>
288
         *
289 21200 vcaballero
         * @see #getDistanceUnits()
290
         * @see #setDistanceUnits(int)
291
         */
292
        private int distanceUnits = 1;
293
        /**
294 29519 jtorres
         * <p>
295
         * Measurement unit used for measuring areas and displaying information.
296
         * </p>
297
         *
298 21200 vcaballero
         * @see #getDistanceArea()
299
         * @see #setDistanceArea(int)
300
         */
301
        private int distanceArea = 1;
302
        /**
303 29519 jtorres
         * <p>
304
         * Measurement unit used by this view port for the map.
305
         * </p>
306
         *
307 21200 vcaballero
         * @see #getMapUnits()
308
         * @see #setMapUnits(int)
309
         */
310
        private int mapUnits = 1;
311
312
        /**
313 29519 jtorres
         * <p>
314
         * Array with the {@link ViewPortListener ViewPortListener}s registered to
315
         * this view port.
316
         * </p>
317
         *
318 21200 vcaballero
         * @see #addViewPortListener(ViewPortListener)
319
         * @see #removeViewPortListener(ViewPortListener)
320
         */
321
        private ArrayList listeners = new ArrayList();
322
323
        /**
324 29519 jtorres
         * <p>
325
         * The offset is the position where start drawing the map.
326
         * </p>
327
         * <p>
328
         * The offset of a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
329
         * <i>View</i> is always (0, 0) because the drawing area fits with the full
330
         * window area. But in a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
331
         * <i>Layout</i> it's up to the place where the <code>FFrameView</code> is
332
         * located.
333
         * </p>
334
         *
335 21200 vcaballero
         * @see #getOffset()
336
         * @see #setOffset(Point2D)
337
         */
338
        private Point2D offset = new Point2D.Double(0, 0);
339
340
        /**
341 29519 jtorres
         * <p>
342
         * Clipping area.
343
         * </p>
344 21200 vcaballero
         */
345
        private Rectangle2D clip;
346
347
        /**
348 29519 jtorres
         * <p>
349
         * Background color of this view.
350
         * </p>
351
         *
352 21200 vcaballero
         * @see #getBackColor()
353
         * @see #setBackColor(Color)
354
         */
355 29519 jtorres
        private Color backColor = null; // Color.WHITE;
356 21200 vcaballero
357
        /**
358 29519 jtorres
         * <p>
359
         * Information about the map projection used in this view.
360
         * </p>
361
         *
362 21200 vcaballero
         * @see #getProjection()
363
         * @see #setProjection(IProjection)
364
         */
365
        private IProjection proj;
366
367
        /**
368 29519 jtorres
         * <p>
369
         * Represents the distance in <i>world coordinates</i> equivalent to 1 pixel
370
         * in the view with the current extent.
371
         * </p>
372
         *
373 21200 vcaballero
         * @see #getDist1pixel()
374
         * @see #setDist1pixel(double)
375
         */
376
        private double dist1pixel;
377
378
        /**
379 29519 jtorres
         * <p>
380
         * Represents the distance in <i>world coordinates</i> equivalent to 3
381
         * pixels in the view with the current extent.
382
         * </p>
383
         *
384 21200 vcaballero
         * @see #getDist3pixel()
385
         * @see #setDist3pixel(double)
386
         */
387
        private double dist3pixel;
388
389
        /**
390 29519 jtorres
         * <p>
391
         * Ratio between the size of <code>imageSize</code> and <code>extent</code>:
392
         * <br>
393
         * <i>
394
         *
395
         * <pre>
396
         * min{(imageSize.getHeight()/extent.getHeight(), imageSize.getWidth()/extent.getWidth())}
397
         * </pre>
398
         *
399
         * </i>
400
         * </p>
401 21200 vcaballero
         */
402
        private double scale;
403
404
        /**
405 29519 jtorres
         * <p>
406
         * Clipping area.
407
         * </p>
408
         *
409 21200 vcaballero
         * @see #setClipRect(Rectangle2D)
410
         */
411
        private Rectangle2D cliprect;
412
413
        /**
414
         * <p>
415 29519 jtorres
         * Enables or disables the <i>"adjustable extent"</i> mode.
416
         * </p>
417
         *
418
         * <p>
419 21200 vcaballero
         * When calculates the affine transform, if
420
         * <ul>
421 29519 jtorres
         * <li><i>enabled</i>: the new <code>adjustedExtent</code> will have the (X,
422
         * Y) coordinates of the <code>extent</code> and an area that will be an
423
         * scale of the image size. That area will have different height or width
424
         * (not both) of the extent according the least ratio (height or width) in
425
         *
426
         * <pre>
427
         * image.size/extent.size&quot;
428
         * </pre>.
429
         * <li><i>disabled</i>: the new <code>adjustedExtent</code> will be like
430
         * <code>extent</code>.
431 21200 vcaballero
         * </ul>
432
         * </p>
433 29519 jtorres
         *
434 21200 vcaballero
         * @see #setAdjustable(boolean)
435
         */
436 29519 jtorres
        private boolean adjustableExtent = true;
437 21200 vcaballero
438
        /**
439
         * <p>
440 29519 jtorres
         * Creates a new view port with the information of the projection in
441
         * <code>proj</code> argument, and default configuration:
442
         * </p>
443
         * <p>
444 21200 vcaballero
         * <ul>
445 29519 jtorres
         * <li><i><code>distanceUnits</code></i> = meters
446
         * <li><i><code>mapUnits</code></i> = meters
447
         * <li><i><code>backColor</code></i> = <i>undefined</i>
448
         * <li><i><code>offset</code></i> = <code>new Point2D.Double(0, 0);</code>
449 21200 vcaballero
         * </ul>
450
         * </p>
451 29519 jtorres
         *
452
         * @param proj
453
         *            information of the projection for this view port
454 21200 vcaballero
         */
455
        public ViewPort(IProjection proj) {
456
                // Por defecto
457
                this.proj = proj;
458
        }
459
460
        /**
461 29519 jtorres
         * <p>
462
         * Changes the status of the <i>"adjustable extent"</i> option to enabled or
463
         * disabled.
464
         * </p>
465
         *
466
         * <p>
467
         * If view port isn't adjustable, won't bear in mind the aspect ratio of the
468
         * available rectangular area to calculate the affine transform from the
469
         * original map in real coordinates. (Won't scale the image to adapt it to
470
         * the available rectangular area).
471
         * </p>
472
         *
473 21200 vcaballero
         * @param boolean the boolean to be set
474
         */
475
        public void setAdjustable(boolean adjustable) {
476 29519 jtorres
                if (adjustable == adjustableExtent) {
477
                        return;
478 26225 jmvivo
                }
479 21200 vcaballero
                adjustableExtent = adjustable;
480 29519 jtorres
                this.updateDrawVersion();
481 21200 vcaballero
        }
482
483
        /**
484 29519 jtorres
         * <p>
485
         * Appends the specified {@link ViewPortListener ViewPortListener} listener
486
         * if weren't.
487
         * </p>
488
         *
489
         * @param arg0
490
         *            the listener to add
491
         *
492 21200 vcaballero
         * @return <code>true</code> if has been added successfully
493 29519 jtorres
         *
494 21200 vcaballero
         * @see #removeViewPortListener(ViewPortListener)
495
         */
496
        public boolean addViewPortListener(ViewPortListener arg0) {
497 26905 jmvivo
                if (!listeners.contains(arg0)) {
498 21200 vcaballero
                        return listeners.add(arg0);
499 26905 jmvivo
                }
500 21200 vcaballero
                return false;
501
        }
502
503
        /**
504 29519 jtorres
         * <p>
505
         * Removes the specified {@link ViewPortListener ViewPortListener} listener,
506
         * if existed.
507
         * </p>
508
         *
509
         * @param arg0
510
         *            the listener to remove
511
         *
512 21200 vcaballero
         * @return <code>true</code> if the contained the specified listener.
513 29519 jtorres
         *
514 21200 vcaballero
         * @see #addViewPortListener(ViewPortListener)
515
         */
516
        public boolean removeViewPortListener(ViewPortListener arg0) {
517
                return listeners.remove(arg0);
518
        }
519
520
        /**
521 29519 jtorres
         * <p>
522
         * Converts and returns the distance <code>d</code>, that is in <i>map
523
         * coordinates</i> to <i>screen coordinates</i> using a <i>delta
524
         * transform</i> with the transformation affine information in the
525
         * {@link #trans #trans} attribute.
526
         * </p>
527
         *
528
         * @param d
529
         *            distance in <i>map coordinates</i>
530
         *
531 21200 vcaballero
         * @return distance equivalent in <i>screen coordinates</i>
532 29519 jtorres
         *
533 21200 vcaballero
         * @see #toMapDistance(int)
534
         * @see AffineTransform#deltaTransform(Point2D, Point2D)S
535
         */
536
        public int fromMapDistance(double d) {
537
                Point2D.Double pWorld = new Point2D.Double(1, 1);
538
                Point2D.Double pScreen = new Point2D.Double();
539
540
                try {
541
                        trans.deltaTransform(pWorld, pScreen);
542
                } catch (Exception e) {
543
                        System.err.print(e.getMessage());
544
                }
545
546
                return (int) (d * pScreen.x);
547
        }
548
549
        /**
550 29519 jtorres
         * <p>
551
         * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>map
552
         * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
553
         * transformation in the {@link #trans #trans} attribute.
554
         * </p>
555
         *
556
         * @param x
557
         *            the <code>x</code> <i>map coordinate</i> of a 2D point
558
         * @param y
559
         *            the <code>y</code> <i>map coordinate</i> of a 2D point
560
         *
561 21200 vcaballero
         * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
562 29519 jtorres
         *
563 21200 vcaballero
         * @see #fromMapPoint(Point2D)
564
         * @see AffineTransform#transform(Point2D, Point2D)
565
         */
566
        public Point2D fromMapPoint(double x, double y) {
567
                Point2D.Double pWorld = new Point2D.Double(x, y);
568
                Point2D.Double pScreen = new Point2D.Double();
569
570
                try {
571
                        trans.transform(pWorld, pScreen);
572
                } catch (Exception e) {
573
                        System.err.print(e.getMessage());
574
                }
575
576
                return pScreen;
577
        }
578
579
        /**
580 29519 jtorres
         * <p>
581
         * Converts and returns the 2D point argument, that is in <i>map
582
         * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
583
         * transformation in the {@link #trans #trans} attribute.
584
         * </p>
585
         *
586
         * @param point
587
         *            the 2D point in <i>map coordinates</i>
588
         *
589 21200 vcaballero
         * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
590 29519 jtorres
         *
591 21200 vcaballero
         * @see #toMapPoint(Point2D)
592
         * @see #fromMapPoint(double, double)
593
         */
594
        public Point2D fromMapPoint(Point2D point) {
595
                return fromMapPoint(point.getX(), point.getY());
596
        }
597
598
        /**
599 29519 jtorres
         * <p>
600
         * Converts and returns the 2D point <code>(x,y)</code>, that is in
601
         * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using the
602
         * affine transformation in the {@link #trans #trans} attribute.
603
         * </p>
604
         *
605
         * @param x
606
         *            the <code>x</code> <i>screen coordinate</i> of a 2D point
607
         * @param y
608
         *            the <code>y</code> <i>screen coordinate</i> of a 2D point
609
         *
610 21200 vcaballero
         * @return 2D point equivalent in <i>map coordinates</i>
611 29519 jtorres
         *
612 21200 vcaballero
         * @see #toMapPoint(Point2D)
613
         * @see #fromMapPoint(double, double)
614
         */
615
        public Point2D toMapPoint(int x, int y) {
616 29279 jldominguez
                Point2D pScreen = new Point2D.Double(x, y);
617 21200 vcaballero
618
                return toMapPoint(pScreen);
619
        }
620
621
        /**
622 29519 jtorres
         * <p>
623
         * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
624
         * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using
625
         * {@linkplain #toMapDistance(int)}, and {@linkplain #toMapPoint(int, int)}.
626
         * </p>
627
         *
628
         * @param r
629
         *            the 2D rectangle in <i>screen coordinates</i> (pixels)
630 21200 vcaballero
         * @return 2D rectangle equivalent in <i>map coordinates</i>
631 29519 jtorres
         *
632 21200 vcaballero
         * @see #fromMapRectangle(Rectangle2D)
633
         * @see #toMapDistance(int)
634
         * @see #toMapPoint(int, int)
635
         */
636 29519 jtorres
        public Rectangle2D toMapRectangle(Rectangle2D r) {
637
                Rectangle2D rect = new Rectangle2D.Double();
638
                Point2D p1 = toMapPoint((int) r.getX(), (int) r.getY());
639
                Point2D p2 = toMapPoint((int) r.getMaxX(), (int) r.getMaxY());
640
                rect.setFrameFromDiagonal(p1, p2);
641 21200 vcaballero
                return rect;
642
        }
643
644
        /**
645 29519 jtorres
         * <p>
646
         * Converts and returns the distance <code>d</code>, that is in <i>screen
647
         * coordinates</i> to <i>map coordinates</i> using the transformation affine
648
         * information in the {@link #trans #trans} attribute.
649
         * </p>
650
         *
651
         * @param d
652
         *            distance in pixels
653
         *
654 21200 vcaballero
         * @return distance equivalent in <i>map coordinates</i>
655 29519 jtorres
         *
656 21200 vcaballero
         * @see #fromMapDistance(double)
657
         * @see AffineTransform
658
         */
659
        public double toMapDistance(int d) {
660
                double dist = d / trans.getScaleX();
661
662
                return dist;
663
        }
664
665
        /**
666 29519 jtorres
         * <p>
667
         * Converts and returns the 2D point argument, that is in <i>screen
668
         * coordinates</i> (pixels) to <i>map coordinates</i> using the inverse
669
         * affine transformation of the {@link #trans #trans} attribute.
670
         * </p>
671
         *
672
         * @param pScreen
673
         *            the 2D point in <i>screen coordinates</i> (pixels)
674
         *
675 21200 vcaballero
         * @return 2D point equivalent in <i>map coordinates</i>
676 29519 jtorres
         *
677 21200 vcaballero
         * @see #toMapPoint(int, int)
678
         * @see AffineTransform#createInverse()
679
         * @see AffineTransform#transform(Point2D, Point2D)
680
         */
681
        public Point2D toMapPoint(Point2D pScreen) {
682
                Point2D.Double pWorld = new Point2D.Double();
683
                AffineTransform at;
684
685
                try {
686
                        at = trans.createInverse();
687
                        at.transform(pScreen, pWorld);
688
                } catch (NoninvertibleTransformException e) {
689 29519 jtorres
                        throw new RuntimeException("Non invertible transform Exception", e);
690 21200 vcaballero
                }
691
692
                return pWorld;
693
        }
694
695
        /**
696 29519 jtorres
         * <p>
697
         * Returns the real distance (in <i>world coordinates</i>) at the graphic
698
         * layers of two 2D points (in <i>map coordinates</i>) of the plane where is
699
         * selected the <i>extent</i>.
700
         * </p>
701
         * <p>
702
         * If the projection of this view is UTM, considers the Earth curvature.
703
         * </p>
704
         *
705
         * @param pt1
706
         *            a 2D point in <i>map coordinates</i>
707
         * @param pt2
708
         *            another 2D point in <i>map coordinates</i>
709
         *
710 21200 vcaballero
         * @return the distance in meters between the two points 2D
711 29519 jtorres
         *
712 27514 cmartinez
         * @see GeoCalcImpl#distanceVincenty(Point2D, Point2D)
713 21200 vcaballero
         */
714
        public double distanceWorld(Point2D pt1, Point2D pt2) {
715
                double dist = -1;
716
                dist = pt1.distance(pt2);
717
718 27514 cmartinez
                if ((proj != null) && !(proj instanceof UTM)) {
719 29519 jtorres
                        dist = new GeoCalc(proj).distanceVincenty(proj.toGeo(pt1), proj
720
                                        .toGeo(pt2));
721 21200 vcaballero
                        return dist;
722
                }
723 29519 jtorres
                return (dist * MapContext.getDistanceTrans2Meter()[getMapUnits()]);
724 21200 vcaballero
        }
725
726
        /**
727 29519 jtorres
         * <p>
728
         * Sets as extent and adjusted extent of this view port, the previous.
729
         * Recalculating its parameters.
730
         * </p>
731
         *
732 21200 vcaballero
         * @see #getExtents()
733
         * @see #calculateAffineTransform()
734 29503 jpiera
         * @deprecated use {@link ViewPort#setPreviousEnvelope()}
735 21200 vcaballero
         */
736
        public void setPreviousExtent() {
737 29503 jpiera
                setPreviousEnvelope();
738
        }
739 29519 jtorres
740 29503 jpiera
        /**
741 29519 jtorres
         * <p>
742
         * Sets as envelope and adjusted envelope of this view port, the previous.
743
         * Recalculating its parameters.
744
         * </p>
745
         *
746 29503 jpiera
         * @see #getExtents()
747
         * @see #calculateAffineTransform()
748
         */
749
        public void setPreviousEnvelope() {
750 26225 jmvivo
                this.updateDrawVersion();
751 21200 vcaballero
                extent = extents.removePrev();
752
753 29519 jtorres
                // Calcula la transformaci�n af�n
754 21200 vcaballero
                calculateAffineTransform();
755
756
                // Lanzamos los eventos de extent cambiado
757
                callExtentChanged(getAdjustedExtent());
758
        }
759
760
        /**
761 29519 jtorres
         * <p>
762
         * Gets the area selected by user using some tool.
763
         * </p>
764
         *
765
         * <p>
766
         * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
767
         * out</i> tools, but also zooming to a selected feature or shape) the
768
         * extent that covers that area is the value returned by this method. It is
769
         * not the actual area shown because it doesn't care about the aspect ratio
770
         * of the image size of the view. However, any part of the real world
771
         * contained in this extent is shown in the view.
772
         * </p>
773
         *
774
         * <p>
775
         * If you are looking for the complete extent currently shown, you must use
776
         * the {@linkplain #getAdjustedExtent()} method.
777
         * </p>
778
         *
779 21200 vcaballero
         * @return the current extent
780 29519 jtorres
         *
781 21426 vcaballero
         * @see #setEnvelope(Envelope)
782 21200 vcaballero
         * @see #getAdjustedExtent()
783
         * @see #setPreviousExtent()
784
         * @see #getExtents()
785 29503 jpiera
         *
786
         * @deprecated use {@link ViewPort#getEnvelope()}
787 21200 vcaballero
         */
788
        public Rectangle2D getExtent() {
789
                return extent;
790
        }
791 29519 jtorres
792 29503 jpiera
        /**
793 29519 jtorres
         * <p>
794
         * Gets the envelope selected by user using some tool.
795
         * </p>
796
         *
797
         * <p>
798
         * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
799
         * out</i> tools, but also zooming to a selected feature or shape) the
800
         * envelope that covers that area is the value returned by this method. It
801
         * is not the actual envelope shown because it doesn't care about the aspect
802
         * ratio of the image size of the view. However, any part of the real world
803
         * contained in this envelope is shown in the view.
804
         * </p>
805
         *
806
         * <p>
807
         * If you are looking for the complete extent currently shown, you must use
808
         * the {@linkplain #getAdjustedEnvelope()} method.
809
         * </p>
810
         *
811 29503 jpiera
         * @return the current envelope
812 29519 jtorres
         *
813 29503 jpiera
         * @see #setEnvelope(Envelope)
814
         * @see #getAdjustedEnvelope()
815
         * @see #setPreviousEnvelope()
816
         * @see #getEnvelopes()
817
         */
818 29519 jtorres
        public Envelope getEnvelope() {
819 29503 jpiera
                try {
820 29519 jtorres
                        return geomManager.createEnvelope(extent.getMinX(), extent
821
                                        .getMinY(), extent.getMaxX(), extent.getMaxY(),
822 29503 jpiera
                                        SUBTYPES.GEOM2D);
823 29519 jtorres
                        // This class has to use Envelope instead of Rectangle2D. This catch
824
                        // will disappear
825 29503 jpiera
                } catch (CreateEnvelopeException e) {
826 29519 jtorres
                        logger.error("Error creating the envelope");
827 29503 jpiera
                }
828
                return null;
829
        }
830 21200 vcaballero
831
        /**
832 29519 jtorres
         * <p>
833
         * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
834 21200 vcaballero
         * <ul>
835
         * <li>Stores the previous extent.
836
         * <li>Calculates the new extent using <code>r</code>:
837 29519 jtorres
         *
838
         * <pre>
839
         * extent = new Rectangle2D.Double(r.getMinX() - 0.1, r.getMinY() - 0.1, r
840
         *                 .getWidth() + 0.2, r.getHeight() + 0.2);
841
         * </pre>
842
         *
843
         * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
844
         * scale, adjusted extent, affine transformation between map and screen
845
         * coordinates, the real world coordinates equivalent to 1 pixel, and the
846
         * real world coordinates equivalent to 3 pixels.
847
         * <li>Notifies all {@link ViewPortListener ViewPortListener} registered
848
         * that the extent has changed.
849 21200 vcaballero
         * </ul>
850
         * </p>
851 29519 jtorres
         *
852
         * @param r
853
         *            the new extent
854
         *
855 21200 vcaballero
         * @see #getExtent()
856
         * @see #getExtents()
857
         * @see #calculateAffineTransform()
858
         * @see #setPreviousExtent()
859
         */
860 21426 vcaballero
        public void setEnvelope(Envelope r) {
861 29519 jtorres
                Rectangle2D newExtent = null;
862
                // Esto comprueba que el extent no es de anchura o altura = "0"
863
                // y si es as� lo redimensiona.
864
                if (r != null) {
865 26905 jmvivo
                        if ((r.getMaximum(0) - r.getMinimum(0) == 0)
866
                                        || (r.getMaximum(1) - r.getMinimum(1) == 0)) {
867 29519 jtorres
                                newExtent = new Rectangle2D.Double(r.getMinimum(0) - 0.1, r
868
                                                .getMinimum(1) - 0.1, r.getMaximum(0) - r.getMinimum(0)
869
                                                + 0.2, r.getMaximum(1) - r.getMinimum(1) + 0.2);
870 26905 jmvivo
                        } else {
871 29519 jtorres
                                newExtent = new Rectangle2D.Double(r.getMinimum(0), r
872
                                                .getMinimum(1), Math.abs(r.getMaximum(0)
873
                                                - r.getMinimum(0)), Math.abs(r.getMaximum(1)
874
                                                - r.getMinimum(1)));
875 26905 jmvivo
                        }
876 21200 vcaballero
                }
877
878 29519 jtorres
                if (this.extent != null && this.extent.equals(newExtent)) {
879 26225 jmvivo
                        return;
880
                }
881
                if (extent != null) {
882
                        extents.put(extent);
883
                }
884
                this.updateDrawVersion();
885
                this.extent = newExtent;
886 26905 jmvivo
887 29519 jtorres
                // Calcula la transformaci�n af�n
888 21200 vcaballero
                calculateAffineTransform();
889
890
                // Lanzamos los eventos de extent cambiado
891
                callExtentChanged(getAdjustedExtent());
892
        }
893
894
        /**
895 29519 jtorres
         * <p>
896
         * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
897 21200 vcaballero
         * <ul>
898 29519 jtorres
         * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
899
         * scale, adjusted extent, affine transformation between map and screen
900
         * coordinates, the real world coordinates equivalent to 1 pixel, and the
901
         * real world coordinates equivalent to 3 pixels.
902
         * <li>Notifies to all {@link ViewPortListener ViewPortListener} registered
903
         * that the extent has changed.
904 21200 vcaballero
         * </ul>
905
         * </p>
906 29519 jtorres
         *
907 21426 vcaballero
         * @see #setEnvelope(Envelope)
908 21200 vcaballero
         * @see #calculateAffineTransform()
909
         */
910
        public void refreshExtent() {
911 29519 jtorres
                // this.scale = scale;
912 21200 vcaballero
913 29519 jtorres
                // Calcula la transformaci�n af�n
914 21200 vcaballero
                calculateAffineTransform();
915
916
                // Lanzamos los eventos de extent cambiado
917
                callExtentChanged(getAdjustedExtent());
918
        }
919
920
        /**
921 29519 jtorres
         * <p>
922
         * Calculates and returns using the current projection of this view port,
923
         * the scale that is the extent in <i>screen coordinates</i> from the image
924
         * in <i>map coordinates</i>.
925
         * </p>
926
         *
927 21200 vcaballero
         * @return the scale <i>extent / image size</i> projected by this view port
928 29519 jtorres
         *
929 21200 vcaballero
         * @deprecated since 07/09/07, use {@linkplain MapContext#getScaleView()}
930
         */
931
        public double getScale() {
932
                return proj.getScale(extent.getMinX(), extent.getMaxX(),
933 29519 jtorres
                                imageSize.width, dpi);
934 21200 vcaballero
        }
935
936
        /**
937 29519 jtorres
         * <p>
938
         * Affine transformation between <i>map 2D coordinates</i> to <i>screen 2D
939
         * coordinates</i> (pixels), preserving the "straightness" and "parallelism"
940
         * of the lines.
941
         * </p>
942
         *
943 21200 vcaballero
         * @return the affine transformation
944 29519 jtorres
         *
945 21200 vcaballero
         * @see #setAffineTransform(AffineTransform)
946
         * @see #calculateAffineTransform()
947
         */
948
        public AffineTransform getAffineTransform() {
949
                return trans;
950
        }
951
952
        /**
953 29519 jtorres
         * <p>
954
         * Returns the size of the image projected.
955
         * </p>
956
         *
957 21200 vcaballero
         * @return the image size
958 29519 jtorres
         *
959 21200 vcaballero
         * @see #setImageSize(Dimension)
960
         * @see #getImageHeight()
961
         * @see #getImageWidth()
962
         */
963
        public Dimension getImageSize() {
964
                return imageSize;
965
        }
966
967
        /**
968 29519 jtorres
         * <p>
969
         * Sets the size of the image projected, recalculating the parameters of
970
         * this view port.
971
         * </p>
972
         *
973
         * @param imageSize
974
         *            the image size
975
         *
976 21200 vcaballero
         * @see #getImageSize()
977
         * @see #calculateAffineTransform()
978
         */
979
        public void setImageSize(Dimension imageSize) {
980 26225 jmvivo
981 29519 jtorres
                if (this.imageSize == null || (!this.imageSize.equals(imageSize))) {
982
                        this.updateDrawVersion();
983
                        this.imageSize = imageSize;
984
                        calculateAffineTransform();
985 26225 jmvivo
                }
986 21200 vcaballero
        }
987
988
        /**
989 29519 jtorres
         * <p>
990
         * Notifies to all view port listeners registered, that the adjusted extent
991
         * of this view port has changed.
992
         * </p>
993
         *
994
         * @param newRect
995
         *            the new adjusted extend
996
         *
997 21200 vcaballero
         * @see #refreshExtent()
998 21426 vcaballero
         * @see #setEnvelope(Envelope)
999 21200 vcaballero
         * @see #setPreviousExtent()
1000
         * @see ExtentEvent
1001
         * @see ViewPortListener
1002
         */
1003 21531 vcaballero
        protected void callExtentChanged(Envelope newRect) {
1004 21200 vcaballero
                ExtentEvent ev = ExtentEvent.createExtentEvent(newRect);
1005
1006
                for (int i = 0; i < listeners.size(); i++) {
1007
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
1008
                        listener.extentChanged(ev);
1009
                }
1010
        }
1011
1012
        /**
1013 29519 jtorres
         * <p>
1014
         * Notifies to all view port listeners registered, that the background color
1015
         * of this view port has changed.
1016
         * </p>
1017
         *
1018
         * @param c
1019
         *            the new background color
1020
         *
1021 21200 vcaballero
         * @see #setBackColor(Color)
1022
         * @see ColorEvent
1023
         * @see ViewPortListener
1024
         */
1025
        private void callColorChanged(Color c) {
1026
                ColorEvent ce = ColorEvent.createColorEvent(c);
1027
1028
                for (int i = 0; i < listeners.size(); i++) {
1029
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
1030
                        listener.backColorChanged(ce);
1031
                }
1032
        }
1033
1034
        /**
1035 29519 jtorres
         * <p>
1036
         * Notifies to all view port listeners registered, that the projection of
1037
         * this view port has changed.
1038
         * </p>
1039
         *
1040
         * @param projection
1041
         *            the new projection
1042
         *
1043 21200 vcaballero
         * @see #setProjection(IProjection)
1044
         * @see ProjectionEvent
1045
         * @see ViewPortListener
1046
         */
1047
        private void callProjectionChanged(IProjection projection) {
1048
                ProjectionEvent ev = ProjectionEvent.createProjectionEvent(projection);
1049
1050
                for (int i = 0; i < listeners.size(); i++) {
1051
                        ViewPortListener listener = (ViewPortListener) listeners.get(i);
1052
                        listener.projectionChanged(ev);
1053
                }
1054
        }
1055
1056
        /**
1057 29519 jtorres
         * <p>
1058
         * Calculates the affine transformation between the {@link #extent extent}
1059
         * in <i>map 2D coordinates</i> to the image area in the screen, in
1060
         * <i>screen 2D coordinates</i> (pixels).
1061
         * </p>
1062
         *
1063
         * <p>
1064
         * This process recalculates some parameters of this view port:<br>
1065
         *
1066 21200 vcaballero
         * <ul>
1067
         * <li>The new {@link #scale scale} .
1068
         * <li>The new {@link #adjustedExtent adjustedExtent} .
1069
         * <li>The new {@link #trans trans} .
1070 29519 jtorres
         * <li>The new real world coordinates equivalent to 1 pixel (
1071
         * {@link #dist1pixel dist1pixel}) .
1072
         * <li>The new real world coordinates equivalent to 3 pixels (
1073
         * {@link #dist3pixel dist3pixel}) .
1074 21200 vcaballero
         * </ul>
1075
         * </p>
1076 29519 jtorres
         *
1077 21200 vcaballero
         * @see #getAffineTransform()
1078
         * @see #setAffineTransform(AffineTransform)
1079
         * @see #refreshExtent()
1080 21426 vcaballero
         * @see #setEnvelope(Envelope)
1081 21200 vcaballero
         * @see #setImageSize(Dimension)
1082
         * @see #setPreviousExtent()
1083
         * @see #createFromXML(XMLEntity)
1084
         * @see AffineTransform
1085
         */
1086
        private void calculateAffineTransform() {
1087 29519 jtorres
                if ((imageSize == null) || (extent == null) || (imageSize.width <= 0)
1088
                                || (imageSize.height <= 0)) {
1089 21200 vcaballero
                        return;
1090
                }
1091
1092
                AffineTransform escalado = new AffineTransform();
1093
                AffineTransform translacion = new AffineTransform();
1094
1095
                double escalaX;
1096
                double escalaY;
1097
1098 29279 jldominguez
                escalaX = imageSize.width / extent.getWidth();
1099
                escalaY = imageSize.height / extent.getHeight();
1100 21200 vcaballero
1101
                double xCenter = extent.getCenterX();
1102
                double yCenter = extent.getCenterY();
1103
                double newHeight;
1104
                double newWidth;
1105
1106
                adjustedExtent = new Rectangle2D.Double();
1107
1108
                if (adjustableExtent) {
1109
                        if (escalaX < escalaY) {
1110
                                scale = escalaX;
1111 29279 jldominguez
                                newHeight = imageSize.height / scale;
1112 21200 vcaballero
                                adjustedExtent.setRect(xCenter - (extent.getWidth() / 2.0),
1113 29519 jtorres
                                                yCenter - (newHeight / 2.0), extent.getWidth(),
1114
                                                newHeight);
1115 21200 vcaballero
                        } else {
1116
                                scale = escalaY;
1117 29279 jldominguez
                                newWidth = imageSize.width / scale;
1118 29519 jtorres
                                adjustedExtent.setRect(xCenter - (newWidth / 2.0), yCenter
1119
                                                - (extent.getHeight() / 2.0), newWidth, extent
1120
                                                .getHeight());
1121 21200 vcaballero
                        }
1122
                        escalado.setToScale(scale, -scale);
1123 29519 jtorres
                } else { // adjusted is same as extent
1124 21200 vcaballero
                        scale = escalaX;
1125
                        adjustedExtent.setFrame(extent);
1126
                        escalado.setToScale(escalaX, -escalaY);
1127
                }
1128 29519 jtorres
                Envelope env = getAdjustedExtent();
1129 26905 jmvivo
                if (env == null) {
1130 21886 vcaballero
                        return;
1131 26905 jmvivo
                }
1132 29519 jtorres
                translacion.setToTranslation(-env.getMinimum(0), -env.getMinimum(1)
1133
                                - getAdjustedExtent().getLength(1));
1134 21200 vcaballero
1135
                AffineTransform offsetTrans = new AffineTransform();
1136
                offsetTrans.setToTranslation(offset.getX(), offset.getY());
1137
1138
                trans.setToIdentity();
1139
                trans.concatenate(offsetTrans);
1140
                trans.concatenate(escalado);
1141
1142
                trans.concatenate(translacion);
1143
1144 29519 jtorres
                // Calculamos las distancias de 1 pixel y 3 pixel con esa
1145
                // transformaci�n
1146
                // de coordenadas, de forma que est�n precalculadas para cuando las
1147
                // necesitemos
1148 21200 vcaballero
                AffineTransform at;
1149
1150
                try {
1151
                        at = trans.createInverse();
1152
1153
                        java.awt.Point pPixel = new java.awt.Point(1, 1);
1154
                        Point2D.Float pProv = new Point2D.Float();
1155
                        at.deltaTransform(pPixel, pProv);
1156
1157
                        dist1pixel = pProv.x;
1158
                        dist3pixel = 3 * pProv.x;
1159
                } catch (NoninvertibleTransformException e) {
1160
                        System.err.println("transformada afin = " + trans.toString());
1161 29519 jtorres
                        System.err.println("extent = " + extent.toString() + " imageSize= "
1162
                                        + imageSize.toString());
1163
                        throw new RuntimeException("Non invertible transform Exception", e);
1164 21200 vcaballero
                }
1165
        }
1166
1167
        /**
1168 29519 jtorres
         * <p>
1169
         * Sets the offset.
1170
         * </p>
1171
         * <p>
1172
         * The offset is the position where start drawing the map.
1173
         * </p>
1174
         *
1175
         * @param p
1176
         *            2D point that represents the offset in pixels
1177
         *
1178 21200 vcaballero
         * @see #getOffset()
1179
         */
1180
        public void setOffset(Point2D p) {
1181 29519 jtorres
                if (!offset.equals(p)) {
1182 26225 jmvivo
                        this.updateDrawVersion();
1183 26905 jmvivo
                        offset = p;
1184 26225 jmvivo
                }
1185 21200 vcaballero
        }
1186
1187
        /**
1188 29519 jtorres
         * <p>
1189
         * Gets the offset.
1190
         * </p>
1191
         * <p>
1192
         * The offset is the position where start drawing the map.
1193
         * </p>
1194
         *
1195 21200 vcaballero
         * @return 2D point that represents the offset in pixels
1196 29519 jtorres
         *
1197 21200 vcaballero
         * @see #setOffset(Point2D)
1198
         */
1199
        public Point2D getOffset() {
1200
                return offset;
1201
        }
1202
1203
        /**
1204 29519 jtorres
         * <p>
1205
         * Sets the background color.
1206
         * </p>
1207
         *
1208
         * @param c
1209
         *            the new background color
1210
         *
1211 21200 vcaballero
         * @see #getBackColor()
1212
         */
1213
        public void setBackColor(Color c) {
1214 29519 jtorres
                if (!c.equals(this.backColor)) {
1215 26225 jmvivo
                        this.updateDrawVersion();
1216
                        backColor = c;
1217
                        callColorChanged(backColor);
1218
                }
1219 21200 vcaballero
        }
1220
1221
        /**
1222 29519 jtorres
         * <p>
1223
         * Gets the background color.
1224
         * </p>
1225
         *
1226 21200 vcaballero
         * @return the background color of the view
1227 29519 jtorres
         *
1228 21200 vcaballero
         * @see #setBackColor(Color)
1229
         */
1230
        public Color getBackColor() {
1231
                return backColor;
1232
        }
1233
1234
        /**
1235 29519 jtorres
         * <p>
1236
         * Returns the extent currently covered by the view adjusted (scaled) to the
1237
         * image size aspect.
1238
         * </p>
1239
         *
1240 21200 vcaballero
         * @return extent of the view adjusted to the image size aspect
1241 29519 jtorres
         *
1242 21200 vcaballero
         * @see #setAdjustable(boolean)
1243 29503 jpiera
         * @deprecated use {@link ViewPort#getAdjustedEnvelope()} instead
1244 21200 vcaballero
         */
1245 21531 vcaballero
        public Envelope getAdjustedExtent() {
1246 29503 jpiera
                return getAdjustedEnvelope();
1247
        }
1248 29519 jtorres
1249 29503 jpiera
        /**
1250 29519 jtorres
         * <p>
1251
         * Returns the envelope currently covered by the view adjusted (scaled) to
1252
         * the image size aspect.
1253
         * </p>
1254
         *
1255 29503 jpiera
         * @return envelope of the view adjusted to the image size aspect
1256 29519 jtorres
         *
1257 29503 jpiera
         * @see #setAdjustable(boolean)
1258
         */
1259
        public Envelope getAdjustedEnvelope() {
1260 29519 jtorres
                if (cliprect != null) {
1261
                        Rectangle2D r = adjustedExtent.createIntersection(cliprect);
1262 27414 jpiera
                        try {
1263 29519 jtorres
                                return geomManager.createEnvelope(r.getX(), r.getY(), r
1264
                                                .getMaxX(), r.getMaxY(), SUBTYPES.GEOM2D);
1265 27414 jpiera
                        } catch (CreateEnvelopeException e) {
1266
                                e.printStackTrace();
1267
                                logger.error("Error adjusting the extent", e);
1268
                        }
1269 21200 vcaballero
                }
1270 29519 jtorres
                if (adjustedExtent != null) {
1271 27414 jpiera
                        try {
1272 29519 jtorres
                                return geomManager.createEnvelope(adjustedExtent.getX(),
1273
                                                adjustedExtent.getY(), adjustedExtent.getMaxX(),
1274
                                                adjustedExtent.getMaxY(), SUBTYPES.GEOM2D);
1275 27414 jpiera
                        } catch (CreateEnvelopeException e) {
1276
                                e.printStackTrace();
1277
                                logger.error("Error adjusting the extent", e);
1278
                        }
1279 26905 jmvivo
                }
1280 21742 vcaballero
                return null;
1281 21200 vcaballero
        }
1282
1283
        /**
1284 29519 jtorres
         * <p>
1285
         * Returns the measurement unit of this view port used for measuring
1286
         * distances and displaying information.
1287
         * </p>
1288
         *
1289
         * @return the measurement unit of this view used for measuring distances
1290
         *         and displaying information
1291
         *
1292 21200 vcaballero
         * @see #setDistanceUnits(int)
1293
         */
1294
        public int getDistanceUnits() {
1295
                return distanceUnits;
1296
        }
1297 29519 jtorres
1298 21200 vcaballero
        /**
1299 29519 jtorres
         * <p>
1300
         * Returns the measurement unit of this view port used for measuring areas
1301
         * and displaying information.
1302
         * </p>
1303
         *
1304
         * @return the measurement unit of this view used for measuring areas and
1305
         *         displaying information
1306
         *
1307 21200 vcaballero
         * @see #setDistanceUnits(int)
1308
         */
1309
        public int getDistanceArea() {
1310
                return distanceArea;
1311
        }
1312 29519 jtorres
1313 21200 vcaballero
        /**
1314 29519 jtorres
         * <p>
1315
         * Sets the measurement unit of this view port used for measuring distances
1316
         * and displaying information.
1317
         * </p>
1318
         *
1319
         * @param distanceUnits
1320
         *            the measurement unit of this view used for measuring distances
1321
         *            and displaying information
1322
         *
1323 21200 vcaballero
         * @see #getDistanceUnits()
1324
         */
1325
        public void setDistanceUnits(int distanceUnits) {
1326
                this.distanceUnits = distanceUnits;
1327
        }
1328 29519 jtorres
1329 21200 vcaballero
        /**
1330 29519 jtorres
         * <p>
1331
         * Sets the measurement unit of this view port used for measuring areas and
1332
         * displaying information.
1333
         * </p>
1334
         *
1335
         * @param distanceUnits
1336
         *            the measurement unit of this view used for measuring areas and
1337
         *            displaying information
1338
         *
1339 21200 vcaballero
         * @see #getDistanceUnits()
1340
         */
1341
        public void setDistanceArea(int distanceArea) {
1342
                this.distanceArea = distanceArea;
1343
        }
1344 29519 jtorres
1345 21200 vcaballero
        /**
1346 29519 jtorres
         * <p>
1347
         * Gets the measurement unit used by this view port for the map.
1348
         * </p>
1349
         *
1350 21200 vcaballero
         * @return Returns the current map measure unit
1351 29519 jtorres
         *
1352 21200 vcaballero
         * @see #setMapUnits(int)
1353
         */
1354
        public int getMapUnits() {
1355
                return mapUnits;
1356
        }
1357
1358
        /**
1359 29519 jtorres
         * <p>
1360
         * Sets the measurement unit used by this view port for the map.
1361
         * </p>
1362
         *
1363
         * @param mapUnits
1364
         *            the new map measure unit
1365
         *
1366 21200 vcaballero
         * @see #getMapUnits()
1367
         */
1368
        public void setMapUnits(int mapUnits) {
1369
                this.mapUnits = mapUnits;
1370
        }
1371
1372
        /**
1373 29519 jtorres
         * <p>
1374
         * Gets the width in <i>screen coordinates</i> of the rectangle where the
1375
         * image is displayed.
1376
         * </p>
1377
         * <p>
1378
         * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
1379
         *
1380 21200 vcaballero
         * <ul>
1381
         * <li>The new {@link #scale scale} .
1382
         * <li>The new {@link #adjustedExtent adjustableExtent} .
1383
         * <li>The new {@link #trans trans} .
1384 29519 jtorres
         * <li>The new real world coordinates equivalent to 1 pixel (
1385
         * {@link #dist1pixel dist1pixel}) .
1386
         * <li>The new real world coordinates equivalent to 3 pixels (
1387
         * {@link #dist3pixel dist3pixel}) .
1388 21200 vcaballero
         * </ul>
1389
         * </p>
1390 29519 jtorres
         *
1391 21200 vcaballero
         * @see #getImageHeight()
1392
         * @see #getImageSize()
1393
         * @see #setImageSize(Dimension)
1394
         */
1395
        public int getImageWidth() {
1396
                return imageSize.width;
1397
        }
1398
1399
        /**
1400 29519 jtorres
         * <p>
1401
         * Gets the height in <i>screen coordinates</i> of the rectangle where the
1402
         * image is displayed.
1403
         * </p>
1404
         * <p>
1405
         * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
1406
         *
1407 21200 vcaballero
         * <ul>
1408
         * <li>The new {@link #scale scale} .
1409
         * <li>The new {@link #adjustedExtent adjustableExtent} .
1410
         * <li>The new {@link #trans trans} .
1411 29519 jtorres
         * <li>The new real world coordinates equivalent to 1 pixel (
1412
         * {@link #dist1pixel dist1pixel}) .
1413
         * <li>The new real world coordinates equivalent to 3 pixels (
1414
         * {@link #dist3pixel dist3pixel}) .
1415 21200 vcaballero
         * </ul>
1416
         * </p>
1417 29519 jtorres
         *
1418 21200 vcaballero
         * @see #getImageWidth()
1419
         * @see #getImageSize()
1420
         * @see #setImageSize(Dimension)
1421
         */
1422
        public int getImageHeight() {
1423
                return imageSize.height;
1424
        }
1425
1426
        /**
1427 29519 jtorres
         * <p>
1428
         * Gets the distance in <i>world coordinates</i> equivalent to 1 pixel in
1429
         * the view with the current extent.
1430
         * </p>
1431
         *
1432 21200 vcaballero
         * @return the distance
1433 29519 jtorres
         *
1434 21200 vcaballero
         * @see #setDist1pixel(double)
1435
         */
1436
        public double getDist1pixel() {
1437
                return dist1pixel;
1438
        }
1439
1440
        /**
1441 29519 jtorres
         * <p>
1442
         * Sets the distance in <i>world coordinates</i> equivalent to 1 pixel in
1443
         * the view with the current extent.
1444
         * </p>
1445
         *
1446
         * @param dist1pixel
1447
         *            the distance
1448
         *
1449 21200 vcaballero
         * @see #getDist1pixel()
1450
         */
1451
        public void setDist1pixel(double dist1pixel) {
1452 29519 jtorres
                if (dist1pixel == this.dist1pixel) {
1453
                        return;
1454
                }
1455
                this.updateDrawVersion();
1456 21200 vcaballero
                this.dist1pixel = dist1pixel;
1457
        }
1458
1459
        /**
1460 29519 jtorres
         * <p>
1461
         * Gets the distance in <i>world coordinates</i> equivalent to 3 pixels in
1462
         * the view with the current extent.
1463
         * </p>
1464
         *
1465 21200 vcaballero
         * @return the distance
1466 29519 jtorres
         *
1467 21200 vcaballero
         * @see #setDist3pixel(double)
1468
         */
1469
        public double getDist3pixel() {
1470
                return dist3pixel;
1471
        }
1472
1473
        /**
1474 29519 jtorres
         * <p>
1475
         * Sets the distance in <i>world coordinates</i> equivalent to 3 pixels in
1476
         * the view with the current extent.
1477
         * </p>
1478
         *
1479
         * @param dist3pixel
1480
         *            the distance
1481
         *
1482 21200 vcaballero
         * @see #getDist3pixel()
1483
         */
1484
        public void setDist3pixel(double dist3pixel) {
1485 29519 jtorres
                if (this.dist3pixel == dist3pixel) {
1486
                        return;
1487
                }
1488
                this.updateDrawVersion();
1489 21200 vcaballero
                this.dist3pixel = dist3pixel;
1490
        }
1491
1492
        /**
1493 29519 jtorres
         * <p>
1494
         * Returns the last previous extents of this view port.
1495
         * </p>
1496
         *
1497 21200 vcaballero
         * @return the last previous extents of this view port
1498 29519 jtorres
         *
1499 21200 vcaballero
         * @see #setPreviousExtent()
1500 29503 jpiera
         * @deprecated use {@link ViewPort#getEnvelopes()}
1501 21200 vcaballero
         */
1502
        public ExtentHistory getExtents() {
1503 29503 jpiera
                return getEnvelopes();
1504
        }
1505 29519 jtorres
1506 29503 jpiera
        /**
1507 29519 jtorres
         * <p>
1508
         * Returns the last previous extents of this view port.
1509
         * </p>
1510
         *
1511 29503 jpiera
         * @return the last previous extents of this view port
1512 29519 jtorres
         *
1513 29503 jpiera
         * @see #setPreviousExtent()
1514
         */
1515
        public ExtentHistory getEnvelopes() {
1516 21200 vcaballero
                return extents;
1517
        }
1518
1519
        /**
1520 29519 jtorres
         * <p>
1521
         * Gets the projection used in this view port.
1522
         * </p>
1523
         *
1524 21200 vcaballero
         * @return projection used in this view port
1525 29519 jtorres
         *
1526 21200 vcaballero
         * @see #setProjection(IProjection)
1527
         */
1528
        public IProjection getProjection() {
1529
                return proj;
1530
        }
1531
1532
        /**
1533 29519 jtorres
         * <p>
1534
         * Sets the projection to this view port.
1535
         * </p>
1536
         *
1537
         * @param proj
1538
         *            the new projection
1539
         *
1540 21200 vcaballero
         * @see #getProjection()
1541
         */
1542
        public void setProjection(IProjection proj) {
1543 29519 jtorres
                if (this.proj == null || !this.proj.getAbrev().equals(proj.getAbrev())) {
1544
                        this.updateDrawVersion();
1545 21200 vcaballero
                        this.proj = proj;
1546
                        callProjectionChanged(proj);
1547
                }
1548
        }
1549
1550 29519 jtorres
        // -----------------------------------------------------------------------------------------------------------
1551
        // NOTA PARA DESARROLLADORES SOBRE EL M�TODO
1552
        // "public void setAffineTransform(AffineTransform at)"
1553
        // ==============================================================================================
1554
        // Only used for print, should be removed, redefining the {@link
1555
        // RasterAdapter RasterAdapter} interface,
1556
        // allowing it to receive a {@link ViewPortData ViewPortData} .
1557
        // -----------------------------------------------------------------------------------------------------------
1558 21200 vcaballero
1559
        /**
1560 29519 jtorres
         * <p>
1561
         * Sets only the affine transform to this view port, without updating
1562
         * dependent attributes.
1563
         * </p>
1564
         * <p>
1565
         * <b><i>This method could be problematic!</i></b>
1566
         * </p>
1567
         *
1568
         * @param at
1569
         *            the affine transform to set
1570
         *
1571 21200 vcaballero
         * @see #getAffineTransform()
1572
         * @see #calculateAffineTransform()
1573
         */
1574 29519 jtorres
        public void setAffineTransform(AffineTransform at) {
1575
                this.trans = at;
1576 21200 vcaballero
        }
1577
1578
        /**
1579 29519 jtorres
         * <p>
1580
         * Returns an XML entity that represents this view port instance:<br>
1581 21200 vcaballero
         * <ul>
1582
         * <li>Properties:
1583 29519 jtorres
         * <ul>
1584
         * <li><i>className</i>: name of this class.
1585
         * <li>If defined, the adjusted extent:
1586
         * <ul>
1587
         * <li><i>adjustedExtentX</i>: X coordinate of the adjusted extent.
1588
         * <li><i>adjustedExtentY</i>: Y coordinate of the adjusted extent.
1589
         * <li><i>adjustedExtentW</i>: width of the adjusted extent.
1590
         * <li><i>adjustedExtentH</i>: height of the adjusted extent.
1591
         * </ul>
1592
         * <li>If defined, the background color:
1593
         * <ul>
1594
         * <li><i>backColor</i>: background color.
1595
         * </ul>
1596
         * <li>If defined, the clip:
1597
         * <ul>
1598
         * <li><i>clipX</i>: X coordinate of the clip.
1599
         * <li><i>clipY</i>: Y coordinate of clip.
1600
         * <li><i>clipW</i>: width of the clip.
1601
         * <li><i>clipH</i>: height of the clip.
1602
         * </ul>
1603
         * <li><i>dist1pixel</i>: the distance in world coordinates equivalent to 1
1604
         * pixel in the view.
1605
         * <li><i>dist3pixel</i>: the distance in world coordinates equivalent to 3
1606
         * pixels in the view.
1607
         * <li><i>distanceUnits</i>: the distance measurement unit.
1608
         * <li>If defined, the extent:
1609
         * <ul>
1610
         * <li><i>extentX</i>: X coordinate of the extent.
1611
         * <li><i>extentY</i>: Y coordinate of the extent.
1612
         * <li><i>extentW</i>: width of the extent.
1613
         * <li><i>extentH</i>: height of the extent.
1614
         * </ul>
1615
         * <li><i>mapUnits</i>: the map measurement unit.
1616
         * <li><i>offsetX</i>: X coordinate of the offset.
1617
         * <li><i>offsetY</i>: Y coordinate of the offset.
1618
         * <li>If defined, the projection:
1619
         * <ul>
1620
         * <li>If its defined, the projection:
1621
         * <ul>
1622
         * <li><i>proj</i>: the projection.</li>
1623
         * </ul>
1624
         * </ul>
1625
         * <li><i>scale</i>: ratio between the size of <code>imageSize</code> and
1626
         * <code>extent</code>.
1627
         * </ul>
1628 21200 vcaballero
         * <li>Child branches:
1629 29519 jtorres
         * <ul>
1630
         * <li>XML entity of the internal {@link ExtentHistory ExtentHistory} .
1631 21200 vcaballero
         * </ul>
1632 29519 jtorres
         * </ul>
1633
         *
1634 21200 vcaballero
         * @return the XML entity
1635 29519 jtorres
         *
1636 21200 vcaballero
         * @see #createFromXML(XMLEntity)
1637
         */
1638
        public XMLEntity getXMLEntity() {
1639
                XMLEntity xml = new XMLEntity();
1640 29519 jtorres
                xml.putProperty("className", this.getClass().getName());
1641 21200 vcaballero
1642
                if (adjustedExtent != null) {
1643
                        xml.putProperty("adjustedExtentX", adjustedExtent.getX());
1644
                        xml.putProperty("adjustedExtentY", adjustedExtent.getY());
1645
                        xml.putProperty("adjustedExtentW", adjustedExtent.getWidth());
1646
                        xml.putProperty("adjustedExtentH", adjustedExtent.getHeight());
1647
                }
1648
1649 26905 jmvivo
                if (backColor != null) {
1650 29519 jtorres
                        xml.putProperty("backColor", StringUtilities
1651
                                        .color2String(backColor));
1652 26905 jmvivo
                }
1653 21200 vcaballero
1654
                if (clip != null) {
1655
                        xml.putProperty("clipX", clip.getX());
1656
                        xml.putProperty("clipY", clip.getY());
1657
                        xml.putProperty("clipW", clip.getWidth());
1658
                        xml.putProperty("clipH", clip.getHeight());
1659
                }
1660
1661
                xml.putProperty("dist1pixel", dist1pixel);
1662
                xml.putProperty("dist3pixel", dist3pixel);
1663
                xml.putProperty("distanceUnits", distanceUnits);
1664
1665
                if (extent != null) {
1666
                        xml.putProperty("extentX", extent.getX());
1667
                        xml.putProperty("extentY", extent.getY());
1668
                        xml.putProperty("extentW", extent.getWidth());
1669
                        xml.putProperty("extentH", extent.getHeight());
1670
                }
1671
1672
                xml.addChild(extents.getXMLEntity());
1673
                xml.putProperty("mapUnits", mapUnits);
1674
                xml.putProperty("offsetX", offset.getX());
1675
                xml.putProperty("offsetY", offset.getY());
1676
1677
                if (proj != null) {
1678
                        xml.putProperty("proj", proj.getAbrev());
1679
                }
1680
1681
                xml.putProperty("scale", scale);
1682
1683
                return xml;
1684
        }
1685
1686
        /**
1687 29519 jtorres
         * <p>
1688
         * Creates a new <code>ViewPort</code> from an XML entity.
1689
         * </p>
1690
         *
1691
         * @param xml
1692
         *            an XML entity
1693
         *
1694 21200 vcaballero
         * @return the new <code>ViewPort</code>
1695 29519 jtorres
         *
1696 21200 vcaballero
         * @see #getXMLEntity()
1697
         */
1698
        public static ViewPort createFromXML(XMLEntity xml) {
1699
                ViewPort vp = new ViewPort(null);
1700
1701
                if (xml.contains("adjustedExtentX")) {
1702 29519 jtorres
                        vp.adjustedExtent = new Rectangle2D.Double(xml
1703
                                        .getDoubleProperty("adjustedExtentX"), xml
1704
                                        .getDoubleProperty("adjustedExtentY"), xml
1705
                                        .getDoubleProperty("adjustedExtentW"), xml
1706
                                        .getDoubleProperty("adjustedExtentH"));
1707 21200 vcaballero
                }
1708
1709
                if (xml.contains("backColor")) {
1710 29519 jtorres
                        vp.setBackColor(StringUtilities.string2Color(xml
1711
                                        .getStringProperty("backColor")));
1712
                } else {
1713 21200 vcaballero
                        vp.setBackColor(Color.white);
1714
                }
1715
1716
                if (xml.contains("clipX")) {
1717
                        vp.clip = new Rectangle2D.Double(xml.getDoubleProperty("clipX"),
1718 29519 jtorres
                                        xml.getDoubleProperty("clipY"), xml
1719
                                                        .getDoubleProperty("clipW"), xml
1720
                                                        .getDoubleProperty("clipH"));
1721 21200 vcaballero
                }
1722
1723
                vp.setDist1pixel(xml.getDoubleProperty("dist1pixel"));
1724
                vp.setDist3pixel(xml.getDoubleProperty("dist3pixel"));
1725
                vp.setDistanceUnits(xml.getIntProperty("distanceUnits"));
1726 29519 jtorres
                if (xml.contains("distanceArea")) {
1727 21200 vcaballero
                        vp.setDistanceArea(xml.getIntProperty("distanceArea"));
1728 29519 jtorres
                } else {
1729 21200 vcaballero
                        vp.setDistanceArea(xml.getIntProperty("distanceUnits"));
1730
                }
1731
                vp.extents = ExtentHistory.createFromXML(xml.getChild(0));
1732
1733
                if (xml.contains("extentX")) {
1734 29519 jtorres
                        double x = xml.getDoubleProperty("extentX");
1735
                        double y = xml.getDoubleProperty("extentY");
1736 27414 jpiera
                        try {
1737 29519 jtorres
                                vp.setEnvelope(geomManager.createEnvelope(x, y, x
1738
                                                + xml.getDoubleProperty("extentW"), y
1739
                                                + xml.getDoubleProperty("extentH"), SUBTYPES.GEOM2D));
1740 27414 jpiera
                        } catch (CreateEnvelopeException e) {
1741
                                e.printStackTrace();
1742
                                logger.error("Error setting the extent", e);
1743
                        }
1744 21200 vcaballero
1745 29519 jtorres
                        // Calcula la transformaci�n af�n
1746 21200 vcaballero
                        vp.calculateAffineTransform();
1747
1748
                        // Lanzamos los eventos de extent cambiado
1749
                        // vp.callExtentListeners(vp.adjustedExtent);
1750
                }
1751
1752
                vp.setMapUnits(xml.getIntProperty("mapUnits"));
1753 29519 jtorres
                vp.setOffset(new Point2D.Double(xml.getDoubleProperty("offsetX"), xml
1754
                                .getDoubleProperty("offsetY")));
1755 21200 vcaballero
1756
                if (xml.contains("proj")) {
1757
                        vp.proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
1758
                }
1759
1760 29519 jtorres
                // vp.setScale(xml.getDoubleProperty("scale"));
1761 21200 vcaballero
                vp.refreshExtent();
1762
                return vp;
1763
        }
1764
1765
        /**
1766 29519 jtorres
         * <p>
1767
         * Fast clone implementation: creates and returns a clone of this view port
1768
         * using XML entities.
1769
         * </p>
1770
         * <p>
1771
         * Isn't a <i>deepclone</i> to avoid unnecessary memory consumption.
1772
         * </p>
1773
         *
1774 21200 vcaballero
         * @return the new view port
1775 29519 jtorres
         *
1776 21200 vcaballero
         * @see #createFromXML(XMLEntity)
1777
         */
1778
        public ViewPort cloneViewPort() {
1779
                return createFromXML(getXMLEntity());
1780
        }
1781
1782
        /**
1783 29519 jtorres
         * <p>
1784
         * Returns a <code>String</code> representation of the main values of this
1785
         * view port: <code>{@linkplain #extent}</code>,
1786
         * <code>{@linkplain #adjustedExtent}</code>,
1787
         * <code>{@linkplain #imageSize}</code>, <code>{@linkplain #scale}</code>,
1788
         * and <code>{@linkplain #trans}</code>.
1789
         * </p>
1790
         *
1791
         * @return a <code>string</code> representation of the main values of this
1792
         *         view port
1793 21200 vcaballero
         */
1794
        public String toString() {
1795
1796
                String str;
1797 29519 jtorres
                str = "Datos del viewPort:\nExtent=" + extent + "\nadjustedExtent="
1798
                                + adjustedExtent + "\nimageSize=" + imageSize + "\nescale="
1799
                                + scale + "\ntrans=" + trans;
1800 21200 vcaballero
1801
                return str;
1802
        }
1803
1804
        /**
1805 29519 jtorres
         * <p>
1806
         * Sets the position and size of the clipping rectangle.
1807
         * </p>
1808
         *
1809
         * @param rectView
1810
         *            the clipping rectangle to set
1811 21200 vcaballero
         */
1812
        public void setClipRect(Rectangle2D rectView) {
1813 26225 jmvivo
                this.updateDrawVersion();
1814 29519 jtorres
                cliprect = rectView;
1815 21200 vcaballero
        }
1816 26905 jmvivo
1817 21200 vcaballero
        /**
1818 29519 jtorres
         * <p>
1819
         * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
1820
         * <i>map coordinates</i> to <i>screen coordinates</i> (pixels) using an
1821
         * <i>inverse transform</i> with the transformation affine information in
1822
         * the {@link #trans #trans} attribute.
1823
         * </p>
1824
         *
1825
         * @param r
1826
         *            the 2D rectangle in <i>map coordinates</i>
1827 21200 vcaballero
         * @return 2D rectangle equivalent in <i>screen coordinates</i> (pixels)
1828 29519 jtorres
         *
1829 21200 vcaballero
         * @see #toMapRectangle(Rectangle2D)
1830
         * @see #fromMapDistance(double)
1831
         * @see #fromMapPoint(Point2D)
1832
         */
1833
        public Rectangle2D fromMapRectangle(Rectangle2D r) {
1834 29519 jtorres
                Rectangle2D rect = new Rectangle2D.Double();
1835
                Point2D p1 = fromMapPoint((int) r.getX(), (int) r.getY());
1836
                Point2D p2 = fromMapPoint((int) r.getMaxX(), (int) r.getMaxY());
1837
                rect.setFrameFromDiagonal(p1, p2);
1838 21200 vcaballero
                return rect;
1839
        }
1840
1841
        /**
1842 29519 jtorres
         * <p>
1843
         * Recalculates the current <code>{@linkplain #extent}</code> using an
1844
         * scale. It's necessary execute {@linkplain #refreshExtent()} after.
1845
         * </p>
1846
         *
1847
         * @param s
1848
         *            the scale to set
1849
         *
1850
         * @deprecated since 07/09/07, use
1851
         *             {@linkplain MapContext#setScaleView(long)}
1852 21200 vcaballero
         */
1853 29519 jtorres
        public void setScale(long s) {
1854
                double x = extent.getX();
1855
                double y = extent.getY();
1856 29279 jldominguez
                double escalaX = imageSize.width / extent.getWidth();
1857 29519 jtorres
                double w = imageSize.width / s;
1858
                double h = imageSize.height / s;
1859
                double difw = escalaX / s;
1860 21200 vcaballero
1861 29519 jtorres
                double x1 = (-x * difw) - x + extent.getWidth() / 2;
1862
                double y1 = (-y * difw) - y + extent.getHeight() / 2;
1863
                double w1 = extent.getWidth() * difw;
1864
                double h1 = extent.getHeight() * difw;
1865
                extent.setRect(-x1, -y1, w1, h1);
1866 21200 vcaballero
        }
1867 29519 jtorres
1868
        public long getDrawVersion() {
1869
                return this.drawVersion;
1870
        }
1871
1872
        protected void updateDrawVersion() {
1873
                this.drawVersion++;
1874
        }
1875
1876 21200 vcaballero
}