use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class AuthorityFactories method log.
/**
* Logs the given exception at the given level. This method pretends that the logging come from
* {@link CRS#getAuthorityFactory(String)}, which is the public facade for {@link #EPSG()}.
*/
private static void log(final Exception e, final boolean isWarning) {
// Prefer the locale of system administrator.
String message = e.getMessage();
if (message == null) {
message = e.toString();
}
final LogRecord record = new LogRecord(isWarning ? Level.WARNING : Level.CONFIG, message);
if (isWarning && !(e instanceof UnavailableFactoryException)) {
record.setThrown(e);
}
record.setLoggerName(Loggers.CRS_FACTORY);
Logging.log(CRS.class, "getAuthorityFactory", record);
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class CRS method findOperations.
/**
* Finds mathematical operations that transform or convert coordinates from the given source to the
* given target coordinate reference system. If at least one operation exists, they are returned in
* preference order: the operation having the widest intersection between its
* {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}
* and the given area of interest are returned first.
*
* @param sourceCRS the CRS of source coordinates.
* @param targetCRS the CRS of target coordinates.
* @param areaOfInterest the area of interest, or {@code null} if none.
* @return mathematical operations from {@code sourceCRS} to {@code targetCRS}.
* @throws OperationNotFoundException if no operation was found between the given pair of CRS.
* @throws FactoryException if the operation can not be created for another reason.
*
* @see DefaultCoordinateOperationFactory#createOperations(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
*
* @since 1.0
*/
public static List<CoordinateOperation> findOperations(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final GeographicBoundingBox areaOfInterest) throws FactoryException {
ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
final CoordinateOperationContext context = CoordinateOperationContext.fromBoundingBox(areaOfInterest);
final DefaultCoordinateOperationFactory factory = CoordinateOperations.factory();
try {
return factory.createOperations(sourceCRS, targetCRS, context);
} catch (UnavailableFactoryException e) {
if (AuthorityFactories.failure(e)) {
throw e;
} else
try {
return Collections.singletonList(factory.createOperation(sourceCRS, targetCRS, context));
} catch (FactoryException ex) {
ex.addSuppressed(e);
throw ex;
}
}
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class CRS method findOperation.
/**
* Finds a mathematical operation that transforms or converts coordinates from the given source to the
* given target coordinate reference system. If an estimation of the geographic area containing the points
* to transform is known, it can be specified for helping this method to find a better suited operation.
* If no area of interest is specified, then the current default is the widest
* {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}.
* A future Apache SIS version may also take the country of current locale in account.
*
* <div class="note"><b>Note:</b>
* the area of interest is just one aspect that may affect the coordinate operation.
* Other aspects are the time of interest (because some coordinate operations take in account the
* plate tectonics movement) or the desired accuracy. For more control on the coordinate operation
* to create, see {@link CoordinateOperationContext}.</div>
*
* After the caller received a {@code CoordinateOperation} instance, the following methods can be invoked
* for checking if the operation suits the caller's needs:
*
* <ul>
* <li>{@link #getGeographicBoundingBox(CoordinateOperation)}
* for checking if the operation is valid in the caller's area of interest.</li>
* <li>{@link #getLinearAccuracy(CoordinateOperation)}
* for checking if the operation has sufficient accuracy for caller's purpose.</li>
* </ul>
*
* If the source and target CRS are equivalent, then this method returns an operation backed by an
* {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#isIdentity() identity}
* transform. If there is no known operation between the given pair of CRS, then this method throws an
* {@link OperationNotFoundException}.
*
* @param sourceCRS the CRS of source coordinates.
* @param targetCRS the CRS of target coordinates.
* @param areaOfInterest the area of interest, or {@code null} if none.
* @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}.
* @throws OperationNotFoundException if no operation was found between the given pair of CRS.
* @throws FactoryException if the operation can not be created for another reason.
*
* @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
*
* @since 0.7
*/
public static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final GeographicBoundingBox areaOfInterest) throws FactoryException {
ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
final CoordinateOperationContext context = CoordinateOperationContext.fromBoundingBox(areaOfInterest);
/*
* In principle we should just delegate to factory.createOperation(…). However this operation may fail
* if a connection to the EPSG database has been found, but the EPSG tables do not yet exist in that
* database and
*/
final DefaultCoordinateOperationFactory factory = CoordinateOperations.factory();
try {
return factory.createOperation(sourceCRS, targetCRS, context);
} catch (UnavailableFactoryException e) {
if (AuthorityFactories.failure(e)) {
throw e;
} else
try {
// Above method call replaced the EPSG factory by a fallback. Try again.
return factory.createOperation(sourceCRS, targetCRS, context);
} catch (FactoryException ex) {
ex.addSuppressed(e);
throw ex;
}
}
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class ConsistencyTest method testCoordinateReferenceSystems.
/**
* Verifies the WKT consistency of all CRS instances.
*
* @throws FactoryException if an error other than "unsupported operation method" occurred.
*/
@Test
public void testCoordinateReferenceSystems() throws FactoryException {
assumeTrue(RUN_EXTENSIVE_TESTS);
final WKTFormat v1 = new WKTFormat(null, null);
final WKTFormat v1c = new WKTFormat(null, null);
final WKTFormat v2 = new WKTFormat(null, null);
final WKTFormat v2s = new WKTFormat(null, null);
v1.setConvention(Convention.WKT1);
v1c.setConvention(Convention.WKT1_COMMON_UNITS);
v2.setConvention(Convention.WKT2);
v2s.setConvention(Convention.WKT2_SIMPLIFIED);
for (final String code : CRS.getAuthorityFactory(null).getAuthorityCodes(CoordinateReferenceSystem.class)) {
if (!EXCLUDES.contains(code)) {
final CoordinateReferenceSystem crs;
try {
crs = CRS.forCode(code);
} catch (UnavailableFactoryException | NoSuchIdentifierException | FactoryDataException e) {
print(code, "WARNING", e.getLocalizedMessage());
continue;
}
lookup(parseAndFormat(v2, code, crs), crs);
lookup(parseAndFormat(v2s, code, crs), crs);
/*
* There is more information lost in WKT 1 than in WKT 2, so we can not test everything.
* For example we can not format fully three-dimensional geographic CRS because the unit
* is not the same for all axes. We can not format neither some axis directions.
*/
try {
parseAndFormat(v1, code, crs);
} catch (UnformattableObjectException e) {
print(code, "WARNING", e.getLocalizedMessage());
continue;
}
parseAndFormat(v1c, code, crs);
}
}
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class EPSGFactory method install.
/**
* Creates the EPSG schema in the database and populates the tables with geodetic definitions.
* This method is invoked automatically when {@link #newDataAccess()} detects that the EPSG dataset is not installed.
* Users can also invoke this method explicitely if they wish to force the dataset installation.
*
* <p>This method uses the following properties from the map specified at
* {@linkplain #EPSGFactory(Map) construction time}:</p>
*
* <ul class="verbose">
* <li><b>{@code catalog}:</b><br>
* a {@link String} giving the name of the database catalog where to create the EPSG schema.
* If non-null, that catalog shall exist prior this method call (this method does not create any catalog).
* If no catalog is specified or if the catalog is an empty string,
* then the EPSG schema will be created without catalog.
* If the database does not {@linkplain DatabaseMetaData#supportsCatalogsInTableDefinitions() support
* catalogs in table definitions} or in {@linkplain DatabaseMetaData#supportsCatalogsInDataManipulation()
* data manipulation}, then this property is ignored.</li>
*
* <li><b>{@code schema}:</b><br>
* a {@link String} giving the name of the database schema where to create the EPSG tables.
* That schema shall <strong>not</strong> exist prior this method call;
* the schema will be created by this {@code install(…)} method.
* If the schema is an empty string, then the tables will be created without schema.
* If no schema is specified, then the default schema is {@code "EPSG"}.
* If the database does not {@linkplain DatabaseMetaData#supportsSchemasInTableDefinitions() support
* schemas in table definitions} or in {@linkplain DatabaseMetaData#supportsSchemasInDataManipulation()
* data manipulation}, then this property is ignored.</li>
*
* <li><b>{@code scriptProvider}:</b><br>
* an {@link InstallationScriptProvider} giving the SQL scripts to execute for creating the EPSG database.
* If no provider is specified, then this method will search on the classpath (with {@link java.util.ServiceLoader})
* for user-provided implementations of {@code InstallationScriptProvider}.
* If no user-specified provider is found, then this method will search for
* {@code "EPSG_*Tables.sql"}, {@code "EPSG_*Data.sql"} and {@code "EPSG_*FKeys.sql"} files in the
* {@code $SIS_DATA/Databases/ExternalSources} directory where {@code *} stands for any characters
* provided that there is no ambiguity.</li>
* </ul>
*
* <p><b>Legal constraint:</b>
* the EPSG dataset can not be distributed with Apache SIS at this time for licensing reasons.
* Users need to either install the dataset manually (for example with the help of this method),
* or add on the classpath a non-Apache bundle like {@code geotk-epsg.jar}.
* See <a href="https://issues.apache.org/jira/browse/LEGAL-183">LEGAL-183</a> for more information.</p>
*
* @param connection connection to the database where to create the EPSG schema.
* @throws UnavailableFactoryException if installation failed. The exception will have a
* {@link FileNotFoundException} cause if a SQL script has not been found
* (typically because a required resource is not on the classpath), an
* {@link IOException} if an I/O error occurred while reading a SQL script, or a
* {@link SQLException} if an error occurred while writing to the database.
*
* @see InstallationScriptProvider
*/
public synchronized void install(final Connection connection) throws UnavailableFactoryException {
ArgumentChecks.ensureNonNull("connection", connection);
String message = null;
Exception failure = null;
try (EPSGInstaller installer = new EPSGInstaller(connection)) {
final boolean ac = connection.getAutoCommit();
if (ac) {
connection.setAutoCommit(false);
}
try {
boolean success = false;
try {
if (!"".equals(schema)) {
// Schema may be null.
installer.setSchema(schema != null ? schema : Constants.EPSG);
if (catalog != null && !catalog.isEmpty()) {
installer.prependNamespace(catalog);
}
}
installer.run(scriptProvider, locale);
success = true;
} finally {
if (ac) {
if (success) {
connection.commit();
} else {
connection.rollback();
}
connection.setAutoCommit(true);
}
}
} catch (IOException | SQLException e) {
message = installer.failure(locale, e);
failure = e;
}
} catch (SQLException e) {
message = Messages.getResources(locale).getString(Messages.Keys.CanNotCreateSchema_1, Constants.EPSG);
failure = e;
}
if (failure != null) {
/*
* Derby sometime wraps SQLException into another SQLException. For making the stack strace a
* little bit simpler, keep only the root cause provided that the exception type is compatible.
*/
UnavailableFactoryException exception = new UnavailableFactoryException(message, Exceptions.unwrap(failure));
exception.setUnavailableFactory(this);
throw exception;
}
}
Aggregations