Search in sources :

Example 26 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class IdentifiedObjectFinder method find.

/**
 * Lookups objects which are approximatively equal to the specified object.
 * The default implementation tries to instantiate some {@linkplain AbstractIdentifiedObject identified objects}
 * from the authority factory specified at construction time, in the following order:
 *
 * <ul>
 *   <li>If the specified object contains {@linkplain AbstractIdentifiedObject#getIdentifiers() identifiers}
 *       associated to the same authority than the factory, then those identifiers are used for
 *       {@linkplain GeodeticAuthorityFactory#createObject(String) creating objects} to be tested.</li>
 *   <li>If the authority factory can create objects from their {@linkplain AbstractIdentifiedObject#getName() name}
 *       in addition of identifiers, then the name and {@linkplain AbstractIdentifiedObject#getAlias() aliases} are
 *       used for creating objects to be tested.</li>
 *   <li>If a full scan of the dataset is allowed, then full {@linkplain #getCodeCandidates set of candidate codes}
 *       is used for creating objects to be tested.</li>
 * </ul>
 *
 * The created objects which are equal to the specified object in the
 * the sense of {@link ComparisonMode#APPROXIMATIVE} are returned.
 *
 * @param  object  the object looked up.
 * @return the identified objects, or an empty set if not found.
 * @throws FactoryException if an error occurred while creating an object.
 */
public Set<IdentifiedObject> find(final IdentifiedObject object) throws FactoryException {
    ArgumentChecks.ensureNonNull("object", object);
    Set<IdentifiedObject> result = getFromCache(object);
    if (result == null) {
        final AuthorityFactoryProxy<?> previous = proxy;
        proxy = AuthorityFactoryProxy.getInstance(object.getClass());
        try {
            if (!ignoreIdentifiers && !ignoreAxes) {
                /*
                     * First check if one of the identifiers can be used to find directly an identified object.
                     * Verify that the object that we found is actually equal to given one; we do not blindly
                     * trust the identifiers in the user object.
                     */
                IdentifiedObject candidate = createFromIdentifiers(object);
                if (candidate != null) {
                    // Not worth to cache.
                    return Collections.singleton(candidate);
                }
                /*
                     * We are unable to find the object from its identifiers. Try a quick name lookup.
                     * Some implementations like the one backed by the EPSG database are capable to find
                     * an object from its name.
                     */
                candidate = createFromNames(object);
                if (candidate != null) {
                    // Not worth to cache.
                    return Collections.singleton(candidate);
                }
            }
            /*
                 * Here we exhausted the quick paths.
                 * Perform a full scan (costly) if we are allowed to, otherwise abandon.
                 */
            if (domain == Domain.DECLARATION) {
                // Do NOT cache.
                return Collections.emptySet();
            }
            result = createFromCodes(object);
        } finally {
            proxy = previous;
        }
        // Costly operation (even if the result is empty) worth to cache.
        result = cache(object, result);
    }
    return result;
}
Also used : IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject)

Example 27 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class DefaultOperationMethod method getProperties.

/**
 * Returns the properties to be given to an identified object derived from the specified one.
 * This method returns the same properties than the supplied argument
 * (as of <code>{@linkplain IdentifiedObjects#getProperties getProperties}(info)</code>),
 * except for the following:
 *
 * <ul>
 *   <li>The {@linkplain IdentifiedObject#getName() name}'s authority is replaced by the specified one.</li>
 *   <li>All {@linkplain IdentifiedObject#getIdentifiers identifiers} are removed, because the new object
 *       to be created is probably not endorsed by the original authority.</li>
 * </ul>
 *
 * This method returns a mutable map. Consequently, callers can add their own identifiers
 * directly to this map if they wish.
 *
 * @param  info       the identified object to view as a properties map.
 * @param  authority  the new authority for the object to be created,
 *                    or {@code null} if it is not going to have any declared authority.
 * @return the identified object properties in a mutable map.
 */
