use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class EPSGFactory method newDataAccess.
/**
* Creates the factory which will perform the actual geodetic object creation work.
* This method is invoked automatically when a new worker is required, either because the previous
* one has been disposed after its timeout or because a new one is required for concurrency.
*
* <p>The default implementation performs the following steps:</p>
* <ol>
* <li>Gets a new connection from the {@link #dataSource}.</li>
* <li>If this method is invoked for the first time, verifies if the EPSG tables exists.
* If the tables are not found, invokes {@link #install(Connection)}.</li>
* <li>Delegates to {@link #newDataAccess(Connection, SQLTranslator)}, which provides an easier
* overriding point for subclasses wanting to return a custom {@link EPSGDataAccess} instance.</li>
* </ol>
*
* @return Data Access Object (DAO) to use in {@code createFoo(String)} methods.
* @throws FactoryException if the constructor failed to connect to the EPSG database.
* This exception usually has a {@link SQLException} as its cause.
*/
@Override
protected EPSGDataAccess newDataAccess() throws FactoryException {
UnavailableFactoryException exception;
Connection connection = null;
try {
connection = dataSource.getConnection();
Logging.log(EPSGFactory.class, "newDataAccess", Initializer.connected(connection.getMetaData()));
SQLTranslator tr = translator;
if (tr == null) {
synchronized (this) {
tr = translator;
if (tr == null) {
tr = new SQLTranslator(connection.getMetaData(), catalog, schema);
try {
if (!tr.isTableFound()) {
install(connection);
// Set only on success.
tr.setup(connection.getMetaData());
}
} finally {
// Set only after installation in order to block other threads.
translator = tr;
}
}
}
}
if (tr.isTableFound()) {
return newDataAccess(connection, tr);
} else {
connection.close();
exception = new UnavailableFactoryException(canNotUse(SQLTranslator.tableNotFound(locale)));
}
} catch (Exception e) {
// Really want to catch all exceptions here.
if (connection != null)
try {
connection.close();
} catch (SQLException e2) {
e.addSuppressed(e2);
}
if (e instanceof FactoryException) {
throw (FactoryException) e;
}
/*
* 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.
*/
exception = new UnavailableFactoryException(canNotUse(e), Exceptions.unwrap(e));
}
exception.setUnavailableFactory(this);
throw exception;
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class Proj4 method createCRS.
/**
* Creates a new CRS from the given {@literal Proj.4} definition string.
* Some examples of definition strings are:
* <ul>
* <li>{@code "+init=epsg:3395 +over"} (see warning below)</li>
* <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"}</li>
* <li>{@code "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +ellps=WGS84 +towgs84=0,0,0"}</li>
* </ul>
*
* <b>Warning:</b> despite the {@code "epsg"} word, coordinate reference systems created by {@code "+init=epsg:"}
* syntax are not necessarily compliant with EPSG definitions. In particular, the axis order is often different.
* Units of measurement may also differ.
*
* @param definition the Proj.4 definition string.
* @param dimension the number of dimension of the CRS to create (2 or 3).
* @return a CRS created from the given definition string and number of dimensions.
* @throws NullPointerException if the definition string is {@code null}.
* @throws IllegalArgumentException if the definition string is empty or the dimension argument is out of range.
* @throws UnavailableFactoryException if the Proj.4 native library is not available.
* @throws FactoryException if the CRS creation failed for another reason.
*
* @see Proj4Factory#createCoordinateReferenceSystem(String)
*/
public static CoordinateReferenceSystem createCRS(String definition, final int dimension) throws FactoryException {
ArgumentChecks.ensureNonEmpty("definition", definition);
ArgumentChecks.ensureBetween("dimension", 2, 3, dimension);
definition = definition.trim();
try {
return Proj4Factory.INSTANCE.createCRS(definition, dimension >= 3);
} catch (IllegalArgumentException | ParserException e) {
throw new InvalidGeodeticParameterException(canNotParse(definition), e);
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
throw new UnavailableFactoryException(unavailable(e), e);
}
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class Proj4 method createOperation.
/**
* Creates an operation for conversion or transformation between two coordinate reference systems.
* The given CRSs should be instances created by this package. If not, then there is a choice:
*
* <ul>
* <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
* <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
* regardless if the given CRS were created from Proj.4 definition strings or not.
* This method fails if it can not map the given CRS to Proj.4 data structures.</li>
* </ul>
*
* <p><b>Recommended alternative</b></p>
* Provided that an <a href="http://sis.apache.org/epsg.html">EPSG database is available</a>,
* Apache SIS {@link CRS#findOperation CRS.findOperation(…)} method produces results that are closer
* to the authoritative definitions of coordinate operations (technically, Apache SIS referencing
* engine is a <cite>late-binding</cite> implementation while Proj.4 is an <cite>early-binding</cite>
* implementation — see EPSG guidance notes for a definition of late versus early-binding approaches).
* Apache SIS also attaches metadata about
* {@linkplain AbstractCoordinateOperation#getCoordinateOperationAccuracy() coordinate operation accuracy} and
* {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}, have extended support of
* multi-dimensional CRS and provides transform derivatives. This {@code Proj4.createOperation(…)} method should
* be reserved to situations where an application needs to reproduce the same numerical results than Proj.4.
*
* @param sourceCRS the source coordinate reference system.
* @param targetCRS the target coordinate reference system.
* @param force whether to force the creation of a Proj.4 transform
* even if the given CRS are not wrappers around Proj.4 data structures.
* @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
* {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
* @throws UnavailableFactoryException if {@code force} is {@code true} and the Proj.4 native library is not available.
* @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
* for the given pair of coordinate reference systems for another reason.
*
* @see Proj4Factory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
* @see CRS#findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
*/
public static CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final boolean force) throws FactoryException {
ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
try {
return Proj4Factory.INSTANCE.createOperation(sourceCRS, targetCRS, force);
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
throw new UnavailableFactoryException(unavailable(e), e);
}
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class Proj4Factory method createOperation.
/**
* Creates an operation for conversion or transformation between two coordinate reference systems.
* The given CRSs should be instances {@linkplain #createCoordinateReferenceSystem created by this factory}.
* If not, then there is a choice:
*
* <ul>
* <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
* <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
* regardless if the given CRS were created from Proj.4 definition strings or not.
* This method fails if it can not map the given CRS to Proj.4 data structures.</li>
* </ul>
*
* @param sourceCRS the source coordinate reference system.
* @param targetCRS the target coordinate reference system.
* @param force whether to force the creation of a Proj.4 transform
* even if the given CRS are not wrappers around Proj.4 data structures.
* @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
* {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
* @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
* for the given pair of coordinate reference systems.
*
* @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
* @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
*/
public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final boolean force) throws FactoryException {
final PJ source, target;
try {
if ((source = unwrapOrCreate(sourceCRS, force)) == null || (target = unwrapOrCreate(targetCRS, force)) == null) {
// At least one CRS is not a Proj.4 wrapper and 'force' is false.
return null;
}
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
throw new UnavailableFactoryException(Proj4.unavailable(e), e);
}
/*
* Before to create a transform, verify if the target CRS already contains a suitable transform.
* In such case, returning the existing operation is preferable since it usually contains better
* parameter description than what this method build.
*/
if (targetCRS instanceof GeneralDerivedCRS) {
final CoordinateOperation op = ((GeneralDerivedCRS) targetCRS).getConversionFromBase();
final MathTransform tr = op.getMathTransform();
if (tr instanceof Transform && ((Transform) tr).isFor(sourceCRS, source, targetCRS, target)) {
return op;
}
}
/*
* The 'Transform' construction implies parameter validation, so we do it first before to
* construct other objects.
*/
final Transform tr = new Transform(source, is3D("sourceCRS", sourceCRS), target, is3D("targetCRS", targetCRS));
Identifier id;
String src = null, tgt = null, name = UNNAMED;
if ((id = sourceCRS.getName()) != null)
src = id.getCode();
if ((id = targetCRS.getName()) != null)
tgt = id.getCode();
if (src != null || tgt != null) {
final StringBuilder buffer = new StringBuilder();
if (src != null)
buffer.append("From ").append(src);
if (tgt != null)
buffer.append(buffer.length() == 0 ? "To " : " to ").append(tgt);
name = buffer.toString();
}
return opFactory().createSingleOperation(identifier(name), sourceCRS, targetCRS, null, Transform.METHOD, tr);
}
use of org.apache.sis.referencing.factory.UnavailableFactoryException in project sis by apache.
the class Proj4Factory method createParameterizedTransform.
/**
* Creates a transform from a group of parameters. The {@link OperationMethod} name is inferred from
* the {@linkplain org.opengis.parameter.ParameterDescriptorGroup#getName() parameter group name}.
* Each parameter value is formatted as a Proj.4 parameter in a definition string.
*
* <div class="note"><b>Example:</b>
* {@preformat java
* ParameterValueGroup p = factory.getDefaultParameters("Mercator");
* p.parameter("semi_major").setValue(6378137.000);
* p.parameter("semi_minor").setValue(6356752.314);
* MathTransform mt = factory.createParameterizedTransform(p);
* }
*
* The corresponding Proj.4 definition string is:
*
* {@preformat text
* +proj=merc +a=6378137.0 +b=6356752.314
* }
* </div>
*
* @param parameters the parameter values.
* @return the parameterized transform.
* @throws FactoryException if the object creation failed. This exception is thrown
* if some required parameter has not been supplied, or has illegal value.
*
* @see #getDefaultParameters(String)
* @see #getAvailableMethods(Class)
*/
public MathTransform createParameterizedTransform(final ParameterValueGroup parameters) throws FactoryException {
final String proj = name(parameters.getDescriptor(), Errors.Keys.UnsupportedOperation_1);
final StringBuilder buffer = new StringBuilder(100).append(PROJ_PARAM).append(proj).append(STANDARD_OPTIONS);
for (final GeneralParameterValue p : parameters.values()) {
/*
* Unconditionally ask the parameter name in order to throw an exception
* with better error message in case of unrecognized parameter.
*/
final String name = name(p.getDescriptor(), Errors.Keys.UnexpectedParameter_1);
if (p instanceof ParameterValue) {
final Object value = ((ParameterValue) p).getValue();
if (value != null) {
buffer.append(" +").append(name).append('=').append(value);
}
}
}
final String definition = buffer.toString();
try {
final PJ pj = unique(new PJ(definition));
final PJ base = unique(new PJ(pj));
return new Transform(base, false, pj, false);
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
throw new UnavailableFactoryException(Proj4.unavailable(e), e);
}
}
Aggregations