CRS changes for revisions 24638:25148

Evaluation:

Consequently except for the drop of "spatialschema" in import statements, no change shown on this page will be ported to SIS.

Command line:

svn diff --extensions "--unified --ignore-space-change --ignore-all-space --ignore-eol-style" -r24638:25148 https://svn.osgeo.org/geotools/trunk/modules/library/referencing/src/main/java/org/geotools/referencing/CRS.java
Revision 24638Revision 25148
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.spatialschema.geometry.Envelope;
import org.opengis.spatialschema.geometry.MismatchedDimensionException;

// Geotools dependencies
import org.geotools.factory.Hints;
import org.geotools.factory.Factory;
import org.geotools.factory.FactoryNotFoundException;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;

// Geotools dependencies
import org.geotools.factory.GeoTools;
import org.geotools.factory.Hints;
import org.geotools.factory.Factory;
import org.geotools.factory.FactoryNotFoundException;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.metadata.iso.extent.GeographicBoundingBoxImpl;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.resources.geometry.XRectangle2D;
import org.geotools.resources.CRSUtilities;
import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.ErrorKeys;
import org.geotools.resources.Utilities;
import org.geotools.util.Version;
import org.geotools.util.Logging;
import org.geotools.util.UnsupportedImplementationException;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.metadata.iso.extent.GeographicBoundingBoxImpl;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.factory.epsg.LongitudeFirstFactory;
import org.geotools.resources.geometry.XRectangle2D;
import org.geotools.resources.CRSUtilities;
import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.ErrorKeys;
import org.geotools.util.Version;
import org.geotools.util.Logging;
import org.geotools.util.UnsupportedImplementationException;
* coordinate reference system} and associated {@linkplain org.opengis.referencing.Factory}
* implementations. This utility class is made up of static final functions. This class is
* not a factory or a builder. It makes use of the GeoAPI factory interfaces provided by
* {@link FactoryFinder}.
* <p>
* The following methods may be added in a future version:
* <ul>
* coordinate reference system} and associated {@linkplain org.opengis.referencing.Factory}
* implementations. This utility class is made up of static final functions. This class is
* not a factory or a builder. It makes use of the GeoAPI factory interfaces provided by
* {@link ReferencingFactoryFinder}.
* <p>
* The following methods may be added in a future version:
* <ul>
 * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
 */
public final class CRS {
    /**
     * A set of hints used in order to fetch lenient coordinate operation factory.
     */
    private static final Hints LENIENT = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);

    /**
     * A factory for CRS creation with (<var>latitude</var>, <var>longitude</var>) axis order
     * (unless otherwise specified in system property). Will be created only when first needed.
     */
 * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
 */
