Author: desruisseaux Date: Mon Jul 6 08:59:03 2015 New Revision: 1689340 URL: http://svn.apache.org/r1689340 Log: WKT 2: complete parsing of CoordinateOperation.
Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java (with props) Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -24,6 +24,7 @@ import org.opengis.geometry.Envelope; import org.opengis.metadata.Identifier; import org.opengis.parameter.ParameterDescriptor; import org.opengis.referencing.IdentifiedObject; +import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.SingleCRS; import org.opengis.referencing.crs.DerivedCRS; import org.opengis.referencing.crs.VerticalCRS; @@ -36,7 +37,9 @@ import org.opengis.referencing.operation import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.SingleOperation; import org.opengis.referencing.operation.TransformException; +import org.opengis.util.FactoryException; import org.apache.sis.metadata.iso.extent.DefaultExtent; import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent; import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent; @@ -92,6 +95,15 @@ public class ReferencingServices extends public static final String PARAMETERS_KEY = "parameters"; /** + * The key for specifying the base type of the coordinate operation to create. This optional entry + * is used by {@code DefaultCoordinateOperationFactory.createSingleOperation(…)}. Apache SIS tries + * to infer this value automatically, but this entry may help SIS to perform a better choice in + * some cases. For example an "Affine" operation can be both a conversion or a transformation + * (the later is used in datum shift in geocentric coordinates). + */ + public static final String OPERATION_TYPE_KEY = "operationType"; + + /** * The key for specifying a {@linkplain org.opengis.referencing.operation.MathTransformFactory} * instance to use for the construction of a geodetic object. This is usually not needed for CRS * construction, except in the special case of a derived CRS created from a defining conversion. @@ -422,6 +434,32 @@ public class ReferencingServices extends } /** + * Creates a single operation from the given properties. + * This method is provided here because not yet available in GeoAPI interfaces. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none. + * @param method The coordinate operation method (mandatory in all cases). + * @param factory The factory to use. + * @return The coordinate operation created from the given arguments. + * @throws FactoryException if the object creation failed. + * + * @since 0.6 + */ + public SingleOperation createSingleOperation( + final Map<String,?> properties, + final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS, + final CoordinateReferenceSystem interpolationCRS, + final OperationMethod method, + final CoordinateOperationFactory factory) throws FactoryException + { + throw moduleNotFound(); + } + + /** * Returns the coordinate operation factory to use for the given properties and math transform factory. * If the given properties are empty and the {@code mtFactory} is the system default, then this method * returns the system default {@code CoordinateOperationFactory} instead of creating a new one. Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -1253,7 +1253,7 @@ final class GeodeticObjectParser extends } name = parent.pullString("name"); } - OperationMethod method = parseMethod(parent, WKTKeywords.Method, WKTKeywords.Projection); + final OperationMethod method = parseMethod(parent, WKTKeywords.Method, WKTKeywords.Projection); Map<String,?> properties = this.properties; // Same properties then OperationMethod, with ID removed. /* * Set the list of parameters. @@ -2078,15 +2078,20 @@ final class GeodeticObjectParser extends final CoordinateReferenceSystem sourceCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.SourceCRS); final CoordinateReferenceSystem targetCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.TargetCRS); final CoordinateReferenceSystem interpolationCRS = parseCoordinateReferenceSystem(element, OPTIONAL, WKTKeywords.InterpolationCRS); - final OperationMethod method = parseMethod(parent, WKTKeywords.Method); - final Element accuracy = parent.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy); - final Map<String,Object> properties = parseMetadataAndClose(parent, name, method); + final OperationMethod method = parseMethod(element, WKTKeywords.Method); + final Element accuracy = element.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy); + final Map<String,Object> properties = parseMetadataAndClose(element, name, method); final ParameterValueGroup parameters = method.getParameters().createValue(); - parseParameters(parent, parameters, null, null); + parseParameters(element, parameters, null, null); + properties.put(ReferencingServices.PARAMETERS_KEY, parameters); if (accuracy != null) { accuracy.pullDouble("accuracy"); // TODO: share the code from EPSG factory. accuracy.close(ignoredElements); } - return null; // Not yet implemented. + try { + return referencing.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, opFactory); + } catch (FactoryException e) { + throw element.parseFailed(e); + } } } Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -42,6 +42,7 @@ import org.opengis.referencing.operation import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.SingleOperation; import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.metadata.extent.GeographicBoundingBox; @@ -570,6 +571,39 @@ public final class ServicesForMetadata e } /** + * Creates a single operation from the given properties. + * This method is provided here because not yet available in GeoAPI interfaces. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none. + * @param method The coordinate operation method (mandatory in all cases). + * @param factory The factory to use. + * @return The coordinate operation created from the given arguments. + * @throws FactoryException if the object creation failed. + * + * @since 0.6 + */ + @Override + public SingleOperation createSingleOperation( + final Map<String,?> properties, + final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS, + final CoordinateReferenceSystem interpolationCRS, + final OperationMethod method, + final CoordinateOperationFactory factory) throws FactoryException + { + final DefaultCoordinateOperationFactory df; + if (factory instanceof DefaultCoordinateOperationFactory) { + df = (DefaultCoordinateOperationFactory) factory; + } else { + df = DefaultFactories.forBuildin(CoordinateOperationFactory.class, DefaultCoordinateOperationFactory.class); + } + return df.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, null); + } + + /** * Returns the coordinate operation factory to use for the given properties and math transform factory. * If the given properties are empty and the {@code mtFactory} is the system default, then this method * returns the system default {@code CoordinateOperationFactory} instead of creating a new one. Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -16,12 +16,17 @@ */ package org.apache.sis.referencing.operation; +import java.util.Map; import javax.xml.bind.annotation.XmlTransient; import org.opengis.util.FactoryException; import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.ConicProjection; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ProjectedCRS; /** @@ -43,6 +48,24 @@ final class DefaultConicProjection exten private static final long serialVersionUID = -8717453834398763963L; /** + * Creates a projection from the given properties. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param method The coordinate operation method. + * @param transform Transform from positions in the source CRS to positions in the target CRS. + */ + public DefaultConicProjection(final Map<String,?> properties, + final GeographicCRS sourceCRS, + final ProjectedCRS targetCRS, + final OperationMethod method, + final MathTransform transform) + { + super(properties, sourceCRS, targetCRS, method, transform); + } + + /** * Creates a new projection with the same values than the specified one, together with the * specified source and target CRS. While the source conversion can be an arbitrary one, it * is typically a defining conversion. Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -26,16 +26,20 @@ import org.opengis.parameter.ParameterDe import org.opengis.referencing.operation.*; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ProjectedCRS; import org.apache.sis.internal.referencing.MergedProperties; import org.apache.sis.internal.metadata.ReferencingServices; import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.util.CollectionsExt; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.util.collection.WeakHashSet; +import org.apache.sis.util.collection.Containers; import org.apache.sis.util.iso.AbstractFactory; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.CharSequences; +import org.apache.sis.util.NullArgumentException; /** @@ -203,7 +207,7 @@ public class DefaultCoordinateOperationF * </tr> * <tr> * <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td> - * <td>{@link Identifier} or {@link String}</td> + * <td>{@link org.opengis.metadata.Identifier} or {@link String}</td> * <td>{@link DefaultOperationMethod#getName()}</td> * </tr> * <tr> @@ -213,7 +217,7 @@ public class DefaultCoordinateOperationF * </tr> * <tr> * <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td> - * <td>{@link Identifier} (optionally as array)</td> + * <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td> * <td>{@link DefaultOperationMethod#getIdentifiers()}</td> * </tr> * <tr> @@ -247,7 +251,7 @@ public class DefaultCoordinateOperationF } /** - * Constructs a defining conversion from the given operation parameters. + * Creates a defining conversion from the given operation parameters. * This conversion has no source and target CRS since those elements are usually unknown at this stage. * The source and target CRS will become known later, at the * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS Derived CRS} or @@ -308,6 +312,170 @@ public class DefaultCoordinateOperationF } /** + * Creates a transformation or conversion from the given properties. + * This method infers by itself if the operation to create is a + * {@link Transformation}, a {@link Conversion} or a {@link Projection} sub-type + * ({@link CylindricalProjection}, {@link ConicProjection} or {@link PlanarProjection}) + * using the {@linkplain DefaultOperationMethod#getOperationType() information provided by the given method}. + * + * <p>The properties given in argument follow the same rules than for the + * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem, + * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) coordinate operation} constructor. + * The following table is a reminder of main (not all) properties:</p> + * + * <table class="sis"> + * <caption>Recognized properties (non exhaustive list)</caption> + * <tr> + * <th>Property name</th> + * <th>Value type</th> + * <th>Returned by</th> + * </tr> + * <tr> + * <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td> + * <td>{@link org.opengis.metadata.Identifier} or {@link String}</td> + * <td>{@link DefaultConversion#getName()}</td> + * </tr> + * <tr> + * <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td> + * <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td> + * <td>{@link DefaultConversion#getIdentifiers()}</td> + * </tr> + * <tr> + * <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td> + * <td>{@link org.opengis.metadata.extent.Extent}</td> + * <td>{@link DefaultConversion#getDomainOfValidity()}</td> + * </tr> + * </table> + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none. + * @param method The coordinate operation method (mandatory in all cases). + * @param transform Transform from positions in the source CRS to positions in the target CRS. + * @return The coordinate operation created from the given arguments. + * @throws FactoryException if the object creation failed. + * + * @see DefaultOperationMethod#getOperationType() + * @see DefaultTransformation + * @see DefaultConversion + */ + public SingleOperation createSingleOperation( + final Map<String,?> properties, + final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS, + final CoordinateReferenceSystem interpolationCRS, + final OperationMethod method, + MathTransform transform) throws FactoryException + { + ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS); + ArgumentChecks.ensureNonNull("targetCRS", targetCRS); + ArgumentChecks.ensureNonNull("method", method); + /* + * Undocumented (for now) feature: if the 'transform' argument is null but parameters are + * found in the given properties, create the MathTransform instance from those parameters. + */ + if (transform == null) { + final ParameterValueGroup parameters = Containers.property(properties, + ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class); + if (parameters == null) { + throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, "transform")); + } + transform = mtFactory.createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem()); + } + /* + * The "operationType" property is currently undocumented. The intend is to help this factory method in + * situations where the given operation method is not an Apache SIS implementation or does not override + * getOperationType(), or the method is ambiguous (e.g. "Affine" can be used for both a transformation + * or a conversion). + * + * If we have both a 'baseType' and a Method.getOperationType(), take the most specific type. + * An exception will be thrown if the two types are incompatible. + */ + Class<?> baseType = Containers.property(properties, ReferencingServices.OPERATION_TYPE_KEY, Class.class); + if (baseType == null) { + baseType = SingleOperation.class; + } + if (method instanceof DefaultOperationMethod) { + final Class<? extends SingleOperation> c = ((DefaultOperationMethod) method).getOperationType(); + if (c != null) { // Paranoiac check (above method should not return null). + if (baseType.isAssignableFrom(c)) { + baseType = c; + } else if (!c.isAssignableFrom(baseType)) { + throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1, + ReferencingServices.OPERATION_TYPE_KEY)); + } + } + } + /* + * If the base type is still abstract (probably because it was not specified neither in the given OperationMethod + * or in the properties), then try to find a concrete type using the following rules derived from the definitions + * given in ISO 19111: + * + * - If the two CRS uses the same datum (ignoring metadata), assume that we have a Conversion. + * - Otherwise we have a datum change, which implies that we have a Transformation. + * + * In the case of Conversion, we can specialize one step more if the conversion is going from a geographic CRS + * to a projected CRS. It may seems that we should check if ProjectedCRS.getBaseCRS() is equals (ignoring meta + * data) to source CRS. But we already checked the datum, which is the important part. The axis order and unit + * could be different, which we want to allow. + */ + if (baseType == SingleOperation.class) { + if (OperationPathFinder.isConversion(sourceCRS, targetCRS)) { + if (interpolationCRS == null && sourceCRS instanceof GeographicCRS + && targetCRS instanceof ProjectedCRS) + { + baseType = Projection.class; + } else { + baseType = Conversion.class; + } + } else { + baseType = Transformation.class; + } + } + /* + * Now create the coordinate operation of the requested type. If we can not find a concrete class for the + * requested type, we will instantiate an SingleOperation in last resort. The later action is a departure + * from ISO 19111 since 'SingleOperation' is conceptually abstract. But we do that as a way to said that + * we are missing this important piece of information but still go ahead. + * + * It is unconvenient to guarantee that the created operation is an instance of 'baseType' since the user + * could have specified an implementation class or a custom sub-interface. We will perform the type check + * only after object creation. + */ + final AbstractSingleOperation op; + if (Transformation.class.isAssignableFrom(baseType)) { + op = new DefaultTransformation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform); + } else if (Projection.class.isAssignableFrom(baseType)) { + ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS); + ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS .class, targetCRS); + if (interpolationCRS != null) { + throw new IllegalArgumentException(Errors.format( + Errors.Keys.ForbiddenAttribute_2, "interpolationCRS", baseType)); + } + final GeographicCRS baseCRS = (GeographicCRS) sourceCRS; + final ProjectedCRS crs = (ProjectedCRS) targetCRS; + if (CylindricalProjection.class.isAssignableFrom(baseType)) { + op = new DefaultCylindricalProjection(properties, baseCRS, crs, method, transform); + } else if (ConicProjection.class.isAssignableFrom(baseType)) { + op = new DefaultConicProjection(properties, baseCRS, crs, method, transform); + } else if (PlanarProjection.class.isAssignableFrom(baseType)) { + op = new DefaultPlanarProjection(properties, baseCRS, crs, method, transform); + } else { + op = new DefaultProjection(properties, baseCRS, crs, method, transform); + } + } else if (Conversion.class.isAssignableFrom(baseType)) { + op = new DefaultConversion(properties, sourceCRS, targetCRS, interpolationCRS, method, transform); + } else { // See above comment about this last-resort fallback. + op = new AbstractSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform); + } + if (!baseType.isInstance(op)) { + throw new FactoryException(Errors.format(Errors.Keys.CanNotInstantiate_1, baseType)); + } + return pool.unique(op); + } + + /** * Creates an ordered sequence of two or more single coordinate operations. * The sequence of operations is constrained by the requirement that the source coordinate reference system * of step (<var>n</var>+1) must be the same as the target coordinate reference system of step (<var>n</var>). Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -16,12 +16,17 @@ */ package org.apache.sis.referencing.operation; +import java.util.Map; import javax.xml.bind.annotation.XmlTransient; import org.opengis.util.FactoryException; import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.CylindricalProjection; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ProjectedCRS; /** @@ -43,6 +48,24 @@ final class DefaultCylindricalProjection private static final long serialVersionUID = -969486613826553580L; /** + * Creates a projection from the given properties. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param method The coordinate operation method. + * @param transform Transform from positions in the source CRS to positions in the target CRS. + */ + public DefaultCylindricalProjection(final Map<String,?> properties, + final GeographicCRS sourceCRS, + final ProjectedCRS targetCRS, + final OperationMethod method, + final MathTransform transform) + { + super(properties, sourceCRS, targetCRS, method, transform); + } + + /** * Creates a new projection with the same values than the specified one, together with the * specified source and target CRS. While the source conversion can be an arbitrary one, it * is typically a defining conversion. Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -16,12 +16,17 @@ */ package org.apache.sis.referencing.operation; +import java.util.Map; import javax.xml.bind.annotation.XmlTransient; import org.opengis.util.FactoryException; import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.PlanarProjection; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ProjectedCRS; /** @@ -43,6 +48,24 @@ final class DefaultPlanarProjection exte private static final long serialVersionUID = 8171256287775067736L; /** + * Creates a projection from the given properties. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param method The coordinate operation method. + * @param transform Transform from positions in the source CRS to positions in the target CRS. + */ + public DefaultPlanarProjection(final Map<String,?> properties, + final GeographicCRS sourceCRS, + final ProjectedCRS targetCRS, + final OperationMethod method, + final MathTransform transform) + { + super(properties, sourceCRS, targetCRS, method, transform); + } + + /** * Creates a new projection with the same values than the specified one, together with the * specified source and target CRS. While the source conversion can be an arbitrary one, it * is typically a defining conversion. Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -16,10 +16,13 @@ */ package org.apache.sis.referencing.operation; +import java.util.Map; import javax.xml.bind.annotation.XmlTransient; import org.opengis.util.FactoryException; import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.Projection; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.crs.GeographicCRS; @@ -58,6 +61,24 @@ class DefaultProjection extends DefaultC private static final long serialVersionUID = -7176751851369816864L; /** + * Creates a projection from the given properties. + * + * @param properties The properties to be given to the identified object. + * @param sourceCRS The source CRS. + * @param targetCRS The target CRS. + * @param method The coordinate operation method. + * @param transform Transform from positions in the source CRS to positions in the target CRS. + */ + public DefaultProjection(final Map<String,?> properties, + final GeographicCRS sourceCRS, + final ProjectedCRS targetCRS, + final OperationMethod method, + final MathTransform transform) + { + super(properties, sourceCRS, targetCRS, null, method, transform); + } + + /** * Creates a new projection with the same values than the specified one, together with the * specified source and target CRS. While the source conversion can be an arbitrary one, it * is typically a defining conversion. Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java?rev=1689340&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java (added) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java [UTF-8] Mon Jul 6 08:59:03 2015 @@ -0,0 +1,72 @@ +/* + * 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.referencing.operation; + +import java.util.List; +import org.opengis.referencing.crs.*; +import org.opengis.referencing.datum.Datum; +import org.apache.sis.referencing.CRS; +import org.apache.sis.util.Utilities; + + +/** + * Infers a conversion of transformation path from a source CRS to a target CRS. + * + * This is currently only a placeholder for future SIS development (code to be ported from Geotk). + * + * @author Martin Desruisseaux (Geomatys) + * @since 0.6 + * @version 0.6 + * @module + */ +final class OperationPathFinder { + private OperationPathFinder() { + } + + /** + * Returns {@code true} if the given CRS are using equivalent (ignoring metadata) datum. + * If the CRS are {@link CompoundCRS}, then this method verifies that all datum in the + * target CRS exists in the source CRS, but not necessarily in the same order. + * The target CRS may have less datum than the source CRS. + * + * @param sourceCRS The target CRS. + * @param targetCRS The source CRS. + * @return {@code true} if all datum in the {@code targetCRS} exists in the {@code sourceCRS}. + */ + static boolean isConversion(final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS) + { + List<SingleCRS> components = CRS.getSingleComponents(sourceCRS); + int n = components.size(); // Number of remaining datum from sourceCRS to verify. + final Datum[] datum = new Datum[n]; + for (int i=0; i<n; i++) { + datum[i] = components.get(i).getDatum(); + } + components = CRS.getSingleComponents(targetCRS); +next: for (int i=components.size(); --i >= 0;) { + final Datum d = components.get(i).getDatum(); + for (int j=n; --j >= 0;) { + if (Utilities.equalsIgnoreMetadata(d, datum[j])) { + System.arraycopy(datum, j+1, datum, j, --n - j); // Remove the datum from the list. + continue next; + } + } + return false; // Datum from 'targetCRS' not found in 'sourceCRS'. + } + return true; + } +} Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8