use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.
the class CoordinateOperationRegistry method recreate.
/**
* Creates a new coordinate operation with the same method than the given operation, but different CRS.
* The CRS may differ either in the number of dimensions (i.e. let the vertical coordinate pass through),
* or in axis order (i.e. axis order in user CRS were not compliant with authority definition).
*
* @param operation the operation specified by the authority.
* @param sourceCRS the source CRS specified by the user.
* @param targetCRS the target CRS specified by the user
* @param transform the math transform to use in replacement to the one in {@code operation}.
* @param method the operation method, or {@code null} for attempting an automatic detection.
* @return a new operation from the given source CRS to target CRS using the given transform.
* @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
* @throws FactoryException if an error occurred while creating the new operation.
*/
private CoordinateOperation recreate(final CoordinateOperation operation, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, final MathTransform transform, OperationMethod method) throws IllegalArgumentException, FactoryException {
/*
* If the user-provided CRS are approximatively equal to the coordinate operation CRS, keep the later.
* The reason is that coordinate operation CRS are built from the definitions provided by the authority,
* while the user-provided CRS can be anything (e.g. parsed from a quite approximative WKT).
*/
CoordinateReferenceSystem crs;
if (Utilities.equalsApproximatively(sourceCRS, crs = operation.getSourceCRS()))
sourceCRS = crs;
if (Utilities.equalsApproximatively(targetCRS, crs = operation.getTargetCRS()))
targetCRS = crs;
final Map<String, Object> properties = new HashMap<>(derivedFrom(operation));
/*
* Determine whether the operation to create is a Conversion or a Transformation
* (could also be a Conversion subtype like Projection, but this is less important).
* We want the GeoAPI interface, not the implementation class.
* The most reliable way is to ask to the 'AbstractOperation.getInterface()' method,
* but this is SIS-specific. The fallback uses reflection.
*/
final Class<? extends IdentifiedObject> type;
if (operation instanceof AbstractIdentifiedObject) {
type = ((AbstractIdentifiedObject) operation).getInterface();
} else {
type = Classes.getLeafInterfaces(operation.getClass(), CoordinateOperation.class)[0];
}
properties.put(ReferencingServices.OPERATION_TYPE_KEY, type);
/*
* Reuse the same operation method, but we may need to change its number of dimension.
* The capability to resize an OperationMethod is specific to Apache SIS, so we must
* be prepared to see the 'redimension' call fails. In such case, we will try to get
* the SIS implementation of the operation method and try again.
*/
if (SubTypes.isSingleOperation(operation)) {
final SingleOperation single = (SingleOperation) operation;
properties.put(ReferencingServices.PARAMETERS_KEY, single.getParameterValues());
if (method == null) {
final int sourceDimensions = transform.getSourceDimensions();
final int targetDimensions = transform.getTargetDimensions();
method = single.getMethod();
try {
method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
} catch (IllegalArgumentException ex) {
try {
method = factorySIS.getOperationMethod(method.getName().getCode());
method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
} catch (NoSuchIdentifierException | IllegalArgumentException se) {
ex.addSuppressed(se);
throw ex;
}
}
}
}
return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS, AbstractCoordinateOperation.getInterpolationCRS(operation), method, transform);
}
use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.
the class IdentifiedObjectFinder method createFromNames.
/**
* Creates an object equals (optionally ignoring metadata), to the specified object using only the
* {@linkplain AbstractIdentifiedObject#getName name} and {@linkplain AbstractIdentifiedObject#getAlias aliases}.
* If no such object is found, returns {@code null}.
*
* <p>This method may be used with some {@linkplain GeodeticAuthorityFactory authority factory}
* implementations like the one backed by the EPSG database, which are capable to find an object
* from its name when the identifier is unknown.</p>
*
* @param object the object looked up.
* @return the identified object, or {@code null} if not found.
* @throws FactoryException if an error occurred while creating an object.
*
* @see #createFromCodes(IdentifiedObject)
* @see #createFromIdentifiers(IdentifiedObject)
*/
private IdentifiedObject createFromNames(final IdentifiedObject object) throws FactoryException {
String code = object.getName().getCode();
IdentifiedObject candidate;
try {
candidate = create(code);
} catch (FactoryException e) {
/*
* The identifier was not recognized. We will continue later with aliases.
* Note: we catch a more generic exception than NoSuchAuthorityCodeException because
* this attempt may fail for various reasons (character string not supported
* by the underlying database for primary key, duplicated name found, etc.).
*/
exceptionOccurred(e);
candidate = null;
}
if (match(candidate, object)) {
return candidate;
}
for (final GenericName id : object.getAlias()) {
code = id.toString();
try {
candidate = create(code);
} catch (FactoryException e) {
// The name was not recognized. No problem, let's go on.
exceptionOccurred(e);
continue;
}
if (match(candidate, object)) {
return candidate;
}
}
return null;
}
use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.
the class ReferencingFunctions method getAxis.
/**
* Returns the axis name and units for the specified dimension in a coordinate reference system or coordinate system.
* This method returns a short axis name as used in Well Known Text (WKT) format, for example <cite>"Latitude"</cite>
* instead of <cite>"Geodetic latitude"</cite>.
*
* @param codeOrPath the code allocated by an authority, or the path to a file.
* @param dimension the dimension (1, 2, …).
* @return the name of the requested axis.
*/
@Override
public String getAxis(final String codeOrPath, final int dimension) {
final CacheKey<String> key = new CacheKey<>(String.class, codeOrPath, dimension, null);
String name = key.peek();
if (name == null) {
final Cache.Handler<String> handler = key.lock();
try {
name = handler.peek();
if (name == null) {
final IdentifiedObject object;
try {
object = getIdentifiedObject(codeOrPath, null);
} catch (Exception exception) {
return getLocalizedMessage(exception);
}
CoordinateSystem cs = null;
final CoordinateSystemAxis axis;
if (object instanceof CoordinateSystemAxis) {
axis = (CoordinateSystemAxis) object;
} else {
if (object instanceof CoordinateReferenceSystem) {
cs = ((CoordinateReferenceSystem) object).getCoordinateSystem();
} else if (object instanceof CoordinateSystem) {
cs = (CoordinateSystem) object;
} else {
final Class<?> actual;
if (object instanceof AbstractIdentifiedObject) {
actual = ((AbstractIdentifiedObject) object).getInterface();
} else {
actual = Classes.getClass(object);
}
return Errors.getResources(getJavaLocale()).getString(Errors.Keys.UnexpectedTypeForReference_3, codeOrPath, CoordinateReferenceSystem.class, actual);
}
if (dimension >= 1 && dimension <= cs.getDimension()) {
axis = cs.getAxis(dimension - 1);
} else {
return Errors.getResources(getJavaLocale()).getString(Errors.Keys.IndexOutOfBounds_1, dimension);
}
}
final String unit = axis.getUnit().toString();
name = Transliterator.DEFAULT.toShortAxisName(cs, axis.getDirection(), axis.getName().getCode());
if (unit != null && !unit.isEmpty()) {
name = name + " (" + unit + ')';
}
}
} finally {
handler.putAndUnlock(name);
}
}
return name;
}
use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.
the class CRSPair method label.
/**
* Returns the name of the GeoAPI interface implemented by the specified object. In the GeographicCRS
* or EllipsoidalCS cases, the trailing CRS or CS suffix is replaced by the number of dimensions
* (e.g. "Geographic3D").
*/
static String label(final IdentifiedObject object) {
if (object == null) {
return null;
}
Class<? extends IdentifiedObject> type;
if (object instanceof AbstractIdentifiedObject) {
type = ((AbstractIdentifiedObject) object).getInterface();
} else {
type = Classes.getLeafInterfaces(object.getClass(), IdentifiedObject.class)[0];
}
String suffix, label = Classes.getShortName(type);
if (label.endsWith((suffix = "CRS")) || label.endsWith(suffix = "CS")) {
Object cs = object;
if (object instanceof CoordinateReferenceSystem) {
cs = ((CoordinateReferenceSystem) object).getCoordinateSystem();
}
if (cs instanceof EllipsoidalCS) {
final StringBuilder sb = new StringBuilder(label);
sb.setLength(label.length() - suffix.length());
label = sb.append(((CoordinateSystem) cs).getDimension()).append('D').toString();
}
}
String name = IdentifiedObjects.getName(object, null);
if (name != null) {
// Arbitrary length threshold.
int i = 30;
if (name.length() >= i) {
while (i > 15) {
// Arbitrary minimal length.
final int c = name.codePointBefore(i);
if (Character.isSpaceChar(c))
break;
i -= Character.charCount(c);
}
name = CharSequences.trimWhitespaces(name, 0, i).toString() + '…';
}
label = label + "[“" + name + "”]";
}
return label;
}
use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.
the class GeodeticAuthorityFactory method cast.
/**
* Casts the given object to the given type, or throws an exception if the object can not be casted.
* This convenience method is provided for implementation of {@code createXXX} methods.
*
* @param type the type to return (e.g. {@code CoordinateReferenceSystem.class}).
* @param object the object to cast.
* @param code the authority code, used only for formatting an error message.
* @return the object casted to the given type.
* @throws NoSuchAuthorityCodeException if the given object is not an instance of the given type.
*/
@SuppressWarnings("unchecked")
private <T> T cast(final Class<T> type, final IdentifiedObject object, final String code) throws NoSuchAuthorityCodeException {
if (type.isInstance(object)) {
return (T) object;
}
/*
* Get the actual type of the object. Returns the GeoAPI type if possible,
* or fallback on the implementation class otherwise.
*/
final Class<?> actual;
if (object instanceof AbstractIdentifiedObject) {
actual = ((AbstractIdentifiedObject) object).getInterface();
} else {
actual = object.getClass();
}
/*
* Get the authority from the object if possible, in order to avoid a call
* to the potentially costly (for EPSGDataAccess) getAuthority() method.
*/
final Identifier id = object.getName();
final Citation authority = (id != null) ? id.getAuthority() : getAuthority();
throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnexpectedTypeForReference_3, code, type, actual), Citations.getIdentifier(authority, false), trimNamespace(code), code);
}
Aggregations