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/06/25 12:18:31 UTC
svn commit: r1687467 - in /sis/branches/JDK8/core:
sis-metadata/src/main/java/org/apache/sis/internal/metadata/
sis-metadata/src/main/java/org/apache/sis/io/wkt/
sis-referencing/src/main/java/org/apache/sis/referencing/datum/
sis-referencing/src/test/j...
Author: desruisseaux
Date: Thu Jun 25 10:18:31 2015
New Revision: 1687467
URL: http://svn.apache.org/r1687467
Log:
WKT 2: initial support of "GeodeticCRS" element.
This imply the merge of parsing methods for GeographicCRS and GeocentricCRS into a single method.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.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-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -93,13 +93,14 @@ public final class WKTKeywords extends S
* and {@link org.apache.sis.referencing.crs.DefaultGeographicCRS}.
*/
public static final String
- BBox = "BBox",
- Datum = "Datum",
- GeodeticCRS = "GeodeticCRS",
- BaseGeodCRS = "BaseGeodCRS",
- GeodCRS = "GeodCRS",
- GeogCS = "GeogCS",
- GeocCS = "GeocCS";
+ BBox = "BBox",
+ Datum = "Datum",
+ GeodeticDatum = "GeodeticDatum",
+ GeodeticCRS = "GeodeticCRS",
+ BaseGeodCRS = "BaseGeodCRS",
+ GeodCRS = "GeodCRS",
+ GeogCS = "GeogCS",
+ GeocCS = "GeocCS";
/**
* Related to {@link org.apache.sis.referencing.crs.DefaultVerticalCRS}.
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -535,7 +535,7 @@ final class Element {
if (element.list != null) {
for (int i=0; i<keys.length; i++) {
if (element.keyword.equalsIgnoreCase(keys[i])) {
- keywordIndex = (byte) i;
+ element.keywordIndex = (byte) i;
iterator.remove();
return element;
}
@@ -604,8 +604,7 @@ final class Element {
}
/**
- * Returns the index of the keyword in the array given to the {@link #pullElement(String...)}
- * or {@link #pullOptionalElement(String...)} method.
+ * Returns the index of the keyword in the array given to the {@link #pullElement(int, String...)} method.
*/
final int getKeywordIndex() {
return keywordIndex;
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -346,9 +346,8 @@ final class GeodeticObjectParser extends
throws ParseException
{
CoordinateReferenceSystem crs;
- if ((crs = parseGeographicCRS (FIRST, element)) == null &&
+ if ((crs = parseGeodeticCRS (FIRST, element)) == null &&
(crs = parseProjectedCRS (FIRST, element)) == null &&
- (crs = parseGeocentricCRS (FIRST, element)) == null &&
(crs = parseVerticalCRS (FIRST, element)) == null &&
(crs = parseTimeCRS (FIRST, element)) == null &&
(crs = parseEngineeringCRS (FIRST, element)) == null &&
@@ -476,7 +475,7 @@ final class GeodeticObjectParser extends
while ((element = parent.pullElement(OPTIONAL, WKTKeywords.VerticalExtent)) != null) {
final double minimum = element.pullDouble("minimum");
final double maximum = element.pullDouble("maximum");
- Unit<Length> unit = parseDerivedUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ Unit<Length> unit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
element.close(ignoredElements);
if (unit == null) unit = SI.METRE;
if (extent == null) extent = new DefaultExtent();
@@ -537,7 +536,7 @@ final class GeodeticObjectParser extends
* @todo Authority code is currently ignored. We may consider to create a subclass of
* {@link Unit} which implements {@link IdentifiedObject} in a future version.
*/
- private <Q extends Quantity> Unit<Q> parseDerivedUnit(final Element parent,
+ private <Q extends Quantity> Unit<Q> parseScaledUnit(final Element parent,
final String keyword, final Unit<Q> baseUnit) throws ParseException
{
final Element element = parent.pullElement(OPTIONAL, keyword, WKTKeywords.Unit);
@@ -568,7 +567,7 @@ final class GeodeticObjectParser extends
final int index = element.getKeywordIndex() - 1;
parseMetadataAndClose(element, name);
if (index >= 0 && index < BASE_UNITS.length) {
- return Units.multiply(BASE_UNITS[index - 1], factor);
+ return Units.multiply(BASE_UNITS[index], factor);
}
// If we can not infer the base type, we have to rely on the name.
return parseUnit(name);
@@ -907,7 +906,7 @@ final class GeodeticObjectParser extends
final Element meridian = element.pullElement(OPTIONAL, WKTKeywords.Meridian);
if (meridian != null) {
double angle = meridian.pullDouble("meridian");
- final Unit<Angle> m = parseDerivedUnit(meridian, WKTKeywords.AngleUnit, SI.RADIAN);
+ final Unit<Angle> m = parseScaledUnit(meridian, WKTKeywords.AngleUnit, SI.RADIAN);
meridian.close(ignoredElements);
if (m != null) {
angle = m.getConverterTo(NonSI.DEGREE_ANGLE).convert(angle);
@@ -990,7 +989,10 @@ final class GeodeticObjectParser extends
}
/**
- * Parses a {@code "PRIMEM"} element. This element has the following pattern:
+ * Parses a {@code "PrimeMeridian"} element. The syntax is given by
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#53">WKT 2 specification §8.2.2</a>.
+ *
+ * The legacy WKT 1 pattern was:
*
* {@preformat text
* PRIMEM["<name>", <longitude> {,<authority>}]
@@ -999,8 +1001,10 @@ final class GeodeticObjectParser extends
* @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
* @param angularUnit The contextual unit.
- * @return The {@code "PRIMEM"} element as a {@link PrimeMeridian} object.
- * @throws ParseException if the {@code "PRIMEM"} element can not be parsed.
+ * @return The {@code "PrimeMeridian"} element as a {@link PrimeMeridian} object.
+ * @throws ParseException if the {@code "PrimeMeridian"} element can not be parsed.
+ *
+ * @see org.apache.sis.referencing.datum.DefaultPrimeMeridian#formatTo(Formatter)
*/
private PrimeMeridian parsePrimeMeridian(final int mode, final Element parent, Unit<Angle> angularUnit)
throws ParseException
@@ -1026,7 +1030,7 @@ final class GeodeticObjectParser extends
/**
* Parses an <strong>optional</strong> {@code "TOWGS84"} element.
- * This element has the following pattern:
+ * This element is specific to WKT 1 and has the following pattern:
*
* {@preformat text
* TOWGS84[<dx>, <dy>, <dz>, <ex>, <ey>, <ez>, <ppm>]
@@ -1055,7 +1059,10 @@ final class GeodeticObjectParser extends
}
/**
- * Parses a {@code "SPHEROID"} element. This element has the following pattern:
+ * Parses an {@code "Ellipsoid"} element. The syntax is given by
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#52">WKT 2 specification §8.2.1</a>.
+ *
+ * The legacy WKT 1 pattern was:
*
* {@preformat text
* SPHEROID["<name>", <semi-major axis>, <inverse flattening> {,<authority>}]
@@ -1063,8 +1070,10 @@ final class GeodeticObjectParser extends
*
* @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
- * @return The {@code "SPHEROID"} element as an {@link Ellipsoid} object.
- * @throws ParseException if the {@code "SPHEROID"} element can not be parsed.
+ * @return The {@code "Ellipsoid"} element as an {@link Ellipsoid} object.
+ * @throws ParseException if the {@code "Ellipsoid"} element can not be parsed.
+ *
+ * @see org.apache.sis.referencing.datum.DefaultEllipsoid#formatTo(Formatter)
*/
private Ellipsoid parseEllipsoid(final int mode, final Element parent) throws ParseException {
final Element element = parent.pullElement(mode, WKTKeywords.Ellipsoid, WKTKeywords.Spheroid);
@@ -1074,12 +1083,17 @@ final class GeodeticObjectParser extends
final String name = element.pullString("name");
final double semiMajorAxis = element.pullDouble("semiMajorAxis");
double inverseFlattening = element.pullDouble("inverseFlattening");
- if (inverseFlattening == 0) { // OGC convention for a sphere.
- inverseFlattening = Double.POSITIVE_INFINITY;
+ Unit<Length> unit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ if (unit == null) {
+ unit = SI.METRE;
}
+ final Map<String,?> properties = parseMetadataAndClose(element, name);
try {
- return datumFactory.createFlattenedSphere(parseMetadataAndClose(element, name),
- semiMajorAxis, inverseFlattening, SI.METRE);
+ if (inverseFlattening == 0) { // OGC convention for a sphere.
+ return datumFactory.createEllipsoid(properties, semiMajorAxis, semiMajorAxis, unit);
+ } else {
+ return datumFactory.createFlattenedSphere(properties, semiMajorAxis, inverseFlattening, unit);
+ }
} catch (FactoryException exception) {
throw element.parseFailed(exception);
}
@@ -1122,7 +1136,10 @@ final class GeodeticObjectParser extends
}
/**
- * Parses a {@code "DATUM"} element. This element has the following pattern:
+ * Parses a {@code "Datum"} (WKT 2) element. The syntax is given by
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#54">WKT 2 specification §8.2.4</a>.
+ *
+ * The legacy WKT 1 pattern was:
*
* {@preformat text
* DATUM["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
@@ -1131,21 +1148,28 @@ final class GeodeticObjectParser extends
* @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
* @param meridian the prime meridian, or {@code null} for Greenwich.
- * @return The {@code "DATUM"} element as a {@link GeodeticDatum} object.
- * @throws ParseException if the {@code "DATUM"} element can not be parsed.
+ * @return The {@code "Datum"} element as a {@link GeodeticDatum} object.
+ * @throws ParseException if the {@code "Datum"} element can not be parsed.
+ *
+ * @see org.apache.sis.referencing.datum.DefaultGeodeticDatum#formatTo(Formatter)
*/
private GeodeticDatum parseDatum(final int mode, final Element parent, PrimeMeridian meridian) throws ParseException {
- final Element element = parent.pullElement(mode, WKTKeywords.Datum);
+ final Element element = parent.pullElement(mode, WKTKeywords.Datum, WKTKeywords.GeodeticDatum);
if (element == null) {
return null;
}
final String name = element.pullString("name");
final Ellipsoid ellipsoid = parseEllipsoid(MANDATORY, element);
+ final Element anchor = element.pullElement(OPTIONAL, WKTKeywords.Anchor);
final Object toWGS84 = parseToWGS84(OPTIONAL, element);
final Map<String,Object> properties = parseMetadataAndClose(element, name);
if (meridian == null) {
meridian = referencing.getGreenwich();
}
+ if (anchor != null) {
+ properties.put(GeodeticDatum.ANCHOR_POINT_KEY, anchor.pullString("anchorDefinition"));
+ anchor.close(ignoredElements);
+ }
if (toWGS84 != null) {
properties.put(ReferencingServices.BURSA_WOLF_KEY, toWGS84);
}
@@ -1173,8 +1197,8 @@ final class GeodeticObjectParser extends
if (element == null) {
return null;
}
- final String name = element.pullString ("name");
- final int datum = element.pullInteger("datum");
+ final String name = element.pullString ("name");
+ final int datum = element.pullInteger("datum");
final VerticalDatumType type = VerticalDatumTypes.fromLegacy(datum);
// TODO: need to find a default value if null.
try {
@@ -1270,35 +1294,96 @@ final class GeodeticObjectParser extends
}
/**
- * Parses a {@code "GEOCCS"} element.
- * This element has the following pattern:
+ * Parses a {@code "GeodeticCRS"} (WKT 2) element. The syntax is given by
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#49">WKT 2 specification §8</a>.
+ *
+ * The legacy WKT 1 specification had two elements for this:
+ *
+ * {@preformat text
+ * GEOGCS["<name>", <datum>, <prime meridian>, <angular unit> {,<twin axes>} {,<authority>}]
+ * }
+ *
+ * and
*
* {@preformat text
- * GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>
- * {,<axis> ,<axis> ,<axis>} {,<authority>}]
+ * GEOCCS["<name>", <datum>, <prime meridian>, <linear unit> {,<axis> ,<axis> ,<axis>} {,<authority>}]
* }
*
* @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
- * @return The {@code "GEOCCS"} element as a {@link GeocentricCRS} object.
- * @throws ParseException if the {@code "GEOCCS"} element can not be parsed.
+ * @return The {@code "GeodeticCRS"} element as a {@link GeocentricCRS} object.
+ * @throws ParseException if the {@code "GeodeticCRS"} element can not be parsed.
+ *
+ * @see org.apache.sis.referencing.crs.DefaultGeographicCRS#formatTo(Formatter)
+ * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS#formatTo(Formatter)
*/
- private GeocentricCRS parseGeocentricCRS(final int mode, final Element parent) throws ParseException {
- final Element element = parent.pullElement(mode, WKTKeywords.GeocCS);
+ private GeodeticCRS parseGeodeticCRS(final int mode, final Element parent) throws ParseException {
+ final Element element = parent.pullElement(mode,
+ WKTKeywords.GeodeticCRS, // [0] WKT 2
+ WKTKeywords.GeodCRS, // [1] WKT 2
+ WKTKeywords.BaseGeodCRS, // [2] WKT 2
+ WKTKeywords.GeogCS, // [3] WKT 1
+ WKTKeywords.GeocCS); // [4] WKT 1
if (element == null) {
return null;
}
- final String name = element.pullString("name");
- final PrimeMeridian meridian = parsePrimeMeridian(MANDATORY, element, NonSI.DEGREE_ANGLE);
- final GeodeticDatum datum = parseDatum(MANDATORY, element, meridian);
- final Unit<Length> linearUnit = parseDerivedUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ final String csType;
+ final Unit<Angle> angularUnit;
+ final Unit<?> defaultUnit;
+ final int dimension;
+ switch (element.getKeywordIndex()) {
+ default: { // WKT2 element.
+ csType = null;
+ defaultUnit = parseUnit(element);
+ angularUnit = Units.isAngular(defaultUnit) ? defaultUnit.asType(Angle.class) : NonSI.DEGREE_ANGLE;
+ dimension = 2;
+ break;
+ }
+ case 3: { // WKT1 "GeogCS" element.
+ csType = WKTKeywords.ellipsoidal;
+ angularUnit = parseScaledUnit(element, WKTKeywords.AngleUnit, SI.RADIAN);
+ defaultUnit = angularUnit;
+ dimension = 2;
+ break;
+ }
+ case 4: { // WKT1 "GeocCS" element.
+ csType = WKTKeywords.Cartesian;
+ angularUnit = NonSI.DEGREE_ANGLE;
+ defaultUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ dimension = 3;
+ break;
+ }
+ }
+ Object name = element.pullString("name");
+ final PrimeMeridian meridian = parsePrimeMeridian(MANDATORY, element, angularUnit);
+ final GeodeticDatum datum = parseDatum(MANDATORY, element, meridian);
+ if (((String) name).isEmpty()) {
+ /*
+ * GeographicCRS name is a mandatory property, but some invalid WKT with an empty string exist.
+ * In such case, we will use the name of the enclosed datum. Indeed, it is not uncommon to have
+ * the same name for a geographic CRS and its geodetic datum.
+ */
+ name = datum.getName();
+ }
+ final CoordinateSystem cs;
try {
- final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 3, linearUnit, datum);
- return crsFactory.createGeocentricCRS(parseMetadataAndClose(element, name), datum,
- referencing.upgradeGeocentricCS((CartesianCS) cs));
+ cs = parseCoordinateSystem(element, csType, dimension, defaultUnit, datum);
+ final Map<String,?> properties = parseMetadataAndClose(element, name);
+ if (cs instanceof EllipsoidalCS) {
+ return crsFactory.createGeographicCRS(properties, datum, (EllipsoidalCS) cs);
+ }
+ if (cs instanceof CartesianCS) {
+ return crsFactory.createGeocentricCRS(properties, datum,
+ referencing.upgradeGeocentricCS((CartesianCS) cs));
+ }
+ if (cs instanceof SphericalCS) {
+ return crsFactory.createGeocentricCRS(properties, datum, (SphericalCS) cs);
+ }
} catch (FactoryException exception) {
throw element.parseFailed(exception);
}
+ throw new LocalizedParseException(errorLocale, Errors.Keys.IllegalCoordinateSystem_1,
+ new Object[] {cs.getClass()}, element.offset);
}
/**
@@ -1319,9 +1404,9 @@ final class GeodeticObjectParser extends
if (element == null) {
return null;
}
- final String name = element.pullString("name");
- final VerticalDatum datum = parseVerticalDatum(MANDATORY, element);
- final Unit<Length> linearUnit = parseDerivedUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ final String name = element.pullString("name");
+ final VerticalDatum datum = parseVerticalDatum(MANDATORY, element);
+ final Unit<Length> linearUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
try {
final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.vertical, 1, linearUnit, datum);
verticalCRS = crsFactory.createVerticalCRS(parseMetadataAndClose(element, name), datum, (VerticalCS) cs);
@@ -1353,7 +1438,7 @@ final class GeodeticObjectParser extends
}
final String name = element.pullString("name");
final TemporalDatum datum = parseTimeDatum(MANDATORY, element);
- final Unit<Duration> timeUnit = parseDerivedUnit(element, WKTKeywords.TimeUnit, SI.SECOND);
+ final Unit<Duration> timeUnit = parseScaledUnit(element, WKTKeywords.TimeUnit, SI.SECOND);
try {
final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.temporal, 1, timeUnit, datum);
return crsFactory.createTemporalCRS(parseMetadataAndClose(element, name), datum, (TimeCS) cs);
@@ -1363,43 +1448,6 @@ final class GeodeticObjectParser extends
}
/**
- * Parses a {@code "GEOGCS"} element. This element has the following pattern:
- *
- * {@preformat text
- * GEOGCS["<name>", <datum>, <prime meridian>, <angular unit> {,<twin axes>} {,<authority>}]
- * }
- *
- * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
- * @param parent The parent element.
- * @return The {@code "GEOGCS"} element as a {@link GeographicCRS} object.
- * @throws ParseException if the {@code "GEOGCS"} element can not be parsed.
- */
- private GeographicCRS parseGeographicCRS(final int mode, final Element parent) throws ParseException {
- final Element element = parent.pullElement(mode, WKTKeywords.GeodeticCRS, WKTKeywords.GeodCRS, WKTKeywords.GeogCS);
- if (element == null) {
- return null;
- }
- Object name = element.pullString("name");
- final Unit<Angle> angularUnit = parseDerivedUnit(element, WKTKeywords.AngleUnit, SI.RADIAN);
- final PrimeMeridian meridian = parsePrimeMeridian(MANDATORY, element, angularUnit);
- final GeodeticDatum datum = parseDatum(MANDATORY, element, meridian);
- if (((String) name).isEmpty()) {
- /*
- * GeographicCRS name is a mandatory property, but some invalid WKT with an empty string exist.
- * In such case, we will use the name of the enclosed datum. Indeed, it is not uncommon to have
- * the same name for a geographic CRS and its geodetic datum.
- */
- name = datum.getName();
- }
- try {
- final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.ellipsoidal, 2, angularUnit, datum);
- return crsFactory.createGeographicCRS(parseMetadataAndClose(element, name), datum, (EllipsoidalCS) cs);
- } catch (FactoryException exception) {
- throw element.parseFailed(exception);
- }
- }
-
- /**
* Parses a {@code "PROJCS"} element.
* This element has the following pattern:
*
@@ -1418,15 +1466,19 @@ final class GeodeticObjectParser extends
if (element == null) {
return null;
}
- final String name = element.pullString("name");
- final GeographicCRS geoCRS = parseGeographicCRS(MANDATORY, element);
- final Unit<Length> linearUnit = parseDerivedUnit(element, WKTKeywords.LengthUnit, SI.METRE);
- final boolean usesCommonUnits = convention.usesCommonUnits;
- final Conversion conversion = parseProjection(MANDATORY, element, usesCommonUnits ? SI.METRE : linearUnit,
+ final String name = element.pullString("name");
+ final GeodeticCRS geoCRS = parseGeodeticCRS(MANDATORY, element);
+ if (!(geoCRS instanceof GeographicCRS)) {
+ throw new LocalizedParseException(errorLocale, Errors.Keys.IllegalCRSType_1,
+ new Object[] {geoCRS.getClass()}, element.offset);
+ }
+ final Unit<Length> linearUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ final boolean usesCommonUnits = convention.usesCommonUnits;
+ final Conversion conversion = parseProjection(MANDATORY, element, usesCommonUnits ? SI.METRE : linearUnit,
usesCommonUnits ? NonSI.DEGREE_ANGLE : geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class));
try {
final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, linearUnit, geoCRS.getDatum());
- return crsFactory.createProjectedCRS(parseMetadataAndClose(element, name), geoCRS, conversion, (CartesianCS) cs);
+ return crsFactory.createProjectedCRS(parseMetadataAndClose(element, name), (GeographicCRS) geoCRS, conversion, (CartesianCS) cs);
} catch (FactoryException exception) {
throw element.parseFailed(exception);
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -280,8 +280,7 @@ public class AbstractDatum extends Abstr
* {@linkplain DefaultTemporalDatum#getOrigin() origin} instead.</li>
* </ul>
*
- * @return Description, possibly including coordinates, of the point or points used to anchor the datum
- * to the Earth.
+ * @return Description, possibly including coordinates, of the point or points used to anchor the datum to the Earth.
*/
@Override
public InternationalString getAnchorPoint() {
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -26,6 +26,7 @@ import org.opengis.util.GenericName;
import org.opengis.util.InternationalString;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.extent.Extent;
+import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.datum.PrimeMeridian;
import org.opengis.referencing.datum.GeodeticDatum;
@@ -535,7 +536,7 @@ public class DefaultGeodeticDatum extend
* Note that the {@linkplain #getPrimeMeridian() prime meridian} shall be formatted by the caller
* as a separated element after the geodetic datum (for compatibility with WKT 1).
*
- * @return {@code "Datum"}.
+ * @return {@code "Datum"} or {@code "GeodeticDatum"}.
*
* @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#51">WKT 2 specification §8.2</a>
*/
@@ -544,7 +545,8 @@ public class DefaultGeodeticDatum extend
super.formatTo(formatter);
formatter.newLine();
formatter.append(toFormattable(getEllipsoid()));
- if (formatter.getConvention().majorVersion() == 1) {
+ final boolean isWKT1 = formatter.getConvention().majorVersion() == 1;
+ if (isWKT1) {
/*
* Note that at the different of other datum (in particular vertical datum),
* WKT of geodetic datum do not have a numerical code for the datum type.
@@ -560,7 +562,19 @@ public class DefaultGeodeticDatum extend
}
}
// For the WKT 2 case, the ANCHOR[…] element is added by Formatter itself.
+
formatter.newLine(); // For writing the ID[…] element on its own line.
+ if (!isWKT1) {
+ /*
+ * In WKT 2, both "Datum" and "GeodeticDatum" keywords are permitted. The standard recommends
+ * to use "Datum" for simplicity. We will follow this advice when the Datum element is inside
+ * a GeodeticCRS element since the "Geodetic" aspect is more obvious in such case. But if the
+ * Datum appears in another context, then we will use "GeodeticDatum" for clarity.
+ */
+ if (!(formatter.getEnclosingElement(1) instanceof GeodeticCRS)) {
+ return WKTKeywords.GeodeticDatum;
+ }
+ }
return WKTKeywords.Datum;
}
}
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -181,6 +181,29 @@ public final strictfp class GeodeticObje
}
/**
+ * Tests the parsing of a geodetic datum from a WKT 2 string.
+ *
+ * @throws ParseException if the parsing failed.
+ */
+ @Test
+ public void testDatum() throws ParseException {
+ final GeodeticDatum datum = parse(GeodeticDatum.class,
+ "DATUM[“Tananarive 1925”,\n" +
+ " ELLIPSOID[“International 1924”, 6378.388, 297.0, LENGTHUNIT[“km”, 1000]],\n" +
+ " ANCHOR[“Tananarive observatory”]]");
+
+ assertNameAndIdentifierEqual("Tananarive 1925", 0, datum);
+ assertEquals("anchor", "Tananarive observatory", String.valueOf(datum.getAnchorPoint()));
+
+ final Ellipsoid ellipsoid = datum.getEllipsoid();
+ assertNameAndIdentifierEqual("International 1924", 0, ellipsoid);
+ assertEquals("unit", SI.KILOMETRE, ellipsoid.getAxisUnit());
+ assertEquals("semiMajor", 6378.388, ellipsoid.getSemiMajorAxis(), STRICT);
+ assertEquals("inverseFlattening", 297, ellipsoid.getInverseFlattening(), STRICT);
+ assertEquals("greenwichLongitude", 0, datum.getPrimeMeridian().getGreenwichLongitude(), STRICT);
+ }
+
+ /**
* Tests the parsing of a geocentric CRS from a WKT 1 string. The parser
* shall replace the OGC 01-009 axis directions (OTHER, EAST, NORTH) by
* ISO 19111 axis directions (Geocentric X, Geocentric Y, Geocentric Z).
@@ -188,7 +211,7 @@ public final strictfp class GeodeticObje
* @throws ParseException if the parsing failed.
*/
@Test
- @DependsOnMethod("testAxis")
+ @DependsOnMethod({"testAxis", "testDatum"})
public void testGeocentricCRS() throws ParseException {
final GeocentricCRS crs = parse(GeocentricCRS.class,
"GEOCCS[“Geocentric”,\n" +
@@ -226,6 +249,7 @@ public final strictfp class GeodeticObje
* @throws ParseException if the parsing failed.
*/
@Test
+ @DependsOnMethod({"testAxis", "testDatum"})
public void testGeographicCRS() throws ParseException {
verifyGeographicCRS(0, parse(GeographicCRS.class,
" GEOGCS[“WGS 84”,\n" +
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java?rev=1687467&r1=1687466&r2=1687467&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] Thu Jun 25 10:18:31 2015
@@ -184,7 +184,7 @@ public final strictfp class DefaultGeode
public void testToWKT() {
final DefaultGeodeticDatum datum = new DefaultGeodeticDatum(WGS84);
assertWktEquals(
- "Datum[“WGS84”,\n" +
+ "GeodeticDatum[“WGS84”,\n" +
" Ellipsoid[“WGS84”, 6378137.0, 298.257223563, LengthUnit[“metre”, 1]]]",
datum);
}
@@ -266,13 +266,13 @@ public final strictfp class DefaultGeode
datum);
assertWktEquals(Convention.WKT2,
- "Datum[“World Geodetic System 1984”,\n" +
+ "GeodeticDatum[“World Geodetic System 1984”,\n" +
" Ellipsoid[“WGS 84”, 6378137.0, 298.257223563, LengthUnit[“metre”, 1]],\n" +
" Id[“EPSG”, 6326, URI[“urn:ogc:def:datum:EPSG::6326”]]]",
datum);
assertWktEquals(Convention.INTERNAL,
- "Datum[“World Geodetic System 1984”,\n" +
+ "GeodeticDatum[“World Geodetic System 1984”,\n" +
" Ellipsoid[“WGS 84”, 6378137.0, 298.257223563, Id[“EPSG”, 7030],\n" +
" Remark[“Defining parameters cited in EPSG database.”]],\n" +
" Anchor[“Station coordinates changed by a few centimetres in 1994, 1997, 2002 and 2012.”],\n" +
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=1687467&r1=1687466&r2=1687467&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] Thu Jun 25 10:18:31 2015
@@ -323,11 +323,21 @@ public final class Errors extends Indexe
public static final short IllegalBitsPattern_1 = 33;
/**
+ * Coordinate reference system can not be of type ‘{0}’.
+ */
+ public static final short IllegalCRSType_1 = 194;
+
+ /**
* Class ‘{1}’ is illegal. It must be ‘{0}’ or a derived class.
*/
public static final short IllegalClass_2 = 34;
/**
+ * Coordinate system can not be “{0}”.
+ */
+ public static final short IllegalCoordinateSystem_1 = 193;
+
+ /**
* The “{1}” pattern can not be applied to formating of objects of type ‘{0}’.
*/
public static final short IllegalFormatPatternForClass_2 = 35;
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=1687467&r1=1687466&r2=1687467&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] Thu Jun 25 10:18:31 2015
@@ -75,6 +75,8 @@ IllegalArgumentValue_2 = Argu
IllegalAxisDirection_2 = Coordinate system of class \u2018{0}\u2019 can not have axis in the {1} direction.
IllegalBitsPattern_1 = Illegal bits pattern: {0}.
IllegalClass_2 = Class \u2018{1}\u2019 is illegal. It must be \u2018{0}\u2019 or a derived class.
+IllegalCoordinateSystem_1 = Coordinate system can not be \u201c{0}\u201d.
+IllegalCRSType_1 = Coordinate reference system can not be of type \u2018{0}\u2019.
IllegalFormatPatternForClass_2 = The \u201c{1}\u201d pattern can not be applied to formating of objects of type \u2018{0}\u2019.
IllegalLanguageCode_1 = The \u201c{0}\u201d language is not recognized.
IllegalMemberType_2 = Member \u201c{0}\u201d can not be associated to type \u201c{1}\u201d.
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=1687467&r1=1687466&r2=1687467&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] Thu Jun 25 10:18:31 2015
@@ -72,6 +72,8 @@ IllegalArgumentValue_2 = L\u2
IllegalAxisDirection_2 = Les syst\u00e8mes de coordonn\u00e9es de classe \u2018{0}\u2019 ne peuvent pas avoir d\u2019axe dans la direction \u00ab\u202f{1}\u202f\u00bb.
IllegalBitsPattern_1 = Pattern de bits invalide: {0}.
IllegalClass_2 = La classe \u2018{1}\u2019 est ill\u00e9gale. Il doit s\u2019agir d\u2019une classe \u2018{0}\u2019 ou d\u00e9riv\u00e9e.
+IllegalCoordinateSystem_1 = Le syst\u00e8me de coordonn\u00e9es ne peut pas \u00eatre \u00ab\u202f{0}\u202f\u00bb.
+IllegalCRSType_1 = Le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es ne peut pas \u00eatre de type \u2018{0}\u2019.
IllegalFormatPatternForClass_2 = Le mod\u00e8le \u00ab\u202f{1}\u202f\u00bb ne peut pas \u00eatre appliqu\u00e9 au formatage d\u2019objets de type \u2018{0}\u2019.
IllegalLanguageCode_1 = Le code de langue \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnu.
IllegalMemberType_2 = Le membre \u00ab\u202f{0}\u202f\u00bb ne peut pas \u00eatre associ\u00e9 au type \u00ab\u202f{1}\u202f\u00bb.