Search in sources :

Example 1 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class CoordinateOperationRegistry method recreate.

/**
 * Creates a new coordinate operation with the same method than the given operation, but different CRS.
 * The CRS may differ either in the number of dimensions (i.e. let the vertical coordinate pass through),
 * or in axis order (i.e. axis order in user CRS were not compliant with authority definition).
 *
 * @param  operation  the operation specified by the authority.
 * @param  sourceCRS  the source CRS specified by the user.
 * @param  targetCRS  the target CRS specified by the user
 * @param  transform  the math transform to use in replacement to the one in {@code operation}.
 * @param  method     the operation method, or {@code null} for attempting an automatic detection.
 * @return a new operation from the given source CRS to target CRS using the given transform.
 * @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
 * @throws FactoryException if an error occurred while creating the new operation.
 */
private CoordinateOperation recreate(final CoordinateOperation operation, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, final MathTransform transform, OperationMethod method) throws IllegalArgumentException, FactoryException {
    /*
         * If the user-provided CRS are approximatively equal to the coordinate operation CRS, keep the later.
         * The reason is that coordinate operation CRS are built from the definitions provided by the authority,
         * while the user-provided CRS can be anything (e.g. parsed from a quite approximative WKT).
         */
    CoordinateReferenceSystem crs;
    if (Utilities.equalsApproximatively(sourceCRS, crs = operation.getSourceCRS()))
        sourceCRS = crs;
    if (Utilities.equalsApproximatively(targetCRS, crs = operation.getTargetCRS()))
        targetCRS = crs;
    final Map<String, Object> properties = new HashMap<>(derivedFrom(operation));
    /*
         * Determine whether the operation to create is a Conversion or a Transformation
         * (could also be a Conversion subtype like Projection, but this is less important).
         * We want the GeoAPI interface, not the implementation class.
         * The most reliable way is to ask to the 'AbstractOperation.getInterface()' method,
         * but this is SIS-specific. The fallback uses reflection.
         */
    final Class<? extends IdentifiedObject> type;
    if (operation instanceof AbstractIdentifiedObject) {
        type = ((AbstractIdentifiedObject) operation).getInterface();
    } else {
        type = Classes.getLeafInterfaces(operation.getClass(), CoordinateOperation.class)[0];
    }
    properties.put(ReferencingServices.OPERATION_TYPE_KEY, type);
    /*
         * Reuse the same operation method, but we may need to change its number of dimension.
         * The capability to resize an OperationMethod is specific to Apache SIS, so we must
         * be prepared to see the 'redimension' call fails. In such case, we will try to get
         * the SIS implementation of the operation method and try again.
         */
    if (SubTypes.isSingleOperation(operation)) {
        final SingleOperation single = (SingleOperation) operation;
        properties.put(ReferencingServices.PARAMETERS_KEY, single.getParameterValues());
        if (method == null) {
            final int sourceDimensions = transform.getSourceDimensions();
            final int targetDimensions = transform.getTargetDimensions();
            method = single.getMethod();
            try {
                method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
            } catch (IllegalArgumentException ex) {
                try {
                    method = factorySIS.getOperationMethod(method.getName().getCode());
                    method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
                } catch (NoSuchIdentifierException | IllegalArgumentException se) {
                    ex.addSuppressed(se);
                    throw ex;
                }
            }
        }
    }
    return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS, AbstractCoordinateOperation.getInterpolationCRS(operation), method, transform);
}
Also used : AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) HashMap(java.util.HashMap) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 2 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class IdentifiedObjectFinder method createFromNames.

/**
 * Creates an object equals (optionally ignoring metadata), to the specified object using only the
 * {@linkplain AbstractIdentifiedObject#getName name} and {@linkplain AbstractIdentifiedObject#getAlias aliases}.
 * If no such object is found, returns {@code null}.
 *
 * <p>This method may be used with some {@linkplain GeodeticAuthorityFactory authority factory}
 * implementations like the one backed by the EPSG database, which are capable to find an object
 * from its name when the identifier is unknown.</p>
 *
 * @param  object  the object looked up.
 * @return the identified object, or {@code null} if not found.
 * @throws FactoryException if an error occurred while creating an object.
 *
 * @see #createFromCodes(IdentifiedObject)
 * @see #createFromIdentifiers(IdentifiedObject)
 */