private static Map<String, Object> getProperties(final IdentifiedObject info, final Citation authority) {
    final Map<String, Object> properties = new HashMap<>(IdentifiedObjects.getProperties(info));
    properties.put(NAME_KEY, new NamedIdentifier(authority, info.getName().getCode()));
    properties.remove(IDENTIFIERS_KEY);
    return properties;
}
Also used : HashMap(java.util.HashMap) NamedIdentifier(org.apache.sis.referencing.NamedIdentifier) NilReferencingObject(org.apache.sis.internal.referencing.NilReferencingObject) FormattableObject(org.apache.sis.io.wkt.FormattableObject) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString)

Example 28 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class ReferencingUtilities method getPropertiesForModifiedCRS.

/**
 * Returns the properties of the given object but potentially with a modified name.
 * Current implement truncates the name at the first non-white character which is not
 * a valid Unicode identifier part, with the following exception:
 *
 * <ul>
 *   <li>If the character is {@code '('} and the content until the closing {@code ')'} is a valid
 *       Unicode identifier, then that part is included. The intent is to keep the prime meridian
 *       name in names like <cite>"NTF (Paris)"</cite>.</li>
 * </ul>
 *
 * <div class="note"><b>Example:</b><ul>
 *   <li><cite>"NTF (Paris)"</cite> is left unchanged.</li>
 *   <li><cite>"WGS 84 (3D)"</cite> is truncated as <cite>"WGS 84"</cite>.</li>
 *   <li><cite>"Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: degree"</cite>
 *       is truncated as <cite>"Ellipsoidal 2D CS"</cite>.</li>
 * </ul></div>
 *
 * @param  object    the identified object to view as a properties map.
 * @return a view of the identified object properties.
 *
 * @see IdentifiedObjects#getProperties(IdentifiedObject, String...)
 *
 * @since 0.7
 */
public static Map<String, ?> getPropertiesForModifiedCRS(final IdentifiedObject object) {
    final Map<String, ?> properties = IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY);
    final Identifier id = (Identifier) properties.get(IdentifiedObject.NAME_KEY);
    if (id != null) {
        String name = id.getCode();
        if (name != null) {
            for (int i = 0; i < name.length(); ) {
                final int c = name.codePointAt(i);
                if (!Character.isUnicodeIdentifierPart(c) && !Character.isSpaceChar(c)) {
                    if (c == '(') {
                        final int endAt = name.indexOf(')', i);
                        if (endAt >= 0) {
                            final String extra = name.substring(i + 1, endAt);
                            if (CharSequences.isUnicodeIdentifier(extra)) {
                                i += extra.length() + 2;
                            }
                        }
                    }
                    name = CharSequences.trimWhitespaces(name, 0, i).toString();
                    if (!name.isEmpty()) {
                        final Map<String, Object> copy = new HashMap<>(properties);
                        copy.put(IdentifiedObject.NAME_KEY, name);
                        return copy;
                    }
                }
                i += Character.charCount(c);
            }
        }
    }
    return properties;
}
Also used : Identifier(org.opengis.metadata.Identifier) HashMap(java.util.HashMap) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 29 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class DefinitionVerifier method withAuthority.

/**
 * Compares the given CRS description with the authoritative description.
 * The authoritative description is inferred from the identifier, if any.
 *
 * @param  crs      the CRS to compare with the authoritative description.
 * @param  factory  the factory to use for fetching authoritative description, or {@code null} for the default.
 * @param  lookup   whether this method is allowed to use {@link IdentifiedObjectFinder}.
 * @return verification result, or {@code null} if the given CRS should be used as-is.
 * @throws FactoryException if an error occurred while querying the authority factory.
 */
