sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1558577 - in /sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs: AbstractCRS.java DefaultCompoundCRS.java DefaultGeographicCRS.java SubTypes.java
Date Wed, 15 Jan 2014 21:52:56 GMT
Author: desruisseaux
Date: Wed Jan 15 21:52:55 2014
New Revision: 1558577

URL: http://svn.apache.org/r1558577
Log:
Implemented DefaultCompoundCRS.forConvention(...).

Added:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java
      - copied, changed from r1558164, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/SubTypes.java
Modified:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1558577&r1=1558576&r2=1558577&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
[UTF-8] Wed Jan 15 21:52:55 2014
@@ -178,6 +178,8 @@ public class AbstractCRS extends Abstrac
      * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p>
      *
      * @param crs The coordinate reference system to copy.
+     *
+     * @see #castOrCopy(CoordinateReferenceSystem)
      */
     protected AbstractCRS(final CoordinateReferenceSystem crs) {
         super(crs);
@@ -185,6 +187,40 @@ public class AbstractCRS extends Abstrac
     }
 
     /**
+     * Returns a SIS coordinate reference system implementation with the values of the given
arbitrary implementation.
+     * This method performs the first applicable actions in the following choices:
+     *
+     * <ul>
+     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
+     *   <li>Otherwise if the given object is is an instance of
+     *       {@link org.opengis.referencing.crs.GeodeticCRS} (including the
+     *       {@link org.opengis.referencing.crs.GeographicCRS} and
+     *       {@link org.opengis.referencing.crs.GeocentricCRS} subtypes),
+     *       {@link org.opengis.referencing.crs.VerticalCRS},
+     *       {@link org.opengis.referencing.crs.TemporalCRS},
+     *       {@link org.opengis.referencing.crs.EngineeringCRS},
+     *       {@link org.opengis.referencing.crs.ImageCRS} or
+     *       {@link org.opengis.referencing.cs.CompoundCRS},
+     *       then this method delegates to the {@code castOrCopy(…)} method of the corresponding
SIS subclass.
+     *       Note that if the given object implements more than one of the above-cited interfaces,
+     *       then the {@code castOrCopy(…)} method to be used is unspecified.</li>
+     *   <li>Otherwise if the given object is already an instance of
+     *       {@code AbstractCRS}, then it is returned unchanged.</li>
+     *   <li>Otherwise a new {@code AbstractCRS} instance is created using the
+     *       {@linkplain #AbstractCRS(CoordinateReferenceSystem) copy constructor}
+     *       and returned. Note that this is a <cite>shallow</cite> copy operation,
since the other
+     *       properties contained in the given object are not recursively copied.</li>
+     * </ul>
+     *
+     * @param  object The object to get as a SIS implementation, or {@code null} if none.
+     * @return A SIS implementation containing the values of the given object (may be the
+     *         given object itself), or {@code null} if the argument was null.
+     */
+    public static AbstractCRS castOrCopy(final CoordinateReferenceSystem object) {
+        return SubTypes.castOrCopy(object);
+    }
+
+    /**
      * Returns the GeoAPI interface implemented by this class.
      * The default implementation returns {@code CoordinateReferenceSystem.class}.
      * Subclasses implementing a more specific GeoAPI interface shall override this method.
@@ -254,6 +290,18 @@ public class AbstractCRS extends Abstrac
     }
 
     /**
+     * Returns the map of cached CRS for axes conventions.
+     * This method shall be invoked in a synchronized block.
+     */
+    final Map<AxesConvention,AbstractCRS> derived() {
+        assert Thread.holdsLock(this);
+        if (derived == null) {
+            derived = new EnumMap<>(AxesConvention.class);
+        }
+        return derived;
+    }
+
+    /**
      * Returns a coordinate reference system equivalent to this one but with axes rearranged
according the given
      * convention. If this CRS is already compatible with the given convention, then this
method returns {@code this}.
      *
@@ -264,9 +312,7 @@ public class AbstractCRS extends Abstrac
      */
     public synchronized AbstractCRS forConvention(final AxesConvention convention) {
         ensureNonNull("convention", convention);
-        if (derived == null) {
-            derived = new EnumMap<>(AxesConvention.class);
-        }
+        final Map<AxesConvention,AbstractCRS> derived = derived();
         AbstractCRS crs = derived.get(convention);
         if (crs == null) {
             final AbstractCS cs = AbstractCS.castOrCopy(coordinateSystem);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java?rev=1558577&r1=1558576&r2=1558577&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
[UTF-8] Wed Jan 15 21:52:55 2014
@@ -28,8 +28,10 @@ import org.opengis.referencing.crs.Singl
 import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.cs.CoordinateSystem;
+import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.DefaultCompoundCS;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.util.collection.CheckedContainer;
@@ -306,6 +308,38 @@ public class DefaultCompoundCRS extends 
     }
 
     /**
+     * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    public synchronized DefaultCompoundCRS forConvention(final AxesConvention convention)
{
+        ensureNonNull("convention", convention);
+        final Map<AxesConvention,AbstractCRS> derived = derived();
+        DefaultCompoundCRS crs = (DefaultCompoundCRS) derived.get(convention);
+        if (crs == null) {
+            crs = this;
+            boolean changed = false;
+            final CoordinateReferenceSystem[] components = new CoordinateReferenceSystem[singles.size()];
+            for (int i=0; i<components.length; i++) {
+                CoordinateReferenceSystem component = singles.get(i);
+                AbstractCRS m = castOrCopy(component);
+                if (m != (m = m.forConvention(convention))) {
+                    component = m;
+                    changed = true;
+                }
+                components[i] = component;
+            }
+            if (changed) {
+                Arrays.sort(components, SubTypes.BY_TYPE); // This array typically has less
than 4 elements.
+                crs = new DefaultCompoundCRS(IdentifiedObjects.getProperties(this, IDENTIFIERS_KEY),
components);
+            }
+            derived.put(convention, crs);
+        }
+        return crs;
+    }
+
+    /**
      * Compares this coordinate reference system with the specified object for equality.
      *
      * @param  object The object to compare to {@code this}.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java?rev=1558577&r1=1558576&r2=1558577&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
[UTF-8] Wed Jan 15 21:52:55 2014
@@ -132,7 +132,7 @@ public class DefaultGeographicCRS extend
      *
      * @param crs The coordinate reference system to copy.
      *
-     * @see #castOrCopy(GeocentricCRS)
+     * @see #castOrCopy(GeographicCRS)
      */
     protected DefaultGeographicCRS(final GeographicCRS crs) {
         super(crs);

Copied: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java
(from r1558164, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/SubTypes.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java?p2=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/SubTypes.java&r1=1558164&r2=1558577&rev=1558577&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/SubTypes.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java
[UTF-8] Wed Jan 15 21:52:55 2014
@@ -14,28 +14,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.cs;
+package org.apache.sis.referencing.crs;
 
-import org.opengis.referencing.cs.AffineCS;
+import java.util.Map;
+import java.util.Comparator;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.crs.GeocentricCRS;
+import org.opengis.referencing.crs.GeodeticCRS;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ImageCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.cs.CylindricalCS;
+import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.EllipsoidalCS;
-import org.opengis.referencing.cs.LinearCS;
-import org.opengis.referencing.cs.PolarCS;
 import org.opengis.referencing.cs.SphericalCS;
-import org.opengis.referencing.cs.TimeCS;
-import org.opengis.referencing.cs.UserDefinedCS;
-import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.cs.AxesConvention;
 
 
 /**
- * Implementation of {@link AbstractCS} methods that require knowledge about subclasses.
+ * Implementation of {@link AbstractCRS} methods that require knowledge about subclasses.
  * Those methods are defined in a separated static class for avoiding class loading of all
- * coordinate system implementations before necessary.
+ * coordinate reference system implementations before necessary.
  *
  * <p>This class currently provides implementation for the following methods:</p>
  * <ul>
- *   <li>{@link AbstractCS#castOrCopy(CoordinateSystem)}</li>
+ *   <li>{@link AbstractCRS#castOrCopy(CoordinateReferenceSystem)}</li>
+ *   <li>{@link DefaultCompoundCRS#forConvention(AxesConvention)}</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -43,55 +53,107 @@ import org.opengis.referencing.cs.Vertic
  * @version 0.4
  * @module
  */
-final class SubTypes {
+final class SubTypes implements Comparator<Object> {
     /**
-     * Do not allow instantiation of this class.
+     * CRS types to sort first in a compound CRS. Any type not in this list will be sorted
last.
+     * Used for implementation of {@link #BY_TYPE} comparator.
+     */
+    private static final Class<?>[] TYPE_ORDER = {
+        ProjectedCRS.class,
+        GeodeticCRS.class,
+        VerticalCRS.class,
+        TemporalCRS.class
+    };
+
+    /**
+     * A comparator for sorting CRS objects by their types.
+     * The comparison sorts projected CRS first, followed by geodetic, vertical then temporal
CRS.
+     */
+    static final Comparator<Object> BY_TYPE = new SubTypes();
+
+    /**
+     * Do not allow instantiation of this class (except the singleton).
      */
     private SubTypes() {
     }
 
     /**
-     * Returns a SIS implementation for the given coordinate system.
-     *
-     * @see AbstractCS#castOrCopy(CoordinateSystem)
+     * Returns the index of the interface implemented by the given object.
      */
-    static AbstractCS castOrCopy(final CoordinateSystem object) {
-        if (object instanceof AffineCS) {
-            return DefaultAffineCS.castOrCopy((AffineCS) object);
-        }
-        if (object instanceof SphericalCS) {
-            return DefaultSphericalCS.castOrCopy((SphericalCS) object);
-        }
-        if (object instanceof EllipsoidalCS) {
-            return DefaultEllipsoidalCS.castOrCopy((EllipsoidalCS) object);
-        }
-        if (object instanceof CylindricalCS) {
-            return DefaultCylindricalCS.castOrCopy((CylindricalCS) object);
+    private static int indexOf(final Object object) {
+        int i = 0;
+        while (i < TYPE_ORDER.length) {
+            if (TYPE_ORDER[i].isInstance(object)) {
+                break;
+            }
         }
-        if (object instanceof PolarCS) {
-            return DefaultPolarCS.castOrCopy((PolarCS) object);
-        }
-        if (object instanceof LinearCS) {
-            return DefaultLinearCS.castOrCopy((LinearCS) object);
+        return i;
+    }
+
+    /**
+     * Implementation of {@link #BY_TYPE} comparator.
+     */
+    @Override
+    public int compare(final Object o1, final Object o2) {
+        return indexOf(o1) - indexOf(o2);
+    }
+
+    /**
+     * Returns a SIS implementation for the given coordinate reference system.
+     *
+     * @see AbstractCRS#castOrCopy(CoordinateReferenceSystem)
+     */
+    static AbstractCRS castOrCopy(final CoordinateReferenceSystem object) {
+        if (object instanceof GeodeticCRS) {
+            if (object instanceof GeographicCRS) {
+                return DefaultGeographicCRS.castOrCopy((GeographicCRS) object);
+            }
+            if (object instanceof GeocentricCRS) {
+                return DefaultGeocentricCRS.castOrCopy((GeocentricCRS) object);
+            }
+            /*
+             * The GeographicCRS and GeocentricCRS types are not part of ISO 19111.
+             * ISO uses a single type, GeodeticCRS, for both of them and infer the
+             * geographic or geocentric type from the coordinate system. We do this
+             * check here for instantiating the most appropriate SIS type.
+             */
+            final Map<String,?> properties = IdentifiedObjects.getProperties(object);
+            final GeodeticDatum datum = ((GeodeticCRS) object).getDatum();
+            final CoordinateSystem cs = object.getCoordinateSystem();
+            if (cs instanceof EllipsoidalCS) {
+                return new DefaultGeographicCRS(properties, datum, (EllipsoidalCS) cs);
+            }
+            if (cs instanceof SphericalCS) {
+                return new DefaultGeocentricCRS(properties, datum, (SphericalCS) cs);
+            }
+            if (cs instanceof CartesianCS) {
+                return new DefaultGeocentricCRS(properties, datum, (CartesianCS) cs);
+            }
+        }
+        if (object instanceof VerticalCRS) {
+            return DefaultVerticalCRS.castOrCopy((VerticalCRS) object);
+        }
+        if (object instanceof TemporalCRS) {
+            return DefaultTemporalCRS.castOrCopy((TemporalCRS) object);
         }
-        if (object instanceof VerticalCS) {
-            return DefaultVerticalCS.castOrCopy((VerticalCS) object);
+        if (object instanceof EngineeringCRS) {
+            return DefaultEngineeringCRS.castOrCopy((EngineeringCRS) object);
         }
-        if (object instanceof TimeCS) {
-            return DefaultTimeCS.castOrCopy((TimeCS) object);
+        if (object instanceof ImageCRS) {
+            return DefaultImageCRS.castOrCopy((ImageCRS) object);
         }
-        if (object instanceof UserDefinedCS) {
-            return DefaultUserDefinedCS.castOrCopy((UserDefinedCS) object);
+        if (object instanceof CompoundCRS) {
+            return DefaultCompoundCRS.castOrCopy((CompoundCRS) object);
         }
         /*
-         * Intentionally check for AbstractCS after the interfaces because user may have
defined his own
-         * subclass implementing the interface. If we were checking for AbstractCS before
the interfaces,
+         * Intentionally check for AbstractCRS after the interfaces because user may have
defined his own
+         * subclass implementing the interface. If we were checking for AbstractCRS before
the interfaces,
          * the returned instance could have been a user subclass without the JAXB annotations
required
          * for XML marshalling.
          */
-        if (object == null || object instanceof AbstractCS) {
-            return (AbstractCS) object;
+        if (object == null || object instanceof AbstractCRS) {
+            return (AbstractCRS) object;
         }
-        return new AbstractCS(object);
+        return new AbstractCRS(object);
     }
 }



Mime
View raw message