From 3287824b784bb055d586903eb5c93bf0dbce29ed Mon Sep 17 00:00:00 2001 From: Sebastian Schulz Date: Tue, 11 Jan 2022 12:41:51 +0100 Subject: [PATCH] Add method to create a default ReferencedEnvelope --- .../internal/ViewportModelImplTest.java | 15 +- .../impl/InitMapBoundsInterceptor.java | 17 +- .../internal/render/ViewportModel.java | 130 +++++--- .../render/impl/ViewportModelImpl.java | 281 +++++++++--------- .../udig/project/render/IViewportModel.java | 15 +- 5 files changed, 242 insertions(+), 216 deletions(-) diff --git a/plugins/org.locationtech.udig.project.tests/src/org/locationtech/udig/project/internal/ViewportModelImplTest.java b/plugins/org.locationtech.udig.project.tests/src/org/locationtech/udig/project/internal/ViewportModelImplTest.java index 48c8033be..45d05852f 100644 --- a/plugins/org.locationtech.udig.project.tests/src/org/locationtech/udig/project/internal/ViewportModelImplTest.java +++ b/plugins/org.locationtech.udig.project.tests/src/org/locationtech/udig/project/internal/ViewportModelImplTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.awt.Dimension; import java.util.Collections; @@ -62,9 +63,6 @@ public void testGetScaleDenominatorAlbersBoundsSmallerThanWorld() throws Excepti viewportModel.setBounds(-140, -120, 40, 60); assertEquals(1.0d, viewportModel.getBounds().getWidth() / viewportModel.getHeight(), ACCURACY); - - // assertEquals(calculateScale(viewportModel.getBounds(), viewportModel.getCRS(), 500,500), - // viewportModel.getScaleDenominator()); } /** @@ -84,6 +82,7 @@ public void testGetScaleDenominatorWGS84BoundsLongerThanWorldIn1Direction() thro 250, 250); double viewportResults = viewportModel.getScaleDenominator(); double d = Math.abs(trueScale - viewportResults); + assertTrue(d + " should be less than " + ACCURACY, d < ACCURACY); //$NON-NLS-1$ } /** @@ -103,7 +102,7 @@ public void testGetScaleDenominatorWGS84BoundsLargerThanWorld() throws Exception 100, 100); double viewportResults = viewportModel.getScaleDenominator(); double d = Math.abs(trueScale - viewportResults); - // assertTrue(d+" should be less than "+ACCURACY_SCALE, d< ACCURACY_SCALE ); //$NON-NLS-1$ + assertTrue(d + " should be less than " + ACCURACY, d < ACCURACY); //$NON-NLS-1$ } /** @@ -116,14 +115,14 @@ public void testGetScaleDenominatorWGS84BoundsLargerThanWorldOffScreenData() thr ViewportModel viewportModel = map.getViewportModelInternal(); viewportModel.setCRS(DefaultGeographicCRS.WGS84); viewportModel.setBounds(500, 500, 1000, 1000); - // assertEquals(1.0d, viewportModel.getBounds().getWidth()/viewportModel.getHeight(), - // ACCURACY); + assertEquals(1.0d, viewportModel.getBounds().getWidth() / viewportModel.getHeight(), + ACCURACY); double trueScale = calculateScale(new Envelope(-180, -80, -90, 10), viewportModel.getCRS(), 100, 100); double viewportResults = viewportModel.getScaleDenominator(); double d = Math.abs(trueScale - viewportResults); - // assertTrue(d+" should be less than "+ACCURACY_SCALE, d< ACCURACY_SCALE ); //$NON-NLS-1$ + assertTrue(d + " should be less than " + ACCURACY, d < ACCURACY); //$NON-NLS-1$ } @Test @@ -139,7 +138,7 @@ public void testNonNullFromViewPortModel() throws Exception { private static double calculateScale(Envelope envelope, CoordinateReferenceSystem coordinateReferenceSystem, int imageWidth, int imageHeight) - throws Exception { + throws Exception { ReferencedEnvelope bounds = new ReferencedEnvelope(envelope, coordinateReferenceSystem); bounds.transform(DefaultGeographicCRS.WGS84, true); diff --git a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/impl/InitMapBoundsInterceptor.java b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/impl/InitMapBoundsInterceptor.java index 44f6f24d4..9cf01127f 100644 --- a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/impl/InitMapBoundsInterceptor.java +++ b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/impl/InitMapBoundsInterceptor.java @@ -10,12 +10,14 @@ */ package org.locationtech.udig.project.internal.impl; +import java.util.List; + import org.geotools.geometry.jts.ReferencedEnvelope; +import org.locationtech.udig.project.ILayer; import org.locationtech.udig.project.interceptor.LayerInterceptor; import org.locationtech.udig.project.internal.Layer; import org.locationtech.udig.project.internal.Map; import org.locationtech.udig.project.internal.render.ViewportModel; -import org.locationtech.udig.project.internal.render.impl.ViewportModelImpl; import org.locationtech.udig.ui.ProgressManager; /** @@ -40,11 +42,14 @@ public void run(final Layer layer) { final ViewportModel viewportModel = map.getViewportModelInternal(); ReferencedEnvelope bounds = viewportModel.getBounds(); - // If first layer or if the CRS has been unchanged from the original BBox - if (map.getMapLayers().size() == 1 - || bounds == ViewportModelImpl.getDefaultReferencedEnvelope()) { - bounds = map.getBounds(ProgressManager.instance().get()); - viewportModel.setBounds(bounds); + // If the map has one layer and if the CRS has been unchanged from the original BBox + final List mapLayers = map.getMapLayers(); + if (mapLayers.size() == 1 || bounds.equals(ViewportModel.getNullReferenceEnvelope())) { + bounds = mapLayers.get(0).getBounds(ProgressManager.instance().get(), + viewportModel.getCRS()); + if (!bounds.isNull()) { + viewportModel.setBounds(bounds); + } } } diff --git a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/ViewportModel.java b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/ViewportModel.java index 25071c11f..d93d60892 100644 --- a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/ViewportModel.java +++ b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/ViewportModel.java @@ -1,4 +1,5 @@ -/* uDig - User Friendly Desktop Internet GIS client +/** + * uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2004-2012, Refractions Research Inc. * @@ -52,8 +53,10 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo public CoordinateReferenceSystem getCRS(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' attribute. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' + * attribute. + * * @param value the new value of the 'CRS' attribute. * @see #isSetCRS() * @see #unsetCRS() @@ -68,9 +71,10 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo * This set is used to provide good options for a user to change the scale *

