This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 55abc84f28 Add a specialized event class for change of zoom, pan, 
translation, etc.
55abc84f28 is described below

commit 55abc84f28a894d7d5e25a5dd8de586be9eb41fa
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Jun 9 19:17:49 2022 +0200

    Add a specialized event class for change of zoom, pan, translation, etc.
---
 .../main/java/org/apache/sis/portrayal/Canvas.java |  52 ++++++---
 .../org/apache/sis/portrayal/PlanarCanvas.java     |  14 ++-
 .../apache/sis/portrayal/TransformChangeEvent.java | 122 +++++++++++++++++++++
 3 files changed, 167 insertions(+), 21 deletions(-)

diff --git 
a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java 
b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
index 20f03709a0..ce293db612 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
@@ -143,7 +143,7 @@ import org.apache.sis.coverage.grid.GridExtent;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -164,6 +164,7 @@ public class Canvas extends Observable implements Localized 
{
      * The {@value} property name, used for notifications about changes in 
<cite>objective to display</cite> conversion.
      * This conversion maps coordinates in the {@linkplain #getObjectiveCRS() 
objective CRS} to coordinates in the
      * {@linkplain #getDisplayCRS() display CRS}. Associated values are 
instances of {@link LinearTransform}.
+     * The event class is the {@link TransformChangeEvent} specialization.
      *
      * @see #getObjectiveToDisplay()
      * @see #setObjectiveToDisplay(LinearTransform)
@@ -585,9 +586,7 @@ public class Canvas extends Observable implements Localized 
{
             objectiveCRS = newValue;                                // Set 
only after everything else succeeded.
             operationContext.setObjectiveToGeographic(newToGeo);
             firePropertyChange(OBJECTIVE_CRS_PROPERTY, oldValue, newValue);
-            if (!Objects.equals(oldObjectiveToDisplay, newObjectiveToDisplay)) 
{
-                firePropertyChange(OBJECTIVE_TO_DISPLAY_PROPERTY, 
oldObjectiveToDisplay, newObjectiveToDisplay);
-            }
+            fireIfChanged(oldObjectiveToDisplay, newObjectiveToDisplay);
         } catch (FactoryException | TransformException e) {
             throw new 
RenderException(errors().getString(Errors.Keys.CanNotSetPropertyValue_1, 
OBJECTIVE_CRS_PROPERTY), e);
         }
@@ -694,7 +693,7 @@ public class Canvas extends Observable implements Localized 
{
      * @return snapshot of objective to display conversion, never null.
      *
      * @see #updateObjectiveToDisplay(LinearTransform)
-     * @see #invalidateObjectiveToDisplay(LinearTransform)
+     * @see #invalidateObjectiveToDisplay()
      */
     LinearTransform updateObjectiveToDisplay() {
         return MathTransforms.identity(getDisplayDimensions());
@@ -726,7 +725,7 @@ public class Canvas extends Observable implements Localized 
{
                 }
                 if (!oldValue.equals(newValue)) {
                     updateObjectiveToDisplay(newValue);
-                    firePropertyChange(OBJECTIVE_TO_DISPLAY_PROPERTY, 
oldValue, newValue);
+                    fireTransformChange(oldValue, newValue);
                 }
                 return;
             }
@@ -752,19 +751,14 @@ public class Canvas extends Observable implements 
Localized {
     /**
      * Declares that the {@link #objectiveToDisplay} transform became invalid 
and will need to be recomputed.
      * It is subclasses responsibility to recompute the transform in their 
{@link #updateObjectiveToDisplay()}
-     * method.
-     *
-     * @param  oldValue  the old value, or {@code null} for not firing change 
event.
+     * method and to invoke {@link #fireTransformChange(LinearTransform, 
LinearTransform)} (or equivalent).
      *
      * @see #updateObjectiveToDisplay()
      */
-    final void invalidateObjectiveToDisplay(final LinearTransform oldValue) {
+    final void invalidateObjectiveToDisplay() {
         objectiveToDisplay = null;
         gridGeometry       = null;
         operationContext.clear();
-        if (oldValue != null) {
-            firePropertyChange(OBJECTIVE_TO_DISPLAY_PROPERTY, oldValue, 
getObjectiveToDisplay());
-        }
     }
 
     /**
@@ -1119,10 +1113,10 @@ public class Canvas extends Observable implements 
Localized {
              * other listeners will not be notified but this Canvas will not 
be corrupted since all the work to
              * do in this class is already completed.
              */
-            fireIfChanged(DISPLAY_BOUNDS_PROPERTY,       oldBounds,            
 newBounds);
-            fireIfChanged(OBJECTIVE_CRS_PROPERTY,        oldObjectiveCRS,      
 newObjectiveCRS);
-            fireIfChanged(OBJECTIVE_TO_DISPLAY_PROPERTY, 
oldObjectiveToDisplay, newObjectiveToDisplay);
-            fireIfChanged(POINT_OF_INTEREST_PROPERTY,    oldPOI,               
 newPOI);
+            fireIfChanged(DISPLAY_BOUNDS_PROPERTY,    oldBounds,             
newBounds);
+            fireIfChanged(OBJECTIVE_CRS_PROPERTY,     oldObjectiveCRS,       
newObjectiveCRS);
+            fireIfChanged(/* OBJECTIVE_TO_DISPLAY */  oldObjectiveToDisplay, 
newObjectiveToDisplay);
+            fireIfChanged(POINT_OF_INTEREST_PROPERTY, oldPOI,                
newPOI);
         } catch (IncompleteGridGeometryException | CannotEvaluateException | 
FactoryException | TransformException e) {
             throw new 
RenderException(errors().getString(Errors.Keys.CanNotSetPropertyValue_1, 
GRID_GEOMETRY_PROPERTY), e);
         }
@@ -1130,7 +1124,6 @@ public class Canvas extends Observable implements 
Localized {
 
     /**
      * Fires a property change event if the old and new values are not equal.
-     * This method assumes that the new value is never null (but the old value 
can be null).
      *
      * @param  propertyName  name of the property that changed its value.
      * @param  oldValue      the old property value (may be {@code null}).
@@ -1142,6 +1135,29 @@ public class Canvas extends Observable implements 
Localized {
         }
     }
 
+    /**
+     * Fires a property change event if the old and new transforms are not 
equal.
+     *
+     * @param  oldValue  the old "objective to display" transform.
+     * @param  newValue  the new transform, or {@code null} for lazy 
computation.
+     */
+    private void fireIfChanged(final LinearTransform oldValue, final 
LinearTransform newValue) {
+        if (!Objects.equals(oldValue, newValue)) {
+            fireTransformChange(oldValue, newValue);
+        }
+    }
+
+    /**
+     * Fires a {@link TransformChangeEvent}.
+     * It is caller responsibility to verify that the old and new values are 
different.
+     *
+     * @param  oldValue  the old "objective to display" transform.
+     * @param  newValue  the new transform, or {@code null} for lazy 
computation.
+     */
+    final void fireTransformChange(final LinearTransform oldValue, final 
LinearTransform newValue) {
+        firePropertyChange(new TransformChangeEvent(this, oldValue, newValue));
+    }
+
     /**
      * Returns the geographic bounding box encompassing the area shown on the 
display device.
      * If the {@linkplain #getObjectiveCRS() objective CRS} is not convertible 
to a geographic CRS,
diff --git 
a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/PlanarCanvas.java 
b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/PlanarCanvas.java
index fcc59cc824..f5c20bb139 100644
--- 
a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/PlanarCanvas.java
+++ 
b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/PlanarCanvas.java
@@ -41,7 +41,7 @@ import 
org.apache.sis.internal.referencing.j2d.AffineTransform2D;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -168,7 +168,10 @@ public abstract class PlanarCanvas extends Canvas {
         if (!before.isIdentity()) {
             final LinearTransform old = 
hasListener(OBJECTIVE_TO_DISPLAY_PROPERTY) ? getObjectiveToDisplay() : null;
             objectiveToDisplay.concatenate(before);
-            invalidateObjectiveToDisplay(old);
+            invalidateObjectiveToDisplay();
+            if (old != null) {
+                fireTransformChange(old, null);
+            }
         }
     }
 
@@ -183,7 +186,12 @@ public abstract class PlanarCanvas extends Canvas {
         if (!after.isIdentity()) {
             final LinearTransform old = 
hasListener(OBJECTIVE_TO_DISPLAY_PROPERTY) ? getObjectiveToDisplay() : null;
             objectiveToDisplay.preConcatenate(after);
-            invalidateObjectiveToDisplay(old);
+            invalidateObjectiveToDisplay();
+            if (old != null) {
+                final TransformChangeEvent event = new 
TransformChangeEvent(this, old, null);
+                event.change = AffineTransforms2D.toMathTransform(after);
+                firePropertyChange(event);
+            }
         }
     }
 }
diff --git 
a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
 
b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
new file mode 100644
index 0000000000..756d7ee7fd
--- /dev/null
+++ 
b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.portrayal;
+
+import java.beans.PropertyChangeEvent;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.referencing.operation.transform.LinearTransform;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+
+
+/**
+ * A change in the zoom, pan or translation applied for viewing a map. All 
events fired by
+ * {@link Canvas} for the {@value Canvas#OBJECTIVE_TO_DISPLAY_PROPERTY} 
property are of this kind.
+ * This specialization provides a method for computing the difference between 
the old and new state.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.3
+ *
+ * @see Canvas#OBJECTIVE_TO_DISPLAY_PROPERTY
+ *
+ * @since 1.3
+ * @module
+ */
+public class TransformChangeEvent extends PropertyChangeEvent {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 4065626270969827867L;
+
+    /**
+     * The change in display coordinates, computed when first needed.
+     * This field may be precomputed by the code that fired this event.
+     *
+     * @see #getChangeInDisplayCoordinates()
+     */
+    LinearTransform change;
+
+    /**
+     * Creates a new event for a change of the "objective to display" property.
+     * The old and new transforms should not be null, except for lazy 
computation:
+     * a null {@code newValue} means to take the value from {@link 
Canvas#getObjectiveToDisplay()} when needed.
+     *
+     * @param  source    the canvas that fired the event.
+     * @param  oldValue  the old "objective to display" transform.
+     * @param  newValue  the new transform, or {@code null} for lazy 
computation.
+     * @throws IllegalArgumentException if {@code source} is {@code null}.
+     */
+    public TransformChangeEvent(final Canvas source, final LinearTransform 
oldValue, final LinearTransform newValue) {
+        super(source, Canvas.OBJECTIVE_TO_DISPLAY_PROPERTY, oldValue, 
newValue);
+    }
+
+    /**
+     * Returns the canvas on which this event initially occurred.
+     *
+     * @return the canvas on which this event initially occurred.
+     */
+    @Override
+    public Canvas getSource() {
+        return (Canvas) source;
+    }
+
+    /**
+     * Gets the old "objective to display" transform.
+     *
+     * @return the old "objective to display" transform.
+     */
+    @Override
+    public LinearTransform getOldValue() {
+        return (LinearTransform) super.getOldValue();
+    }
+
+    /**
+     * Gets the new "objective to display" transform.
+     * It should be the current value of {@link 
Canvas#getObjectiveToDisplay()}.
+     *
+     * @return the new "objective to display" transform.
+     */
+    @Override
+    public LinearTransform getNewValue() {
+        LinearTransform transform = (LinearTransform) super.getNewValue();
+        if (transform == null) {
+            transform = getSource().getObjectiveToDisplay();
+        }
+        return transform;
+    }
+
+    /**
+     * Returns the change in display coordinates from the old state to the new 
state.
+     * If the "objective to display" transform changed because the users did a 
zoom,
+     * pan or translation, this is the transform representing that change in 
display
+     * coordinates.
+     *
+     * @return the change in display coordinates, or {@code null} if the old 
or new transform is missing.
+     * @throws NoninvertibleTransformException if a singular matrix prevent 
the change to be computed.
+     */
+    public LinearTransform getChangeInDisplayCoordinates() throws 
NoninvertibleTransformException {
+        if (change == null) {
+            final LinearTransform oldValue = getOldValue();
+            if (oldValue != null) {
+                final LinearTransform newValue = getNewValue();
+                if (newValue != null) {
+                    change = (LinearTransform) 
MathTransforms.concatenate(oldValue.inverse(), newValue);
+                }
+            }
+        }
+        return change;
+    }
+}

Reply via email to