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 *

This constructor performs a shallow copy, i.e. the properties are not cloned.

* * @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: + * + * + * + * @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 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 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 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; iThis class currently provides implementation for the following methods:

*
    - *
  • {@link AbstractCS#castOrCopy(CoordinateSystem)}
  • + *
  • {@link AbstractCRS#castOrCopy(CoordinateReferenceSystem)}
  • + *
  • {@link DefaultCompoundCRS#forConvention(AxesConvention)}
  • *
* * @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 { /** - * 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 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 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); } }