public final class CRS {
    /** Set to true to use GeoTools.getDefaultHints() */
    public static final boolean USE_DEFAULTS = false;
    /**
     * A factory for CRS creation with (<var>latitude</var>, <var>longitude</var>) axis order
     * (unless otherwise specified in system property). Will be created only when first needed.
     */
* {@linkplain org.geotools.referencing.factory.BufferedAuthorityFactory buffered}, scans over
* {@linkplain org.geotools.referencing.factory.AllAuthoritiesFactory all factories} and uses
* additional factories as {@linkplain org.geotools.referencing.factory.FallbackAuthorityFactory
* fallbacks} if there is more than one {@linkplain FactoryFinder#getCRSAuthorityFactories
* registered factory} for the same authority.
* <p>
* This factory can be used as a kind of <cite>system-wide</cite> factory for all authorities.
* However for more determinist behavior, consider using a more specific factory (as returned
* by {@link FactoryFinder#getCRSAuthorityFactory} when the authority in known.
*
* @param  longitudeFirst {@code true} if axis order should be forced to
*         (<var>longitude</var>,<var>latitude</var>).
* {@linkplain org.geotools.referencing.factory.BufferedAuthorityFactory buffered}, scans over
* {@linkplain org.geotools.referencing.factory.AllAuthoritiesFactory all factories} and uses
* additional factories as {@linkplain org.geotools.referencing.factory.FallbackAuthorityFactory
* fallbacks} if there is more than one {@linkplain ReferencingFactoryFinder#getCRSAuthorityFactories
* registered factory} for the same authority.
* <p>
* This factory can be used as a kind of <cite>system-wide</cite> factory for all authorities.
* However for more determinist behavior, consider using a more specific factory (as returned
* by {@link ReferencingFactoryFinder#getCRSAuthorityFactory} when the authority in known.
*
* @param  longitudeFirst {@code true} if axis order should be forced to
*         (<var>longitude</var>,<var>latitude</var>).
public static synchronized CRSAuthorityFactory getAuthorityFactory(final boolean longitudeFirst)
        throws FactoryRegistryException
{
    if (FactoryFinder.updated) {
        FactoryFinder.updated = false;
        defaultFactory = xyFactory = null;
    }
    CRSAuthorityFactory factory = (longitudeFirst) ? xyFactory : defaultFactory;
    if (factory == null) try {
        factory = new DefaultAuthorityFactory(longitudeFirst);
        if (longitudeFirst) {
            xyFactory = factory;
        } else {
            defaultFactory = factory;
public static synchronized CRSAuthorityFactory getAuthorityFactory(final boolean longitudeFirst)
        throws FactoryRegistryException
{
    if (ReferencingFactoryFinder.updated) {
        ReferencingFactoryFinder.updated = false;
        defaultFactory = xyFactory = null;
    }
    CRSAuthorityFactory factory = (longitudeFirst) ? xyFactory : defaultFactory;
    if (factory == null) try {
        Hints hints = USE_DEFAULTS ? GeoTools.getDefaultHints() : new Hints( null );
        if (longitudeFirst) {
            hints.put( Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
        }
        else {
            hints.put( Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.FALSE);
        }
        factory = new DefaultAuthorityFactory( hints );
        if (longitudeFirst) {
            xyFactory = factory;
        } else {
            defaultFactory = factory;
 * @since 2.4
 */
public static Version getVersion(final String authority) throws FactoryRegistryException {
    Object factory = FactoryFinder.getCRSAuthorityFactory(authority, null);
    final Set guard = new HashSet(); // Safety against never-ending recursivity.
    while (factory instanceof Factory && guard.add(factory)) {
        final Map hints = ((Factory) factory).getImplementationHints();
 * @since 2.4
 */
public static Version getVersion(final String authority) throws FactoryRegistryException {
    Object factory = ReferencingFactoryFinder.getCRSAuthorityFactory(authority, USE_DEFAULTS ? GeoTools.getDefaultHints() : null );
    final Set guard = new HashSet(); // Safety against never-ending recursivity.
    while (factory instanceof Factory && guard.add(factory)) {
        final Map hints = ((Factory) factory).getImplementationHints();
*
* <blockquote><code>
* {@linkplain CRSAuthorityFactory} factory = FactoryFinder.{@linkplain
* FactoryFinder#getCRSAuthorityFactory getCRSAuthorityFactory}(authority, null);<br>
* Set&lt;String&gt; codes = factory.{@linkplain CRSAuthorityFactory#getAuthorityCodes
* getAuthorityCodes}(CoordinateReferenceSystem.class);<br>
* String code = <cite>...choose a code here...</cite><br>
*
* <blockquote><code>
* {@linkplain CRSAuthorityFactory} factory = FactoryFinder.{@linkplain
* ReferencingFactoryFinder#getCRSAuthorityFactory getCRSAuthorityFactory}(authority, null);<br>
* Set&lt;String&gt; codes = factory.{@linkplain CRSAuthorityFactory#getAuthorityCodes
* getAuthorityCodes}(CoordinateReferenceSystem.class);<br>
* String code = <cite>...choose a code here...</cite><br>
public static CoordinateReferenceSystem decode(final String code)
        throws NoSuchAuthorityCodeException, FactoryException
{
    return decode(code, false);
}

/**
public static CoordinateReferenceSystem decode(final String code)
        throws NoSuchAuthorityCodeException, FactoryException
{
    return decode(code, Boolean.getBoolean(LongitudeFirstFactory.SYSTEM_DEFAULT_KEY));
}

/**
 * shorthand for the following:
 *
 * <blockquote><code>
 * FactoryFinder.{@linkplain FactoryFinder#getCRSFactory getCRSFactory}(null).{@linkplain
 * org.opengis.referencing.crs.CRSFactory#createFromWKT createFromWKT}(wkt);
 * </code></blockquote>
 */
public static CoordinateReferenceSystem parseWKT(final String wkt) throws FactoryException {
    return FactoryFinder.getCRSFactory(null).createFromWKT(wkt);
}

/**
 * shorthand for the following:
 *
 * <blockquote><code>
 * FactoryFinder.{@linkplain ReferencingFactoryFinder#getCRSFactory getCRSFactory}(null).{@linkplain
 * org.opengis.referencing.crs.CRSFactory#createFromWKT createFromWKT}(wkt);
 * </code></blockquote>
 */
public static CoordinateReferenceSystem parseWKT(final String wkt) throws FactoryException {
    return ReferencingFactoryFinder.getCRSFactory(null).createFromWKT(wkt);
}

/**
final GeneralEnvelope candidate;
if (geo instanceof GeographicBoundingBox) {
    final GeographicBoundingBox bounds = (GeographicBoundingBox) geo;
    if (!bounds.getInclusion()) {
        // TODO: we could uses Envelope.substract if such
        //       a method is defined in a future version.
        continue;
final GeneralEnvelope candidate;
if (geo instanceof GeographicBoundingBox) {
    final GeographicBoundingBox bounds = (GeographicBoundingBox) geo;
    if (!bounds.getInclusion().booleanValue()) {
        // TODO: we could uses Envelope.substract if such
        //       a method is defined in a future version.
        continue;
try {
    final CoordinateReferenceSystem candidate;
    if(code.indexOf(":") == -1)
        candidate = CRS.decode(authority + ":" + code, true);
    else
        candidate = CRS.decode(code, true);
    if (CRS.equalsIgnoreMetadata(candidate, crs)) {
        return getSRSFromCRS(candidate, Collections.singleton(authority));
    }
try {
    final CoordinateReferenceSystem candidate;
    if(code.indexOf(":") == -1)
        candidate = CRS.decode(authority + ":" + code);
    else
        candidate = CRS.decode(code);
    if (CRS.equalsIgnoreMetadata(candidate, crs)) {
        return getSRSFromCRS(candidate, Collections.singleton(authority));
    }
* Grab a transform between two Coordinate Reference Systems. This convenience method is a
* shorthand for the following:
*
* <blockquote><code>FactoryFinder.{@linkplain FactoryFinder#getCoordinateOperationFactory
* getCoordinateOperationFactory}(null).{@linkplain CoordinateOperationFactory#createOperation
* createOperation}(sourceCRS, targetCRS).{@linkplain CoordinateOperation#getMathTransform
* getMathTransform}();</code></blockquote>
* Grab a transform between two Coordinate Reference Systems. This convenience method is a
* shorthand for the following:
*
* <blockquote><code>FactoryFinder.{@linkplain ReferencingFactoryFinder#getCoordinateOperationFactory
* getCoordinateOperationFactory}(null).{@linkplain CoordinateOperationFactory#createOperation
* createOperation}(sourceCRS, targetCRS).{@linkplain CoordinateOperation#getMathTransform
* getMathTransform}();</code></blockquote>
                                              boolean lenient)
        throws FactoryException
{
    final CoordinateOperationFactory factory =
            FactoryFinder.getCoordinateOperationFactory(lenient ? LENIENT : null);
    return factory.createOperation(sourceCRS, targetCRS).getMathTransform();
}
                                              boolean lenient)
        throws FactoryException
{
    Hints hints = USE_DEFAULTS ? GeoTools.getDefaultHints() : new Hints( null );
    if( lenient = true ){
        if( hints == null ) {
            hints = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
        }
        else {
            hints.put(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
        }
    }
    final CoordinateOperationFactory factory = ReferencingFactoryFinder.getCoordinateOperationFactory( hints );
    return factory.createOperation(sourceCRS, targetCRS).getMathTransform();
}