Search in sources :

Example 1 with IdentifiedObjectFinder

use of org.apache.sis.referencing.factory.IdentifiedObjectFinder in project sis by apache.

the class EPSGFactoryTest method testFindGeographic.

/**
 * Tests {@link EPSGFactory#newIdentifiedObjectFinder()} method with a geographic CRS.
 *
 * @throws FactoryException if an error occurred while querying the factory.
 */
@Test
@DependsOnMethod("testWGS84")
public void testFindGeographic() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder();
    final DefaultGeographicCRS crs = (DefaultGeographicCRS) CRS.fromWKT("GEOGCS[“WGS 84”,\n" + // Use the alias instead than primary name for forcing a deeper search.
    "  DATUM[“WGS 84”,\n" + // Different name for forcing a deeper search.
    "    SPHEROID[“WGS 1984”, 6378137.0, 298.257223563]],\n" + "  PRIMEM[“Greenwich”, 0.0],\n" + "  UNIT[“degree”, 0.017453292519943295],\n" + "  AXIS[“Geodetic latitude”, NORTH],\n" + "  AXIS[“Geodetic longitude”, EAST]]");
    /*
         * First, search for a CRS with axis order that does not match the ones in the EPSG database.
         * IdentifiedObjectFinder should not accept EPSG:4326 as a match for the given CRS.
         */
    assertEquals("Full scan should be enabled by default.", IdentifiedObjectFinder.Domain.VALID_DATASET, finder.getSearchDomain());
    assertTrue("Should not find WGS84 because the axis order is not the same.", finder.find(crs.forConvention(AxesConvention.NORMALIZED)).isEmpty());
    /*
         * Ensure that the cache is empty.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.DECLARATION);
    assertTrue("Should not find without a full scan, because the WKT contains no identifier " + "and the CRS name is ambiguous (more than one EPSG object have this name).", finder.find(crs).isEmpty());
    /*
         * Scan the database for searching the CRS.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
    final IdentifiedObject found = finder.findSingleton(crs);
    assertNotNull("With full scan allowed, the CRS should be found.", found);
    assertEpsgNameAndIdentifierEqual("WGS 84", 4326, found);
    /*
         * Should find the CRS without the need of a full scan, because of the cache.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.DECLARATION);
    assertSame("The CRS should still in the cache.", found, finder.findSingleton(crs));
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) IdentifiedObject(org.opengis.referencing.IdentifiedObject) DefaultGeographicCRS(org.apache.sis.referencing.crs.DefaultGeographicCRS) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 2 with IdentifiedObjectFinder

use of org.apache.sis.referencing.factory.IdentifiedObjectFinder in project sis by apache.

the class AuthorityFactoriesTest method testFind.

/**
 * Tests the {@code IdentifiedObjectFinder.find(…)} method.
 *
 * @throws FactoryException if the operation failed creation failed.
 */
@Test
public void testFind() throws FactoryException {
    final CRSAuthorityFactory factory = AuthorityFactories.ALL;
    final IdentifiedObjectFinder finder = AuthorityFactories.ALL.newIdentifiedObjectFinder();
    final IdentifiedObject find = finder.findSingleton(HardCodedCRS.WGS84);
    assertNotNull("With scan allowed, should find the CRS.", find);
    assertTrue(HardCodedCRS.WGS84.equals(find, ComparisonMode.DEBUG));
    assertSame(factory.createCoordinateReferenceSystem("CRS:84"), find);
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) CRSAuthorityFactory(org.opengis.referencing.crs.CRSAuthorityFactory) IdentifiedObject(org.opengis.referencing.IdentifiedObject) Test(org.junit.Test)

Example 3 with IdentifiedObjectFinder

use of org.apache.sis.referencing.factory.IdentifiedObjectFinder in project sis by apache.

the class IdentifiedObjects method lookupURN.

