use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class EPSGDataAccess method createCoordinateReferenceSystem.
/**
* Creates an arbitrary coordinate reference system from a code.
* The returned object will typically be an instance of {@link GeographicCRS}, {@link ProjectedCRS},
* {@link VerticalCRS} or {@link CompoundCRS}.
*
* <div class="note"><b>Example:</b>
* some EPSG codes for coordinate reference systems are:
*
* <table class="sis" summary="EPSG codes examples">
* <tr><th>Code</th> <th>Type</th> <th>Description</th></tr>
* <tr><td>4326</td> <td>Geographic</td> <td>World Geodetic System 1984</td></tr>
* <tr><td>4979</td> <td>Geographic 3D</td> <td>World Geodetic System 1984</td></tr>
* <tr><td>4978</td> <td>Geocentric</td> <td>World Geodetic System 1984</td></tr>
* <tr><td>3395</td> <td>Projected</td> <td>WGS 84 / World Mercator</td></tr>
* <tr><td>5714</td> <td>Vertical</td> <td>Mean Sea Level height</td></tr>
* <tr><td>6349</td> <td>Compound</td> <td>NAD83(2011) + NAVD88 height</td></tr>
* <tr><td>5800</td> <td>Engineering</td> <td>Astra Minas Grid</td></tr>
* </table></div>
*
* @param code value allocated by EPSG.
* @return the coordinate reference system for the given code.
* @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
* @throws FactoryException if the object creation failed for some other reason.
*/
@Override
public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(final String code) throws NoSuchAuthorityCodeException, FactoryException {
ArgumentChecks.ensureNonNull("code", code);
CoordinateReferenceSystem returnValue = null;
try (ResultSet result = executeQuery("Coordinate Reference System", "COORD_REF_SYS_CODE", "COORD_REF_SYS_NAME", // [ 1]
"SELECT COORD_REF_SYS_CODE," + // [ 2]
" COORD_REF_SYS_NAME," + // [ 3]
" AREA_OF_USE_CODE," + // [ 4]
" CRS_SCOPE," + // [ 5]
" REMARKS," + // [ 6]
" DEPRECATED," + // [ 7]
" COORD_REF_SYS_KIND," + // [ 8] Null for CompoundCRS
" COORD_SYS_CODE," + // [ 9] Null for ProjectedCRS
" DATUM_CODE," + // [10] For ProjectedCRS
" SOURCE_GEOGCRS_CODE," + // [11] For ProjectedCRS
" PROJECTION_CONV_CODE," + // [12] For CompoundCRS only
" CMPD_HORIZCRS_CODE," + // [13] For CompoundCRS only
" CMPD_VERTCRS_CODE" + " FROM [Coordinate Reference System]" + " WHERE COORD_REF_SYS_CODE = ?", code)) {
while (result.next()) {
final Integer epsg = getInteger(code, result, 1);
final String name = getString(code, result, 2);
final String area = getOptionalString(result, 3);
final String scope = getOptionalString(result, 4);
final String remarks = getOptionalString(result, 5);
final boolean deprecated = getOptionalBoolean(result, 6);
final String type = getString(code, result, 7);
/*
* Note: Do not invoke 'createProperties' now, even if we have all required informations,
* because the 'properties' map is going to overwritten by calls to 'createDatum', etc.
*
* The following switch statement should have a case for all "epsg_crs_kind" values enumerated
* in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases.
*/
final CRSFactory crsFactory = owner.crsFactory;
final CoordinateReferenceSystem crs;
switch(type.toLowerCase(Locale.US)) {
/* ----------------------------------------------------------------------
* GEOGRAPHIC CRS
*
* NOTE: 'createProperties' MUST be invoked after any call to an other
* 'createFoo' method. Consequently, do not factor out.
* ---------------------------------------------------------------------- */
case "geographic 2d":
case "geographic 3d":
{
Integer csCode = getInteger(code, result, 8);
if (replaceDeprecatedCS) {
csCode = DEPRECATED_CS.getOrDefault(csCode, csCode);
}
final EllipsoidalCS cs = owner.createEllipsoidalCS(csCode.toString());
final String datumCode = getOptionalString(result, 9);
final GeodeticDatum datum;
if (datumCode != null) {
datum = owner.createGeodeticDatum(datumCode);
} else {
final String geoCode = getString(code, result, 10, 9);
// Must be closed before call to createGeographicCRS(String)
result.close();
ensureNoCycle(GeographicCRS.class, epsg);
try {
datum = owner.createGeographicCRS(geoCode).getDatum();
} finally {
endOfRecursivity(GeographicCRS.class, epsg);
}
}
crs = crsFactory.createGeographicCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
break;
}
/* ----------------------------------------------------------------------
* PROJECTED CRS
*
* NOTE: This method invokes itself indirectly, through createGeographicCRS.
* Consequently we can not use 'result' anymore after this block.
* ---------------------------------------------------------------------- */
case "projected":
{
final String csCode = getString(code, result, 8);
final String geoCode = getString(code, result, 10);
final String opCode = getString(code, result, 11);
// Must be closed before call to createFoo(String)
result.close();
ensureNoCycle(ProjectedCRS.class, epsg);
try {
final CartesianCS cs = owner.createCartesianCS(csCode);
final Conversion op;
try {
op = (Conversion) owner.createCoordinateOperation(opCode);
} catch (ClassCastException e) {
// If happen anyway, the ClassCastException cause will give more hints than just the message.
throw (NoSuchAuthorityCodeException) noSuchAuthorityCode(Projection.class, opCode).initCause(e);
}
final CoordinateReferenceSystem baseCRS;
final boolean resumeParamChecks;
if (!deprecated) {
baseCRS = owner.createCoordinateReferenceSystem(geoCode);
resumeParamChecks = false;
} else {
/*
* If the ProjectedCRS is deprecated, one reason among others may be that it uses one of
* the deprecated coordinate systems. Those deprecated CS used non-linear units like DMS.
* Apache SIS can not instantiate a ProjectedCRS when the baseCRS uses such units, so we
* set a flag asking to replace the deprecated CS by a supported one. Since that baseCRS
* would not be exactly as defined by EPSG, we must not cache it because we do not want
* 'owner.createGeographicCRS(geoCode)' to return that modified CRS. Since the same CRS
* may be recreated every time a deprecated ProjectedCRS is created, we temporarily
* shutdown the loggings in order to avoid the same warning to be logged many time.
*/
final boolean old = quiet;
try {
quiet = true;
replaceDeprecatedCS = true;
// Do not cache that CRS.
baseCRS = createCoordinateReferenceSystem(geoCode);
} finally {
replaceDeprecatedCS = false;
quiet = old;
}
/*
* The crsFactory method calls will indirectly create a parameterized MathTransform.
* Their constructor will try to verify the parameter validity. But some deprecated
* CRS had invalid parameter values (they were deprecated precisely for that reason).
* If and only if we are creating a deprecated CRS, temporarily suspend the parameter
* checks.
*/
resumeParamChecks = !Semaphores.queryAndSet(Semaphores.SUSPEND_PARAMETER_CHECK);
// Try block must be immediately after above line (do not insert any code between).
}
try {
/*
* For a ProjectedCRS, the baseCRS is always geographic. So in theory we would not
* need the 'instanceof' check. However the EPSG dataset version 8.9 also uses the
* "projected" type for CRS that are actually derived CRS. See EPSG:5820 and 5821.
*/
final Map<String, Object> properties = createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated);
if (baseCRS instanceof GeographicCRS) {
crs = crsFactory.createProjectedCRS(properties, (GeographicCRS) baseCRS, op, cs);
} else {
crs = crsFactory.createDerivedCRS(properties, baseCRS, op, cs);
}
} finally {
if (resumeParamChecks) {
Semaphores.clear(Semaphores.SUSPEND_PARAMETER_CHECK);
}
}
} finally {
endOfRecursivity(ProjectedCRS.class, epsg);
}
break;
}
/* ----------------------------------------------------------------------
* VERTICAL CRS
* ---------------------------------------------------------------------- */
case "vertical":
{
final VerticalCS cs = owner.createVerticalCS(getString(code, result, 8));
final VerticalDatum datum = owner.createVerticalDatum(getString(code, result, 9));
crs = crsFactory.createVerticalCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
break;
}
/* ----------------------------------------------------------------------
* TEMPORAL CRS
*
* NOTE : The original EPSG database does not define any temporal CRS.
* This block is a SIS-specific extension.
* ---------------------------------------------------------------------- */
case "time":
case "temporal":
{
final TimeCS cs = owner.createTimeCS(getString(code, result, 8));
final TemporalDatum datum = owner.createTemporalDatum(getString(code, result, 9));
crs = crsFactory.createTemporalCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
break;
}
/* ----------------------------------------------------------------------
* COMPOUND CRS
*
* NOTE: This method invokes itself recursively.
* Consequently, we can not use 'result' anymore.
* ---------------------------------------------------------------------- */
case "compound":
{
final String code1 = getString(code, result, 12);
final String code2 = getString(code, result, 13);
result.close();
final CoordinateReferenceSystem crs1, crs2;
ensureNoCycle(CompoundCRS.class, epsg);
try {
crs1 = owner.createCoordinateReferenceSystem(code1);
crs2 = owner.createCoordinateReferenceSystem(code2);
} finally {
endOfRecursivity(CompoundCRS.class, epsg);
}
// Note: Do not invoke 'createProperties' sooner.
crs = crsFactory.createCompoundCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), crs1, crs2);
break;
}
/* ----------------------------------------------------------------------
* GEOCENTRIC CRS
* ---------------------------------------------------------------------- */
case "geocentric":
{
final CoordinateSystem cs = owner.createCoordinateSystem(getString(code, result, 8));
final GeodeticDatum datum = owner.createGeodeticDatum(getString(code, result, 9));
final Map<String, Object> properties = createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated);
if (cs instanceof CartesianCS) {
crs = crsFactory.createGeocentricCRS(properties, datum, (CartesianCS) cs);
} else if (cs instanceof SphericalCS) {
crs = crsFactory.createGeocentricCRS(properties, datum, (SphericalCS) cs);
} else {
throw new FactoryDataException(error().getString(Errors.Keys.IllegalCoordinateSystem_1, cs.getName()));
}
break;
}
/* ----------------------------------------------------------------------
* ENGINEERING CRS
* ---------------------------------------------------------------------- */
case "engineering":
{
final CoordinateSystem cs = owner.createCoordinateSystem(getString(code, result, 8));
final EngineeringDatum datum = owner.createEngineeringDatum(getString(code, result, 9));
crs = crsFactory.createEngineeringCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
break;
}
/* ----------------------------------------------------------------------
* PARAMETRIC CRS
* ---------------------------------------------------------------------- */
case "parametric":
{
final DefaultParametricCS cs = owner.createParametricCS(getString(code, result, 8));
final DefaultParametricDatum datum = owner.createParametricDatum(getString(code, result, 9));
crs = ReferencingServices.getInstance().createParametricCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs, crsFactory);
break;
}
/* ----------------------------------------------------------------------
* UNKNOWN CRS
* ---------------------------------------------------------------------- */
default:
{
throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
}
}
returnValue = ensureSingleton(crs, returnValue, code);
if (result.isClosed()) {
return returnValue;
}
}
} catch (SQLException exception) {
throw databaseFailure(CoordinateReferenceSystem.class, code, exception);
}
if (returnValue == null) {
throw noSuchAuthorityCode(CoordinateReferenceSystem.class, code);
}
return returnValue;
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class CommonAuthorityFactory method createCoordinateReferenceSystem.
/**
* Creates a coordinate reference system from the specified code.
* This method performs the following steps:
*
* <ol>
* <li>Skip the {@code "OGC"}, {@code "CRS"}, {@code "AUTO"}, {@code "AUTO1"} or {@code "AUTO2"} namespace
* if present (ignoring case). All other namespaces will cause an exception to be thrown.</li>
* <li>Skip the {@code "CRS"} prefix if present. This additional check is for accepting codes like
* {@code "OGC:CRS84"} (not a valid CRS code, but seen in practice).</li>
* <li>In the remaining text, interpret the integer value as documented in this class javadoc.
* Note that some codes require coma-separated parameters after the integer value.</li>
* </ol>
*
* @param code value allocated by OGC.
* @return the coordinate reference system for the given code.
* @throws FactoryException if the object creation failed.
*/
@Override
public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code) throws FactoryException {
ArgumentChecks.ensureNonNull("code", code);
final String localCode;
final boolean isLegacy;
String complement = null;
{
// Block for keeping 'start' and 'end' variables locale.
int start = skipNamespace(code);
isLegacy = (start & LEGACY_MASK) != 0;
start &= ~LEGACY_MASK;
final int startOfParameters = code.indexOf(SEPARATOR, start);
int end = CharSequences.skipTrailingWhitespaces(code, start, code.length());
if (startOfParameters >= 0) {
complement = code.substring(startOfParameters + 1);
end = CharSequences.skipTrailingWhitespaces(code, start, startOfParameters);
}
localCode = code.substring(start, end);
}
int codeValue = 0;
double[] parameters = ArraysExt.EMPTY_DOUBLE;
try {
codeValue = Integer.parseInt(localCode);
if (complement != null) {
parameters = CharSequences.parseDoubles(complement, SEPARATOR);
}
} catch (NumberFormatException exception) {
throw noSuchAuthorityCode(localCode, code, exception);
}
/*
* At this point we have isolated the code value from the parameters (if any). Verify the number of arguments.
* Then codes in the AUTO(2) namespace are delegated to a separated method while codes in the CRS namespaces
* are handled below.
*/
final int count = parameters.length;
if (codeValue >= FIRST_PROJECTION_CODE) {
int expected;
short errorKey = 0;
if (count < (expected = 2)) {
errorKey = Errors.Keys.TooFewArguments_2;
} else if (count > (expected = 3)) {
errorKey = Errors.Keys.TooManyArguments_2;
}
if (errorKey == 0) {
return createAuto(code, codeValue, isLegacy, (count > 2) ? parameters[0] : isLegacy ? Constants.EPSG_METRE : 1, parameters[count - 2], parameters[count - 1]);
}
throw new NoSuchAuthorityCodeException(Errors.format(errorKey, expected, count), AUTO2, localCode, code);
}
if (count != 0) {
throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnexpectedCharactersAfter_2, localCode, complement), Constants.CRS, localCode, code);
}
final CommonCRS crs;
switch(codeValue) {
case Constants.CRS1:
return displayCRS();
case Constants.CRS84:
crs = CommonCRS.WGS84;
break;
case Constants.CRS83:
crs = CommonCRS.NAD83;
break;
case Constants.CRS27:
crs = CommonCRS.NAD27;
break;
case Constants.CRS88:
return CommonCRS.Vertical.NAVD88.crs();
default:
throw noSuchAuthorityCode(localCode, code, null);
}
return crs.normalizedGeographic();
}
use of org.opengis.referencing.NoSuchAuthorityCodeException 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.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class AuthorityFactoriesTest method testCreateCRS.
/**
* Tests the {@code createCoordinateReferenceSystem(…)} method with various code.
*
* @throws FactoryException if a CRS creation failed.
*/
@Test
@DependsOnMethod("testCRS84")
public void testCreateCRS() throws FactoryException {
final CRSAuthorityFactory factory = AuthorityFactories.ALL;
final CRSAuthorityFactory wms = AuthorityFactories.ALL.getAuthorityFactory(CRSAuthorityFactory.class, Constants.OGC, null);
CoordinateReferenceSystem actual, expected;
actual = factory.createCoordinateReferenceSystem("CRS:84");
expected = wms.createCoordinateReferenceSystem("84");
assertSame(expected, actual);
assertSame(expected, factory.createObject("CRS:84"));
actual = factory.createCoordinateReferenceSystem("AUTO:42001,0,0");
expected = wms.createCoordinateReferenceSystem("42001,0,0");
assertSame(expected, actual);
assertSame(expected, factory.createObject("AUTO:42001,0,0"));
actual = factory.createCoordinateReferenceSystem("CRS:27");
expected = wms.createCoordinateReferenceSystem("27");
assertSame(expected, actual);
assertSame(expected, factory.createObject("CRS:27"));
try {
factory.createCoordinateReferenceSystem("84");
fail("Should not work without authority.");
} catch (NoSuchAuthorityCodeException exception) {
// This is the expected exception.
assertEquals("84", exception.getAuthorityCode());
}
try {
factory.createCoordinateReferenceSystem("FOO:84");
fail("Should not work with unknown authority.");
} catch (NoSuchAuthorityFactoryException exception) {
// This is the expected exception.
assertEquals("FOO", exception.getAuthority());
}
}
use of org.opengis.referencing.NoSuchAuthorityCodeException in project sis by apache.
the class AuthorityFactoryMock method createObject.
/**
* Returns the geodetic object for the given code.
*
* @throws NoSuchAuthorityCodeException if the given code is unknown.
*/
@Override
public IdentifiedObject createObject(final String code) throws NoSuchAuthorityCodeException {
assertFalse("This factory has been closed.", isClosed());
final int n;
try {
n = Integer.parseInt(trimNamespace(code));
} catch (NumberFormatException e) {
throw new NoSuchAuthorityCodeException(e.toString(), "MOCK", code);
}
switch(n) {
case 84:
return HardCodedCRS.WGS84;
case 4326:
return HardCodedCRS.WGS84_φλ;
case 4979:
return HardCodedCRS.GEOCENTRIC;
case 5714:
return HardCodedCRS.GRAVITY_RELATED_HEIGHT;
case 9905:
return HardCodedCRS.DEPTH;
case 8901:
return HardCodedDatum.GREENWICH;
case 8903:
return HardCodedDatum.PARIS;
case 8914:
return HardCodedDatum.PARIS_RGS;
case 6326:
return HardCodedDatum.WGS84;
case 6322:
return HardCodedDatum.WGS72;
case 6807:
return HardCodedDatum.NTF;
case 6301:
return HardCodedDatum.TOKYO;
case 6612:
return HardCodedDatum.JGD2000;
case 6047:
return HardCodedDatum.SPHERE;
case 5100:
return HardCodedDatum.MEAN_SEA_LEVEL;
case 6422:
return HardCodedCS.GEODETIC_φλ;
case 6424:
return HardCodedCS.GEODETIC_2D;
default:
throw new NoSuchAuthorityCodeException(code, authority.getTitle().toString(), code);
}
}
Aggregations