private IdentifiedObject createFromNames(final IdentifiedObject object) throws FactoryException {
    String code = object.getName().getCode();
    IdentifiedObject candidate;
    try {
        candidate = create(code);
    } catch (FactoryException e) {
        /*
             * The identifier was not recognized. We will continue later with aliases.
             * Note: we catch a more generic exception than NoSuchAuthorityCodeException because
             *       this attempt may fail for various reasons (character string not supported
             *       by the underlying database for primary key, duplicated name found, etc.).
             */
        exceptionOccurred(e);
        candidate = null;
    }
    if (match(candidate, object)) {
        return candidate;
    }
    for (final GenericName id : object.getAlias()) {
        code = id.toString();
        try {
            candidate = create(code);
        } catch (FactoryException e) {
            // The name was not recognized. No problem, let's go on.
            exceptionOccurred(e);
            continue;
        }
        if (match(candidate, object)) {
            return candidate;
        }
    }
    return null;
}
Also used : GenericName(org.opengis.util.GenericName) FactoryException(org.opengis.util.FactoryException) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject)

Example 3 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class ReferencingFunctions method getAxis.

/**
 * Returns the axis name and units for the specified dimension in a coordinate reference system or coordinate system.
 * This method returns a short axis name as used in Well Known Text (WKT) format, for example <cite>"Latitude"</cite>
 * instead of <cite>"Geodetic latitude"</cite>.
 *
 * @param  codeOrPath  the code allocated by an authority, or the path to a file.
 * @param  dimension   the dimension (1, 2, …).
 * @return the name of the requested axis.
 */
@Override
public String getAxis(final String codeOrPath, final int dimension) {
    final CacheKey<String> key = new CacheKey<>(String.class, codeOrPath, dimension, null);
    String name = key.peek();
    if (name == null) {
        final Cache.Handler<String> handler = key.lock();
        try {
            name = handler.peek();
            if (name == null) {
                final IdentifiedObject object;
                try {
                    object = getIdentifiedObject(codeOrPath, null);
                } catch (Exception exception) {
                    return getLocalizedMessage(exception);
                }
                CoordinateSystem cs = null;
                final CoordinateSystemAxis axis;
                if (object instanceof CoordinateSystemAxis) {
                    axis = (CoordinateSystemAxis) object;
                } else {
                    if (object instanceof CoordinateReferenceSystem) {
                        cs = ((CoordinateReferenceSystem) object).getCoordinateSystem();
                    } else if (object instanceof CoordinateSystem) {
                        cs = (CoordinateSystem) object;
                    } else {
                        final Class<?> actual;
                        if (object instanceof AbstractIdentifiedObject) {
                            actual = ((AbstractIdentifiedObject) object).getInterface();
                        } else {
                            actual = Classes.getClass(object);
                        }
                        return Errors.getResources(getJavaLocale()).getString(Errors.Keys.UnexpectedTypeForReference_3, codeOrPath, CoordinateReferenceSystem.class, actual);
                    }
                    if (dimension >= 1 && dimension <= cs.getDimension()) {
                        axis = cs.getAxis(dimension - 1);
                    } else {
                        return Errors.getResources(getJavaLocale()).getString(Errors.Keys.IndexOutOfBounds_1, dimension);
                    }
                }
                final String unit = axis.getUnit().toString();
                name = Transliterator.DEFAULT.toShortAxisName(cs, axis.getDirection(), axis.getName().getCode());
                if (unit != null && !unit.isEmpty()) {
                    name = name + " (" + unit + ')';
                }
            }
        } finally {
            handler.putAndUnlock(name);
        }
    }
    return name;
}
Also used : AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) InternationalString(org.opengis.util.InternationalString) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) DataStoreException(org.apache.sis.storage.DataStoreException) IllegalArgumentException(com.sun.star.lang.IllegalArgumentException) FactoryException(org.opengis.util.FactoryException) Cache(org.apache.sis.util.collection.Cache)

