You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/12/16 23:32:30 UTC
svn commit: r1720471 - in /sis/branches/JDK8/core:
sis-referencing/src/main/java/org/apache/sis/referencing/factory/
sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/
sis-utility/src/main/java/org/apache/sis/util/resources/
Author: desruisseaux
Date: Wed Dec 16 22:32:29 2015
New Revision: 1720471
URL: http://svn.apache.org/viewvc?rev=1720471&view=rev
Log:
Ported EPSGFactory.createCoordinateSystem(String) method.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java?rev=1720471&r1=1720470&r2=1720471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java [UTF-8] Wed Dec 16 22:32:29 2015
@@ -24,6 +24,7 @@ import org.opengis.referencing.cs.*;
import org.opengis.referencing.crs.*;
import org.opengis.referencing.datum.*;
import org.opengis.referencing.operation.*;
+import org.opengis.metadata.Identifier;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.citation.Citation;
import org.opengis.parameter.ParameterDescriptor;
@@ -66,8 +67,6 @@ import org.apache.sis.util.ArgumentCheck
public abstract class GeodeticAuthorityFactory extends AbstractFactory implements AuthorityFactory {
/**
* The factory to use for parsing authority code as {@link GenericName} instances.
- *
- * @see #trimAuthority(String)
*/
protected final NameFactory nameFactory;
@@ -874,16 +873,24 @@ public abstract class GeodeticAuthorityF
* @param code The code to trim.
* @return The code without the authority scope.
*/
- protected String trimAuthority(String code) {
- /*
- * IMPLEMENTATION NOTE: This method is overridden in PropertyAuthorityFactory.
- * If implementation below is modified, it is probably worth to revisit the overridden method as well.
- */
+ final String trimAuthority(String code) {
+ return trimAuthority(code, null);
+ }
+
+ /**
+ * Implementation of {@link #trimAuthority(String)}, but with an authority which may be already known.
+ * If the given {@code authority} is null, then it will be fetched by a call to {@link #getAuthority()}
+ * if needed.
+ */
+ private String trimAuthority(String code, Citation authority) {
code = code.trim();
final GenericName name = nameFactory.parseGenericName(null, code);
if (name instanceof ScopedName) {
final GenericName scope = ((ScopedName) name).path();
- if (Citations.identifierMatches(getAuthority(), null, scope.toString())) {
+ if (authority == null) {
+ authority = getAuthority(); // Costly operation for EPSGFactory.
+ }
+ if (Citations.identifierMatches(authority, null, scope.toString())) {
return name.tip().toString().trim();
}
}
@@ -892,17 +899,18 @@ public abstract class GeodeticAuthorityF
/**
* Creates an exception for an unknown authority code.
- * This convenience method is provided for implementation of {@code createFoo(String)} methods.
+ * This convenience method is provided for implementation of {@code createFoo(String)} methods in subclasses.
*
* @param type The GeoAPI interface that was to be created (e.g. {@code CoordinateReferenceSystem.class}).
* @param code The unknown authority code.
* @return An exception initialized with an error message built from the specified informations.
*/
- protected NoSuchAuthorityCodeException noSuchAuthorityCode(final Class<?> type, final String code) {
- final String authority = Citations.getIdentifier(getAuthority(), false);
+ final NoSuchAuthorityCodeException noSuchAuthorityCode(final Class<?> type, final String code) {
+ final Citation authority = getAuthority();
+ final String name = Citations.getIdentifier(authority, false);
return new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.NoSuchAuthorityCode_3,
- (authority != null) ? authority : Vocabulary.formatInternational(Vocabulary.Keys.Untitled),
- type, code), authority, trimAuthority(code), code);
+ (name != null) ? name : Vocabulary.formatInternational(Vocabulary.Keys.Untitled),
+ type, code), name, trimAuthority(code, authority), code);
}
/**
@@ -922,13 +930,31 @@ public abstract class GeodeticAuthorityF
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 EPSGFactory) getAuthority() method.
+ */
+ Citation authority = null;
+ if (object instanceof IdentifiedObject) {
+ final Identifier id = ((IdentifiedObject) object).getName();
+ if (id != null) {
+ authority = id.getAuthority();
+ }
+ }
+ if (authority == null) {
+ authority = getAuthority();
+ }
throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnexpectedTypeForReference_3, code, type, actual),
- Citations.getIdentifier(getAuthority(), false), trimAuthority(code), code);
+ Citations.getIdentifier(authority, false), trimAuthority(code, authority), code);
}
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1720471&r1=1720470&r2=1720471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] Wed Dec 16 22:32:29 2015
@@ -74,6 +74,7 @@ import org.apache.sis.metadata.iso.exten
import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
import org.apache.sis.referencing.NamedIdentifier;
import org.apache.sis.referencing.AbstractIdentifiedObject;
+import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.datum.BursaWolfParameters;
import org.apache.sis.referencing.factory.FactoryDataException;
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
@@ -677,6 +678,24 @@ addURIs: for (int i=0; ; i++) {
/**
* Sets the value of the primary key to search for, and executes the given prepared statement.
+ * Its values is assigned to the parameter #1.
+ *
+ * <p>This trivial method is defined for symmetry with {@link #executeQuery(PreparedStatement, String)}.
+ * The intend is to write the code in the same way without consideration about whether this primary key
+ * is a string or an integer. It also provides a central point where we can revisit query executions if
+ * needed in a future SIS version.</p>
+ *
+ * @param stmt The prepared statement in which to set the primary key.
+ * @param primaryKey The primary key.
+ * @throws SQLException if an error occurred while querying the database.
+ */
+ private static ResultSet executeQuery(final PreparedStatement stmt, final int primaryKey) throws SQLException {
+ stmt.setInt(1, primaryKey);
+ return stmt.executeQuery();
+ }
+
+ /**
+ * Sets the value of the primary key to search for, and executes the given prepared statement.
* The primary key should be the value returned by {@link #toPrimaryKey}.
* Its values is assigned to the parameter #1.
*
@@ -759,7 +778,7 @@ addURIs: for (int i=0; ; i++) {
* @throws SQLException if an error occurred while querying the database.
* @throws FactoryDataException if a null value was found.
*/
- private String getString(final ResultSet result, final int columnIndex, final Object code)
+ private String getString(final ResultSet result, final int columnIndex, final Comparable<?> code)
throws SQLException, FactoryDataException
{
final String value = result.getString(columnIndex);
@@ -773,12 +792,12 @@ addURIs: for (int i=0; ; i++) {
*
* @param result The result set to fetch value from.
* @param columnIndex The column index (1-based).
- * @param code The identifier of the record where the string was found.
+ * @param code The identifier of the record where the double was found.
* @return The double at the specified column.
* @throws SQLException if an error occurred while querying the database.
* @throws FactoryDataException if a null value was found.
*/
- private double getDouble(final ResultSet result, final int columnIndex, final Object code)
+ private double getDouble(final ResultSet result, final int columnIndex, final Comparable<?> code)
throws SQLException, FactoryDataException
{
final double value = result.getDouble(columnIndex);
@@ -792,12 +811,12 @@ addURIs: for (int i=0; ; i++) {
*
* @param result The result set to fetch value from.
* @param columnIndex The column index (1-based).
- * @param code The identifier of the record where the string was found.
+ * @param code The identifier of the record where the integer was found.
* @return The integer at the specified column.
* @throws SQLException if an error occurred while querying the database.
* @throws FactoryDataException if a null value was found.
*/
- private int getInt(final ResultSet result, final int columnIndex, final Object code)
+ private int getInt(final ResultSet result, final int columnIndex, final Comparable<?> code)
throws SQLException, FactoryDataException
{
final int value = result.getInt(columnIndex);
@@ -809,7 +828,7 @@ addURIs: for (int i=0; ; i++) {
* Makes sure that the last result was non-null.
* Used for {@code getString(…)}, {@code getDouble(…)} and {@code getInt(…)} methods only.
*/
- private void ensureNonNull(final ResultSet result, final int columnIndex, final Object code)
+ private void ensureNonNull(final ResultSet result, final int columnIndex, final Comparable<?> code)
throws SQLException, FactoryDataException
{
if (result.wasNull()) {
@@ -834,7 +853,7 @@ addURIs: for (int i=0; ; i++) {
* @param code The EPSG code (for formatting error message).
* @throws FactoryDataException if a duplication has been detected.
*/
- private <T> T ensureSingleton(final T newValue, final T oldValue, final String code) throws FactoryDataException {
+ private <T> T ensureSingleton(final T newValue, final T oldValue, final Comparable<?> code) throws FactoryDataException {
if (oldValue == null) {
return newValue;
}
@@ -870,7 +889,7 @@ addURIs: for (int i=0; ; i++) {
* @param code The deprecated code.
* @return A message proposing a replacement, or {@code null} if none.
*/
- private InternationalString getDeprecation(final String table, final String code)
+ private InternationalString getDeprecation(final String table, final int code)
throws SQLException, NoSuchIdentifierException
{
final PreparedStatement stmt = prepareStatement("[Deprecation]",
@@ -923,7 +942,7 @@ addURIs: for (int i=0; ; i++) {
* @return The name together with a set of properties.
*/
@SuppressWarnings("ReturnOfCollectionOrArrayField")
- private Map<String,Object> createProperties(final String table, String name, String code,
+ private Map<String,Object> createProperties(final String table, String name, final int code,
String remarks, final boolean deprecated) throws SQLException, FactoryException
{
properties.clear();
@@ -943,17 +962,15 @@ addURIs: for (int i=0; ; i++) {
properties.clear();
properties.put(IdentifiedObject.NAME_KEY, id);
}
- if (code != null) {
- code = code.trim();
- final ImmutableIdentifier identifier;
- if (deprecated) {
- identifier = new DeprecatedCode(authority, Constants.EPSG, code, version, getDeprecation(table, code));
- } else {
- identifier = new ImmutableIdentifier(authority, Constants.EPSG, code, version,
- (gn != null) ? gn.toInternationalString() : null);
- }
- properties.put(IdentifiedObject.IDENTIFIERS_KEY, identifier);
+ final String codeString = String.valueOf(code);
+ final ImmutableIdentifier identifier;
+ if (deprecated) {
+ identifier = new DeprecatedCode(authority, Constants.EPSG, codeString, version, getDeprecation(table, code));
+ } else {
+ identifier = new ImmutableIdentifier(authority, Constants.EPSG, codeString, version,
+ (gn != null) ? gn.toInternationalString() : null);
}
+ properties.put(IdentifiedObject.IDENTIFIERS_KEY, identifier);
if (remarks != null && !(remarks = remarks.trim()).isEmpty()) {
properties.put(IdentifiedObject.REMARKS_KEY, remarks);
}
@@ -972,7 +989,7 @@ addURIs: for (int i=0; ; i++) {
while (result.next()) {
if (tableMatches(table, result.getString(1))) {
String naming = result.getString(2);
- String alias = getString(result, 3, code);
+ String alias = getString(result, 3, codeString);
NameSpace ns = null;
if (naming != null) {
naming = naming.trim();
@@ -1005,7 +1022,7 @@ addURIs: for (int i=0; ; i++) {
* @param deprecated {@code true} if the object to create is deprecated.
* @return The name together with a set of properties.
*/
- private Map<String,Object> createProperties(final String table, final String name, final String code,
+ private Map<String,Object> createProperties(final String table, final String name, final int code,
String domainCode, String scope, String remarks, final boolean deprecated) throws SQLException, FactoryException
{
final Map<String,Object> properties = createProperties(table, name, code, remarks, deprecated);
@@ -1188,7 +1205,7 @@ addURIs: for (int i=0; ; i++) {
* Consequently, we don't use 'getString(ResultSet, int)' for those parameters because
* we do not want to thrown an exception if a NULL value is found.
*/
- final String epsg = getString(result, 1, code);
+ final int epsg = getInt (result, 1, code);
final String name = getString(result, 2, code);
final double semiMajorAxis = getDouble(result, 3, code);
final double inverseFlattening = result.getDouble( 4);
@@ -1262,7 +1279,7 @@ addURIs: for (int i=0; ; i++) {
" WHERE PRIME_MERIDIAN_CODE = ?");
try (ResultSet result = executeQuery(stmt, primaryKey)) {
while (result.next()) {
- final String epsg = getString(result, 1, code);
+ final int epsg = getInt (result, 1, code);
final String name = getString(result, 2, code);
final double longitude = getDouble(result, 3, code);
final String unitCode = getString(result, 4, code);
@@ -1355,6 +1372,257 @@ addURIs: for (int i=0; ; i++) {
}
/**
+ * Creates an arbitrary coordinate system from a code. The returned object will typically be an
+ * instance of {@link EllipsoidalCS}, {@link CartesianCS} or {@link VerticalCS}.
+ *
+ * @param code Value allocated by EPSG.
+ * @return The coordinate 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 CoordinateSystem createCoordinateSystem(final String code)
+ throws NoSuchAuthorityCodeException, FactoryException
+ {
+ ArgumentChecks.ensureNonNull("code", code);
+ CoordinateSystem returnValue = null;
+ try {
+ final String primaryKey = toPrimaryKey(CoordinateSystem.class, code,
+ "[Coordinate System]", "COORD_SYS_CODE", "COORD_SYS_NAME");
+ final PreparedStatement stmt = prepareStatement("[Coordinate System]",
+ "SELECT COORD_SYS_CODE," +
+ " COORD_SYS_NAME," +
+ " COORD_SYS_TYPE," +
+ " DIMENSION," +
+ " REMARKS," +
+ " DEPRECATED" +
+ " FROM [Coordinate System]" +
+ " WHERE COORD_SYS_CODE = ?");
+ try (ResultSet result = executeQuery(stmt, primaryKey)) {
+ while (result.next()) {
+ final int epsg = getInt (result, 1, code);
+ final String name = getString(result, 2, code);
+ final String type = getString(result, 3, code).trim();
+ final int dimension = getInt (result, 4, code);
+ final String remarks = result.getString( 5);
+ final boolean deprecated = result.getInt ( 6) != 0;
+ final CoordinateSystemAxis[] axis = createCoordinateSystemAxes(primaryKey, dimension);
+ final Map<String,Object> properties = createProperties("[Coordinate System]",
+ name, epsg, remarks, deprecated); // Must be after axis
+ CoordinateSystem cs = null;
+ switch (type.toLowerCase(Locale.US)) {
+ case "ellipsoidal": {
+ switch (dimension) {
+ case 2: cs = csFactory.createEllipsoidalCS(properties, axis[0], axis[1]); break;
+ case 3: cs = csFactory.createEllipsoidalCS(properties, axis[0], axis[1], axis[2]); break;
+ }
+ break;
+ }
+ case "cartesian": {
+ switch (dimension) {
+ case 2: cs = csFactory.createCartesianCS(properties, axis[0], axis[1]); break;
+ case 3: cs = csFactory.createCartesianCS(properties, axis[0], axis[1], axis[2]); break;
+ }
+ break;
+ }
+ case "spherical": {
+ switch (dimension) {
+ case 3: cs = csFactory.createSphericalCS(properties, axis[0], axis[1], axis[2]); break;
+ }
+ break;
+ }
+ case "vertical":
+ case "gravity-related": {
+ switch (dimension) {
+ case 1: cs = csFactory.createVerticalCS(properties, axis[0]); break;
+ }
+ break;
+ }
+ case "time": // Was used in older ISO-19111 versions.
+ case "temporal": {
+ switch (dimension) {
+ case 1: cs = csFactory.createTimeCS(properties, axis[0]); break;
+ }
+ break;
+ }
+ case "linear": {
+ switch (dimension) {
+ case 1: cs = csFactory.createLinearCS(properties, axis[0]); break;
+ }
+ break;
+ }
+ case "polar": {
+ switch (dimension) {
+ case 2: cs = csFactory.createPolarCS(properties, axis[0], axis[1]); break;
+ }
+ break;
+ }
+ case "cylindrical": {
+ switch (dimension) {
+ case 3: cs = csFactory.createCylindricalCS(properties, axis[0], axis[1], axis[2]); break;
+ }
+ break;
+ }
+ case "affine": {
+ switch (dimension) {
+ case 2: cs = csFactory.createAffineCS(properties, axis[0], axis[1]); break;
+ case 3: cs = csFactory.createAffineCS(properties, axis[0], axis[1], axis[2]); break;
+ }
+ break;
+ }
+ default: {
+ throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
+ }
+ }
+ if (cs == null) {
+ throw new FactoryDataException(error().getString(Errors.Keys.UnexpectedDimensionForCS_1, type));
+ }
+ returnValue = ensureSingleton(cs, returnValue, code);
+ }
+ }
+ } catch (SQLException exception) {
+ throw databaseFailure(CoordinateSystem.class, code, exception);
+ }
+ if (returnValue == null) {
+ throw noSuchAuthorityCode(CoordinateSystem.class, code);
+ }
+ return returnValue;
+ }
+
+ /**
+ * Returns the coordinate system axis from an EPSG code for a {@link CoordinateSystem}.
+ *
+ * <p><strong>WARNING:</strong> The EPSG database uses "{@code ORDER}" as a column name.
+ * This is tolerated by Access, but MySQL does not accept that name.</p>
+ *
+ * @param code the EPSG code for coordinate system owner.
+ * @param dimension of the coordinate system, which is also the size of the returned array.
+ * @return An array of coordinate system axis.
+ * @throws SQLException if an error occurred during database access.
+ * @throws FactoryException if the code has not been found.
+ */
+ private CoordinateSystemAxis[] createCoordinateSystemAxes(final String code, final int dimension)
+ throws SQLException, FactoryException
+ {
+ assert Thread.holdsLock(this);
+ final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[dimension];
+ final PreparedStatement stmt = prepareStatement("AxisOrder",
+ "SELECT COORD_AXIS_CODE" +
+ " FROM [Coordinate Axis]" +
+ " WHERE COORD_SYS_CODE = ?" +
+ " ORDER BY [ORDER]");
+ int i = 0;
+ try (ResultSet result = executeQuery(stmt, code)) {
+ while (result.next()) {
+ final String axisCode = getString(result, 1, code);
+ if (i < axis.length) {
+ // If 'i' is out of bounds, an exception will be thrown after the loop.
+ // We do not want to thrown an ArrayIndexOutOfBoundsException here.
+ axis[i] = buffered.createCoordinateSystemAxis(axisCode);
+ }
+ ++i;
+ }
+ }
+ if (i != axis.length) {
+ throw new FactoryDataException(error().getString(Errors.Keys.MismatchedDimension_2, axis.length, i));
+ }
+ return axis;
+ }
+
+ /**
+ * Creates a coordinate system axis with name, direction, unit and range of values.
+ *
+ * @param code Value allocated by EPSG.
+ * @return The axis 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.
+ *
+ * @see #createCoordinateSystem(String)
+ * @see org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis
+ */
+ @Override
+ public synchronized CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+ throws NoSuchAuthorityCodeException, FactoryException
+ {
+ ArgumentChecks.ensureNonNull("code", code);
+ CoordinateSystemAxis returnValue = null;
+ try {
+ final String primaryKey = trimAuthority(code);
+ final PreparedStatement stmt = prepareStatement("[Coordinate Axis]",
+ "SELECT COORD_AXIS_CODE," +
+ " COORD_AXIS_NAME_CODE," +
+ " COORD_AXIS_ORIENTATION," +
+ " COORD_AXIS_ABBREVIATION," +
+ " UOM_CODE" +
+ " FROM [Coordinate Axis]" +
+ " WHERE COORD_AXIS_CODE = ?");
+ try (ResultSet result = executeQuery(stmt, primaryKey)) {
+ while (result.next()) {
+ final int epsg = getInt (result, 1, code);
+ final int nameCode = getInt (result, 2, code);
+ final String orientation = getString(result, 3, code);
+ final String abbreviation = getString(result, 4, code);
+ final String unit = getString(result, 5, code);
+ AxisDirection direction;
+ try {
+ direction = CoordinateSystems.parseAxisDirection(orientation);
+ } catch (IllegalArgumentException exception) {
+ throw new FactoryDataException(exception.getLocalizedMessage(), exception);
+ }
+ final AxisName an = getAxisName(nameCode);
+ final Map<String,Object> properties = createProperties("[Coordinate Axis]", an.name, epsg, an.description, false);
+ final CoordinateSystemAxis axis = csFactory.createCoordinateSystemAxis(
+ properties, abbreviation, direction, buffered.createUnit(unit));
+ returnValue = ensureSingleton(axis, returnValue, code);
+ }
+ }
+ } catch (SQLException exception) {
+ throw databaseFailure(CoordinateSystemAxis.class, code, exception);
+ }
+ if (returnValue == null) {
+ throw noSuchAuthorityCode(CoordinateSystemAxis.class, code);
+ }
+ return returnValue;
+ }
+
+ /**
+ * Returns the name and description for the specified {@link CoordinateSystemAxis} code.
+ * Many axes share the same name and description, so it is worth to cache them.
+ */
+ private AxisName getAxisName(final int code) throws FactoryException {
+ assert Thread.holdsLock(this);
+ AxisName returnValue = axisNames.get(code);
+ if (returnValue == null) try {
+ final PreparedStatement stmt;
+ stmt = prepareStatement("[Coordinate Axis Name]",
+ "SELECT COORD_AXIS_NAME, DESCRIPTION, REMARKS" +
+ " FROM [Coordinate Axis Name]" +
+ " WHERE COORD_AXIS_NAME_CODE = ?");
+ try (ResultSet result = executeQuery(stmt, code)) {
+ while (result.next()) {
+ final String name = getString(result, 1, code);
+ String description = result.getString (2);
+ String remarks = result.getString (3);
+ if (description == null) {
+ description = remarks;
+ } else if (remarks != null) {
+ description += System.lineSeparator() + remarks;
+ }
+ final AxisName axis = new AxisName(name, description);
+ returnValue = ensureSingleton(axis, returnValue, code);
+ }
+ }
+ if (returnValue == null) {
+ throw noSuchAuthorityCode(AxisName.class, String.valueOf(code));
+ }
+ axisNames.put(code, returnValue);
+ } catch (SQLException exception) {
+ throw databaseFailure(AxisName.class, code, exception);
+ }
+ return returnValue;
+ }
+
+ /**
* Creates an unit of measurement from a code.
*
* @param code Value allocated by EPSG.
@@ -1418,8 +1686,27 @@ addURIs: for (int i=0; ; i++) {
return returnValue;
}
+ /**
+ * Returns {@code true} if the {@link CoordinateOperation} for the specified code is a {@link Projection}.
+ * The caller must have verified that the designed operation is a {@link Conversion} before to invoke this method.
+ *
+ * @throws NoSuchIdentifierException if the given code has not been found.
+ * @throws SQLException If an error occurred while querying the database.
+ */
final boolean isProjection(final int code) throws NoSuchIdentifierException, SQLException {
- return false;
+ Boolean projection = isProjection.get(code);
+ if (projection == null) {
+ final PreparedStatement stmt = prepareStatement("isProjection",
+ "SELECT COORD_REF_SYS_CODE" +
+ " FROM [Coordinate Reference System]" +
+ " WHERE PROJECTION_CONV_CODE = ?" +
+ " AND COORD_REF_SYS_KIND LIKE 'projected%'");
+ try (ResultSet result = executeQuery(stmt, code)) {
+ projection = result.next();
+ }
+ isProjection.put(code, projection);
+ }
+ return projection;
}
/**
@@ -1478,14 +1765,13 @@ addURIs: for (int i=0; ; i++) {
/**
* Removes the {@code "EPSG:"} prefix from the given string, if present.
- * This method overrides the more generic implementation provided by the subclasses for efficiency.
+ * This method is preferred to the more generic implementation provided by the parent class for efficiency reason.
* In particular, this method avoid to call the potentially costly {@link #getAuthority()} method.
*
* @param code The code to trim.
* @return The code without the {@code "EPSG:"} prefix.
*/
- @Override
- protected String trimAuthority(String code) {
+ private String trimAuthority(String code) {
int s = code.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR);
if (s >= 0 && Constants.EPSG.equals(code.substring(0, s).trim())) {
code = code.substring(s+1).trim();
@@ -1501,8 +1787,7 @@ addURIs: for (int i=0; ; i++) {
* @param code The unknown authority code.
* @return An exception initialized with an error message built from the specified informations.
*/
- @Override
- protected NoSuchAuthorityCodeException noSuchAuthorityCode(final Class<?> type, final String code) {
+ private NoSuchAuthorityCodeException noSuchAuthorityCode(final Class<?> type, final String code) {
return new NoSuchAuthorityCodeException(error().getString(Errors.Keys.NoSuchAuthorityCode_3,
Constants.EPSG, type, code), Constants.EPSG, trimAuthority(code), code);
}
@@ -1517,7 +1802,7 @@ addURIs: for (int i=0; ; i++) {
/**
* Constructs an exception for a database failure.
*/
- private FactoryException databaseFailure(Class<?> type, String code, SQLException cause) {
+ private FactoryException databaseFailure(Class<?> type, Comparable<?> code, SQLException cause) {
return new FactoryException(error().getString(Errors.Keys.DatabaseError_2, type, code), cause);
}
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1720471&r1=1720470&r2=1720471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Wed Dec 16 22:32:29 2015
@@ -941,6 +941,11 @@ public final class Errors extends Indexe
public static final short UnexpectedCharactersAfter_2 = 198;
/**
+ * Unexpected dimension for a coordinate system of type ‘{0}’.
+ */
+ public static final short UnexpectedDimensionForCS_1 = 212;
+
+ /**
* Unexpected end of file while reading “{0}”.
*/
public static final short UnexpectedEndOfFile_1 = 109;
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1720471&r1=1720470&r2=1720471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Wed Dec 16 22:32:29 2015
@@ -199,6 +199,7 @@ UndefinedOrderingForElements_2 = Orde
UnexpectedArrayLength_2 = Expected an array of length {0}, but got {1}.
UnexpectedChange_1 = Unexpected change in \u2018{0}\u2019.
UnexpectedCharactersAfter_2 = The \u201c{1}\u201d characters after \u201c{0}\u201d was unexpected.
+UnexpectedDimensionForCS_1 = Unexpected dimension for a coordinate system of type \u2018{0}\u2019.
UnexpectedEndOfFile_1 = Unexpected end of file while reading \u201c{0}\u201d.
UnexpectedEndOfString_1 = More characters were expected at the end of \u201c{0}\u201d.
UnexpectedFileFormat_2 = File \u201c{1}\u201d seems to be encoded in an other format than {0}.
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1720471&r1=1720470&r2=1720471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Wed Dec 16 22:32:29 2015
@@ -195,6 +195,7 @@ UndefinedOrderingForElements_2 = L\u2
UnexpectedArrayLength_2 = Un tableau de longueur {0} \u00e9tait attendu, mais le tableau re\u00e7u est de longueur {1}.
UnexpectedChange_1 = Changement inattendu dans \u2018{0}\u2019.
UnexpectedCharactersAfter_2 = Les caract\u00e8res \u00ab\u202f{1}\u202f\u00bb apr\u00e8s \u00ab\u202f{0}\u202f\u00bb sont inattendus.
+UnexpectedDimensionForCS_1 = Dimension inattendue pour un syst\u00e8me de coordonn\u00e9es de type \u2018{0}\u2019.
UnexpectedEndOfFile_1 = Fin de fichier inattendue lors de la lecture de \u00ab\u202f{0}\u202f\u00bb.
UnexpectedEndOfString_1 = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0 la fin du texte \u00ab\u202f{0}\u202f\u00bb.
UnexpectedFileFormat_2 = Le fichier \u00ab\u202f{1}\u202f\u00bb semble \u00eatre encod\u00e9 dans un autre format que {0}.