*

- * The values will always be present but if the object returned by {@link #getDefaultPreferredScaleDenominators()} and this method - * are the same instance then they are simply defaults and can be ignored if desired. However if they are not the same - * then assume that the values are only hints and can be ignored + * The values will always be present but if the object returned by + * {@link #getDefaultPreferredScaleDenominators()} and this method are the same + * instance then they are simply defaults and can be ignored if desired. However if + * they are not the same then assume that the values are only hints and can be ignored *

* * @see #getScaleDenominator() for a definition of scale denominator @@ -81,7 +85,9 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo public SortedSet getPreferredScaleDenominators(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getPreferredScaleDenominators Preferred Scale Denominators}' attribute. + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getPreferredScaleDenominators + * Preferred Scale Denominators}' attribute. * * If set to null getPreferredScaleDenominators will return the defaults. * @@ -92,8 +98,10 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo void setPreferredScaleDenominators(SortedSet value); /** - * Unsets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' attribute. - * + * Unsets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' + * attribute. + * * @see #isSetCRS() * @see #getCRS() * @see #setCRS(CoordinateReferenceSystem) @@ -102,8 +110,10 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo void unsetCRS(); /** - * Returns whether the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' attribute is set. - * + * Returns whether the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCRS CRS}' + * attribute is set. + * * @return whether the value of the 'CRS' attribute is set. * @see #unsetCRS() * @see #getCRS() @@ -127,9 +137,10 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo public ReferencedEnvelope getBounds(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getBounds Bounds}' attribute. - * - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getBounds + * Bounds}' attribute. + * * @param value the new value of the 'Bounds' attribute. * @see #getBounds() * @generated @@ -138,20 +149,23 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo /** * Set the bounds of the viewport model + * * @param value the new desired bounds - * @param forceContainBBoxZoom Whether or not the {@link #setBounds(ReferencedEnvelope)} will always contain the - * envelope after execution. In normal execution this is not an issue but if - * {@link #setPreferredScaleDenominators(SortedSet)} has been called then this does matter because - * zoom to features will not necessary contain all the features. When taking into account - * preferredScaleDenominators setting the bounds the closest scale to the desired scale is chosen. - * This can mean that the scale chosen will not be able to fit the entire bounds. This is fine - * when zooming but in other cases it is not acceptable + * @param forceContainBBoxZoom Whether or not the {@link #setBounds(ReferencedEnvelope)} will + * always contain the envelope after execution. In normal execution this is not an issue + * but if {@link #setPreferredScaleDenominators(SortedSet)} has been called then this + * does matter because zoom to features will not necessary contain all the features. When + * taking into account preferredScaleDenominators setting the bounds the closest scale to + * the desired scale is chosen. This can mean that the scale chosen will not be able to + * fit the entire bounds. This is fine when zooming but in other cases it is not + * acceptable */ void setBounds(ReferencedEnvelope value, boolean forceContainBBoxZoom); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getBounds Bounds}' - * attribute. + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getBounds + * Bounds}' attribute. *

* The bbox must have a positive width and height and must have a aspect ratio within 0.0000001 * units of the value returned by {@linkplain #getAspectRatio()} . @@ -159,7 +173,7 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo *

* It is recommended that setHeight() or setWidth() methods are used since they preserve the * aspect ratio of the Viewport - *

+ *

* * * @param value the new value of the 'Bounds' attribute. @@ -169,8 +183,8 @@ public interface ViewportModel extends EObject, IMapDisplayListener, IViewportMo void setBounds(Envelope value); /** - * Sets the viewport's bounding box. The bounding box will be fit to the window based on the MapDisplay so - * the bounds provided here may not be the final bounds. + * Sets the viewport's bounding box. The bounding box will be fit to the window based on the + * MapDisplay so the bounds provided here may not be the final bounds. * * @param minx the minimum x value of the new bounding box. * @param maxx the maximum x value of the new bounding box. @@ -193,8 +207,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) public Coordinate getCenter(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCenter Center}' attribute. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getCenter + * Center}' attribute. + * * @param value the new value of the 'Center' attribute. * @see #getCenter() * @generated @@ -212,8 +228,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) public double getHeight(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getHeight Height}' attribute. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getHeight + * Height}' attribute. + * * @param value the new value of the 'Height' attribute. * @see #getHeight() * @generated @@ -231,8 +249,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) public double getWidth(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getWidth Width}' attribute. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getWidth Width}' + * attribute. + * * @param value the new value of the 'Width' attribute. * @see #getWidth() * @generated @@ -257,8 +277,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) public Map getMapInternal(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getMapInternal Map Internal}' container reference. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getMapInternal Map + * Internal}' container reference. + * * @param value the new value of the 'Map Internal' container reference. * @see #getMapInternal() * @generated @@ -266,14 +288,16 @@ public void setBounds(double minx, double maxx, double miny, double maxy) void setMapInternal(Map value); /** - * Returns the value of the 'Render Manager Internal' reference. - * It is bidirectional and its opposite is '{@link org.locationtech.udig.project.internal.render.RenderManager#getViewportModelInternal Viewport Model Internal}'. - * + * Returns the value of the 'Render Manager Internal' reference. It is + * bidirectional and its opposite is + * '{@link org.locationtech.udig.project.internal.render.RenderManager#getViewportModelInternal + * Viewport Model Internal}'. *

- * If the meaning of the 'Render Manager' reference isn't clear, there really - * should be more of a description here... + * If the meaning of the 'Render Manager' reference isn't clear, there really should be + * more of a description here... *

* + * * @return the value of the 'Render Manager Internal' reference. * @see #setRenderManagerInternal(RenderManager) * @see org.locationtech.udig.project.internal.render.RenderPackage#getViewportModel_RenderManagerInternal() @@ -284,8 +308,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) RenderManager getRenderManagerInternal(); /** - * Sets the value of the '{@link org.locationtech.udig.project.internal.render.ViewportModel#getRenderManagerInternal Render Manager Internal}' reference. - * + * Sets the value of the + * '{@link org.locationtech.udig.project.internal.render.ViewportModel#getRenderManagerInternal + * Render Manager Internal}' reference. + * * @param value the new value of the 'Render Manager Internal' reference. * @see #getRenderManagerInternal() * @generated @@ -325,9 +351,10 @@ public void setBounds(double minx, double maxx, double miny, double maxy) /** * Returns the size of a pixel in world units. - *

For example if the world is in WGS 84(lat long) then - * the size will be in degrees + *

+ * For example if the world is in WGS 84(lat long) then the size will be in degrees *

+ * * @return the size of a pixel in world units. * @model volatile="true" changeable="false" transient="true" */ @@ -423,27 +450,32 @@ public void setBounds(double minx, double maxx, double miny, double maxy) public void setInitialized(boolean initialized); /** - * Sets the zoom level of the viewport so that the scale denominator will be equal to - * scale + * Sets the zoom level of the viewport so that the scale denominator will be equal to scale * * @param scaleDenominator desired scale denominator */ public void setScale(double scaleDenominator); /** - * Sets the zoom level of the viewport so that the scale denominator will be equal to - * scale + * Sets the zoom level of the viewport so that the scale denominator will be equal to scale * * @param scaleDenominator desired scale denominator */ public void setScale(double scaleDenominator, int dpi, int displayWidth, int displayHeight); /** - * The attribute indicates that any upcoming changes to the value - * of the model should be consider a single event. + * The attribute indicates that any upcoming changes to the value of the model should be + * consider a single event. * * @param changing */ public void setIsBoundsChanging(boolean changing); + /** + * @return reverence envelope with BAD_DEFAULT CRS and zero width and zero height for the + * envelope at position 0/0. + */ + static ReferencedEnvelope getNullReferenceEnvelope() { + return new ReferencedEnvelope(0, 0, 0, 0, BAD_DEFAULT); + } } diff --git a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/impl/ViewportModelImpl.java b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/impl/ViewportModelImpl.java index 44cb69982..34ad0aa94 100644 --- a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/impl/ViewportModelImpl.java +++ b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/internal/render/impl/ViewportModelImpl.java @@ -1,5 +1,12 @@ /** - * $Id$ + * uDig - User Friendly Desktop Internet GIS client + * http://udig.refractions.net + * (C) 2022, Refractions Research Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD + * License v1.0 (http://udig.refractions.net/files/bsd3-v10.html). */ package org.locationtech.udig.project.internal.render.impl; @@ -13,6 +20,7 @@ import java.util.TreeSet; import java.util.concurrent.CopyOnWriteArraySet; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.ecore.EClass; @@ -35,7 +43,6 @@ import org.locationtech.udig.project.internal.Map; import org.locationtech.udig.project.internal.ProjectPackage; import org.locationtech.udig.project.internal.ProjectPlugin; -import org.locationtech.udig.project.internal.render.RenderFactory; import org.locationtech.udig.project.internal.render.RenderManager; import org.locationtech.udig.project.internal.render.RenderPackage; import org.locationtech.udig.project.internal.render.ViewportModel; @@ -56,18 +63,18 @@ /** * TODO Purpose of org.locationtech.udig.project.internal.render.impl - *

- *

* * @author Jesse * @since 1.0.0 * @generated */ public class ViewportModelImpl extends EObjectImpl implements ViewportModel { + private static final int DEFAULT_CRS = 4326; // WGS84 + /** - * The default value of the '{@link #getCRS() CRS}' attribute. - * + * The default value of the '{@link #getCRS() CRS}' attribute. * + * * @see #getCRS() * @generated * @ordered @@ -93,25 +100,20 @@ public class ViewportModelImpl extends EObjectImpl implements ViewportModel { protected boolean cRSESet = false; /** - * The default value of the '{@link #getBounds() Bounds}' attribute. - * - * + * The cached value of the '{@link #getBounds() Bounds}' attribute. + * * @see #getBounds() - * @generated + * @generated NOT * @ordered */ - protected static final ReferencedEnvelope BOUNDS_EDEFAULT = (ReferencedEnvelope) RenderFactory.eINSTANCE - .createFromString(RenderPackage.eINSTANCE.getReferencedEnvelope(), ""); //$NON-NLS-1$ + protected ReferencedEnvelope bounds = null; /** - * The cached value of the '{@link #getBounds() Bounds}' attribute. - * - * @see #getBounds() - * @generated NOT - * @ordered + * The default value of the '{@link #getBounds() Bounds}' attribute. */ - protected ReferencedEnvelope bounds = ViewportModelImpl.getDefaultReferencedEnvelope(); + protected static final ReferencedEnvelope BOUNDS_EDEFAULT = ViewportModel + .getNullReferenceEnvelope(); /** * The default value of the '{@link #getCenter() Center}' attribute. + * The default value of the '{@link #getWidth() Width}' attribute. * * @see #getWidth() * @generated @@ -164,8 +166,9 @@ public class ViewportModelImpl extends EObjectImpl implements ViewportModel { protected static final Coordinate PIXEL_SIZE_EDEFAULT = null; /** - * The cached value of the '{@link #getRenderManagerInternal() Render Manager Internal}' reference. - * + * The cached value of the '{@link #getRenderManagerInternal() Render Manager + * Internal}' reference. + * * @see #getRenderManagerInternal() * @generated * @ordered @@ -173,9 +176,9 @@ public class ViewportModelImpl extends EObjectImpl implements ViewportModel { protected RenderManager renderManagerInternal; /** - * The cached value of the '{@link #getPreferredScaleDenominators() Preferred Scale Denominators}' attribute. - * - * + * The cached value of the '{@link #getPreferredScaleDenominators() Preferred Scale + * Denominators}' attribute. + * * @see #getPreferredScaleDenominators() * @generated * @ordered @@ -194,6 +197,7 @@ protected ViewportModelImpl() { /** * + * * @generated */ @Override @@ -203,6 +207,7 @@ protected EClass eStaticClass() { /** * + * * @generated */ @Override @@ -218,16 +223,16 @@ public void setCRS(CoordinateReferenceSystem newCRS) { if (newCRS.equals(cRS)) return; CoordinateReferenceSystem oldCRS = getCRS(); - if (getBounds().isNull() || !validState()) { + ReferencedEnvelope oldBounds = getBounds(); + if (oldBounds.isNull() || !validState()) { setCRSGen(newCRS); - } else { Coordinate center = getCenter(); DirectPosition2D position = new DirectPosition2D(oldCRS, center.x, center.y); try { eSetDeliver(false); cRS = newCRS; - bounds = new ReferencedEnvelope(bounds, cRS); + bounds = new ReferencedEnvelope(oldBounds, cRS); if (oldCRS != DefaultEngineeringCRS.GENERIC_2D && oldCRS != DefaultEngineeringCRS.GENERIC_3D && oldCRS != DefaultEngineeringCRS.CARTESIAN_2D @@ -286,6 +291,7 @@ public void unsetCRS() { /** * + * * @generated */ @Override @@ -300,8 +306,10 @@ public boolean isSetCRS() { */ @Override public synchronized ReferencedEnvelope getBounds() { - if (bounds == null) { - return getMapInternal().getBounds(ProgressManager.instance().get()); + ReferencedEnvelope nullReferenceEnvelope = ViewportModel.getNullReferenceEnvelope(); + if (bounds == null || nullReferenceEnvelope.equals(bounds)) { + ReferencedEnvelope calculateExtent = calculateExtent(getMap(), getCRS()); + bounds = (calculateExtent == null ? nullReferenceEnvelope : calculateExtent); } return bounds; @@ -343,7 +351,8 @@ && validState()) { mapDisplay.getDPI(), referenced); if (forceContainBBoxZoom && !finalBounds.contains(newBounds)) { Iterator tail = getPreferredScaleDenominators().tailSet(scale).iterator(); - // the tail will include scale because scale is one of the elements in the set. So drop that + // the tail will include scale because scale is one of the elements in the set. So + // drop that tail.next(); Double nextLargest = tail.next(); if (nextLargest != null) { @@ -353,8 +362,8 @@ && validState()) { } } - Envelope oldBounds = bounds == null ? new Envelope() : bounds; - if (!getBounds().isNull() && !Double.isNaN(getAspectRatio()) + Envelope oldBounds = getBounds(); + if (!oldBounds.isNull() && !Double.isNaN(getAspectRatio()) && !Double.isNaN(finalBounds.getWidth()) && !Double.isNaN(finalBounds.getHeight())) { double nRatio = finalBounds.getWidth() / finalBounds.getHeight(); @@ -376,7 +385,7 @@ && validState()) { } } bounds = new ReferencedEnvelope(finalBounds, getCRS()); - fireNotification(oldBounds); + fireNotification(oldBounds, bounds); } /** @@ -386,8 +395,9 @@ && validState()) { */ @Override public Coordinate getCenter() { - return new Coordinate(bounds.getMinX() + bounds.getWidth() / 2, - bounds.getMinY() + bounds.getHeight() / 2); + final ReferencedEnvelope currentBounds = getBounds(); + return new Coordinate(currentBounds.getMinX() + currentBounds.getWidth() / 2, currentBounds.getMinY() + + currentBounds.getHeight() / 2); } /** @@ -397,8 +407,9 @@ public Coordinate getCenter() { */ @Override public void setCenter(Coordinate newCenter) { - // Coordinate center=getCenter(); - double dw = getBounds().getWidth() / 2, dh = getBounds().getHeight() / 2; + final ReferencedEnvelope currentBounds = getBounds(); + final double dw = currentBounds.getWidth() / 2; + final double dh = currentBounds.getHeight() / 2; setBounds(new Envelope(newCenter.x - dw, newCenter.x + dw, newCenter.y - dh, newCenter.y + dh)); } @@ -410,7 +421,7 @@ public void setCenter(Coordinate newCenter) { */ @Override public double getHeight() { - return bounds.getHeight(); + return getBounds().getHeight(); } /** @@ -471,6 +482,7 @@ && getRenderManagerInternal().getMapDisplay().getWidth() > 0 /** * + * * @generated */ @Override @@ -481,8 +493,8 @@ public Map getMapInternal() { } /** - * - * + * + * * @generated */ public NotificationChain basicSetMapInternal(Map newMapInternal, NotificationChain msgs) { @@ -493,6 +505,7 @@ public NotificationChain basicSetMapInternal(Map newMapInternal, NotificationCha /** * + * * @generated */ public void setMapInternalGen(Map newMapInternal) { @@ -518,7 +531,7 @@ public void setMapInternalGen(Map newMapInternal) { boolean viewer = false; - // can't expect to great of accuracy since ASPECT RATIO is based on ints + // can't expect to great of accuracy since ASPECT RATIO is based on integers private static final double ACCURACY = 0.0001; private boolean initialized; @@ -539,9 +552,6 @@ public void setViewer(boolean viewer) { this.viewer = viewer; } - /** - * @see org.locationtech.udig.project.internal.render.RenderManager#setMap(IMap) - */ @Override public void setMapInternal(Map newMap) { if (isViewer()) { @@ -553,6 +563,7 @@ public void setMapInternal(Map newMap) { /** * + * * @generated */ @Override @@ -562,6 +573,7 @@ public RenderManager getRenderManagerInternal() { /** * + * * @generated */ public NotificationChain basicSetRenderManagerInternal(RenderManager newRenderManagerInternal, @@ -582,6 +594,7 @@ public NotificationChain basicSetRenderManagerInternal(RenderManager newRenderMa /** * + * * @generated */ @Override @@ -645,15 +658,12 @@ public void setBounds(double minx, double maxx, double miny, double maxy) { @Override public AffineTransform worldToScreenTransform() { if (!validState()) - return new AffineTransform(); //Identity (screen-space is arbitrary here.) + return new AffineTransform(); // Identity (screen-space is arbitrary here.) // set up the affine transform and calculate scale values return worldToScreenTransform(getBounds(), getRenderManagerInternal().getMapDisplay().getDisplaySize()); } - /** - * @see ViewportModel#worldToScreenTransform(Envelope, Dimension) - */ @Override public AffineTransform worldToScreenTransform(Envelope mapExtent, Dimension screenSize) { if (!validState()) @@ -725,8 +735,7 @@ public ViewportModel zoom(double zoom, Coordinate fixedPoint) { double effectiveZoom = zoom; AffineTransform transformer = ScaleUtils.createScaleTransformWithFixedPoint(effectiveZoom, fixedPoint); - ReferencedEnvelope srcEnvelope = getBounds(); - Envelope transformedEnvelope = ScaleUtils.transformEnvelope(srcEnvelope, transformer); + Envelope transformedEnvelope = ScaleUtils.transformEnvelope(getBounds(), transformer); setBounds(transformedEnvelope); return this; } @@ -742,45 +751,7 @@ public void zoomToExtent() { if (!validState()) return; - ReferencedEnvelope bounds2 = new ReferencedEnvelope(getCRS()); - - // check the limit service - IAOIService aOIService = PlatformGIS.getAOIService(); - ReferencedEnvelope extent = aOIService.getExtent(); - - if (extent != null && !extent.isNull() && !extent.isEmpty()) { - bounds2 = new ReferencedEnvelope(extent); - } else { - boolean hasVisibleLayer = false; - // search the map for visible layers and construct a bounds from those layers. - // otherwise default to what the map's extent is. - List layers = getMap().getMapLayers(); - for (ILayer layer : layers) { - ReferencedEnvelope layerBounds = layer - .getBounds(ProgressManager.instance().get(), getCRS()); - if (layer.isVisible() && !layerBounds.isNull()) { - hasVisibleLayer = true; - // consider zooming in (or zooming out) to a scale the layer is visible - ReferencedEnvelope fitted = ScaleUtils.fitToMinAndMax(layerBounds, layer); - if (fitted.getCoordinateReferenceSystem() == bounds2 - .getCoordinateReferenceSystem()) { - bounds2.expandToInclude(fitted); - } else if (bounds2.getCoordinateReferenceSystem() == layerBounds - .getCoordinateReferenceSystem()) { - // We have a small problem here? Should do the fitting - // before transform to viewport CRS - - // use layerBounds which should match - bounds2.expandToInclude(layerBounds); - } else { - // ignore as it probably does not have a CRS - } - } - } - if (!hasVisibleLayer) { - bounds2 = getMap().getBounds(ProgressManager.instance().get()); - } - } + ReferencedEnvelope bounds2 = calculateExtent(getMap(), getCRS()); if (bounds2.getCoordinateReferenceSystem() == null || getCRS() == null || bounds2.getCoordinateReferenceSystem().equals(getCRS())) { @@ -792,15 +763,58 @@ public void zoomToExtent() { zoomToBox(JTS.transform(bounds2, transform)); } - } catch (FactoryException e) { - zoomToBox(new Envelope(-180, 180, -90, 90)); - } catch (TransformException e) { + } catch (FactoryException | TransformException e) { zoomToBox(new Envelope(-180, 180, -90, 90)); } } + private ReferencedEnvelope calculateExtent(final IMap map, + final CoordinateReferenceSystem crs) { + ReferencedEnvelope calculatedBounds = new ReferencedEnvelope(crs); + + // check the limit service + IAOIService aOIService = PlatformGIS.getAOIService(); + ReferencedEnvelope extent = aOIService.getExtent(); + + if (extent != null && !extent.isNull() && !extent.isEmpty()) { + calculatedBounds = new ReferencedEnvelope(extent); + } else { + IProgressMonitor progressMonitor = ProgressManager.instance().get(); + boolean hasVisibleLayer = false; + // search the map for visible layers and construct a bounds from those layers. + // otherwise default to what the map's extent is. + List layers = (map == null ? Collections.emptyList() : map.getMapLayers()); + for (ILayer layer : layers) { + ReferencedEnvelope layerBounds = layer.getBounds(progressMonitor, crs); + if (layer.isVisible() && !layerBounds.isNull()) { + hasVisibleLayer = true; + // consider zooming in (or zooming out) to a scale the layer is visible + ReferencedEnvelope fitted = ScaleUtils.fitToMinAndMax(layerBounds, layer); + if (fitted.getCoordinateReferenceSystem() == calculatedBounds + .getCoordinateReferenceSystem()) { + calculatedBounds.expandToInclude(fitted); + } else if (calculatedBounds.getCoordinateReferenceSystem() == layerBounds + .getCoordinateReferenceSystem()) { + // We have a small problem here? Should do the fitting + // before transform to viewport CRS + + // use layerBounds which should match + calculatedBounds.expandToInclude(layerBounds); + } else { + // ignore as it probably does not have a CRS + } + } + } + if (!hasVisibleLayer && map != null) { + calculatedBounds = map.getBounds(progressMonitor); + } + } + return calculatedBounds; + } + /** * + * * @generated */ @Override @@ -822,9 +836,6 @@ public String toString() { return result.toString(); } - /** - * @see org.locationtech.udig.project.render.displayAdapter.IMapDisplayListener#sizeChanged(org.locationtech.udig.project.render.displayAdapter.MapDisplayEvent) - */ @Override public void sizeChanged(final MapDisplayEvent event) { if (event.getSize().width < 1 || event.getSize().height < 1) @@ -844,8 +855,8 @@ public void run() { zoomToExtent(); } else { if (oldSizeIsValid(event)) { - calculateNewBounds(event, oldBounds); - fireNotification(oldBounds); + bounds = calculateNewBounds(event, oldBounds); + fireNotification(oldBounds, bounds); } else { zoomToBox(getBounds()); } @@ -862,24 +873,23 @@ public void run() { } } - private void fireNotification(Envelope oldBounds) { + private void fireNotification(Envelope oldBounds, Envelope newBounds) { if (eNotificationRequired()) { eNotify(new ENotificationImpl(this, Notification.SET, - RenderPackage.VIEWPORT_MODEL__BOUNDS, oldBounds, bounds)); + RenderPackage.VIEWPORT_MODEL__BOUNDS, oldBounds, newBounds)); - //notifyListeners(new ViewportModelEvent(this, EventType.CRS, bounds, oldBounds)); - notifyListeners(new ViewportModelEvent(this, EventType.BOUNDS, bounds, oldBounds)); + notifyListeners(new ViewportModelEvent(this, EventType.BOUNDS, newBounds, oldBounds)); } } - private void calculateNewBounds(MapDisplayEvent event, Envelope oldBounds) { + private ReferencedEnvelope calculateNewBounds(MapDisplayEvent event, Envelope oldBounds) { double oldXscale = getWidth() / event.getOldSize().width; double oldYscale = getHeight() / event.getOldSize().height; double minx = oldBounds.getMinX(); double maxy = oldBounds.getMaxY(); double maxx = minx + (event.getSize().width * oldXscale); double miny = maxy - (event.getSize().height * oldYscale); - this.bounds = new ReferencedEnvelope(minx, maxx, miny, maxy, getCRS()); + return new ReferencedEnvelope(minx, maxx, miny, maxy, getCRS()); } private boolean oldSizeIsValid(MapDisplayEvent event) { @@ -894,9 +904,6 @@ private boolean newSizeIsSmaller(MapDisplayEvent event) { && event.getOldSize().height > event.getSize().height; } - /** - * @see org.locationtech.udig.project.internal.render.ViewportModel#zoomToBox(org.locationtech.jts.geom.Envelope) - */ @Override public void zoomToBox(Envelope newbbox) { setInitialized(true); @@ -923,8 +930,8 @@ public void zoomToBox(Envelope newbbox) { } /** - * - * + * + * * @generated */ @Override @@ -946,8 +953,8 @@ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, } /** - * - * + * + * * @generated */ @Override @@ -963,8 +970,8 @@ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, } /** - * - * + * + * * @generated */ @Override @@ -978,8 +985,8 @@ public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs } /** - * - * + * + * * @generated */ @Override @@ -1010,8 +1017,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) { } /** - * - * + * + * * @generated */ @SuppressWarnings("unchecked") @@ -1047,8 +1054,8 @@ public void eSet(int featureID, Object newValue) { } /** - * - * + * + * * @generated */ @Override @@ -1083,8 +1090,8 @@ public void eUnset(int featureID) { } /** - * - * + * + * * @generated */ @Override @@ -1122,23 +1129,16 @@ public boolean eIsSet(int featureID) { public static CoordinateReferenceSystem getDefaultCRS() { try { IPreferenceStore store = ProjectPlugin.getPlugin().getPreferenceStore(); - int i = store.getInt(PreferenceConstants.P_DEFAULT_CRS); - if (i == -1) - return CRS.decode("EPSG:4326");//$NON-NLS-1$ - return CRS.decode("EPSG:" + i); //$NON-NLS-1$ + int epsgCode = store.getInt(PreferenceConstants.P_DEFAULT_CRS); + if (epsgCode == -1) { + epsgCode = DEFAULT_CRS; + } + return CRS.decode("EPSG:" + epsgCode); //$NON-NLS-1$ } catch (FactoryException e) { return ViewportModel.BAD_DEFAULT; } } - /** - * @returns a default NIL Bounding Box based on system wide default CRS - * @return - */ - public static ReferencedEnvelope getDefaultReferencedEnvelope() { - return new ReferencedEnvelope(0, 0, 0, 0, ViewportModelImpl.getDefaultCRS()); - } - /** * FIXME, This method was added as a work around for the fact that we do not have the ability to * chain or batch commands. @@ -1172,9 +1172,6 @@ public void setInitialized(boolean initialized) { this.initialized = initialized; } - /** - * @see org.locationtech.udig.project.render.IViewportModel#getMap() - */ @Override public IMap getMap() { return getMapInternal(); @@ -1186,12 +1183,12 @@ public double getScaleDenominator() { return -1; } RenderManager renderManager = getRenderManagerInternal(); - ReferencedEnvelope bounds2 = getBounds(); - if (renderManager == null || renderManager.getMapDisplay() == null) + if (renderManager == null || renderManager.getMapDisplay() == null) { return -1; + } IMapDisplay display = renderManager.getMapDisplay(); - return ScaleUtils.calculateScaleDenominator(bounds2, display.getDisplaySize(), + return ScaleUtils.calculateScaleDenominator(getBounds(), display.getDisplaySize(), display.getDPI()); } @@ -1238,8 +1235,8 @@ public void setPreferredScaleDenominators(SortedSet newPreferredScaleDen } /** - * This method will calculate the current width based on ScaleUtils and - * the current RenderManager. + * This method will calculate the current width based on ScaleUtils and the current + * RenderManager. */ @Override public void setScale(double scaleDenominator) { diff --git a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/render/IViewportModel.java b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/render/IViewportModel.java index f5d810347..470d1d0df 100644 --- a/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/render/IViewportModel.java +++ b/plugins/org.locationtech.udig.project/src/org/locationtech/udig/project/render/IViewportModel.java @@ -1,4 +1,5 @@ -/* uDig - User Friendly Desktop Internet GIS client +/** + * uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2004-2012, Refractions Research Inc. * @@ -14,14 +15,11 @@ import java.awt.geom.AffineTransform; import java.util.SortedSet; -import org.locationtech.udig.project.IMap; -import org.locationtech.udig.project.internal.render.impl.ViewportModelImpl; - import org.geotools.geometry.jts.ReferencedEnvelope; -import org.opengis.referencing.crs.CoordinateReferenceSystem; - import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; +import org.locationtech.udig.project.IMap; +import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * Models the Viewport on the map. @@ -31,11 +29,6 @@ */ public interface IViewportModel { - /** - * A Default setting to use for the viewport CRS. - */ - public static final CoordinateReferenceSystem DEFAULT_CRS = ViewportModelImpl.DEFAULT_CRS; - /** * Returns the local coordinate system. The local coordinate system is the CRS that all the * layer data will be transformed into. Once the layer data is transformed into the local CRS