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);
}
}