public static DefinitionVerifier withAuthority(final CoordinateReferenceSystem crs, final CRSAuthorityFactory factory, final boolean lookup) throws FactoryException {
    final CoordinateReferenceSystem authoritative;
    final Citation authority = (factory != null) ? factory.getAuthority() : null;
    final String identifier = IdentifiedObjects.toString(IdentifiedObjects.getIdentifier(crs, authority));
    if (identifier != null)
        try {
            /*
             * An authority code was explicitly given in the CRS description. Create a CRS for that code
             * (do not try to guess it). If the given code is unknown, we will report a warning and use
             * the given CRS as-is.
             */
            if (factory != null) {
                authoritative = factory.createCoordinateReferenceSystem(identifier);
            } else {
                authoritative = CRS.forCode(identifier);
            }
        } catch (NoSuchAuthorityCodeException e) {
            final DefinitionVerifier verifier = new DefinitionVerifier(crs);
            verifier.arguments = new String[] { e.getLocalizedMessage() };
            return verifier;
        }
    else if (lookup) {
        /*
             * No authority code was given in the CRS description. Try to guess the code with IdentifiedObjectFinder,
             * ignoring axis order. If we can not guess a code or if we guess wrongly, use the given CRS silently
             * (without reporting any warning) since there is apparently nothing wrong in the given CRS.
             */
        final IdentifiedObjectFinder finder;
        if (factory instanceof GeodeticAuthorityFactory) {
            finder = ((GeodeticAuthorityFactory) factory).newIdentifiedObjectFinder();
        } else {
            finder = IdentifiedObjects.newFinder(Citations.getIdentifier(authority, false));
        }
        finder.setIgnoringAxes(true);
        final IdentifiedObject ref = finder.findSingleton(crs);
        if (ref instanceof CoordinateReferenceSystem) {
            authoritative = (CoordinateReferenceSystem) ref;
        } else {
            // Found no identifier. Use the CRS as-is.
            return null;
        }
    } else {
        return null;
    }
    /*
         * At this point we found an authoritative description (typically from EPSG database) for the given CRS.
         * Verify if the given CRS is equal to the authoritative description, or a variant of it. The similarity
         * variable tells us if we have equality (0), mismatch (-), or equality when using a variant (+).
         */
    int similarity = 0;
    final AbstractCRS ca = AbstractCRS.castOrCopy(authoritative);
    AbstractCRS variant = ca;
    while (!variant.equals(crs, ComparisonMode.APPROXIMATIVE)) {
        if (similarity < VARIANTS.length) {
            variant = ca.forConvention(VARIANTS[similarity++]);
        } else if (identifier == null) {
            // Mismatched CRS, but our "authoritative" description was only a guess. Ignore.
            return null;
        } else {
            // Mismatched CRS and our authoritative description was not a guess. Need warning.
            similarity = -1;
            break;
        }
    }
    final DefinitionVerifier verifier;
    if (similarity > 0) {
        /*
             * Warning message (from Resources.properties):
             *
             *     The coordinate system axes in the given “{0}” description do not conform to the expected axes
             *     according “{1}” authoritative description.
             */
        verifier = new DefinitionVerifier(variant);
        if (identifier != null) {
            verifier.resourceKey = Resources.Keys.NonConformAxes_2;
            verifier.arguments = new String[2];
        }
    } else {
        verifier = new DefinitionVerifier(authoritative);
        if (similarity != 0) {
            /*
                 * Warning message (from Resources.properties):
                 *
                 *     The given “{0}” description does not conform to the “{1}” authoritative description.
                 *     Differences are found in {2,choice,0#method|1#conversion|2#coordinate system|3#datum|4#CRS}.
                 */
            verifier.resourceKey = Resources.Keys.NonConformCRS_3;
            verifier.arguments = new Object[3];
            verifier.arguments[2] = diffCode(CRS.getSingleComponents(authoritative).iterator(), CRS.getSingleComponents(crs).iterator());
        }
    }
    if (verifier.arguments != null) {
        verifier.arguments[0] = IdentifiedObjects.getName(crs, null);
        verifier.arguments[1] = IdentifiedObjects.getIdentifierOrName(authoritative);
    }
    return verifier;
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) NoSuchAuthorityCodeException(org.opengis.referencing.NoSuchAuthorityCodeException) AbstractCRS(org.apache.sis.referencing.crs.AbstractCRS) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) Citation(org.opengis.metadata.citation.Citation) IdentifiedObject(org.opengis.referencing.IdentifiedObject) GeodeticAuthorityFactory(org.apache.sis.referencing.factory.GeodeticAuthorityFactory)

Example 30 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class EPSGFactoryTest method testFindProjected.