Example 4 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class CRSPair method label.

/**
 * Returns the name of the GeoAPI interface implemented by the specified object. In the GeographicCRS
 * or EllipsoidalCS cases, the trailing CRS or CS suffix is replaced by the number of dimensions
 * (e.g. "Geographic3D").
 */
static String label(final IdentifiedObject object) {
    if (object == null) {
        return null;
    }
    Class<? extends IdentifiedObject> type;
    if (object instanceof AbstractIdentifiedObject) {
        type = ((AbstractIdentifiedObject) object).getInterface();
    } else {
        type = Classes.getLeafInterfaces(object.getClass(), IdentifiedObject.class)[0];
    }
    String suffix, label = Classes.getShortName(type);
    if (label.endsWith((suffix = "CRS")) || label.endsWith(suffix = "CS")) {
        Object cs = object;
        if (object instanceof CoordinateReferenceSystem) {
            cs = ((CoordinateReferenceSystem) object).getCoordinateSystem();
        }
        if (cs instanceof EllipsoidalCS) {
            final StringBuilder sb = new StringBuilder(label);
            sb.setLength(label.length() - suffix.length());
            label = sb.append(((CoordinateSystem) cs).getDimension()).append('D').toString();
        }
    }
    String name = IdentifiedObjects.getName(object, null);
    if (name != null) {
        // Arbitrary length threshold.
        int i = 30;
        if (name.length() >= i) {
            while (i > 15) {
                // Arbitrary minimal length.
                final int c = name.codePointBefore(i);
                if (Character.isSpaceChar(c))
                    break;
                i -= Character.charCount(c);
            }
            name = CharSequences.trimWhitespaces(name, 0, i).toString() + '…';
        }
        label = label + "[“" + name + "”]";
    }
    return label;
}
Also used : AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 5 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class GeodeticAuthorityFactory method cast.

/**
 * Casts the given object to the given type, or throws an exception if the object can not be casted.
 * This convenience method is provided for implementation of {@code createXXX} methods.
 *
 * @param  type    the type to return (e.g. {@code CoordinateReferenceSystem.class}).
 * @param  object  the object to cast.
 * @param  code    the authority code, used only for formatting an error message.
 * @return the object casted to the given type.
 * @throws NoSuchAuthorityCodeException if the given object is not an instance of the given type.
 */
@SuppressWarnings("unchecked")
private <T> T cast(final Class<T> type, final IdentifiedObject object, final String code) throws NoSuchAuthorityCodeException {
    if (type.isInstance(object)) {
        return (T) object;
    }
    /*
         * Get the actual type of the object. Returns the GeoAPI type if possible,
         * or fallback on the implementation class otherwise.
         */
    final Class<?> actual;
    if (object instanceof AbstractIdentifiedObject) {
        actual = ((AbstractIdentifiedObject) object).getInterface();
    } else {
        actual = object.getClass();
    }
    /*
         * Get the authority from the object if possible, in order to avoid a call
         * to the potentially costly (for EPSGDataAccess) getAuthority() method.
         */
    final Identifier id = object.getName();
    final Citation authority = (id != null) ? id.getAuthority() : getAuthority();
    throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnexpectedTypeForReference_3, code, type, actual), Citations.getIdentifier(authority, false), trimNamespace(code), code);
}
Also used : AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) Identifier(org.opengis.metadata.Identifier) Citation(org.opengis.metadata.citation.Citation)

Aggregations

AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)7 IdentifiedObject (org.opengis.referencing.IdentifiedObject)6 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)3 HashMap (java.util.HashMap)2 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)2 FactoryException (org.opengis.util.FactoryException)2 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)1 InvalidGeodeticParameterException (org.apache.sis.referencing.factory.InvalidGeodeticParameterException)1 DataStoreException (org.apache.sis.storage.DataStoreException)1 Cache (org.apache.sis.util.collection.Cache)1 Identifier (org.opengis.metadata.Identifier)1 Citation (org.opengis.metadata.citation.Citation)1 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)1 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)1 GenericName (org.opengis.util.GenericName)1 InternationalString (org.opengis.util.InternationalString)1