/**
 * Looks up a URN, such as {@code "urn:ogc:def:crs:EPSG:9.1:4326"}, of the specified object.
 * This method searches in all {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory geodetic
 * authority factories} known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE
 * approximatively equals} to the specified object. Then there is a choice:
 *
 * <ul>
 *   <li>If a single matching object is found in the specified authority factory, then its URN is returned.</li>
 *   <li>Otherwise if the given object is a {@link CompoundCRS} or {@link ConcatenatedOperation}
 *       and all components have an URN, then this method returns a combined URN.</li>
 *   <li>Otherwise this method returns {@code null}.</li>
 * </ul>
 *
 * <p><strong>Note that this method checks the identifier validity.</strong>
 * If the given object declares explicitly an identifier, then this method will instantiate an object from the
 * authority factory using that identifier and compare it with the given object. If the comparison fails, then
 * this method returns {@code null}. Consequently this method may return {@code null} even if the given object
 * declares explicitly its identifier. If the declared identifier is wanted unconditionally,
 * one can use the following pattern instead:
 *
 * {@preformat java
 *     String urn = toURN(object.getClass(), getIdentifier(object, authority));
 * }
 *
 * This method can be seen as a converse of {@link CRS#forCode(String)}.
 *
 * @param  object  the object (usually a {@linkplain org.apache.sis.referencing.crs.AbstractCRS
 *         coordinate reference system}) whose identifier is to be found, or {@code null}.
 * @param  authority  the authority for the identifier to return, or {@code null} for
 *         the first identifier regardless its authority.
 * @return the identifier, or {@code null} if none was found without ambiguity or if the given object was null.
 * @throws FactoryException if an error occurred during the search.
 *
 * @see #newFinder(String)
 * @see #toURN(Class, Identifier)
 *
 * @since 0.7
 */
public static String lookupURN(final IdentifiedObject object, final Citation authority) throws FactoryException {
    if (object == null) {
        return null;
    }
    IdentifiedObjectFinder finder;
    try {
        finder = newFinder(Citations.getCodeSpace(authority));
    } catch (NoSuchAuthorityFactoryException e) {
        warning("lookupURN", e);
        finder = newFinder(null);
    }
    String urn = lookupURN(object, authority, finder);
    if (urn != null) {
        return urn;
    }
    /*
         * If we didn't found a URN but the given object is made of smaller components, build a combined URN.
         * Example: "urn:ogc:def:crs, crs:EPSG::27700, crs:EPSG::5701" (without spaces actually).
         */
    final List<? extends IdentifiedObject> components;
    if (object instanceof CompoundCRS) {
        components = CRS.getSingleComponents((CompoundCRS) object);
    } else if (object instanceof ConcatenatedOperation) {
        components = ((ConcatenatedOperation) object).getOperations();
    } else {
        return null;
    }
    StringBuilder buffer = null;
    for (final IdentifiedObject component : components) {
        urn = lookupURN(component, authority, finder);
        if (urn == null) {
            return null;
        }
        assert urn.startsWith(DefinitionURI.PREFIX) : urn;
        if (buffer == null) {
            buffer = new StringBuilder(40).append(DefinitionURI.PREFIX).append(DefinitionURI.SEPARATOR).append(NameMeaning.toObjectType(object.getClass()));
        }
        buffer.append(DefinitionURI.COMPONENT_SEPARATOR).append(urn, DefinitionURI.PREFIX.length() + 1, urn.length());
    }
    return (buffer != null) ? buffer.toString() : null;
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) NoSuchAuthorityFactoryException(org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException) CompoundCRS(org.opengis.referencing.crs.CompoundCRS) ConcatenatedOperation(org.opengis.referencing.operation.ConcatenatedOperation) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 4 with IdentifiedObjectFinder

use of org.apache.sis.referencing.factory.IdentifiedObjectFinder 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 5 with IdentifiedObjectFinder

use of org.apache.sis.referencing.factory.IdentifiedObjectFinder 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

IdentifiedObjectFinder (org.apache.sis.referencing.factory.IdentifiedObjectFinder)5 IdentifiedObject (org.opengis.referencing.IdentifiedObject)5 Test (org.junit.Test)3 DependsOnMethod (org.apache.sis.test.DependsOnMethod)2 AbstractCRS (org.apache.sis.referencing.crs.AbstractCRS)1 DefaultGeographicCRS (org.apache.sis.referencing.crs.DefaultGeographicCRS)1 GeodeticAuthorityFactory (org.apache.sis.referencing.factory.GeodeticAuthorityFactory)1 NoSuchAuthorityFactoryException (org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException)1 Citation (org.opengis.metadata.citation.Citation)1 NoSuchAuthorityCodeException (org.opengis.referencing.NoSuchAuthorityCodeException)1 CRSAuthorityFactory (org.opengis.referencing.crs.CRSAuthorityFactory)1 CompoundCRS (org.opengis.referencing.crs.CompoundCRS)1 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)1 ConcatenatedOperation (org.opengis.referencing.operation.ConcatenatedOperation)1