/**
 * Tests {@link EPSGFactory#newIdentifiedObjectFinder()} method with a projected CRS.
 *
 * @throws FactoryException if an error occurred while querying the factory.
 */
@Test
@DependsOnMethod("testFindGeographic")
public void testFindProjected() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder();
    /*
         * The PROJCS below intentionally uses a name different from the one found in the
         * EPSG database, in order to force a full scan (otherwise the EPSG database would
         * find it by name, but we want to test the scan).
         */
    final CoordinateReferenceSystem crs = CRS.fromWKT("PROJCS[“Beijing 1954 (modified)”,\n" + "   GEOGCS[“Beijing 1954 (modified)”,\n" + // Datum name matter.
    "     DATUM[“Beijing 1954”,\n" + // Intentional rounding error.
    "       SPHEROID[“Krassowsky 1940”, 6378245.00000006, 298.299999999998]],\n" + "     PRIMEM[“Greenwich”, 0.0],\n" + "     UNIT[“degree”, 0.017453292519943295],\n" + "     AXIS[“Geodetic longitude”, EAST],\n" + // Wrong axis order, but should not block.
    "     AXIS[“Geodetic latitude”, NORTH]],\n" + "   PROJECTION[“Transverse Mercator”],\n" + // Intentional rounding error.
    "   PARAMETER[“central_meridian”, 135.0000000000013],\n" + "   PARAMETER[“latitude_of_origin”, 0.0],\n" + "   PARAMETER[“scale_factor”, 1.0],\n" + // Intentional rounding error.
    "   PARAMETER[“false_easting”, 500000.000000004],\n" + "   PARAMETER[“false_northing”, 0.0],\n" + "   UNIT[“m”, 1.0],\n" + "   AXIS[“Northing”, NORTH],\n" + "   AXIS[“Easting”, EAST]]");
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.DECLARATION);
    assertTrue("Should not find the CRS without a full scan.", finder.find(crs).isEmpty());
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.VALID_DATASET);
    final Set<IdentifiedObject> find = finder.find(crs);
    assertFalse("With full scan allowed, the CRS should be found.", find.isEmpty());
    /*
         * Both EPSG:2442 and EPSG:21463 defines the same projection with the same parameters
         * and the same base GeographicCRS (EPSG:4214). The only difference I found was the
         * area of validity...
         *
         * Note that there is also a EPSG:21483 code, but that one is deprecated and should
         * not be selected in this test.
         */
    final Iterator<IdentifiedObject> it = find.iterator();
    assertEpsgNameAndIdentifierEqual("Beijing 1954 / 3-degree Gauss-Kruger CM 135E", 2442, it.next());
    assertEpsgNameAndIdentifierEqual("Beijing 1954 / Gauss-Kruger CM 135E", 21463, it.next());
    assertFalse("Expected no more element.", it.hasNext());
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) IdentifiedObject(org.opengis.referencing.IdentifiedObject) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Aggregations

IdentifiedObject (org.opengis.referencing.IdentifiedObject)30 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)15 InternationalString (org.opengis.util.InternationalString)10 FactoryException (org.opengis.util.FactoryException)8 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)5 IdentifiedObjectFinder (org.apache.sis.referencing.factory.IdentifiedObjectFinder)5 DataStoreException (org.apache.sis.storage.DataStoreException)5 Identifier (org.opengis.metadata.Identifier)5 ReferenceIdentifier (org.opengis.referencing.ReferenceIdentifier)5 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)5 HashMap (java.util.HashMap)4 Cache (org.apache.sis.util.collection.Cache)3 Test (org.junit.Test)3 GenericName (org.opengis.util.GenericName)3 NameToIdentifier (org.apache.sis.internal.metadata.NameToIdentifier)2 FormattableObject (org.apache.sis.io.wkt.FormattableObject)2 NamedIdentifier (org.apache.sis.referencing.NamedIdentifier)2 DependsOnMethod (org.apache.sis.test.DependsOnMethod)2 SimpleInternationalString (org.apache.sis.util.iso.SimpleInternationalString)2 Extent (org.opengis.metadata.extent.Extent)2