Revision 33613 branches/v2_0_0_prep/libraries/libFMap_mapcontext/src/org/gvsig/fmap/mapcontext/ViewPort.java

View differences:

ViewPort.java
43 43
import java.awt.Color;
44 44
import java.awt.Dimension;
45 45
import java.awt.Toolkit;
46
import java.awt.color.ColorSpace;
46 47
import java.awt.geom.AffineTransform;
47 48
import java.awt.geom.NoninvertibleTransformException;
48 49
import java.awt.geom.Point2D;
49 50
import java.awt.geom.Rectangle2D;
50 51
import java.util.ArrayList;
52
import java.util.Iterator;
51 53

  
52 54
import org.cresques.cts.GeoCalc;
53 55
import org.cresques.cts.IProjection;
......
71 73
import org.slf4j.Logger;
72 74
import org.slf4j.LoggerFactory;
73 75

  
76
import org.gvsig.tools.lang.Cloneable;
77

  
74 78
/**
75 79
 * <p>
76 80
 * <code>ViewPort</code> class represents the logic needed to transform a
......
117 121
 * 
118 122
 * @author Vicente Caballero Navarro
119 123
 */
120
public class ViewPort implements Persistent {
121
	private static final String FIELD_DISTANCE_AREA = "distanceArea";
122
	private static final String FIELD_IMAGE_SIZE = "imageSize";
123
	private static final String FIELD_PROJ = "proj";
124
	private static final String FIELD_OFFSET = "offset";
125
	private static final String FIELD_MAP_UNITS = "mapUnits";
126
	private static final String FIELD_EXTENT = "extent";
127
	private static final String FIELD_EXTENTS = "extents";
128
	private static final String FIELD_DISTANCE_UNITS = "distanceUnits";
129
	private static final String FIELD_DIST3PIXEL = "dist3pixel";
130
	private static final String FIELD_DIST1PIXEL = "dist1pixel";
131
	private static final String FIELD_CLIP = "clip";
132
	private static final String FIELD_BACK_COLOR = "backColor";
133
	private static final String FIELD_ADJUSTED_EXTENT = "adjustedExtent";
124
public class ViewPort implements Persistent, Cloneable {
134 125

  
135
	private static final GeometryManager geomManager = GeometryLocator
136
			.getGeometryManager();
137
	private static final Logger logger = LoggerFactory.getLogger(ViewPort.class);
126
    private static final String FIELD_DISTANCE_AREA = "distanceArea";
127
    private static final String FIELD_IMAGE_SIZE = "imageSize";
128
    private static final String FIELD_PROJ = "proj";
129
    private static final String FIELD_OFFSET = "offset";
130
    private static final String FIELD_MAP_UNITS = "mapUnits";
131
    private static final String FIELD_EXTENT = "extent";
132
    private static final String FIELD_EXTENTS = "extents";
133
    private static final String FIELD_DISTANCE_UNITS = "distanceUnits";
134
    private static final String FIELD_DIST3PIXEL = "dist3pixel";
135
    private static final String FIELD_DIST1PIXEL = "dist1pixel";
136
    private static final String FIELD_CLIP = "clip";
137
    private static final String FIELD_BACK_COLOR = "backColor";
138
    private static final String FIELD_ADJUSTED_EXTENT = "adjustedExtent";
138 139

  
139
	/**
140
	 * <p>
141
	 * Screen resolution in <i>dots-per-inch</i>. Useful to calculate the
142
	 * geographic scale of the view.
143
	 * </p>
144
	 * 
145
	 * @see Toolkit#getScreenResolution()
146
	 * @see #getScale()
147
	 */
148
	private static int dpi = java.awt.Toolkit.getDefaultToolkit()
149
			.getScreenResolution();
140
    private static final GeometryManager geomManager =
141
        GeometryLocator.getGeometryManager();
142
    private static final Logger logger =
143
        LoggerFactory.getLogger(ViewPort.class);
150 144

  
151
	/**
152
	 * <p>
153
	 * Area selected by user using some tool.
154
	 * </p>
155
	 * 
156
	 * <p>
157
	 * When the zoom changes (for instance when using the zoom in or zoom out
158
	 * tools, but also zooming to a selected feature or shape) the extent that
159
	 * covers that area is the value returned by this method. It is not the
160
	 * actual area shown in the view because it does not care about the aspect
161
	 * ratio of the available area. However, any part of the real world
162
	 * contained in this extent is shown in the view.
163
	 * </p>
164
	 * <p>
165
	 * Probably this is not what you are looking for. If you are looking for the
166
	 * complete extent currently shown, you must use
167
	 * {@linkplain #getAdjustedExtent()} method which returns the extent that
168
	 * contains this one but regarding the current view's aspect ratio.
169
	 * </p>
170
	 * 
171
	 * @see #getExtent()
172
	 * @see #setEnvelope(Envelope)
173
	 */
174
	protected Rectangle2D extent;
145
    /**
146
     * <p>
147
     * Screen resolution in <i>dots-per-inch</i>. Useful to calculate the
148
     * geographic scale of the view.
149
     * </p>
150
     * 
151
     * @see Toolkit#getScreenResolution()
152
     * @see #getScale()
153
     */
154
    private static int dpi = java.awt.Toolkit.getDefaultToolkit()
155
        .getScreenResolution();
175 156

  
176
	/**
177
	 * <p>
178
	 * Location and dimensions of the extent adjusted to the image size.
179
	 * </p>
180
	 * 
181
	 * @see #getAdjustedExtent()
182
	 */
183
	protected Rectangle2D adjustedExtent;
157
    /**
158
     * <p>
159
     * Area selected by user using some tool.
160
     * </p>
161
     * 
162
     * <p>
163
     * When the zoom changes (for instance when using the zoom in or zoom out
164
     * tools, but also zooming to a selected feature or shape) the extent that
165
     * covers that area is the value returned by this method. It is not the
166
     * actual area shown in the view because it does not care about the aspect
167
     * ratio of the available area. However, any part of the real world
168
     * contained in this extent is shown in the view.
169
     * </p>
170
     * <p>
171
     * Probably this is not what you are looking for. If you are looking for the
172
     * complete extent currently shown, you must use
173
     * {@linkplain #getAdjustedExtent()} method which returns the extent that
174
     * contains this one but regarding the current view's aspect ratio.
175
     * </p>
176
     * 
177
     * @see #getExtent()
178
     * @see #setEnvelope(Envelope)
179
     */
180
    protected Rectangle2D extent;
184 181

  
185
	/**
186
	 * Draw version of the context. It's used for know when de componend has
187
	 * changed any visualization property
188
	 * 
189
	 * @see getDrawVersion
190
	 * @see updateDrawVersion
191
	 */
192
	private long drawVersion = 0L;
182
    /**
183
     * <p>
184
     * Location and dimensions of the extent adjusted to the image size.
185
     * </p>
186
     * 
187
     * @see #getAdjustedExtent()
188
     */
189
    protected Rectangle2D adjustedExtent;
193 190

  
194
	/**
195
	 * <p>
196
	 * History with the last extents of the view.
197
	 * </p>
198
	 * 
199
	 * @see #setPreviousExtent()
200
	 * @see #getExtents()
201
	 */
202
	protected ExtentHistory extents = new ExtentHistory();
191
    /**
192
     * Draw version of the context. It's used for know when de componend has
193
     * changed any visualization property
194
     * 
195
     * @see getDrawVersion
196
     * @see updateDrawVersion
197
     */
198
    private long drawVersion = 0L;
203 199

  
204
	/**
205
	 * <p>
206
	 * Size in <i>screen coordinates</i> of the rectangle where the image is
207
	 * displayed.
208
	 * </p>
209
	 * <p>
210
	 * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
211
	 * 
212
	 * <ul>
213
	 * <li>The new {@link #scale scale} .
214
	 * <li>The new {@link #adjustedExtent adjustableExtent} .
215
	 * <li>The new {@link #trans trans} .
216
	 * <li>The new real world coordinates equivalent to 1 pixel (
217
	 * {@link #dist1pixel dist1pixel}) .
218
	 * <li>The new real world coordinates equivalent to 3 pixels (
219
	 * {@link #dist3pixel dist3pixel}) .
220
	 * </ul>
221
	 * </p>
222
	 * 
223
	 * @see #getImageSize()
224
	 * @see #getImageHeight()
225
	 * @see #getImageWidth()
226
	 * @see #setImageSize(Dimension)
227
	 */
228
	private Dimension imageSize;
200
    /**
201
     * <p>
202
     * History with the last extents of the view.
203
     * </p>
204
     * 
205
     * @see #setPreviousExtent()
206
     * @see #getExtents()
207
     */
208
    protected ExtentHistory extents = new ExtentHistory();
229 209

  
230
	/**
231
	 * <p>
232
	 * the affine transformation between the {@link #extent extent} in <i>map 2D
233
	 * coordinates</i> to the image area in the screen, in <i>screen 2D
234
	 * coordinates</i> (pixels).
235
	 * </p>
236
	 * 
237
	 * @see AffineTransform
238
	 * 
239
	 * @see #getAffineTransform()
240
	 * @see #setAffineTransform(AffineTransform)
241
	 * @see #calculateAffineTransform()
242
	 */
243
	private AffineTransform trans = new AffineTransform();
210
    /**
211
     * <p>
212
     * Size in <i>screen coordinates</i> of the rectangle where the image is
213
     * displayed.
214
     * </p>
215
     * <p>
216
     * Used by {@linkplain #calculateAffineTransform()} to calculate:<br>
217
     * 
218
     * <ul>
219
     * <li>The new {@link #scale scale} .
220
     * <li>The new {@link #adjustedExtent adjustableExtent} .
221
     * <li>The new {@link #trans trans} .
222
     * <li>The new real world coordinates equivalent to 1 pixel (
223
     * {@link #dist1pixel dist1pixel}) .
224
     * <li>The new real world coordinates equivalent to 3 pixels (
225
     * {@link #dist3pixel dist3pixel}) .
226
     * </ul>
227
     * </p>
228
     * 
229
     * @see #getImageSize()
230
     * @see #getImageHeight()
231
     * @see #getImageWidth()
232
     * @see #setImageSize(Dimension)
233
     */
234
    private Dimension imageSize;
244 235

  
245
	/**
246
	 * <p>
247
	 * Measurement unit used for measuring distances and displaying information.
248
	 * </p>
249
	 * 
250
	 * @see #getDistanceUnits()
251
	 * @see #setDistanceUnits(int)
252
	 */
253
	private int distanceUnits = 1;
254
	/**
255
	 * <p>
256
	 * Measurement unit used for measuring areas and displaying information.
257
	 * </p>
258
	 * 
259
	 * @see #getDistanceArea()
260
	 * @see #setDistanceArea(int)
261
	 */
262
	private int distanceArea = 1;
263
	/**
264
	 * <p>
265
	 * Measurement unit used by this view port for the map.
266
	 * </p>
267
	 * 
268
	 * @see #getMapUnits()
269
	 * @see #setMapUnits(int)
270
	 */
271
	private int mapUnits = 1;
236
    /**
237
     * <p>
238
     * the affine transformation between the {@link #extent extent} in <i>map 2D
239
     * coordinates</i> to the image area in the screen, in <i>screen 2D
240
     * coordinates</i> (pixels).
241
     * </p>
242
     * 
243
     * @see AffineTransform
244
     * 
245
     * @see #getAffineTransform()
246
     * @see #setAffineTransform(AffineTransform)
247
     * @see #calculateAffineTransform()
248
     */
249
    private AffineTransform trans = new AffineTransform();
272 250

  
273
	/**
274
	 * <p>
275
	 * Array with the {@link ViewPortListener ViewPortListener}s registered to
276
	 * this view port.
277
	 * </p>
278
	 * 
279
	 * @see #addViewPortListener(ViewPortListener)
280
	 * @see #removeViewPortListener(ViewPortListener)
281
	 */
282
	private ArrayList listeners = new ArrayList();
251
    /**
252
     * <p>
253
     * Measurement unit used for measuring distances and displaying information.
254
     * </p>
255
     * 
256
     * @see #getDistanceUnits()
257
     * @see #setDistanceUnits(int)
258
     */
259
    private int distanceUnits = 1;
260
    /**
261
     * <p>
262
     * Measurement unit used for measuring areas and displaying information.
263
     * </p>
264
     * 
265
     * @see #getDistanceArea()
266
     * @see #setDistanceArea(int)
267
     */
268
    private int distanceArea = 1;
269
    /**
270
     * <p>
271
     * Measurement unit used by this view port for the map.
272
     * </p>
273
     * 
274
     * @see #getMapUnits()
275
     * @see #setMapUnits(int)
276
     */
277
    private int mapUnits = 1;
283 278

  
284
	/**
285
	 * <p>
286
	 * The offset is the position where start drawing the map.
287
	 * </p>
288
	 * <p>
289
	 * The offset of a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
290
	 * <i>View</i> is always (0, 0) because the drawing area fits with the full
291
	 * window area. But in a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
292
	 * <i>Layout</i> it's up to the place where the <code>FFrameView</code> is
293
	 * located.
294
	 * </p>
295
	 * 
296
	 * @see #getOffset()
297
	 * @see #setOffset(Point2D)
298
	 */
299
	private Point2D offset = new Point2D.Double(0, 0);
279
    /**
280
     * <p>
281
     * Array with the {@link ViewPortListener ViewPortListener}s registered to
282
     * this view port.
283
     * </p>
284
     * 
285
     * @see #addViewPortListener(ViewPortListener)
286
     * @see #removeViewPortListener(ViewPortListener)
287
     */
288
    private ArrayList listeners = new ArrayList();
300 289

  
301
	/**
302
	 * <p>
303
	 * Clipping area.
304
	 * </p>
305
	 */
306
	// private Rectangle2D clip;
290
    /**
291
     * <p>
292
     * The offset is the position where start drawing the map.
293
     * </p>
294
     * <p>
295
     * The offset of a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
296
     * <i>View</i> is always (0, 0) because the drawing area fits with the full
297
     * window area. But in a <a href="http://www.gvsig.gva.es/">gvSIG</a>'s
298
     * <i>Layout</i> it's up to the place where the <code>FFrameView</code> is
299
     * located.
300
     * </p>
301
     * 
302
     * @see #getOffset()
303
     * @see #setOffset(Point2D)
304
     */
305
    private Point2D offset = new Point2D.Double(0, 0);
307 306

  
308
	/**
309
	 * <p>
310
	 * Background color of this view.
311
	 * </p>
312
	 * 
313
	 * @see #getBackColor()
314
	 * @see #setBackColor(Color)
315
	 */
316
	private Color backColor = null; // Color.WHITE;
307
    /**
308
     * <p>
309
     * Clipping area.
310
     * </p>
311
     */
312
    // private Rectangle2D clip;
317 313

  
318
	/**
319
	 * <p>
320
	 * Information about the map projection used in this view.
321
	 * </p>
322
	 * 
323
	 * @see #getProjection()
324
	 * @see #setProjection(IProjection)
325
	 */
326
	private IProjection proj;
314
    /**
315
     * <p>
316
     * Background color of this view.
317
     * </p>
318
     * 
319
     * @see #getBackColor()
320
     * @see #setBackColor(Color)
321
     */
322
    private Color backColor = null; // Color.WHITE;
327 323

  
328
	/**
329
	 * <p>
330
	 * Represents the distance in <i>world coordinates</i> equivalent to 1 pixel
331
	 * in the view with the current extent.
332
	 * </p>
333
	 * 
334
	 * @see #getDist1pixel()
335
	 * @see #setDist1pixel(double)
336
	 */
337
	private double dist1pixel;
324
    /**
325
     * <p>
326
     * Information about the map projection used in this view.
327
     * </p>
328
     * 
329
     * @see #getProjection()
330
     * @see #setProjection(IProjection)
331
     */
332
    private IProjection proj;
338 333

  
339
	/**
340
	 * <p>
341
	 * Represents the distance in <i>world coordinates</i> equivalent to 3
342
	 * pixels in the view with the current extent.
343
	 * </p>
344
	 * 
345
	 * @see #getDist3pixel()
346
	 * @see #setDist3pixel(double)
347
	 */
348
	private double dist3pixel;
334
    /**
335
     * <p>
336
     * Represents the distance in <i>world coordinates</i> equivalent to 1 pixel
337
     * in the view with the current extent.
338
     * </p>
339
     * 
340
     * @see #getDist1pixel()
341
     * @see #setDist1pixel(double)
342
     */
343
    private double dist1pixel;
349 344

  
350
	/**
351
	 * <p>
352
	 * Ratio between the size of <code>imageSize</code> and <code>extent</code>:
353
	 * <br>
354
	 * <i>
355
	 * 
356
	 * <pre>
357
	 * min{(imageSize.getHeight()/extent.getHeight(), imageSize.getWidth()/extent.getWidth())}
358
	 * </pre>
359
	 * 
360
	 * </i>
361
	 * </p>
362
	 */
363
	private double scale;
345
    /**
346
     * <p>
347
     * Represents the distance in <i>world coordinates</i> equivalent to 3
348
     * pixels in the view with the current extent.
349
     * </p>
350
     * 
351
     * @see #getDist3pixel()
352
     * @see #setDist3pixel(double)
353
     */
354
    private double dist3pixel;
364 355

  
365
	/**
366
	 * <p>
367
	 * Clipping area.
368
	 * </p>
369
	 * 
370
	 * @see #setClipRect(Rectangle2D)
371
	 */
372
	private Rectangle2D cliprect;
356
    /**
357
     * <p>
358
     * Ratio between the size of <code>imageSize</code> and <code>extent</code>:
359
     * <br>
360
     * <i>
361
     * 
362
     * <pre>
363
     * min{(imageSize.getHeight()/extent.getHeight(), imageSize.getWidth()/extent.getWidth())}
364
     * </pre>
365
     * 
366
     * </i>
367
     * </p>
368
     */
369
    private double scale;
373 370

  
374
	/**
375
	 * <p>
376
	 * Enables or disables the <i>"adjustable extent"</i> mode.
377
	 * </p>
378
	 * 
379
	 * <p>
380
	 * When calculates the affine transform, if
381
	 * <ul>
382
	 * <li><i>enabled</i>: the new <code>adjustedExtent</code> will have the (X,
383
	 * Y) coordinates of the <code>extent</code> and an area that will be an
384
	 * scale of the image size. That area will have different height or width
385
	 * (not both) of the extent according the least ratio (height or width) in
386
	 * 
387
	 * <pre>
388
	 * image.size/extent.size&quot;
389
	 * </pre>.
390
	 * <li><i>disabled</i>: the new <code>adjustedExtent</code> will be like
391
	 * <code>extent</code>.
392
	 * </ul>
393
	 * </p>
394
	 * 
395
	 * @see #setAdjustable(boolean)
396
	 */
397
	private boolean adjustableExtent = true;
371
    /**
372
     * <p>
373
     * Clipping area.
374
     * </p>
375
     * 
376
     * @see #setClipRect(Rectangle2D)
377
     */
378
    private Rectangle2D cliprect;
398 379

  
399
	public ViewPort() {
400
		
401
	}
402
	/**
403
	 * <p>
404
	 * Creates a new view port with the information of the projection in
405
	 * <code>proj</code> argument, and default configuration:
406
	 * </p>
407
	 * <p>
408
	 * <ul>
409
	 * <li><i><code>distanceUnits</code></i> = meters
410
	 * <li><i><code>mapUnits</code></i> = meters
411
	 * <li><i><code>backColor</code></i> = <i>undefined</i>
412
	 * <li><i><code>offset</code></i> = <code>new Point2D.Double(0, 0);</code>
413
	 * </ul>
414
	 * </p>
415
	 * 
416
	 * @param proj
417
	 *            information of the projection for this view port
418
	 */
419
	public ViewPort(IProjection proj) {
420
		// Por defecto
421
		this.proj = proj;
422
	}
380
    /**
381
     * <p>
382
     * Enables or disables the <i>"adjustable extent"</i> mode.
383
     * </p>
384
     * 
385
     * <p>
386
     * When calculates the affine transform, if
387
     * <ul>
388
     * <li><i>enabled</i>: the new <code>adjustedExtent</code> will have the (X,
389
     * Y) coordinates of the <code>extent</code> and an area that will be an
390
     * scale of the image size. That area will have different height or width
391
     * (not both) of the extent according the least ratio (height or width) in
392
     * 
393
     * <pre>
394
     * image.size/extent.size&quot;
395
     * </pre>.
396
     * <li><i>disabled</i>: the new <code>adjustedExtent</code> will be like
397
     * <code>extent</code>.
398
     * </ul>
399
     * </p>
400
     * 
401
     * @see #setAdjustable(boolean)
402
     */
403
    private boolean adjustableExtent = true;
423 404

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

  
447
	/**
448
	 * <p>
449
	 * Appends the specified {@link ViewPortListener ViewPortListener} listener
450
	 * if weren't.
451
	 * </p>
452
	 * 
453
	 * @param arg0
454
	 *            the listener to add
455
	 * 
456
	 * @return <code>true</code> if has been added successfully
457
	 * 
458
	 * @see #removeViewPortListener(ViewPortListener)
459
	 */
460
	public boolean addViewPortListener(ViewPortListener arg0) {
461
		if (!listeners.contains(arg0)) {
462
			return listeners.add(arg0);
463
		}
464
		return false;
465
	}
407
    }
466 408

  
467
	/**
468
	 * <p>
469
	 * Removes the specified {@link ViewPortListener ViewPortListener} listener,
470
	 * if existed.
471
	 * </p>
472
	 * 
473
	 * @param arg0
474
	 *            the listener to remove
475
	 * 
476
	 * @return <code>true</code> if the contained the specified listener.
477
	 * 
478
	 * @see #addViewPortListener(ViewPortListener)
479
	 */
480
	public boolean removeViewPortListener(ViewPortListener arg0) {
481
		return listeners.remove(arg0);
482
	}
409
    /**
410
     * <p>
411
     * Creates a new view port with the information of the projection in
412
     * <code>proj</code> argument, and default configuration:
413
     * </p>
414
     * <p>
415
     * <ul>
416
     * <li><i><code>distanceUnits</code></i> = meters
417
     * <li><i><code>mapUnits</code></i> = meters
418
     * <li><i><code>backColor</code></i> = <i>undefined</i>
419
     * <li><i><code>offset</code></i> = <code>new Point2D.Double(0, 0);</code>
420
     * </ul>
421
     * </p>
422
     * 
423
     * @param proj
424
     *            information of the projection for this view port
425
     */
426
    public ViewPort(IProjection proj) {
427
        // Por defecto
428
        this.proj = proj;
429
    }
483 430

  
484
	/**
485
	 * <p>
486
	 * Converts and returns the distance <code>d</code>, that is in <i>map
487
	 * coordinates</i> to <i>screen coordinates</i> using a <i>delta
488
	 * transform</i> with the transformation affine information in the
489
	 * {@link #trans #trans} attribute.
490
	 * </p>
491
	 * 
492
	 * @param d
493
	 *            distance in <i>map coordinates</i>
494
	 * 
495
	 * @return distance equivalent in <i>screen coordinates</i>
496
	 * 
497
	 * @see #toMapDistance(int)
498
	 * @see AffineTransform#deltaTransform(Point2D, Point2D)S
499
	 */
500
	public int fromMapDistance(double d) {
501
		Point2D.Double pWorld = new Point2D.Double(1, 1);
502
		Point2D.Double pScreen = new Point2D.Double();
431
    /**
432
     * <p>
433
     * Changes the status of the <i>"adjustable extent"</i> option to enabled or
434
     * disabled.
435
     * </p>
436
     * 
437
     * <p>
438
     * If view port isn't adjustable, won't bear in mind the aspect ratio of the
439
     * available rectangular area to calculate the affine transform from the
440
     * original map in real coordinates. (Won't scale the image to adapt it to
441
     * the available rectangular area).
442
     * </p>
443
     * 
444
     * @param boolean the boolean to be set
445
     */
446
    public void setAdjustable(boolean adjustable) {
447
        if (adjustable == adjustableExtent) {
448
            return;
449
        }
450
        adjustableExtent = adjustable;
451
        this.updateDrawVersion();
452
    }
503 453

  
504
		try {
505
			trans.deltaTransform(pWorld, pScreen);
506
		} catch (Exception e) {
507
			System.err.print(e.getMessage());
508
		}
454
    /**
455
     * <p>
456
     * Appends the specified {@link ViewPortListener ViewPortListener} listener
457
     * if weren't.
458
     * </p>
459
     * 
460
     * @param arg0
461
     *            the listener to add
462
     * 
463
     * @return <code>true</code> if has been added successfully
464
     * 
465
     * @see #removeViewPortListener(ViewPortListener)
466
     */
467
    public boolean addViewPortListener(ViewPortListener arg0) {
468
        if (!listeners.contains(arg0)) {
469
            return listeners.add(arg0);
470
        }
471
        return false;
472
    }
509 473

  
510
		return (int) (d * pScreen.x);
511
	}
474
    /**
475
     * <p>
476
     * Removes the specified {@link ViewPortListener ViewPortListener} listener,
477
     * if existed.
478
     * </p>
479
     * 
480
     * @param arg0
481
     *            the listener to remove
482
     * 
483
     * @return <code>true</code> if the contained the specified listener.
484
     * 
485
     * @see #addViewPortListener(ViewPortListener)
486
     */
487
    public boolean removeViewPortListener(ViewPortListener arg0) {
488
        return listeners.remove(arg0);
489
    }
512 490

  
513
	/**
514
	 * <p>
515
	 * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>map
516
	 * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
517
	 * transformation in the {@link #trans #trans} attribute.
518
	 * </p>
519
	 * 
520
	 * @param x
521
	 *            the <code>x</code> <i>map coordinate</i> of a 2D point
522
	 * @param y
523
	 *            the <code>y</code> <i>map coordinate</i> of a 2D point
524
	 * 
525
	 * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
526
	 * 
527
	 * @see #fromMapPoint(Point2D)
528
	 * @see AffineTransform#transform(Point2D, Point2D)
529
	 */
530
	public Point2D fromMapPoint(double x, double y) {
531
		Point2D.Double pWorld = new Point2D.Double(x, y);
532
		Point2D.Double pScreen = new Point2D.Double();
491
    /**
492
     * <p>
493
     * Converts and returns the distance <code>d</code>, that is in <i>map
494
     * coordinates</i> to <i>screen coordinates</i> using a <i>delta
495
     * transform</i> with the transformation affine information in the
496
     * {@link #trans #trans} attribute.
497
     * </p>
498
     * 
499
     * @param d
500
     *            distance in <i>map coordinates</i>
501
     * 
502
     * @return distance equivalent in <i>screen coordinates</i>
503
     * 
504
     * @see #toMapDistance(int)
505
     * @see AffineTransform#deltaTransform(Point2D, Point2D)S
506
     */
507
    public int fromMapDistance(double d) {
508
        Point2D.Double pWorld = new Point2D.Double(1, 1);
509
        Point2D.Double pScreen = new Point2D.Double();
533 510

  
534
		try {
535
			trans.transform(pWorld, pScreen);
536
		} catch (Exception e) {
537
			System.err.print(e.getMessage());
538
		}
511
        try {
512
            trans.deltaTransform(pWorld, pScreen);
513
        } catch (Exception e) {
514
            System.err.print(e.getMessage());
515
        }
539 516

  
540
		return pScreen;
541
	}
517
        return (int) (d * pScreen.x);
518
    }
542 519

  
543
	/**
544
	 * <p>
545
	 * Converts and returns the 2D point argument, that is in <i>map
546
	 * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
547
	 * transformation in the {@link #trans #trans} attribute.
548
	 * </p>
549
	 * 
550
	 * @param point
551
	 *            the 2D point in <i>map coordinates</i>
552
	 * 
553
	 * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
554
	 * 
555
	 * @see #toMapPoint(Point2D)
556
	 * @see #fromMapPoint(double, double)
557
	 */
558
	public Point2D fromMapPoint(Point2D point) {
559
		return fromMapPoint(point.getX(), point.getY());
560
	}
520
    /**
521
     * <p>
522
     * Converts and returns the 2D point <code>(x,y)</code>, that is in <i>map
523
     * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
524
     * transformation in the {@link #trans #trans} attribute.
525
     * </p>
526
     * 
527
     * @param x
528
     *            the <code>x</code> <i>map coordinate</i> of a 2D point
529
     * @param y
530
     *            the <code>y</code> <i>map coordinate</i> of a 2D point
531
     * 
532
     * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
533
     * 
534
     * @see #fromMapPoint(Point2D)
535
     * @see AffineTransform#transform(Point2D, Point2D)
536
     */
537
    public Point2D fromMapPoint(double x, double y) {
538
        Point2D.Double pWorld = new Point2D.Double(x, y);
539
        Point2D.Double pScreen = new Point2D.Double();
561 540

  
562
	/**
563
	 * <p>
564
	 * Converts and returns the 2D point <code>(x,y)</code>, that is in
565
	 * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using the
566
	 * affine transformation in the {@link #trans #trans} attribute.
567
	 * </p>
568
	 * 
569
	 * @param x
570
	 *            the <code>x</code> <i>screen coordinate</i> of a 2D point
571
	 * @param y
572
	 *            the <code>y</code> <i>screen coordinate</i> of a 2D point
573
	 * 
574
	 * @return 2D point equivalent in <i>map coordinates</i>
575
	 * 
576
	 * @see #toMapPoint(Point2D)
577
	 * @see #fromMapPoint(double, double)
578
	 */
579
	public Point2D toMapPoint(int x, int y) {
580
		Point2D pScreen = new Point2D.Double(x, y);
541
        try {
542
            trans.transform(pWorld, pScreen);
543
        } catch (Exception e) {
544
            System.err.print(e.getMessage());
545
        }
581 546

  
582
		return toMapPoint(pScreen);
583
	}
547
        return pScreen;
548
    }
584 549

  
585
	/**
586
	 * <p>
587
	 * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
588
	 * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using
589
	 * {@linkplain #toMapDistance(int)}, and {@linkplain #toMapPoint(int, int)}.
590
	 * </p>
591
	 * 
592
	 * @param r
593
	 *            the 2D rectangle in <i>screen coordinates</i> (pixels)
594
	 * @return 2D rectangle equivalent in <i>map coordinates</i>
595
	 * 
596
	 * @see #fromMapRectangle(Rectangle2D)
597
	 * @see #toMapDistance(int)
598
	 * @see #toMapPoint(int, int)
599
	 */
600
	public Rectangle2D toMapRectangle(Rectangle2D r) {
601
		Rectangle2D rect = new Rectangle2D.Double();
602
		Point2D p1 = toMapPoint((int) r.getX(), (int) r.getY());
603
		Point2D p2 = toMapPoint((int) r.getMaxX(), (int) r.getMaxY());
604
		rect.setFrameFromDiagonal(p1, p2);
605
		return rect;
606
	}
550
    /**
551
     * <p>
552
     * Converts and returns the 2D point argument, that is in <i>map
553
     * coordinates</i> to <i>screen coordinates</i> (pixels) using the affine
554
     * transformation in the {@link #trans #trans} attribute.
555
     * </p>
556
     * 
557
     * @param point
558
     *            the 2D point in <i>map coordinates</i>
559
     * 
560
     * @return 2D point equivalent in <i>screen coordinates</i> (pixels)
561
     * 
562
     * @see #toMapPoint(Point2D)
563
     * @see #fromMapPoint(double, double)
564
     */
565
    public Point2D fromMapPoint(Point2D point) {
566
        return fromMapPoint(point.getX(), point.getY());
567
    }
607 568

  
608
	/**
609
	 * <p>
610
	 * Converts and returns the distance <code>d</code>, that is in <i>screen
611
	 * coordinates</i> to <i>map coordinates</i> using the transformation affine
612
	 * information in the {@link #trans #trans} attribute.
613
	 * </p>
614
	 * 
615
	 * @param d
616
	 *            distance in pixels
617
	 * 
618
	 * @return distance equivalent in <i>map coordinates</i>
619
	 * 
620
	 * @see #fromMapDistance(double)
621
	 * @see AffineTransform
622
	 */
623
	public double toMapDistance(int d) {
624
		double dist = d / trans.getScaleX();
569
    /**
570
     * <p>
571
     * Converts and returns the 2D point <code>(x,y)</code>, that is in
572
     * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using the
573
     * affine transformation in the {@link #trans #trans} attribute.
574
     * </p>
575
     * 
576
     * @param x
577
     *            the <code>x</code> <i>screen coordinate</i> of a 2D point
578
     * @param y
579
     *            the <code>y</code> <i>screen coordinate</i> of a 2D point
580
     * 
581
     * @return 2D point equivalent in <i>map coordinates</i>
582
     * 
583
     * @see #toMapPoint(Point2D)
584
     * @see #fromMapPoint(double, double)
585
     */
586
    public Point2D toMapPoint(int x, int y) {
587
        Point2D pScreen = new Point2D.Double(x, y);
625 588

  
626
		return dist;
627
	}
589
        return toMapPoint(pScreen);
590
    }
628 591

  
629
	/**
630
	 * <p>
631
	 * Converts and returns the 2D point argument, that is in <i>screen
632
	 * coordinates</i> (pixels) to <i>map coordinates</i> using the inverse
633
	 * affine transformation of the {@link #trans #trans} attribute.
634
	 * </p>
635
	 * 
636
	 * @param pScreen
637
	 *            the 2D point in <i>screen coordinates</i> (pixels)
638
	 * 
639
	 * @return 2D point equivalent in <i>map coordinates</i>
640
	 * 
641
	 * @see #toMapPoint(int, int)
642
	 * @see AffineTransform#createInverse()
643
	 * @see AffineTransform#transform(Point2D, Point2D)
644
	 */
645
	public Point2D toMapPoint(Point2D pScreen) {
646
		Point2D.Double pWorld = new Point2D.Double();
647
		AffineTransform at;
592
    /**
593
     * <p>
594
     * Converts and returns the {@link Rectangle2D Rectangle2D}, that is in
595
     * <i>screen coordinates</i> (pixels) to <i>map coordinates</i> using
596
     * {@linkplain #toMapDistance(int)}, and {@linkplain #toMapPoint(int, int)}.
597
     * </p>
598
     * 
599
     * @param r
600
     *            the 2D rectangle in <i>screen coordinates</i> (pixels)
601
     * @return 2D rectangle equivalent in <i>map coordinates</i>
602
     * 
603
     * @see #fromMapRectangle(Rectangle2D)
604
     * @see #toMapDistance(int)
605
     * @see #toMapPoint(int, int)
606
     */
607
    public Rectangle2D toMapRectangle(Rectangle2D r) {
608
        Rectangle2D rect = new Rectangle2D.Double();
609
        Point2D p1 = toMapPoint((int) r.getX(), (int) r.getY());
610
        Point2D p2 = toMapPoint((int) r.getMaxX(), (int) r.getMaxY());
611
        rect.setFrameFromDiagonal(p1, p2);
612
        return rect;
613
    }
648 614

  
649
		try {
650
			at = trans.createInverse();
651
			at.transform(pScreen, pWorld);
652
		} catch (NoninvertibleTransformException e) {
653
			throw new RuntimeException("Non invertible transform Exception", e);
654
		}
615
    /**
616
     * <p>
617
     * Converts and returns the distance <code>d</code>, that is in <i>screen
618
     * coordinates</i> to <i>map coordinates</i> using the transformation affine
619
     * information in the {@link #trans #trans} attribute.
620
     * </p>
621
     * 
622
     * @param d
623
     *            distance in pixels
624
     * 
625
     * @return distance equivalent in <i>map coordinates</i>
626
     * 
627
     * @see #fromMapDistance(double)
628
     * @see AffineTransform
629
     */
630
    public double toMapDistance(int d) {
631
        double dist = d / trans.getScaleX();
655 632

  
656
		return pWorld;
657
	}
633
        return dist;
634
    }
658 635

  
659
	/**
660
	 * <p>
661
	 * Returns the real distance (in <i>world coordinates</i>) at the graphic
662
	 * layers of two 2D points (in <i>map coordinates</i>) of the plane where is
663
	 * selected the <i>extent</i>.
664
	 * </p>
665
	 * <p>
666
	 * If the projection of this view is UTM, considers the Earth curvature.
667
	 * </p>
668
	 * 
669
	 * @param pt1
670
	 *            a 2D point in <i>map coordinates</i>
671
	 * @param pt2
672
	 *            another 2D point in <i>map coordinates</i>
673
	 * 
674
	 * @return the distance in meters between the two points 2D
675
	 * 
676
	 * @see GeoCalcImpl#distanceVincenty(Point2D, Point2D)
677
	 */
678
	public double distanceWorld(Point2D pt1, Point2D pt2) {
679
		double dist = -1;
680
		dist = pt1.distance(pt2);
636
    /**
637
     * <p>
638
     * Converts and returns the 2D point argument, that is in <i>screen
639
     * coordinates</i> (pixels) to <i>map coordinates</i> using the inverse
640
     * affine transformation of the {@link #trans #trans} attribute.
641
     * </p>
642
     * 
643
     * @param pScreen
644
     *            the 2D point in <i>screen coordinates</i> (pixels)
645
     * 
646
     * @return 2D point equivalent in <i>map coordinates</i>
647
     * 
648
     * @see #toMapPoint(int, int)
649
     * @see AffineTransform#createInverse()
650
     * @see AffineTransform#transform(Point2D, Point2D)
651
     */
652
    public Point2D toMapPoint(Point2D pScreen) {
653
        Point2D.Double pWorld = new Point2D.Double();
654
        AffineTransform at;
681 655

  
682
		if ((proj != null) && !(proj instanceof UTM)) {
683
			dist = new GeoCalc(proj).distanceVincenty(proj.toGeo(pt1), proj
684
					.toGeo(pt2));
685
			return dist;
686
		}
687
		return (dist * MapContext.getDistanceTrans2Meter()[getMapUnits()]);
688
	}
656
        try {
657
            at = trans.createInverse();
658
            at.transform(pScreen, pWorld);
659
        } catch (NoninvertibleTransformException e) {
660
            throw new RuntimeException("Non invertible transform Exception", e);
661
        }
689 662

  
690
	/**
691
	 * <p>
692
	 * Sets as extent and adjusted extent of this view port, the previous.
693
	 * Recalculating its parameters.
694
	 * </p>
695
	 * 
696
	 * @see #getExtents()
697
	 * @see #calculateAffineTransform()
698
	 * @deprecated use {@link ViewPort#setPreviousEnvelope()}
699
	 */
700
	public void setPreviousExtent() {
701
		setPreviousEnvelope();
702
	}
663
        return pWorld;
664
    }
703 665

  
704
	/**
705
	 * <p>
706
	 * Sets as envelope and adjusted envelope of this view port, the previous.
707
	 * Recalculating its parameters.
708
	 * </p>
709
	 * 
710
	 * @see #getExtents()
711
	 * @see #calculateAffineTransform()
712
	 */
713
	public void setPreviousEnvelope() {
714
		this.updateDrawVersion();
715
		extent = extents.removePrev();
666
    /**
667
     * <p>
668
     * Returns the real distance (in <i>world coordinates</i>) at the graphic
669
     * layers of two 2D points (in <i>map coordinates</i>) of the plane where is
670
     * selected the <i>extent</i>.
671
     * </p>
672
     * <p>
673
     * If the projection of this view is UTM, considers the Earth curvature.
674
     * </p>
675
     * 
676
     * @param pt1
677
     *            a 2D point in <i>map coordinates</i>
678
     * @param pt2
679
     *            another 2D point in <i>map coordinates</i>
680
     * 
681
     * @return the distance in meters between the two points 2D
682
     * 
683
     * @see GeoCalcImpl#distanceVincenty(Point2D, Point2D)
684
     */
685
    public double distanceWorld(Point2D pt1, Point2D pt2) {
686
        double dist = -1;
687
        dist = pt1.distance(pt2);
716 688

  
717
		// Calcula la transformaci�n af�n
718
		calculateAffineTransform();
689
        if ((proj != null) && !(proj instanceof UTM)) {
690
            dist =
691
                new GeoCalc(proj).distanceVincenty(proj.toGeo(pt1),
692
                    proj.toGeo(pt2));
693
            return dist;
694
        }
695
        return (dist * MapContext.getDistanceTrans2Meter()[getMapUnits()]);
696
    }
719 697

  
720
		// Lanzamos los eventos de extent cambiado
721
		callExtentChanged(getAdjustedExtent());
722
	}
698
    /**
699
     * <p>
700
     * Sets as extent and adjusted extent of this view port, the previous.
701
     * Recalculating its parameters.
702
     * </p>
703
     * 
704
     * @see #getExtents()
705
     * @see #calculateAffineTransform()
706
     * @deprecated use {@link ViewPort#setPreviousEnvelope()}
707
     */
708
    public void setPreviousExtent() {
709
        setPreviousEnvelope();
710
    }
723 711

  
724
	/**
725
	 * <p>
726
	 * Gets the area selected by user using some tool.
727
	 * </p>
728
	 * 
729
	 * <p>
730
	 * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
731
	 * out</i> tools, but also zooming to a selected feature or shape) the
732
	 * extent that covers that area is the value returned by this method. It is
733
	 * not the actual area shown because it doesn't care about the aspect ratio
734
	 * of the image size of the view. However, any part of the real world
735
	 * contained in this extent is shown in the view.
736
	 * </p>
737
	 * 
738
	 * <p>
739
	 * If you are looking for the complete extent currently shown, you must use
740
	 * the {@linkplain #getAdjustedExtent()} method.
741
	 * </p>
742
	 * 
743
	 * @return the current extent
744
	 * 
745
	 * @see #setEnvelope(Envelope)
746
	 * @see #getAdjustedExtent()
747
	 * @see #setPreviousExtent()
748
	 * @see #getExtents()
749
	 * 
750
	 * @deprecated use {@link ViewPort#getEnvelope()}
751
	 */
752
	public Rectangle2D getExtent() {
753
		return extent;
754
	}
712
    /**
713
     * <p>
714
     * Sets as envelope and adjusted envelope of this view port, the previous.
715
     * Recalculating its parameters.
716
     * </p>
717
     * 
718
     * @see #getExtents()
719
     * @see #calculateAffineTransform()
720
     */
721
    public void setPreviousEnvelope() {
722
        this.updateDrawVersion();
723
        extent = extents.removePrev();
755 724

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

  
798
	/**
799
	 * <p>
800
	 * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
801
	 * <ul>
802
	 * <li>Stores the previous extent.
803
	 * <li>Calculates the new extent using <code>r</code>:
804
	 * 
805
	 * <pre>
806
	 * extent = new Rectangle2D.Double(r.getMinX() - 0.1, r.getMinY() - 0.1, r
807
	 * 		.getWidth() + 0.2, r.getHeight() + 0.2);
808
	 * </pre>
809
	 * 
810
	 * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
811
	 * scale, adjusted extent, affine transformation between map and screen
812
	 * coordinates, the real world coordinates equivalent to 1 pixel, and the
813
	 * real world coordinates equivalent to 3 pixels.
814
	 * <li>Notifies all {@link ViewPortListener ViewPortListener} registered
815
	 * that the extent has changed.
816
	 * </ul>
817
	 * </p>
818
	 * 
819
	 * @param r
820
	 *            the new extent
821
	 * 
822
	 * @see #getExtent()
823
	 * @see #getExtents()
824
	 * @see #calculateAffineTransform()
825
	 * @see #setPreviousExtent()
826
	 */
827
	public void setEnvelope(Envelope r) {
828
		Rectangle2D newExtent = null;
829
		// Esto comprueba que el extent no es de anchura o altura = "0"
830
		// y si es as� lo redimensiona.
831
		if (r != null) {
832
			if ((r.getMaximum(0) - r.getMinimum(0) == 0)
833
					|| (r.getMaximum(1) - r.getMinimum(1) == 0)) {
834
				newExtent = new Rectangle2D.Double(r.getMinimum(0) - 0.1, r
835
						.getMinimum(1) - 0.1, r.getMaximum(0) - r.getMinimum(0)
836
						+ 0.2, r.getMaximum(1) - r.getMinimum(1) + 0.2);
837
			} else {
838
				newExtent = new Rectangle2D.Double(r.getMinimum(0), r
839
						.getMinimum(1), Math.abs(r.getMaximum(0)
840
						- r.getMinimum(0)), Math.abs(r.getMaximum(1)
841
						- r.getMinimum(1)));
842
			}
843
		}
728
        // Lanzamos los eventos de extent cambiado
729
        callExtentChanged(getAdjustedExtent());
730
    }
844 731

  
845
		if (this.extent != null && this.extent.equals(newExtent)) {
846
			return;
847
		}
848
		if (extent != null) {
849
			extents.put(extent);
850
		}
851
		this.updateDrawVersion();
852
		this.extent = newExtent;
732
    /**
733
     * <p>
734
     * Gets the area selected by user using some tool.
735
     * </p>
736
     * 
737
     * <p>
738
     * When the zoom changes (for instance using the <i>zoom in</i> or <i>zoom
739
     * out</i> tools, but also zooming to a selected feature or shape) the
740
     * extent that covers that area is the value returned by this method. It is
741
     * not the actual area shown because it doesn't care about the aspect ratio
742
     * of the image size of the view. However, any part of the real world
743
     * contained in this extent is shown in the view.
744
     * </p>
745
     * 
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
     * 
753
     * @see #setEnvelope(Envelope)
754
     * @see #getAdjustedExtent()
755
     * @see #setPreviousExtent()
756
     * @see #getExtents()
757
     * 
758
     * @deprecated use {@link ViewPort#getEnvelope()}
759
     */
760
    public Rectangle2D getExtent() {
761
        return extent;
762
    }
853 763

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

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

  
861
	/**
862
	 * <p>
863
	 * Changes the <i>extent</i> and <i>adjusted extent</i> of this view port:<br>
864
	 * <ul>
865
	 * <li>Executes {@linkplain #calculateAffineTransform()}: getting the new
866
	 * scale, adjusted extent, affine transformation between map and screen
867
	 * coordinates, the real world coordinates equivalent to 1 pixel, and the
868
	 * real world coordinates equivalent to 3 pixels.
869
	 * <li>Notifies to all {@link ViewPortListener ViewPortListener} registered
870
	 * that the extent has changed.
871
	 * </ul>
872
	 * </p>
873
	 * 
874
	 * @see #setEnvelope(Envelope)
875
	 * @see #calculateAffineTransform()
876
	 */
877
	public void refreshExtent() {
878
		// this.scale = scale;
861
        if (this.extent != null && this.extent.equals(newExtent)) {
862
            return;
863
        }
864
        if (extent != null) {
865
            extents.put(extent);
866
        }
867
        this.updateDrawVersion();
868
        this.extent = newExtent;
879 869

  
880
		// Calcula la transformaci�n af�n
881
		calculateAffineTransform();
870
        // Calcula la transformaci�n af�n
871
        calculateAffineTransform();
882 872

  
883
		// Lanzamos los eventos de extent cambiado
884
		callExtentChanged(getAdjustedExtent());
885
	}
873
        // Lanzamos los eventos de extent cambiado
874
        callExtentChanged(getAdjustedExtent());
875
    }
886 876

  
887
	/**
888
	 * <p>
889
	 * Calculates and returns using the current projection of this view port,
890
	 * the scale that is the extent in <i>screen coordinates</i> from the image
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff