Revision 42170

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.mapcontext/org.gvsig.fmap.mapcontext.api/src/main/java/org/gvsig/fmap/mapcontext/ViewPort.java
65 65
 * <code>ViewPort</code> class represents the logic needed to transform a
66 66
 * rectangular area of a map to the available area in screen to display it.
67 67
 * </p>
68
 * 
69 68
 * <p>
70 69
 * Includes an affine transformation, between the rectangular area selected of
71 70
 * the external map, in its own <i>map coordinates</i>, to the rectangular area
72 71
 * available of a view in <i>screen coordinates</i>.
73 72
 * </p>
74
 * 
75 73
 * <p>
76 74
 * Elements:
77 75
 * <ul>
......
108 106
 */
109 107
public class ViewPort implements Persistent, Cloneable {
110 108

  
111
    private static final String FIELD_DISTANCE_AREA = "distanceArea";
112
    private static final String FIELD_IMAGE_SIZE = "imageSize";
113
    private static final String FIELD_PROJ = "proj";
114
    private static final String FIELD_OFFSET = "offset";
115
    private static final String FIELD_MAP_UNITS = "mapUnits";
116
    private static final String FIELD_EXTENT = "extent";
117
    private static final String FIELD_EXTENTS = "extents";
118
    private static final String FIELD_DISTANCE_UNITS = "distanceUnits";
119
    private static final String FIELD_DIST3PIXEL = "dist3pixel";
120
    private static final String FIELD_DIST1PIXEL = "dist1pixel";
121
    private static final String FIELD_CLIP = "clip";
122
    private static final String FIELD_BACK_COLOR = "backColor";
123
    private static final String FIELD_ADJUSTED_EXTENT = "adjustedExtent";
109
  private static final String FIELD_DISTANCE_AREA = "distanceArea";
124 110

  
125
    private static final GeometryManager geomManager =
126
        GeometryLocator.getGeometryManager();
127
    private static final Logger logger =
128
        LoggerFactory.getLogger(ViewPort.class);
111
  private static final String FIELD_IMAGE_SIZE = "imageSize";
129 112

  
113
  private static final String FIELD_PROJ = "proj";
130 114

  
131
    /**
132
     * <p>
133
     * Area selected by user using some tool.
134
     * </p>
135
     * 
136
     * <p>
137
     * When the zoom changes (for instance when using the zoom in or zoom out
138
     * tools, but also zooming to a selected feature or shape) the extent that
139
     * covers that area is the value returned by this method. It is not the
140
     * actual area shown in the view because it does not care about the aspect
141
     * ratio of the available area. However, any part of the real world
142
     * contained in this extent is shown in the view.
143
     * </p>
144
     * <p>
145
     * Probably this is not what you are looking for. If you are looking for the
146
     * complete extent currently shown, you must use
147
     * {@linkplain #getAdjustedExtent()} method which returns the extent that
148
     * contains this one but regarding the current view's aspect ratio.
149
     * </p>
150
     * 
151
     * @see #getExtent()
152
     * @see #setEnvelope(Envelope)
153
     */
154
    protected Rectangle2D extent;
155
    
156
    protected Time time;
115
  private static final String FIELD_OFFSET = "offset";
157 116

  
158
    /**
159
     * <p>
160
     * Location and dimensions of the extent adjusted to the image size.
161
     * </p>
162
     * 
163
     * @see #getAdjustedExtent()
164
     */
165
    protected Rectangle2D adjustedExtent;
117
  private static final String FIELD_MAP_UNITS = "mapUnits";
166 118

  
167
    /**
168
     * Draw version of the context. It's used for know when de componend has
169
     * changed any visualization property
170
     * 
171
     * @see getDrawVersion
172
     * @see updateDrawVersion
173
     */
174
    private long drawVersion = 0L;
119
  private static final String FIELD_EXTENT = "extent";
175 120

  
176
    /**
177
     * <p>
178
     * History with the last extents of the view.
179
     * </p>
180
     * 
181
     * @see #setPreviousExtent()
182
     * @see #getExtents()
183
     */
184
    protected ExtentHistory extents = new ExtentHistory();
121
  private static final String FIELD_EXTENTS = "extents";
185 122

  
186
    /**
187
     * <p>
188
     * Size in <i>screen coordinates</i> of the rectangle where the image is
189
     * displayed.
190
     * </p>
191
     * <p>
192
     * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
193
     * 
194
     * <ul>
195
     * <li>The new {@link #scale scale} .
196
     * <li>The new {@link #adjustedExtent adjustableExtent} .
197
     * <li>The new {@link #trans trans} .
198
     * <li>The new real world coordinates equivalent to 1 pixel (
199
     * {@link #dist1pixel dist1pixel}) .
200
     * <li>The new real world coordinates equivalent to 3 pixels (
201
     * {@link #dist3pixel dist3pixel}) .
202
     * </ul>
203
     * </p>
204
     * 
205
     * @see #getImageSize()
206
     * @see #getImageHeight()
207
     * @see #getImageWidth()
208
     * @see #setImageSize(Dimension)
209
     */
210
    private Dimension imageSize;
123
  private static final String FIELD_DISTANCE_UNITS = "distanceUnits";
211 124

  
212
    /**
213
     * <p>
214
     * the affine transformation between the {@link #extent extent} in <i>map 2D
215
     * coordinates</i> to the image area in the screen, in <i>screen 2D
216
     * coordinates</i> (pixels).
217
     * </p>
218
     * 
219
     * @see AffineTransform
220
     * 
221
     * @see #getAffineTransform()
222
     * @see #setAffineTransform(AffineTransform)
223
     * @see #calculateAffineTransform()
224
     */
225
    private AffineTransform trans = new AffineTransform();
125
  private static final String FIELD_DIST3PIXEL = "dist3pixel";
226 126

  
227
    /**
228
     * <p>
229
     * Measurement unit used for measuring distances and displaying information.
230
     * </p>
231
     * 
232
     * @see #getDistanceUnits()
233
     * @see #setDistanceUnits(int)
234
     */
235
    private int distanceUnits = 1;
236
    /**
237
     * <p>
238
     * Measurement unit used for measuring areas and displaying information.
239
     * </p>
240
     * 
241
     * @see #getDistanceArea()
242
     * @see #setDistanceArea(int)
243
     */
244
    private int distanceArea = 1;
245
    /**
246
     * <p>
247
     * Measurement unit used by this view port for the map.
248
     * </p>
249
     * 
250
     * @see #getMapUnits()
251
     * @see #setMapUnits(int)
252
     */
253
    private int mapUnits = 1;
127
  private static final String FIELD_DIST1PIXEL = "dist1pixel";
254 128

  
255
    /**
256
     * <p>
257
     * Array with the {@link ViewPortListener ViewPortListener}s registered to
258
     * this view port.
259
     * </p>
260
     * 
261
     * @see #addViewPortListener(ViewPortListener)
262
     * @see #removeViewPortListener(ViewPortListener)
263
     */
264
    private ArrayList listeners = new ArrayList();
129
  private static final String FIELD_CLIP = "clip";
265 130

  
266
    /**
267
     * <p>
268
     * The offset is the position where start drawing the map.
269
     * </p>
270
     * <p>
271
     * The offset of a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
272
     * <i>View</i> is always (0, 0) because the drawing area fits with the full
273
     * window area. But in a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
274
     * <i>Layout</i> it's up to the place where the <code>FFrameView</code> is
275
     * located.
276
     * </p>
277
     * 
278
     * @see #getOffset()
279
     * @see #setOffset(Point2D)
280
     */
281
    private Point2D offset = new Point2D.Double(0, 0);
131
  private static final String FIELD_BACK_COLOR = "backColor";
282 132

  
283
    /**
284
     * <p>
285
     * Clipping area.
286
     * </p>
287
     */
288
    // private Rectangle2D clip;
133
  private static final String FIELD_ADJUSTED_EXTENT = "adjustedExtent";
289 134

  
290
    /**
291
     * <p>
292
     * Background color of this view.
293
     * </p>
294
     * 
295
     * @see #getBackColor()
296
     * @see #setBackColor(Color)
297
     */
298
    private Color backColor = null; // Color.WHITE;
135
  private static final GeometryManager geomManager = GeometryLocator
136
      .getGeometryManager();
299 137

  
300
    /**
301
     * <p>
302
     * Information about the map projection used in this view.
303
     * </p>
304
     * 
305
     * @see #getProjection()
306
     * @see #setProjection(IProjection)
307
     */
308
    private IProjection proj;
138
  private static final Logger logger = LoggerFactory.getLogger(ViewPort.class);
309 139

  
310
    /**
311
     * <p>
312
     * Represents the distance in <i>world coordinates</i> equivalent to 1 pixel
313
     * in the view with the current extent.
314
     * </p>
315
     * 
316
     * @see #getDist1pixel()
317
     * @see #setDist1pixel(double)
318
     */
319
    private double dist1pixel;
140
  /**
141
   * <p>
142
   * Area selected by user using some tool.
143
   * </p>
144
   * <p>
145
   * When the zoom changes (for instance when using the zoom in or zoom out
146
   * tools, but also zooming to a selected feature or shape) the extent that
147
   * covers that area is the value returned by this method. It is not the actual
148
   * area shown in the view because it does not care about the aspect ratio of
149
   * the available area. However, any part of the real world contained in this
150
   * extent is shown in the view.
151
   * </p>
152
   * <p>
153
   * Probably this is not what you are looking for. If you are looking for the
154
   * complete extent currently shown, you must use
155
   * {@linkplain #getAdjustedExtent()} method which returns the extent that
156
   * contains this one but regarding the current view's aspect ratio.
157
   * </p>
158
   * 
159
   * @see #getExtent()
160
   * @see #setEnvelope(Envelope)
161
   */
162
  protected Rectangle2D extent;
320 163

  
321
    /**
322
     * <p>
323
     * Represents the distance in <i>world coordinates</i> equivalent to 3
324
     * pixels in the view with the current extent.
325
     * </p>
326
     * 
327
     * @see #getDist3pixel()
328
     * @see #setDist3pixel(double)
329
     */
330
    private double dist3pixel;
164
  protected Time time;
331 165

  
332
    /**
333
     * <p>
334
     * Ratio between the size of <code>imageSize</code> and <code>extent</code>:
335
     * <br>
336
     * <i>
337
     * 
338
     * <pre>
339
     * min{(imageSize.getHeight()/extent.getHeight(), imageSize.getWidth()/extent.getWidth())}
340
     * </pre>
341
     * 
342
     * </i>
343
     * </p>
344
     */
345
    private double scale;
166
  /**
167
   * <p>
168
   * Location and dimensions of the extent adjusted to the image size.
169
   * </p>
170
   * 
171
   * @see #getAdjustedExtent()
172
   */
173
  protected Rectangle2D adjustedExtent;
346 174

  
347
    /**
348
     * <p>
349
     * Clipping area.
350
     * </p>
351
     * 
352
     * @see #setClipRect(Rectangle2D)
353
     */
354
    private Rectangle2D cliprect;
175
  /**
176
   * Draw version of the context. It's used for know when de componend has
177
   * changed any visualization property
178
   * 
179
   * @see getDrawVersion
180
   * @see updateDrawVersion
181
   */
182
  private long drawVersion = 0L;
355 183

  
356
    /**
357
     * <p>
358
     * Enables or disables the <i>"adjustable extent"</i> mode.
359
     * </p>
360
     * 
361
     * <p>
362
     * When calculates the affine transform, if
363
     * <ul>
364
     * <li><i>enabled</i>: the new <code>adjustedExtent</code> will have the (X,
365
     * Y) coordinates of the <code>extent</code> and an area that will be an
366
     * scale of the image size. That area will have different height or width
367
     * (not both) of the extent according the least ratio (height or width) in
368
     * 
369
     * <pre>
370
     * image.size/extent.size&quot;
371
     * </pre>.
372
     * <li><i>disabled</i>: the new <code>adjustedExtent</code> will be like
373
     * <code>extent</code>.
374
     * </ul>
375
     * </p>
376
     * 
377
     * @see #setAdjustable(boolean)
378
     */
379
    private boolean adjustableExtent = true;
184
  /**
185
   * <p>
186
   * History with the last extents of the view.
187
   * </p>
188
   * 
189
   * @see #setPreviousExtent()
190
   * @see #getExtents()
191
   */
192
  protected ExtentHistory extentsHistory = new ExtentHistory();
193
  
194
  /**
195
   * <p>
196
   * Size in <i>screen coordinates</i> of the rectangle where the image is
197
   * displayed.
198
   * </p>
199
   * <p>
200
   * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
201
   * <ul>
202
   * <li>The new {@link #scale scale} .
203
   * <li>The new {@link #adjustedExtent adjustableExtent} .
204
   * <li>The new {@link #trans trans} .
205
   * <li>The new real world coordinates equivalent to 1 pixel (
206
   * {@link #dist1pixel dist1pixel}) .
207
   * <li>The new real world coordinates equivalent to 3 pixels (
208
   * {@link #dist3pixel dist3pixel}) .
209
   * </ul>
210
   * </p>
211
   * 
212
   * @see #getImageSize()
213
   * @see #getImageHeight()
214
   * @see #getImageWidth()
215
   * @see #setImageSize(Dimension)
216
   */
217
  private Dimension imageSize;
380 218

  
381
    /**
382
     * <p>
383
     * ViewPort resolution in <i>dots-per-inch</i>. 
384
     * Useful to calculate the geographic scale of the view.
385
     * </p>
386
     * 
387
     * @see Toolkit#getScreenResolution()
388
     * @see MapContext#getScaleView()
389
     */
390
    private Double dpi = null;
391
    
392
    public ViewPort() {
219
  /**
220
   * <p>
221
   * the affine transformation between the {@link #extent extent} in <i>map 2D
222
   * coordinates</i> to the image area in the screen, in <i>screen 2D
223
   * coordinates</i> (pixels).
224
   * </p>
225
   * 
226
   * @see AffineTransform
227
   * @see #getAffineTransform()
228
   * @see #setAffineTransform(AffineTransform)
229
   * @see #calculateAffineTransform()
230
   */
231
  private AffineTransform trans = new AffineTransform();
393 232

  
394
    }
233
  /**
234
   * <p>
235
   * Measurement unit used for measuring distances and displaying information.
236
   * </p>
237
   * 
238
   * @see #getDistanceUnits()
239
   * @see #setDistanceUnits(int)
240
   */
241
  private int distanceUnits = 1;
395 242

  
396
    /**
397
     * <p>
398
     * Creates a new view port with the information of the projection in
399
     * <code>proj</code> argument, and default configuration:
400
     * </p>
401
     * <p>
402
     * <ul>
403
     * <li><i><code>distanceUnits</code></i> = meters
404
     * <li><i><code>mapUnits</code></i> = meters
405
     * <li><i><code>backColor</code></i> = <i>undefined</i>
406
     * <li><i><code>offset</code></i> = <code>new Point2D.Double(0, 0);</code>
407
     * </ul>
408
     * </p>
409
     * 
410
     * @param proj
411
     *            information of the projection for this view port
412
     */
413
    public ViewPort(IProjection proj) {
414
        // Por defecto
415
        this.proj = proj;
416
    }
243
  /**
244
   * <p>
245
   * Measurement unit used for measuring areas and displaying information.
246
   * </p>
247
   * 
248
   * @see #getDistanceArea()
249
   * @see #setDistanceArea(int)
250
   */
251
  private int distanceArea = 1;
417 252

  
418
    /**
419
     * <p>
420
     * Changes the status of the <i>"adjustable extent"</i> option to enabled or
421
     * disabled.
422
     * </p>
423
     * 
424
     * <p>
425
     * If view port isn't adjustable, won't bear in mind the aspect ratio of the
426
     * available rectangular area to calculate the affine transform from the
427
     * original map in real coordinates. (Won't scale the image to adapt it to
428
     * the available rectangular area).
429
     * </p>
430
     * 
431
     * @param boolean the boolean to be set
432
     */
433
    public void setAdjustable(boolean adjustable) {
434
        if (adjustable == adjustableExtent) {
435
            return;
436
        }
437
        adjustableExtent = adjustable;
438
        this.updateDrawVersion();
439
    }
253
  /**
254
   * <p>
255
   * Measurement unit used by this view port for the map.
256
   * </p>
257
   * 
258
   * @see #getMapUnits()
259
   * @see #setMapUnits(int)
260
   */
261
  private int mapUnits = 1;
440 262

  
441
    /**
442
     * <p>
443
     * Appends the specified {@link ViewPortListener ViewPortListener} listener
444
     * if weren't.
445
     * </p>
446
     * 
447
     * @param arg0
448
     *            the listener to add
449
     * 
450
     * @return <code>true</code> if has been added successfully
451
     * 
452
     * @see #removeViewPortListener(ViewPortListener)
453
     */
454
    public boolean addViewPortListener(ViewPortListener arg0) {
455
        if (!listeners.contains(arg0)) {
456
            return listeners.add(arg0);
457
        }
458
        return false;
459
    }
263
  /**
264
   * <p>
265
   * Array with the {@link ViewPortListener ViewPortListener}s registered to
266
   * this view port.
267
   * </p>
268
   * 
269
   * @see #addViewPortListener(ViewPortListener)
270
   * @see #removeViewPortListener(ViewPortListener)
271
   */
272
  private ArrayList listeners = new ArrayList();
460 273

  
461
    /**
462
     * <p>
463
     * Removes the specified {@link ViewPortListener ViewPortListener} listener,
464
     * if existed.
465
     * </p>
466
     * 
467
     * @param arg0
468
     *            the listener to remove
469
     * 
470
     * @return <code>true</code> if the contained the specified listener.
471
     * 
472
     * @see #addViewPortListener(ViewPortListener)
473
     */
474
    public boolean removeViewPortListener(ViewPortListener arg0) {
475
        return listeners.remove(arg0);
476
    }
274
  /**
275
   * <p>
276
   * The offset is the position where start drawing the map.
277
   * </p>
278
   * <p>
279
   * The offset of a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s <i>View</i>
280
   * is always (0, 0) because the drawing area fits with the full window area.
281
   * But in a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s <i>Layout</i> it's
282
   * up to the place where the <code>FFrameView</code> is located.
283
   * </p>
284
   * 
285
   * @see #getOffset()
286
   * @see #setOffset(Point2D)
287
   */
288
  private Point2D offset = new Point2D.Double(0, 0);
477 289

  
478
    /**
479
     * <p>
480
     * Converts and returns the distance <code>d</code>, that is in <i>map
481
     * coordinates</i> to <i>screen coordinates</i> using a <i>delta
482
     * transform</i> with the transformation affine information in the
483
     * {@link #trans #trans} attribute.
484
     * </p>
485
     * 
486
     * @param d
487
     *            distance in <i>map coordinates</i>
488
     * 
489
     * @return distance equivalent in <i>screen coordinates</i>
490
     * 
491
     * @see #toMapDistance(int)
492
     * @see AffineTransform#deltaTransform(Point2D, Point2D)S
493
     */
494
    public int fromMapDistance(double d) {
495
        Point2D.Double pWorld = new Point2D.Double(1, 1);
496
        Point2D.Double pScreen = new Point2D.Double();
290
  /**
291
   * <p>
292
   * Clipping area.
293
   * </p>
294
   */
295
  // private Rectangle2D clip;
497 296

  
498
        try {
499
            trans.deltaTransform(pWorld, pScreen);
500
        } catch (Exception e) {
501
            System.err.print(e.getMessage());
502
        }
297
  /**
298
   * <p>
299
   * Background color of this view.
300
   * </p>
301
   * 
302
   * @see #getBackColor()
303
   * @see #setBackColor(Color)
304
   */
305
  private Color backColor = null; // Color.WHITE;
503 306

  
504
        return (int) (d * pScreen.x);
505
    }
307
  /**
308
   * <p>
309
   * Information about the map projection used in this view.
310
   * </p>
311
   * 
312
   * @see #getProjection()
313
   * @see #setProjection(IProjection)
314
   */
315
  private IProjection proj;
506 316

  
507
    /**
508
     * <p>
509
     * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>map
510
     * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
511
     * transformation in the {@link #trans #trans} attribute.
512
     * </p>
513
     * 
514
     * @param x
515
     *            the <code>x</code> <i>map coordinate</i> of a 2D point
516
     * @param y
517
     *            the <code>y</code> <i>map coordinate</i> of a 2D point
518
     * 
519
     * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
520
     * 
521
     * @see #fromMapPoint(Point2D)
522
     * @see AffineTransform#transform(Point2D, Point2D)
523
     */
524
    public Point2D fromMapPoint(double x, double y) {
525
        Point2D.Double pWorld = new Point2D.Double(x, y);
526
        Point2D.Double pScreen = new Point2D.Double();
317
  /**
318
   * <p>
319
   * Represents the distance in <i>world coordinates</i> equivalent to 1 pixel
320
   * in the view with the current extent.
321
   * </p>
322
   * 
323
   * @see #getDist1pixel()
324
   * @see #setDist1pixel(double)
325
   */
326
  private double dist1pixel;
527 327

  
528
        try {
529
            trans.transform(pWorld, pScreen);
530
        } catch (Exception e) {
531
            System.err.print(e.getMessage());
532
        }
328
  /**
329
   * <p>
330
   * Represents the distance in <i>world coordinates</i> equivalent to 3 pixels
331
   * in the view with the current extent.
332
   * </p>
333
   * 
334
   * @see #getDist3pixel()
335
   * @see #setDist3pixel(double)
336
   */
337
  private double dist3pixel;
533 338

  
534
        return pScreen;
535
    }
339
  /**
340
   * <p>
341
   * Ratio between the size of <code>imageSize</code> and <code>extent</code>: <br>
342
   * <i>
343
   * 
344
   * <pre>
345
   * min{(imageSize.getHeight()/extent.getHeight(), imageSize.getWidth()/extent.getWidth())}
346
   * </pre>
347
   * 
348
   * </i>
349
   * </p>
350
   */
351
  private double scale;
536 352

  
537
    /**
538
     * <p>
539
     * Converts and returns the 2D point argument, that is in <i>map
540
     * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
541
     * transformation in the {@link #trans #trans} attribute.
542
     * </p>
543
     * 
544
     * @param point
545
     *            the 2D point in <i>map coordinates</i>
546
     * 
547
     * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
548
     * 
549
     * @see #toMapPoint(Point2D)
550
     * @see #fromMapPoint(double, double)
551
     */
552
    public Point2D fromMapPoint(Point2D point) {
553
        return fromMapPoint(point.getX(), point.getY());
554
    }
353
  /**
354
   * <p>
355
   * Clipping area.
356
   * </p>
357
   * 
358
   * @see #setClipRect(Rectangle2D)
359
   */
360
  private Rectangle2D cliprect;
555 361

  
556
    /**
557
     * <p>
558
     * Converts and returns the 2D point <code>(x,y)</code>, that is in
559
     * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using the
560
     * affine transformation in the {@link #trans #trans} attribute.
561
     * </p>
562
     * 
563
     * @param x
564
     *            the <code>x</code> <i>screen coordinate</i> of a 2D point
565
     * @param y
566
     *            the <code>y</code> <i>screen coordinate</i> of a 2D point
567
     * 
568
     * @return 2D point equivalent in <i>map coordinates</i>
569
     * 
570
     * @see #toMapPoint(Point2D)
571
     * @see #fromMapPoint(double, double)
572
     * @deprecated use {@link #convertToMapPoint(int, int)}
573
     */
574
    public Point2D toMapPoint(int x, int y) {
575
        Point2D pScreen = new Point2D.Double(x, y);
362
  /**
363
   * <p>
364
   * Enables or disables the <i>"adjustable extent"</i> mode.
365
   * </p>
366
   * <p>
367
   * When calculates the affine transform, if
368
   * <ul>
369
   * <li><i>enabled</i>: the new <code>adjustedExtent</code> will have the (X,
370
   * Y) coordinates of the <code>extent</code> and an area that will be an scale
371
   * of the image size. That area will have different height or width (not both)
372
   * of the extent according the least ratio (height or width) in
373
   * 
374
   * <pre>
375
   * image.size/extent.size&quot;
376
   * </pre>.
377
   * <li><i>disabled</i>: the new <code>adjustedExtent</code> will be like
378
   * <code>extent</code>.
379
   * </ul>
380
   * </p>
381
   * 
382
   * @see #setAdjustable(boolean)
383
   */
384
  private boolean adjustableExtent = true;
576 385

  
577
        return toMapPoint(pScreen);
386
  /**
387
   * <p>
388
   * ViewPort resolution in <i>dots-per-inch</i>. Useful to calculate the
389
   * geographic scale of the view.
390
   * </p>
391
   * 
392
   * @see Toolkit#getScreenResolution()
393
   * @see MapContext#getScaleView()
394
   */
395
  private Double dpi = null;
396

  
397
  public ViewPort() {
398

  
399
  }
400

  
401
  /**
402
   * <p>
403
   * Creates a new view port with the information of the projection in
404
   * <code>proj</code> argument, and default configuration:
405
   * </p>
406
   * <p>
407
   * <ul>
408
   * <li><i><code>distanceUnits</code></i> = meters
409
   * <li><i><code>mapUnits</code></i> = meters
410
   * <li><i><code>backColor</code></i> = <i>undefined</i>
411
   * <li><i><code>offset</code></i> = <code>new Point2D.Double(0, 0);</code>
412
   * </ul>
413
   * </p>
414
   * 
415
   * @param proj information of the projection for this view port
416
   */
417
  public ViewPort(IProjection proj) {
418
    // Por defecto
419
    this.proj = proj;
420
  }
421

  
422
  /**
423
   * <p>
424
   * Changes the status of the <i>"adjustable extent"</i> option to enabled or
425
   * disabled.
426
   * </p>
427
   * <p>
428
   * If view port isn't adjustable, won't bear in mind the aspect ratio of the
429
   * available rectangular area to calculate the affine transform from the
430
   * original map in real coordinates. (Won't scale the image to adapt it to the
431
   * available rectangular area).
432
   * </p>
433
   * 
434
   * @param boolean the boolean to be set
435
   */
436
  public void setAdjustable(boolean adjustable) {
437
    if (adjustable == adjustableExtent) {
438
      return;
578 439
    }
440
    adjustableExtent = adjustable;
441
    this.updateDrawVersion();
442
  }
579 443

  
580
    /**
581
     * <p>
582
     * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
583
     * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using
584
     * {@linkplain #toMapDistance(int)}, and {@linkplain #toMapPoint(int, int)}.
585
     * </p>
586
     * 
587
     * @param r
588
     *            the 2D rectangle in <i>screen coordinates</i> (pixels)
589
     * @return 2D rectangle equivalent in <i>map coordinates</i>
590
     * 
591
     * @see #fromMapRectangle(Rectangle2D)
592
     * @see #toMapDistance(int)
593
     * @see #toMapPoint(int, int)
594
     */
595
    public Rectangle2D toMapRectangle(Rectangle2D r) {
596
        Rectangle2D rect = new Rectangle2D.Double();
597
        Point2D p1 = toMapPoint((int) r.getX(), (int) r.getY());
598
        Point2D p2 = toMapPoint((int) r.getMaxX(), (int) r.getMaxY());
599
        rect.setFrameFromDiagonal(p1, p2);
600
        return rect;
444
  /**
445
   * <p>
446
   * Appends the specified {@link ViewPortListener ViewPortListener} listener if
447
   * weren't.
448
   * </p>
449
   * 
450
   * @param arg0 the listener to add
451
   * @return <code>true</code> if has been added successfully
452
   * @see #removeViewPortListener(ViewPortListener)
453
   */
454
  public boolean addViewPortListener(ViewPortListener arg0) {
455
    if (!listeners.contains(arg0)) {
456
      return listeners.add(arg0);
601 457
    }
458
    return false;
459
  }
602 460

  
603
    /**
604
     * <p>
605
     * Converts and returns the distance <code>d</code>, that is in <i>screen
606
     * coordinates</i> to <i>map coordinates</i> using the transformation affine
607
     * information in the {@link #trans #trans} attribute.
608
     * </p>
609
     * 
610
     * @param d
611
     *            distance in pixels
612
     * 
613
     * @return distance equivalent in <i>map coordinates</i>
614
     * 
615
     * @see #fromMapDistance(double)
616
     * @see AffineTransform
617
     */
618
    public double toMapDistance(int d) {
619
        double dist = d / trans.getScaleX();
461
  /**
462
   * <p>
463
   * Removes the specified {@link ViewPortListener ViewPortListener} listener,
464
   * if existed.
465
   * </p>
466
   * 
467
   * @param arg0 the listener to remove
468
   * @return <code>true</code> if the contained the specified listener.
469
   * @see #addViewPortListener(ViewPortListener)
470
   */
471
  public boolean removeViewPortListener(ViewPortListener arg0) {
472
    return listeners.remove(arg0);
473
  }
620 474

  
621
        return dist;
475
  /**
476
   * <p>
477
   * Converts and returns the distance <code>d</code>, that is in <i>map
478
   * coordinates</i> to <i>screen coordinates</i> using a <i>delta transform</i>
479
   * with the transformation affine information in the {@link #trans #trans}
480
   * attribute.
481
   * </p>
482
   * 
483
   * @param d distance in <i>map coordinates</i>
484
   * @return distance equivalent in <i>screen coordinates</i>
485
   * @see #toMapDistance(int)
486
   * @see AffineTransform#deltaTransform(Point2D, Point2D)S
487
   */
488
  public int fromMapDistance(double d) {
489
    Point2D.Double pWorld = new Point2D.Double(1, 1);
490
    Point2D.Double pScreen = new Point2D.Double();
491

  
492
    try {
493
      trans.deltaTransform(pWorld, pScreen);
622 494
    }
495
    catch (Exception e) {
496
      System.err.print(e.getMessage());
497
    }
623 498

  
624
    /**
625
     * <p>
626
     * Converts and returns the 2D point argument, that is in <i>screen
627
     * coordinates</i> (pixels) to <i>map coordinates</i> using the inverse
628
     * affine transformation of the {@link #trans #trans} attribute.
629
     * </p>
630
     * 
631
     * @param pScreen
632
     *            the 2D point in <i>screen coordinates</i> (pixels)
633
     * 
634
     * @return 2D point equivalent in <i>map coordinates</i>
635
     * 
636
     * @see #toMapPoint(int, int)
637
     * @see AffineTransform#createInverse()
638
     * @see AffineTransform#transform(Point2D, Point2D)
639
     * @deprecated use {@link #convertToMapPoint(Point2D)}
640
     */
641
    public Point2D toMapPoint(Point2D pScreen) {
642
        Point2D.Double pWorld = new Point2D.Double();
643
        AffineTransform at;
499
    return (int) (d * pScreen.x);
500
  }
644 501

  
645
        try {
646
            at = trans.createInverse();
647
            at.transform(pScreen, pWorld);
648
        } catch (NoninvertibleTransformException e) {
649
            throw new RuntimeException("Non invertible transform Exception", e);
650
        }
502
  /**
503
   * <p>
504
   * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>map
505
   * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
506
   * transformation in the {@link #trans #trans} attribute.
507
   * </p>
508
   * 
509
   * @param x the <code>x</code> <i>map coordinate</i> of a 2D point
510
   * @param y the <code>y</code> <i>map coordinate</i> of a 2D point
511
   * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
512
   * @see #fromMapPoint(Point2D)
513
   * @see AffineTransform#transform(Point2D, Point2D)
514
   */
515
  public Point2D fromMapPoint(double x, double y) {
516
    Point2D.Double pWorld = new Point2D.Double(x, y);
517
    Point2D.Double pScreen = new Point2D.Double();
651 518

  
652
        return pWorld;
519
    try {
520
      trans.transform(pWorld, pScreen);
653 521
    }
654

  
655
    public Point convertToMapPoint(Point2D pScreen) {
656
    	Point2D p = toMapPoint(pScreen);
657
		try {
658
			return geomManager.createPoint(
659
				p.getX(), 
660
				p.getY(), 
661
				Geometry.SUBTYPES.GEOM2D
662
			);
663
		} catch (CreateGeometryException e) {
664
			// FIXME: Use a most especific exception.
665
			throw new RuntimeException(e);
666
		}
522
    catch (Exception e) {
523
      System.err.print(e.getMessage());
667 524
    }
668
    
669
    public Point convertToMapPoint(int x, int y) {
670
        Point2D pScreen = new Point2D.Double(x, y);
671 525

  
672
        return convertToMapPoint(pScreen);
673
    }
526
    return pScreen;
527
  }
674 528

  
675
    
676
    /**
677
     * <p>
678
     * Returns the real distance (in <i>world coordinates</i>) at the graphic
679
     * layers of two 2D points (in <i>map coordinates</i>) of the plane where is
680
     * selected the <i>extent</i>.
681
     * </p>
682
     * <p>
683
     * If the projection of this view is UTM, considers the Earth curvature.
684
     * </p>
685
     * 
686
     * @param pt1
687
     *            a 2D point in <i>map coordinates</i>
688
     * @param pt2
689
     *            another 2D point in <i>map coordinates</i>
690
     * 
691
     * @return the distance in meters between the two points 2D
692
     * 
693
     * @see GeoCalcImpl#distanceVincenty(Point2D, Point2D)
694
     */
695
    public double distanceWorld(Point2D pt1, Point2D pt2) {
696
        
697
        double dist = 0;
698
        if (proj.isProjected()) {
699
            dist = pt1.distance(pt2);
700
            dist = dist * MapContext.getDistanceTrans2Meter()[getMapUnits()];
701
        } else {
702
            GeoCalc geocalc = new GeoCalc(proj);
703
            dist = geocalc.distanceVincenty(pt1, pt2);
704
        }
705
        return dist;
706
    }
529
  /**
530
   * <p>
531
   * Converts and returns the 2D point argument, that is in <i>map
532
   * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
533
   * transformation in the {@link #trans #trans} attribute.
534
   * </p>
535
   * 
536
   * @param point the 2D point in <i>map coordinates</i>
537
   * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
538
   * @see #toMapPoint(Point2D)
539
   * @see #fromMapPoint(double, double)
540
   */
541
  public Point2D fromMapPoint(Point2D point) {
542
    return fromMapPoint(point.getX(), point.getY());
543
  }
707 544

  
708
    /**
709
     * <p>
710
     * Sets as extent and adjusted extent of this view port, the previous.
711
     * Recalculating its parameters.
712
     * </p>
713
     * 
714
     * @see #getExtents()
715
     * @see #calculateAffineTransform()
716
     * @deprecated use {@link ViewPort#setPreviousEnvelope()}
717
     */
718
    public void setPreviousExtent() {
719
        setPreviousEnvelope();
720
    }
545
  /**
546
   * <p>
547
   * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>screen
548
   * coordinates</i> (pixels) to <i>map coordinates</i> using the affine
549
   * transformation in the {@link #trans #trans} attribute.
550
   * </p>
551
   * 
552
   * @param x the <code>x</code> <i>screen coordinate</i> of a 2D point
553
   * @param y the <code>y</code> <i>screen coordinate</i> of a 2D point
554
   * @return 2D point equivalent in <i>map coordinates</i>
555
   * @see #toMapPoint(Point2D)
556
   * @see #fromMapPoint(double, double)
557
   * @deprecated use {@link #convertToMapPoint(int, int)}
558
   */
559
  public Point2D toMapPoint(int x, int y) {
560
    Point2D pScreen = new Point2D.Double(x, y);
721 561

  
722
    /**
723
     * <p>
724
     * Sets as envelope and adjusted envelope of this view port, the previous.
725
     * Recalculating its parameters.
726
     * </p>
727
     * 
728
     * @see #getExtents()
729
     * @see #calculateAffineTransform()
730
     */
731
    public void setPreviousEnvelope() {
732
        this.updateDrawVersion();
733
        extent = extents.removePrev();
562
    return toMapPoint(pScreen);
563
  }
734 564

  
735
        // Calcula la transformaci�n af�n
736
        calculateAffineTransform();
565
  /**
566
   * <p>
567
   * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
568
   * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using
569
   * {@linkplain #toMapDistance(int)}, and {@linkplain #toMapPoint(int, int)}.
570
   * </p>
571
   * 
572
   * @param r the 2D rectangle in <i>screen coordinates</i> (pixels)
573
   * @return 2D rectangle equivalent in <i>map coordinates</i>
574
   * @see #fromMapRectangle(Rectangle2D)
575
   * @see #toMapDistance(int)
576
   * @see #toMapPoint(int, int)
577
   */
578
  public Rectangle2D toMapRectangle(Rectangle2D r) {
579
    Rectangle2D rect = new Rectangle2D.Double();
580
    Point2D p1 = toMapPoint((int) r.getX(), (int) r.getY());
581
    Point2D p2 = toMapPoint((int) r.getMaxX(), (int) r.getMaxY());
582
    rect.setFrameFromDiagonal(p1, p2);
583
    return rect;
584
  }
737 585

  
738
        // Lanzamos los eventos de extent cambiado
739
        callExtentChanged(getAdjustedExtent());
740
    }
586
  /**
587
   * <p>
588
   * Converts and returns the distance <code>d</code>, that is in <i>screen
589
   * coordinates</i> to <i>map coordinates</i> using the transformation affine
590
   * information in the {@link #trans #trans} attribute.
591
   * </p>
592
   * 
593
   * @param d distance in pixels
594
   * @return distance equivalent in <i>map coordinates</i>
595
   * @see #fromMapDistance(double)
596
   * @see AffineTransform
597
   */
598
  public double toMapDistance(int d) {
599
    double dist = d / trans.getScaleX();
741 600

  
742
    /**
743
     * <p>
744
     * Gets the area selected by user using some tool.
745
     * </p>
746
     * 
747
     * <p>
748
     * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
749
     * out</i> tools, but also zooming to a selected feature or shape) the
750
     * extent that covers that area is the value returned by this method. It is
751
     * not the actual area shown because it doesn't care about the aspect ratio
752
     * of the image size of the view. However, any part of the real world
753
     * contained in this extent is shown in the view.
754
     * </p>
755
     * 
756
     * <p>
757
     * If you are looking for the complete extent currently shown, you must use
758
     * the {@linkplain #getAdjustedExtent()} method.
759
     * </p>
760
     * 
761
     * @return the current extent
762
     * 
763
     * @see #setEnvelope(Envelope)
764
     * @see #getAdjustedExtent()
765
     * @see #setPreviousExtent()
766
     * @see #getExtents()
767
     * 
768
     * @deprecated use {@link ViewPort#getEnvelope()}
769
     */
770
    public Rectangle2D getExtent() {
771
        return extent;
601
    return dist;
602
  }
603

  
604
  /**
605
   * <p>
606
   * Converts and returns the 2D point argument, that is in <i>screen
607
   * coordinates</i> (pixels) to <i>map coordinates</i> using the inverse affine
608
   * transformation of the {@link #trans #trans} attribute.
609
   * </p>
610
   * 
611
   * @param pScreen the 2D point in <i>screen coordinates</i> (pixels)
612
   * @return 2D point equivalent in <i>map coordinates</i>
613
   * @see #toMapPoint(int, int)
614
   * @see AffineTransform#createInverse()
615
   * @see AffineTransform#transform(Point2D, Point2D)
616
   * @deprecated use {@link #convertToMapPoint(Point2D)}
617
   */
618
  public Point2D toMapPoint(Point2D pScreen) {
619
    Point2D.Double pWorld = new Point2D.Double();
620
    AffineTransform at;
621

  
622
    try {
623
      at = trans.createInverse();
624
      at.transform(pScreen, pWorld);
772 625
    }
626
    catch (NoninvertibleTransformException e) {
627
      throw new RuntimeException("Non invertible transform Exception", e);
628
    }
773 629

  
774
    /**
775
     * <p>
776
     * Gets the envelope selected by user using some tool.
777
     * </p>
778
     * 
779
     * <p>
780
     * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
781
     * out</i> tools, but also zooming to a selected feature or shape) the
782
     * envelope that covers that area is the value returned by this method. It
783
     * is not the actual envelope shown because it doesn't care about the aspect
784
     * ratio of the image size of the view. However, any part of the real world
785
     * contained in this envelope is shown in the view.
786
     * </p>
787
     * 
788
     * <p>
789
     * If you are looking for the complete extent currently shown, you must use
790
     * the {@linkplain #getAdjustedEnvelope()} method.
791
     * </p>
792
     * 
793
     * @return the current envelope
794
     * 
795
     * @see #setEnvelope(Envelope)
796
     * @see #getAdjustedEnvelope()
797
     * @see #setPreviousEnvelope()
798
     * @see #getEnvelopes()
799
     */
800
    public Envelope getEnvelope() {
801
        if (this.extent == null) {
802
            return null;
803
        }
804
        try {
805
            return geomManager.createEnvelope(extent.getMinX(),
806
                extent.getMinY(),
807
                extent.getMaxX(),
808
                extent.getMaxY(),
809
                SUBTYPES.GEOM2D);
810
            // This class has to use Envelope instead of Rectangle2D. This catch
811
            // will disappear
812
        } catch (CreateEnvelopeException e) {
813
            logger.error("Error creating the envelope");
814
        }
815
        return null;
630
    return pWorld;
631
  }
632

  
633
  public Point convertToMapPoint(Point2D pScreen) {
634
    Point2D p = toMapPoint(pScreen);
635
    try {
636
      return geomManager.createPoint(p.getX(), p.getY(),
637
          Geometry.SUBTYPES.GEOM2D);
816 638
    }
639
    catch (CreateGeometryException e) {
640
      // FIXME: Use a most especific exception.
641
      throw new RuntimeException(e);
642
    }
643
  }
817 644

  
818
    /**
819
     * <p>
820
     * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
821
     * <ul>
822
     * <li>Stores the previous extent.
823
     * <li>Calculates the new extent using <code>r</code>:
824
     * 
825
     * <pre>
826
     * extent =
827
     *     new Rectangle2D.Double(r.getMinX() - 0.1,
828
     *         r.getMinY() - 0.1,
829
     *         r.getWidth() + 0.2,
830
     *         r.getHeight() + 0.2);
831
     * </pre>
832
     * 
833
     * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
834
     * scale, adjusted extent, affine transformation between map and screen
835
     * coordinates, the real world coordinates equivalent to 1 pixel, and the
836
     * real world coordinates equivalent to 3 pixels.
837
     * <li>Notifies all {@link ViewPortListener ViewPortListener} registered
838
     * that the extent has changed.
839
     * </ul>
840
     * </p>
841
     * 
842
     * @param r
843
     *            the new extent
844
     * 
845
     * @see #getExtent()
846
     * @see #getExtents()
847
     * @see #calculateAffineTransform()
848
     * @see #setPreviousExtent()
849
     */
850
    public void setEnvelope(Envelope r) {
851
        Rectangle2D newExtent = null;
852
        // Esto comprueba que el extent no es de anchura o altura = "0"
853
        // y si es as� lo redimensiona.
854
        if (r != null) {
855
            if ((r.getMaximum(0) - r.getMinimum(0) == 0)
856
                || (r.getMaximum(1) - r.getMinimum(1) == 0)) {
857
                newExtent =
858
                    new Rectangle2D.Double(r.getMinimum(0) - 0.1,
859
                        r.getMinimum(1) - 0.1,
860
                        r.getMaximum(0) - r.getMinimum(0) + 0.2,
861
                        r.getMaximum(1) - r.getMinimum(1) + 0.2);
862
            } else {
863
                newExtent =
864
                    new Rectangle2D.Double(r.getMinimum(0),
865
                        r.getMinimum(1),
866
                        Math.abs(r.getMaximum(0) - r.getMinimum(0)),
867
                        Math.abs(r.getMaximum(1) - r.getMinimum(1)));
868
            }
869
        }
645
  public Point convertToMapPoint(int x, int y) {
646
    Point2D pScreen = new Point2D.Double(x, y);
870 647

  
871
        if (this.extent != null && this.extent.equals(newExtent)) {
872
            return;
873
        }
874
        if (extent != null) {
875
            extents.put(extent);
876
        }
877
        this.updateDrawVersion();
878
        this.extent = newExtent;
648
    return convertToMapPoint(pScreen);
649
  }
879 650

  
880
        // Calcula la transformaci�n af�n
881
        calculateAffineTransform();
651
  /**
652
   * <p>
653
   * Returns the real distance (in <i>world coordinates</i>) at the graphic
654
   * layers of two 2D points (in <i>map coordinates</i>) of the plane where is
655
   * selected the <i>extent</i>.
656
   * </p>
657
   * <p>
658
   * If the projection of this view is UTM, considers the Earth curvature.
659
   * </p>
660
   * 
661
   * @param pt1 a 2D point in <i>map coordinates</i>
662
   * @param pt2 another 2D point in <i>map coordinates</i>
663
   * @return the distance in meters between the two points 2D
664
   * @see GeoCalcImpl#distanceVincenty(Point2D, Point2D)
665
   */
666
  public double distanceWorld(Point2D pt1, Point2D pt2) {
882 667

  
883
        // Lanzamos los eventos de extent cambiado
884
        callExtentChanged(getAdjustedExtent());
668
    double dist = 0;
669
    if (proj.isProjected()) {
670
      dist = pt1.distance(pt2);
671
      dist = dist * MapContext.getDistanceTrans2Meter()[getMapUnits()];
885 672
    }
673
    else {
674
      GeoCalc geocalc = new GeoCalc(proj);
675
      dist = geocalc.distanceVincenty(pt1, pt2);
676
    }
677
    return dist;
678
  }
886 679

  
887
    /**
888
     * <p>
889
     * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
890
     * <ul>
891
     * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
892
     * scale, adjusted extent, affine transformation between map and screen
893
     * coordinates, the real world coordinates equivalent to 1 pixel, and the
894
     * real world coordinates equivalent to 3 pixels.
895
     * <li>Notifies to all {@link ViewPortListener ViewPortListener} registered
896
     * that the extent has changed.
897
     * </ul>
898
     * </p>
899
     * 
900
     * @see #setEnvelope(Envelope)
901
     * @see #calculateAffineTransform()
902
     */
903
    public void refreshExtent() {
904
        // this.scale = scale;
680
  /**
681
   * <p>
682
   * Sets as extent and adjusted extent of this view port, the previous.
683
   * Recalculating its parameters.
684
   * </p>
685
   * 
686
   * @see #getExtents()
687
   * @see #calculateAffineTransform()
688
   * @deprecated use {@link ViewPort#setPreviousEnvelope()}
689
   */
690
  public void setPreviousExtent() {
691
    setPreviousEnvelope();
692
  }
905 693

  
906
        // Calcula la transformaci�n af�n
907
        calculateAffineTransform();
694
  /**
695
   * <p>
696
   * Sets as envelope and adjusted envelope of this view port, the previous.
697
   * Recalculating its parameters.
698
   * </p>
699
   * 
700
   * @see #getExtents()
701
   * @see #calculateAffineTransform()
702
   */
703
  public void setPreviousEnvelope() {
704
    this.updateDrawVersion();
705
    extent = extentsHistory.removePrev();
908 706

  
909
        // Lanzamos los eventos de extent cambiado
910
        callExtentChanged(getAdjustedExtent());
911
    }
707
    // Calcula la transformaci�n af�n
708
    calculateAffineTransform();
912 709

  
913
    /**
914
     * <p>
915
     * Calculates and returns using the current projection of this view port,
916
     * the scale that is the extent in <i>screen coordinates</i> from the image
917
     * in <i>map coordinates</i>.
918
     * </p>
919
     * 
920
     * @return the scale <i>extent / image size</i> projected by this view port
921
     * 
922
     * @deprecated since 07/09/07, use {@linkplain MapContext#getScaleView()}
923
     */
924
    private double getScale() {
925
        
926
        double[] trans2Meter = MapContext.getDistanceTrans2Meter();
927
        if (proj == null) {
928
            double wmeters = ((getImageSize().width / this.getDPI()) * 0.0254);
929
            return (long) (
930
                (trans2Meter[getMapUnits()] * getAdjustedEnvelope().getLength(0))
931
                / wmeters);
932
        } else {
933
            return Math.round(proj.getScale(
934
                getAdjustedEnvelope().getMinimum(0)*trans2Meter[getMapUnits()],
935
                getAdjustedEnvelope().getMaximum(0)*trans2Meter[getMapUnits()],
936
                getImageSize().width,
937
                this.getDPI()));
938
        }
710
    // Lanzamos los eventos de extent cambiado
711
    callExtentChanged(getAdjustedExtent());
712
  }
939 713

  
940
        /*
941
        return proj.getScale(extent.getMinX(),
942
            extent.getMaxX(),
943
            imageSize.width,
944
            dpi);
945
        */
714
  /**
715
   * <p>
716
   * Sets as envelope and adjusted envelope of this view port, the next.
717
   * Recalculating its parameters.
718
   * </p>
719
   * 
720
   * @see #getExtents()
721
   * @see #calculateAffineTransform()
722
   */
723
  public void setNextEnvelope() {
724
    this.updateDrawVersion();
725
    extent = extentsHistory.removeNext();
726

  
727
    // Calcula la transformaci�n af�n
728
    calculateAffineTransform();
729

  
730
    // Lanzamos los eventos de extent cambiado
731
    callExtentChanged(getAdjustedExtent());
732
  }
733

  
734
  /**
735
   * <p>
736
   * Gets the area selected by user using some tool.
737
   * </p>
738
   * <p>
739
   * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
740
   * out</i> tools, but also zooming to a selected feature or shape) the extent
741
   * that covers that area is the value returned by this method. It is not the
742
   * actual area shown because it doesn't care about the aspect ratio of the
743
   * image size of the view. However, any part of the real world contained in
744
   * this extent is shown in the view.
745
   * </p>
746
   * <p>
747
   * If you are looking for the complete extent currently shown, you must use
748
   * the {@linkplain #getAdjustedExtent()} method.
749
   * </p>
750
   * 
751
   * @return the current extent
752
   * @see #setEnvelope(Envelope)
753
   * @see #getAdjustedExtent()
754
   * @see #setPreviousExtent()
755
   * @see #getExtents()
756
   * @deprecated use {@link ViewPort#getEnvelope()}
757
   */
758
  public Rectangle2D getExtent() {
759
    return extent;
760
  }
761

  
762
  /**
763
   * <p>
764
   * Gets the envelope selected by user using some tool.
765
   * </p>
766
   * <p>
767
   * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
768
   * out</i> tools, but also zooming to a selected feature or shape) the
769
   * envelope that covers that area is the value returned by this method. It is
770
   * not the actual envelope shown because it doesn't care about the aspect
771
   * ratio of the image size of the view. However, any part of the real world
772
   * contained in this envelope is shown in the view.
773
   * </p>
774
   * <p>
775
   * If you are looking for the complete extent currently shown, you must use
776
   * the {@linkplain #getAdjustedEnvelope()} method.
777
   * </p>
778
   * 
779
   * @return the current envelope
780
   * @see #setEnvelope(Envelope)
781
   * @see #getAdjustedEnvelope()
782
   * @see #setPreviousEnvelope()
783
   * @see #getEnvelopes()
784
   */
785
  public Envelope getEnvelope() {
786
    if (this.extent == null) {
787
      return null;
946 788
    }
789
    try {
790
      return geomManager.createEnvelope(extent.getMinX(), extent.getMinY(),
791
          extent.getMaxX(), extent.getMaxY(), SUBTYPES.GEOM2D);
792
      // This class has to use Envelope instead of Rectangle2D. This catch
793
      // will disappear
794
    }
795
    catch (CreateEnvelopeException e) {
796
      logger.error("Error creating the envelope");
797
    }
798
    return null;
799
  }
947 800

  
948
    /**
949
     * <p>
950
     * Affine transformation between <i>map 2D coordinates</i> to <i>screen 2D
951
     * coordinates</i> (pixels), preserving the "straightness" and "parallelism"
952
     * of the lines.
953
     * </p>
954
     * 
955
     * @return the affine transformation
956
     * 
957
     * @see #setAffineTransform(AffineTransform)
958
     * @see #calculateAffineTransform()
959
     */
960
    public AffineTransform getAffineTransform() {
961
        return trans;
801
  /**
802
   * <p>
803
   * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff