use of org.apache.sis.referencing.factory.GeodeticAuthorityFactory in project sis by apache.
the class AuthorityFactories method fallback.
/**
* Returns the fallback to use if the authority factory is not available. Unless the problem may be temporary,
* this method replaces the {@link EPSGFactory} instance by {@link EPSGFactoryFallback} in order to prevent
* the same exception to be thrown and logged on every calls to {@link CRS#forCode(String)}.
*/
static GeodeticAuthorityFactory fallback(final UnavailableFactoryException e) throws UnavailableFactoryException {
final boolean isTransient = (e.getCause() instanceof SQLTransientException);
final AuthorityFactory unavailable = e.getUnavailableFactory();
GeodeticAuthorityFactory factory;
final boolean alreadyDone;
synchronized (EPSG) {
factory = EPSG[0];
alreadyDone = (factory == EPSGFactoryFallback.INSTANCE);
if (!alreadyDone) {
// May have been set in another thread (race condition).
if (unavailable != factory) {
// Exception did not come from a factory that we control.
throw e;
}
factory = EPSGFactoryFallback.INSTANCE;
if (!isTransient) {
ALL.reload();
EPSG[0] = factory;
}
}
}
if (!alreadyDone) {
log(e, true);
}
return factory;
}
use of org.apache.sis.referencing.factory.GeodeticAuthorityFactory in project sis by apache.
the class AuthorityFactories method failure.
/**
* Notifies that a factory is unavailable, but without giving a fallback and without logging.
* The caller is responsible for throwing an exception, or for logging a warning and provide its own fallback.
*
* @return {@code false} if the caller can try again, or {@code true} if the failure can be considered final.
*/
static boolean failure(final UnavailableFactoryException e) {
if (!(e.getCause() instanceof SQLTransientException)) {
final AuthorityFactory unavailable = e.getUnavailableFactory();
synchronized (EPSG) {
final GeodeticAuthorityFactory factory = EPSG[0];
if (factory == EPSGFactoryFallback.INSTANCE) {
// May have been set in another thread.
return false;
}
if (unavailable == factory) {
ALL.reload();
EPSG[0] = EPSGFactoryFallback.INSTANCE;
return false;
}
}
}
return true;
}
use of org.apache.sis.referencing.factory.GeodeticAuthorityFactory 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;
}
use of org.apache.sis.referencing.factory.GeodeticAuthorityFactory in project sis by apache.
the class EPSGFactoryFallbackTest method compareAllCodes.
/**
* Compares all CRS created by {@link EPSGFactoryFallback} with CRS created by the real EPSG database.
*
* @throws FactoryException if a CRS can not be constructed.
*/
@Test
@DependsOnMethod({ "testGetAuthorityCodes", "testCreateCRS" })
public void compareAllCodes() throws FactoryException {
final GeodeticAuthorityFactory EPSG = AuthorityFactories.EPSG();
try {
setEPSGFactory(EPSGFactoryFallback.INSTANCE);
final ArrayList<String> codes = new ArrayList<>(EPSGFactoryFallback.INSTANCE.getAuthorityCodes(CoordinateReferenceSystem.class));
Collections.shuffle(codes, TestUtilities.createRandomNumberGenerator());
for (final String code : codes) {
final CoordinateReferenceSystem crs = EPSGFactoryFallback.INSTANCE.createCoordinateReferenceSystem(code);
final CoordinateReferenceSystem expected = EPSG.createCoordinateReferenceSystem(code);
assertTrue(code, Utilities.deepEquals(expected, crs, ComparisonMode.DEBUG));
}
} finally {
setEPSGFactory(EPSG);
}
}
Aggregations