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/30 16:09:22 UTC
svn commit: r1688452 - 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/internal/referencing/
sis-referencing/src/mai...
Author: desruisseaux
Date: Tue Jun 30 14:09:21 2015
New Revision: 1688452
URL: http://svn.apache.org/r1688452
Log:
WKT 2: added support for parsing of VerticalCRS element in the WKT 2 syntax.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/VerticalDatumTypes.java
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/GeodeticObjectParser.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1688452&r1=1688451&r2=1688452&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Tue Jun 30 14:09:21 2015
@@ -17,6 +17,7 @@
package org.apache.sis.internal.metadata;
import java.util.Map;
+import java.util.Collections;
import javax.measure.unit.Unit;
import javax.measure.quantity.Length;
import org.opengis.geometry.Envelope;
@@ -446,6 +447,18 @@ public class ReferencingServices extends
}
/**
+ * Returns the properties of the given object.
+ *
+ * @param object The object from which to get the properties.
+ * @return The properties of the given object.
+ *
+ * @since 0.6
+ */
+ public Map<String,?> getProperties(final IdentifiedObject object) {
+ return Collections.singletonMap(IdentifiedObject.NAME_KEY, object.getName());
+ }
+
+ /**
* Returns {@code true} if the {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName()
* primary name} or an aliases of the given object matches the given name. The comparison ignores case,
* some Latin diacritical signs and any characters that are not letters or digits.
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/VerticalDatumTypes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/VerticalDatumTypes.java?rev=1688452&r1=1688451&r2=1688452&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/VerticalDatumTypes.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/VerticalDatumTypes.java [UTF-8] Tue Jun 30 14:09:21 2015
@@ -16,12 +16,15 @@
*/
package org.apache.sis.internal.metadata;
+import java.util.Collection;
+import javax.measure.unit.Unit;
import org.opengis.util.CodeList;
import org.opengis.util.GenericName;
-import org.opengis.metadata.Identifier;
-import org.opengis.referencing.datum.VerticalDatum;
import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.AxisDirection;
import org.apache.sis.util.StringBuilders;
+import org.apache.sis.measure.Units;
/**
@@ -112,27 +115,51 @@ public final class VerticalDatumTypes im
}
/**
- * Guesses the type of the given datum using its name or identifiers. This is sometime needed
- * after XML unmarshalling, since GML 3.2 does not contain any attribute for the datum type.
+ * Guesses the type of a datum from its name, aliases or a given vertical axis. This is sometime needed
+ * after XML unmarshalling or WKT parsing, since GML 3.2 and ISO 19162 do not contain any attribute for
+ * the datum type.
*
* <p>This method uses heuristic rules and may be changed in any future SIS version.
- * If the type can not be determined, defaults on {@link VerticalDatumType#OTHER_SURFACE}.</p>
+ * If the type can not be determined, defaults to {@link VerticalDatumType#OTHER_SURFACE}.</p>
*
- * @param datum The datum for which to guess a type.
+ * @param name The name of the datum for which to guess a type, or {@code null} if unknown.
+ * @param aliases The aliases of the datum for which to guess a type, or {@code null} if unknown.
+ * @param axis The vertical axis for which to guess a type, or {@code null} if unknown.
* @return A datum type, or {@link VerticalDatumType#OTHER_SURFACE} if none can be guessed.
*/
- public static VerticalDatumType guess(final VerticalDatum datum) {
- final Identifier identifier = datum.getName();
- if (identifier != null) {
- final VerticalDatumType type = guess(identifier.getCode());
- if (type != null) {
- return type;
+ public static VerticalDatumType guess(final String name, final Collection<? extends GenericName> aliases,
+ final CoordinateSystemAxis axis)
+ {
+ VerticalDatumType type = guess(name);
+ if (type != null) {
+ return type;
+ }
+ if (aliases != null) {
+ for (final GenericName alias : aliases) {
+ type = guess(alias.tip().toString());
+ if (type != null) {
+ return type;
+ }
}
}
- for (final GenericName alias : datum.getAlias()) {
- final VerticalDatumType type = guess(alias.tip().toString());
- if (type != null) {
- return type;
+ if (axis != null) {
+ final Unit<?> unit = axis.getUnit();
+ if (Units.isLinear(unit)) {
+ final String abbreviation = axis.getAbbreviation();
+ if (abbreviation.length() == 1) {
+ AxisDirection dir = AxisDirection.UP; // Expected direction for accepting the type.
+ switch (abbreviation.charAt(0)) {
+ case 'h': type = ELLIPSOIDAL; break;
+ case 'H': type = VerticalDatumType.GEOIDAL; break;
+ case 'D': type = VerticalDatumType.DEPTH; dir = AxisDirection.DOWN; break;
+ default: return VerticalDatumType.OTHER_SURFACE;
+ }
+ if (dir.equals(axis.getDirection())) {
+ return type;
+ }
+ }
+ } else if (Units.isPressure(unit)) {
+ return VerticalDatumType.BAROMETRIC;
}
}
return VerticalDatumType.OTHER_SURFACE;
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=1688452&r1=1688451&r2=1688452&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] Tue Jun 30 14:09:21 2015
@@ -110,7 +110,9 @@ public final class WKTKeywords extends S
VerticalDatum = "VerticalDatum",
VerticalCRS = "VerticalCRS",
BaseVertCRS = "BaseVertCRS",
+ VDatum = "VDatum",
Vert_Datum = "Vert_Datum",
+ VertCRS = "VertCRS",
Vert_CS = "Vert_CS";
/**
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=1688452&r1=1688451&r2=1688452&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] Tue Jun 30 14:09:21 2015
@@ -317,7 +317,7 @@ final class GeodeticObjectParser extends
(object = parseDatum (FIRST, element, null)) == null &&
(object = parseEllipsoid (FIRST, element)) == null &&
(object = parseToWGS84 (FIRST, element)) == null &&
- (object = parseVerticalDatum (FIRST, element)) == null &&
+ (object = parseVerticalDatum (FIRST, element, false)) == null &&
(object = parseTimeDatum (FIRST, element)) == null &&
(object = parseEngineeringDatum (FIRST, element)) == null &&
(object = parseConversion (FIRST, element, false, SI.METRE, NonSI.DEGREE_ANGLE)) == null)
@@ -522,6 +522,20 @@ final class GeodeticObjectParser extends
}
/**
+ * Parses the datum {@code ANCHOR[]} element and invoke {@link #parseMetadataAndClose(Element, Object)}.
+ * If an anchor has been found, its value is stored in the returned map.
+ */
+ private Map<String,Object> parseAnchorAndClose(final Element element, final String name) throws ParseException {
+ final Element anchor = element.pullElement(OPTIONAL, WKTKeywords.Anchor);
+ final Map<String,Object> properties = parseMetadataAndClose(element, name);
+ if (anchor != null) {
+ properties.put(Datum.ANCHOR_POINT_KEY, anchor.pullString("anchorDefinition"));
+ anchor.close(ignoredElements);
+ }
+ return properties;
+ }
+
+ /**
* Parses an optional {@code "UNIT"} element of a known dimension.
* This element has the following pattern:
*
@@ -1216,16 +1230,11 @@ final class GeodeticObjectParser extends
}
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);
+ final Map<String,Object> properties = parseAnchorAndClose(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);
}
@@ -1243,22 +1252,29 @@ final class GeodeticObjectParser extends
* VERT_DATUM["<name>", <datum type> {,<authority>}]
* }
*
- * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+ * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
+ * @param isWKT1 {@code true} if the parent is a WKT 1 element.
* @return The {@code "VERT_DATUM"} element as a {@link VerticalDatum} object.
* @throws ParseException if the {@code "VERT_DATUM"} element can not be parsed.
*/
- private VerticalDatum parseVerticalDatum(final int mode, final Element parent) throws ParseException {
- final Element element = parent.pullElement(mode, WKTKeywords.VerticalDatum, WKTKeywords.Vert_Datum);
+ private VerticalDatum parseVerticalDatum(final int mode, final Element parent, final boolean isWKT1)
+ throws ParseException
+ {
+ final Element element = parent.pullElement(mode, WKTKeywords.VerticalDatum, WKTKeywords.VDatum, WKTKeywords.Vert_Datum);
if (element == null) {
return null;
}
- 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.
+ final String name = element.pullString("name");
+ VerticalDatumType type = null;
+ if (isWKT1) {
+ type = VerticalDatumTypes.fromLegacy(element.pullInteger("datum"));
+ }
+ if (type == null) {
+ type = VerticalDatumTypes.guess(name, null, null);
+ }
try {
- return datumFactory.createVerticalDatum(parseMetadataAndClose(element, name), type);
+ return datumFactory.createVerticalDatum(parseAnchorAndClose(element, name), type);
} catch (FactoryException exception) {
throw element.parseFailed(exception);
}
@@ -1380,9 +1396,9 @@ final class GeodeticObjectParser extends
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
+ WKTKeywords.GeogCS, // [2] WKT 1
+ WKTKeywords.GeocCS, // [3] WKT 1
+ WKTKeywords.BaseGeodCRS); // [4] WKT 2 in ProjectedCRS or DerivedCRS
if (element == null) {
return null;
}
@@ -1409,7 +1425,7 @@ final class GeodeticObjectParser extends
}
break;
}
- case 3: { // WKT1 "GeogCS" element.
+ case 2: { // WKT1 "GeogCS" element.
isWKT1 = true;
csType = WKTKeywords.ellipsoidal;
angularUnit = parseScaledUnit(element, WKTKeywords.AngleUnit, SI.RADIAN);
@@ -1417,7 +1433,7 @@ final class GeodeticObjectParser extends
dimension = 2;
break;
}
- case 4: { // WKT1 "GeocCS" element.
+ case 3: { // WKT1 "GeocCS" element.
isWKT1 = true;
csType = WKTKeywords.Cartesian;
angularUnit = NonSI.DEGREE_ANGLE;
@@ -1472,16 +1488,31 @@ final class GeodeticObjectParser extends
* @throws ParseException if the {@code "VERT_CS"} element can not be parsed.
*/
private VerticalCRS parseVerticalCRS(final int mode, final Element parent) throws ParseException {
- final Element element = parent.pullElement(mode, WKTKeywords.VerticalCRS, WKTKeywords.Vert_CS);
+ final Element element = parent.pullElement(mode,
+ WKTKeywords.VerticalCRS, // [0] WKT 2
+ WKTKeywords.VertCRS, // [1] WKT 2
+ WKTKeywords.Vert_CS, // [2] WKT 1
+ WKTKeywords.BaseVertCRS); // [3] WKT 2 in DerivedCRS
if (element == null) {
return null;
}
- final boolean isWKT1 = element.getKeywordIndex() == 1; // Index of "Vert_CS" above.
- final String name = element.pullString("name");
- final VerticalDatum datum = parseVerticalDatum(MANDATORY, element);
- final Unit<Length> linearUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+ final boolean isWKT1 = element.getKeywordIndex() == 2; // Index of "Vert_CS" above.
+ final String name = element.pullString("name");
+ VerticalDatum datum = parseVerticalDatum(MANDATORY, element, isWKT1);
+ final Unit<?> unit = parseUnit(element);
try {
- final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.vertical, 1, isWKT1, linearUnit, datum);
+ final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.vertical, 1, isWKT1, unit, datum);
+ /*
+ * The 'parseVerticalDatum(…)' method may have been unable to resolve the datum type.
+ * But sometime the axis (which was not available when we created the datum) provides
+ * more information. Verify if we can have a better type now, and if so rebuild the datum.
+ */
+ if (VerticalDatumType.OTHER_SURFACE.equals(datum.getVerticalDatumType())) {
+ final VerticalDatumType type = VerticalDatumTypes.guess(datum.getName().getCode(), datum.getAlias(), cs.getAxis(0));
+ if (!VerticalDatumType.OTHER_SURFACE.equals(type)) {
+ datum = datumFactory.createVerticalDatum(referencing.getProperties(datum), type);
+ }
+ }
verticalCRS = crsFactory.createVerticalCRS(parseMetadataAndClose(element, name), datum, (VerticalCS) cs);
/*
* Some DefaultVerticalExtent objects may be waiting for the VerticalCRS before to complete
@@ -1540,12 +1571,12 @@ final class GeodeticObjectParser extends
final Element element = parent.pullElement(mode,
WKTKeywords.ProjectedCRS, // [0] WKT 2
WKTKeywords.ProjCRS, // [1] WKT 2
- WKTKeywords.BaseProjCRS, // [2] WKT 2
- WKTKeywords.ProjCS); // [3] WKT 1
+ WKTKeywords.ProjCS, // [2] WKT 1
+ WKTKeywords.BaseProjCRS); // [3] WKT 2 in DerivedCRS
if (element == null) {
return null;
}
- final boolean isWKT1 = element.getKeywordIndex() == 3; // Index of "ProjCS" above.
+ final boolean isWKT1 = element.getKeywordIndex() == 2; // Index of "ProjCS" above.
final String name = element.pullString("name");
final GeodeticCRS geoCRS = parseGeodeticCRS(MANDATORY, element, WKTKeywords.ellipsoidal);
if (!(geoCRS instanceof GeographicCRS)) {
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1688452&r1=1688451&r2=1688452&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Tue Jun 30 14:09:21 2015
@@ -590,6 +590,19 @@ public final class ServicesForMetadata e
}
/**
+ * Returns the properties of the given object.
+ *
+ * @param object The object from which to get the properties.
+ * @return The properties of the given object.
+ *
+ * @since 0.6
+ */
+ @Override
+ public Map<String,?> getProperties(final IdentifiedObject object) {
+ return IdentifiedObjects.getProperties(object);
+ }
+
+ /**
* Returns {@code true} if the {@linkplain AbstractIdentifiedObject#getName() primary name} or an aliases
* of the given object matches the given name.
*
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java?rev=1688452&r1=1688451&r2=1688452&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] Tue Jun 30 14:09:21 2015
@@ -234,7 +234,8 @@ public class DefaultVerticalDatum extend
private VerticalDatumType type() {
VerticalDatumType t = type;
if (t == null) {
- type = t = VerticalDatumTypes.guess(this);
+ final Identifier name = super.getName();
+ type = t = VerticalDatumTypes.guess(name != null ? name.getCode() : null, super.getAlias(), null);
}
return t;
}
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java?rev=1688452&r1=1688451&r2=1688452&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] Tue Jun 30 14:09:21 2015
@@ -18,6 +18,8 @@ package org.apache.sis.io.wkt;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.datum.VerticalDatumType;
import org.opengis.util.FactoryException;
import org.opengis.test.wkt.CRSParserTest;
import org.apache.sis.internal.metadata.AxisNames;
@@ -128,9 +130,9 @@ public class WKTParserTest extends CRSPa
public void testGeocentric() throws FactoryException {
super.testGeocentric();
final CoordinateSystem cs = object.getCoordinateSystem();
- assertEquals(AxisNames.GEOCENTRIC_X, cs.getAxis(0).getName().getCode());
- assertEquals(AxisNames.GEOCENTRIC_Y, cs.getAxis(1).getName().getCode());
- assertEquals(AxisNames.GEOCENTRIC_Z, cs.getAxis(2).getName().getCode());
+ assertEquals("name", AxisNames.GEOCENTRIC_X, cs.getAxis(0).getName().getCode());
+ assertEquals("name", AxisNames.GEOCENTRIC_Y, cs.getAxis(1).getName().getCode());
+ assertEquals("name", AxisNames.GEOCENTRIC_Z, cs.getAxis(2).getName().getCode());
}
/**
@@ -154,8 +156,8 @@ public class WKTParserTest extends CRSPa
public void testProjectedWithFootUnits() throws FactoryException {
super.testProjectedWithFootUnits();
final CoordinateSystem cs = object.getCoordinateSystem();
- assertEquals(AxisNames.EASTING, cs.getAxis(0).getName().getCode());
- assertEquals(AxisNames.NORTHING, cs.getAxis(1).getName().getCode());
+ assertEquals("name", AxisNames.EASTING, cs.getAxis(0).getName().getCode());
+ assertEquals("name", AxisNames.NORTHING, cs.getAxis(1).getName().getCode());
}
/**
@@ -166,6 +168,20 @@ public class WKTParserTest extends CRSPa
@Test
@Override
@Ignore("Transverse Mercator projection method not yet implemented.")
- public void testProjectedWithImplicitUnits() throws FactoryException {
+ public void testProjectedWithImplicitParameterUnits() throws FactoryException {
+ }
+
+ /**
+ * Completes the GeoAPI tests with a check of axis name and vertical datum type.
+ *
+ * @throws FactoryException if an error occurred during the WKT parsing.
+ */
+ @Test
+ @Override
+ public void testVertical() throws FactoryException {
+ super.testVertical();
+ final CoordinateSystem cs = object.getCoordinateSystem();
+ assertEquals("name", AxisNames.GRAVITY_RELATED_HEIGHT, cs.getAxis(0).getName().getCode());
+ assertEquals("datumType", VerticalDatumType.GEOIDAL, ((VerticalCRS) object).getDatum().getVerticalDatumType());
}
}