use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class CoordinateOperationRegistry method search.
/**
* Returns operations for conversions or transformations between two coordinate reference systems.
* This method extracts the authority code from the supplied {@code sourceCRS} and {@code targetCRS},
* and submit them to the {@link #registry}. If no operation is found for those codes, then this method
* returns {@code null}.
*
* @param sourceCRS source coordinate reference system.
* @param targetCRS target coordinate reference system.
* @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}, or {@code null}
* if no such operation is explicitly defined in the underlying database.
* @throws IllegalArgumentException if the coordinate systems are not of the same type or axes do not match.
* @throws IncommensurableException if the units are not compatible or a unit conversion is non-linear.
* @throws FactoryException if an error occurred while creating the operation.
*/
private List<CoordinateOperation> search(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws IllegalArgumentException, IncommensurableException, FactoryException {
final List<String> sources = findCode(sourceCRS);
if (sources.isEmpty())
return null;
final List<String> targets = findCode(targetCRS);
if (targets.isEmpty())
return null;
final List<CoordinateOperation> operations = new ArrayList<>();
boolean foundDirectOperations = false;
boolean useDeprecatedOperations = false;
for (final String sourceID : sources) {
for (final String targetID : targets) {
if (sourceID.equals(targetID)) {
/*
* Above check is necessary because this method may be invoked in some situations where the code
* are equal while the CRS are not. Such situation should be illegal, but unfortunately it still
* happen because many software products are not compliant with EPSG definition of axis order.
* In such cases we will need to compute a transform from sourceCRS to targetCRS ignoring the
* source and target codes. The CoordinateOperationFinder class can do that, providing that we
* prevent this CoordinateOperationRegistry to (legitimately) claims that the operation from
* sourceCode to targetCode is the identity transform.
*/
return null;
}
/*
* Some pairs of CRS have a lot of coordinate operations backed by datum shift grids.
* We do not want to load all of them until we found the right coordinate operation.
* The non-public Semaphores.METADATA_ONLY mechanism instructs EPSGDataAccess to
* instantiate DeferredCoordinateOperation instead of full coordinate operations.
*/
final boolean mdOnly = Semaphores.queryAndSet(Semaphores.METADATA_ONLY);
try {
Collection<CoordinateOperation> authoritatives;
try {
authoritatives = registry.createFromCoordinateReferenceSystemCodes(sourceID, targetID);
final boolean inverse = Containers.isNullOrEmpty(authoritatives);
if (inverse) {
/*
* No operation from 'source' to 'target' available. But maybe there is an inverse operation.
* This is typically the case when the user wants to convert from a projected to a geographic CRS.
* The EPSG database usually contains transformation paths for geographic to projected CRS only.
*/
if (foundDirectOperations) {
// Ignore inverse operations if we already have direct ones.
continue;
}
authoritatives = registry.createFromCoordinateReferenceSystemCodes(targetID, sourceID);
if (Containers.isNullOrEmpty(authoritatives)) {
continue;
}
} else if (!foundDirectOperations) {
foundDirectOperations = true;
// Keep only direct operations.
operations.clear();
}
} catch (NoSuchAuthorityCodeException | MissingFactoryResourceException e) {
/*
* sourceCode or targetCode is unknown to the underlying authority factory.
* Ignores the exception and fallback on the generic algorithm provided by
* CoordinateOperationFinder.
*/
log(null, e);
continue;
}
/*
* If we found at least one non-deprecated operation, we will stop the search at
* the first deprecated one (assuming that deprecated operations are sorted last).
* Deprecated operations are kept only if there is no non-deprecated operations.
*/
try {
for (final CoordinateOperation candidate : authoritatives) {
if (candidate != null) {
// Paranoiac check.
if ((candidate instanceof Deprecable) && ((Deprecable) candidate).isDeprecated()) {
if (!useDeprecatedOperations && !operations.isEmpty())
break;
useDeprecatedOperations = true;
} else if (useDeprecatedOperations) {
useDeprecatedOperations = false;
// Replace deprecated operations by non-deprecated ones.
operations.clear();
}
operations.add(candidate);
}
}
} catch (BackingStoreException exception) {
throw exception.unwrapOrRethrow(FactoryException.class);
}
} finally {
if (!mdOnly) {
Semaphores.clear(Semaphores.METADATA_ONLY);
}
}
}
}
/*
* At this point we got the list of coordinate operations. Now, sort them in preference order.
* We will loop over all coordinate operations and select the one having the largest intersection
* with the area of interest. Note that if the user did not specified an area of interest himself,
* then we need to get one from the CRS. This is necessary for preventing the transformation from
* NAD27 to NAD83 in Idaho to select the transform for Alaska (since the later has a larger area).
*/
CoordinateOperationSorter.sort(operations, Extents.getGeographicBoundingBox(areaOfInterest));
final ListIterator<CoordinateOperation> it = operations.listIterator();
while (it.hasNext()) {
/*
* At this point we filtered a CoordinateOperation by looking only at its metadata.
* Code following this point will need the full coordinate operation, including its
* MathTransform. So if we got a deferred operation, we need to resolve it now.
* Conversely, we should not use metadata below this point because the call to
* inverse(CoordinateOperation) is not guaranteed to preserve all metadata.
*/
CoordinateOperation operation = it.next();
try {
if (operation instanceof DeferredCoordinateOperation) {
operation = ((DeferredCoordinateOperation) operation).create();
}
if (operation instanceof SingleOperation && operation.getMathTransform() == null) {
operation = fromDefiningConversion((SingleOperation) operation, foundDirectOperations ? sourceCRS : targetCRS, foundDirectOperations ? targetCRS : sourceCRS);
if (operation == null) {
it.remove();
continue;
}
}
if (!foundDirectOperations) {
operation = inverse(operation);
}
} catch (NoninvertibleTransformException | MissingFactoryResourceException e) {
/*
* If we failed to get the real CoordinateOperation instance, remove it from
* the collection and try again in order to get the next best choices.
*/
log(null, e);
it.remove();
// Try again with the next best case.
continue;
}
/*
* It is possible that the CRS given to this method were not quite right. For example the user
* may have created his CRS from a WKT using a different axis order than the order specified by
* the authority and still (wrongly) call those CRS "EPSG:xxxx". So we check if the source and
* target CRS for the operation we just created are equivalent to the CRS specified by the user.
*
* NOTE: FactoryException may be thrown if we fail to create a transform from the user-provided
* CRS to the authority-provided CRS. That transform should have been only an identity transform,
* or a simple affine transform if the user specified wrong CRS as explained in above paragraph.
* If we fail here, we are likely to fail for all other transforms. So we are better to let the
* FactoryException propagate.
*/
operation = complete(operation, sourceCRS, targetCRS);
if (filter(operation)) {
if (stopAtFirst) {
operations.clear();
operations.add(operation);
break;
}
it.set(operation);
} else {
it.remove();
}
}
return operations;
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class CommonAuthorityFactory method createUnitFromEPSG.
/**
* Returns the unit of measurement for the given EPSG code.
* This is used only for codes in the legacy {@code "AUTO"} namespace.
*/
private static Unit<?> createUnitFromEPSG(final double code) throws NoSuchAuthorityCodeException {
// Error message to be used only in case of failure.
String message = null;
// The string representation of the code, to be used only in case of failure.
final String s;
final int c = (int) code;
if (c == code) {
final Unit<?> unit = Units.valueOfEPSG(c);
if (Units.isLinear(unit)) {
return unit;
} else if (unit != null) {
message = Errors.format(Errors.Keys.NonLinearUnit_1, unit);
}
s = String.valueOf(c);
} else {
s = String.valueOf(code);
}
if (message == null) {
message = Resources.format(Resources.Keys.NoSuchAuthorityCode_3, Constants.EPSG, Unit.class, s);
}
throw new NoSuchAuthorityCodeException(message, Constants.EPSG, s);
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class AuthorityFactoriesTest method testHttp.
/**
* Tests creation of CRS from codes in the {@code "http://www.opengis.net/gml/srs/"} name space.
*
* @throws FactoryException if a CRS creation failed.
*/
@Test
public void testHttp() throws FactoryException {
final CRSAuthorityFactory factory = AuthorityFactories.ALL;
final CRSAuthorityFactory wms = AuthorityFactories.ALL.getAuthorityFactory(CRSAuthorityFactory.class, Constants.OGC, null);
CoordinateReferenceSystem actual, expected;
actual = factory.createCoordinateReferenceSystem("http://www.opengis.net/gml/srs/CRS#84");
expected = wms.createCoordinateReferenceSystem("84");
assertSame(expected, actual);
actual = factory.createCoordinateReferenceSystem("HTTP://WWW.OPENGIS.NET/GML/SRS/crs#84");
assertSame(expected, actual);
actual = factory.createCoordinateReferenceSystem("http://www.opengis.net/gml/srs/CRS.xml#84");
assertSame(expected, actual);
try {
factory.createCoordinateReferenceSystem("http://www.dummy.net/gml/srs/CRS#84");
fail("Should not accept http://www.dummy.net");
} catch (NoSuchAuthorityCodeException e) {
assertNotNull(e.getMessage());
}
try {
factory.createCoordinateReferenceSystem("http://www.opengis.net/gml/dummy/CRS#84");
fail("Should not accept “dummy” as an authority");
} catch (NoSuchAuthorityCodeException e) {
assertNotNull(e.getMessage());
}
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class ImageFileDirectory method completeMetadata.
/**
* Completes the metadata with the information stored in the field of this IFD.
* This method is invoked only if the user requested the ISO 19115 metadata.
* This method creates a new {@code "metadata/contentInfo"} node for this image.
* Information not under the {@code "metadata/contentInfo"} node will be merged
* with the current content of the given {@code MetadataBuilder}.
*
* @param metadata where to write metadata information. Caller should have already invoked
* {@link MetadataBuilder#setFormat(String)} before {@code completeMetadata(…)} calls.
*/
final void completeMetadata(final MetadataBuilder metadata, final Locale locale) throws DataStoreContentException, FactoryException {
metadata.newCoverage(false);
if (compression != null) {
metadata.addCompression(compression.name().toLowerCase(locale));
}
for (int band = 0; band < samplesPerPixel; ) {
metadata.newSampleDimension();
metadata.setBitPerSample(bitsPerSample);
if (minValues != null)
metadata.addMinimumSampleValue(minValues.doubleValue(Math.min(band, minValues.size() - 1)));
if (maxValues != null)
metadata.addMaximumSampleValue(maxValues.doubleValue(Math.min(band, maxValues.size() - 1)));
metadata.setBandIdentifier(++band);
}
/*
* Add the resolution into the metadata. Our current ISO 19115 implementation restricts
* the resolution unit to metres, but it may be relaxed in a future SIS version.
*/
if (!Double.isNaN(resolution) && resolutionUnit != null) {
metadata.addResolution(resolutionUnit.getConverterTo(Units.METRE).convert(resolution));
}
/*
* Cell size is relevant only if the Threshholding TIFF tag value is 2. By convention in
* this implementation class, other Threshholding values are stored as negative cell sizes:
*
* -1 means that Threshholding is 1 or unspecified.
* -2 means that Threshholding is 2 but the matrix size has not yet been specified.
* -3 means that Threshholding is 3 (randomized process such as error diffusion).
*/
switch(Math.min(cellWidth, cellHeight)) {
case -1:
{
// Nothing to report.
break;
}
case -3:
{
metadata.addProcessDescription(Resources.formatInternational(Resources.Keys.RandomizedProcessApplied));
break;
}
default:
{
metadata.addProcessDescription(Resources.formatInternational(Resources.Keys.DitheringOrHalftoningApplied_2, (cellWidth >= 0) ? cellWidth : '?', (cellHeight >= 0) ? cellHeight : '?'));
break;
}
}
/*
* Add Coordinate Reference System built from GeoTIFF tags. Note that the CRS may not exist,
* in which case the CRS builder returns null. This is safe since all MetadataBuilder methods
* ignore null values (a design choice because this pattern come very often).
*/
final boolean isGeorectified = (modelTiePoints == null) || (gridToCRS != null);
metadata.newGridRepresentation(isGeorectified ? MetadataBuilder.GridType.GEORECTIFIED : MetadataBuilder.GridType.GEOREFERENCEABLE);
metadata.setGeoreferencingAvailability(gridToCRS != null, false, false);
CoordinateReferenceSystem crs = null;
if (geoKeyDirectory != null) {
final CRSBuilder helper = new CRSBuilder(reader);
try {
crs = helper.build(geoKeyDirectory, numericGeoParameters, asciiGeoParameters);
metadata.addReferenceSystem(crs);
helper.complete(metadata);
} catch (NoSuchIdentifierException | ParameterNotFoundException e) {
short key = Resources.Keys.UnsupportedProjectionMethod_1;
if (e instanceof NoSuchAuthorityCodeException) {
key = Resources.Keys.UnknownCRS_1;
}
reader.owner.warning(reader.resources().getString(key, reader.owner.getDisplayName()), e);
} catch (IllegalArgumentException | NoSuchElementException | ClassCastException e) {
if (!helper.alreadyReported) {
reader.owner.warning(null, e);
}
}
}
try {
if (!isGeorectified) {
metadata.addGeolocation(new GridGeometry(filename(), crs, modelTiePoints));
}
} catch (TransformException e) {
reader.owner.warning(null, e);
}
// Not needed anymore, so let GC do its work.
geoKeyDirectory = null;
numericGeoParameters = null;
asciiGeoParameters = null;
modelTiePoints = null;
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project chordatlas by twak.
the class GISGen method initGML.
public void initGML() {
Closer<Point3d> closer = new Closer<>();
LoopL<Point3d> polies = null;
try {
polies = GMLReader.readGML3d(Tweed.toWorkspace(new File(gmlFile)), DefaultGeocentricCRS.CARTESIAN, CRS.decode(crs));
} catch (NoSuchAuthorityCodeException e) {
e.printStackTrace();
return;
} catch (FactoryException e) {
e.printStackTrace();
return;
}
Optional<Gen> hg = tweed.frame.gens(HeightGen.class).stream().findAny();
if (hg.isPresent())
for (Loop<Point3d> poly : polies) {
if (poly instanceof SuperLoop) {
SuperLoop sl = ((SuperLoop) poly);
sl.properties.putAll(((HeightGen) hg.get()).getProperties((String) sl.properties.get("name")));
}
}
for (Loop<Point3d> poly : polies) {
List<Point3d> points = new ArrayList();
for (Pair<Point3d, Point3d> pair : poly.pairs()) {
TweedSettings.settings.toOrigin.transform(pair.first());
pair.first().y = 0;
points.add(pair.first());
lines.add(new Line3d(pair.first(), pair.second()));
}
if (TweedSettings.settings.flipFootprints)
poly.reverse();
closer.add(points.toArray(new Point3d[points.size()]));
}
createBlocks(closer, polies);
}
Aggregations