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/18 19:15:31 UTC
svn commit: r1686280 [3/4] - in /sis/branches/JDK6: ./
core/sis-feature/src/main/java/org/apache/sis/feature/
core/sis-feature/src/test/java/org/apache/sis/feature/
core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/
core/sis-metadata/src...
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -21,6 +21,7 @@ import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.measure.unit.Unit;
+import javax.measure.unit.UnitFormat;
import javax.measure.quantity.Angle;
import javax.measure.quantity.Length;
import org.opengis.util.FactoryException;
@@ -58,7 +59,7 @@ import static org.apache.sis.util.Argume
*
* @see <a href="http://www.geoapi.org/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Know Text specification</a>
*/
-class MathTransformParser extends Parser {
+class MathTransformParser extends AbstractParser {
/**
* The factory to use for creating math transforms.
*/
@@ -94,7 +95,7 @@ class MathTransformParser extends Parser
* @param mtFactory The factory to use to create {@link MathTransform} objects.
*/
public MathTransformParser(final MathTransformFactory mtFactory) {
- this(Symbols.getDefault(), null, null, mtFactory, null);
+ this(Symbols.getDefault(), null, null, null, mtFactory, null);
}
/**
@@ -103,13 +104,14 @@ class MathTransformParser extends Parser
* @param symbols The set of symbols to use.
* @param numberFormat The number format provided by {@link WKTFormat}, or {@code null} for a default format.
* @param dateFormat The date format provided by {@link WKTFormat}, or {@code null} for a default format.
+ * @param unitFormat The unit format provided by {@link WKTFormat}, or {@code null} for a default format.
* @param mtFactory The factory to use to create {@link MathTransform} objects.
* @param errorLocale The locale for error messages (not for parsing), or {@code null} for the system default.
*/
MathTransformParser(final Symbols symbols, final NumberFormat numberFormat, final DateFormat dateFormat,
- final MathTransformFactory mtFactory, final Locale errorLocale)
+ final UnitFormat unitFormat, final MathTransformFactory mtFactory, final Locale errorLocale)
{
- super(symbols, numberFormat, dateFormat, errorLocale);
+ super(symbols, numberFormat, dateFormat, unitFormat, errorLocale);
this.mtFactory = mtFactory;
ensureNonNull("mtFactory", mtFactory);
}
@@ -137,21 +139,17 @@ class MathTransformParser extends Parser
final MathTransform parseMathTransform(final Element element, final boolean mandatory) throws ParseException {
lastMethod = null;
classification = null;
- String keyword = WKTKeywords.Param_MT;
- final Object child = element.peek();
- if (child instanceof Element) {
- keyword = ((Element) child).keyword;
- if (keyword != null) {
- if (keyword.equalsIgnoreCase(WKTKeywords.Param_MT)) return parseParamMT (element);
- if (keyword.equalsIgnoreCase(WKTKeywords.Concat_MT)) return parseConcatMT (element);
- if (keyword.equalsIgnoreCase(WKTKeywords.Inverse_MT)) return parseInverseMT (element);
- if (keyword.equalsIgnoreCase(WKTKeywords.PassThrough_MT)) return parsePassThroughMT(element);
+ MathTransform tr;
+ if ((tr = parseParamMT (element)) == null &&
+ (tr = parseConcatMT (element)) == null &&
+ (tr = parseInverseMT (element)) == null &&
+ (tr = parsePassThroughMT (element)) == null)
+ {
+ if (mandatory) {
+ throw element.missingOrUnknownComponent(WKTKeywords.Param_MT);
}
}
- if (mandatory) {
- throw element.keywordNotFound(keyword, keyword == WKTKeywords.Param_MT);
- }
- return null;
+ return tr;
}
/**
@@ -168,7 +166,7 @@ class MathTransformParser extends Parser
{
Element param = element;
try {
- while ((param = element.pullOptionalElement(WKTKeywords.Parameter)) != null) {
+ while ((param = element.pullElement(OPTIONAL, WKTKeywords.Parameter)) != null) {
final String name = param.pullString("name");
final ParameterValue<?> parameter = parameters.parameter(name);
final ParameterDescriptor<?> descriptor = parameter.getDescriptor();
@@ -211,8 +209,11 @@ class MathTransformParser extends Parser
* @return The {@code "PARAM_MT"} element as an {@link MathTransform} object.
* @throws ParseException if the {@code "PARAM_MT"} element can not be parsed.
*/
- final MathTransform parseParamMT(final Element parent) throws ParseException {
- final Element element = parent.pullElement(WKTKeywords.Param_MT);
+ private MathTransform parseParamMT(final Element parent) throws ParseException {
+ final Element element = parent.pullElement(FIRST, WKTKeywords.Param_MT);
+ if (element == null) {
+ return null;
+ }
classification = element.pullString("classification");
final ParameterValueGroup parameters;
try {
@@ -250,8 +251,11 @@ class MathTransformParser extends Parser
* @return The {@code "INVERSE_MT"} element as an {@link MathTransform} object.
* @throws ParseException if the {@code "INVERSE_MT"} element can not be parsed.
*/
- final MathTransform parseInverseMT(final Element parent) throws ParseException {
- final Element element = parent.pullElement(WKTKeywords.Inverse_MT);
+ private MathTransform parseInverseMT(final Element parent) throws ParseException {
+ final Element element = parent.pullElement(FIRST, WKTKeywords.Inverse_MT);
+ if (element == null) {
+ return null;
+ }
MathTransform transform = parseMathTransform(element, true);
try {
transform = transform.inverse();
@@ -273,8 +277,11 @@ class MathTransformParser extends Parser
* @return The {@code "PASSTHROUGH_MT"} element as an {@link MathTransform} object.
* @throws ParseException if the {@code "PASSTHROUGH_MT"} element can not be parsed.
*/
- final MathTransform parsePassThroughMT(final Element parent) throws ParseException {
- final Element element = parent.pullElement(WKTKeywords.PassThrough_MT);
+ private MathTransform parsePassThroughMT(final Element parent) throws ParseException {
+ final Element element = parent.pullElement(FIRST, WKTKeywords.PassThrough_MT);
+ if (element == null) {
+ return null;
+ }
final int firstAffectedOrdinate = parent.pullInteger("firstAffectedOrdinate");
final MathTransform transform = parseMathTransform(element, true);
element.close(ignoredElements);
@@ -292,12 +299,16 @@ class MathTransformParser extends Parser
* CONCAT_MT[<math transform> {,<math transform>}*]
* }
*
+ * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
* @param parent The parent element.
* @return The {@code "CONCAT_MT"} element as an {@link MathTransform} object.
* @throws ParseException if the {@code "CONCAT_MT"} element can not be parsed.
*/
- final MathTransform parseConcatMT(final Element parent) throws ParseException {
- final Element element = parent.pullElement(WKTKeywords.Concat_MT);
+ private MathTransform parseConcatMT(final Element parent) throws ParseException {
+ final Element element = parent.pullElement(FIRST, WKTKeywords.Concat_MT);
+ if (element == null) {
+ return null;
+ }
MathTransform transform = parseMathTransform(element, true);
MathTransform optionalTransform;
while ((optionalTransform = parseMathTransform(element, false)) != null) {
@@ -313,7 +324,7 @@ class MathTransformParser extends Parser
/**
* Returns the operation method for the last math transform parsed. This is used by
- * {@link Parser} in order to built {@link org.opengis.referencing.crs.DerivedCRS}.
+ * {@link GeodeticObjectParser} in order to built {@link org.opengis.referencing.crs.DerivedCRS}.
*/
final OperationMethod getOperationMethod() {
if (lastMethod == null) {
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -21,6 +21,8 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.Map;
import java.util.HashMap;
+import java.util.Collections;
+import java.util.List;
import java.io.IOException;
import java.text.Format;
import java.text.NumberFormat;
@@ -31,6 +33,7 @@ import java.text.ParseException;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import org.opengis.util.Factory;
+import org.opengis.util.InternationalString;
import org.opengis.metadata.citation.Citation;
import org.opengis.referencing.IdentifiedObject;
import org.apache.sis.io.CompoundFormat;
@@ -76,9 +79,15 @@ import org.apache.sis.util.resources.Err
* PROJECTION[</code> <i>…etc…</i> <code>]]");</code></blockquote>
* </div>
*
- * <div class="section">Thread safety</div>
- * {@code WKTFormat}s are not synchronized. It is recommended to create separated format instances for each thread.
- * If multiple threads access a {@code WKTFormat} concurrently, it must be synchronized externally.
+ * <div class="section">Limitations</div>
+ * <ul>
+ * <li>Instances of this class are not synchronized for multi-threading.
+ * It is recommended to create separated format instances for each thread.
+ * If multiple threads access a {@code WKTFormat} concurrently, it must be synchronized externally.</li>
+ * <li>Serialized objects of this class are not guaranteed to be compatible with future Apache SIS releases.
+ * Serialization support is appropriate for short term storage or RMI between applications running the
+ * same version of Apache SIS.</li>
+ * </ul>
*
* @author Martin Desruisseaux (Geomatys)
* @author Rémi Eve (IRD)
@@ -182,7 +191,7 @@ public class WKTFormat extends CompoundF
/**
* The parser. Will be created when first needed.
*/
- private transient Parser parser;
+ private transient AbstractParser parser;
/**
* The factories needed by the parser. Will be created when first needed.
@@ -190,9 +199,15 @@ public class WKTFormat extends CompoundF
private transient Map<Class<?>,Factory> factories;
/**
+ * The warning produced by the last parsing or formatting operation, or {@code null} if none.
+ *
+ * @see #getWarnings()
+ */
+ private transient Warnings warnings;
+
+ /**
* Creates a format for the given locale and timezone. The given locale will be used for
- * {@link org.opengis.util.InternationalString} localization; this is <strong>not</strong>
- * the locale for number format.
+ * {@link InternationalString} localization; this is <strong>not</strong> the locale for number format.
*
* @param locale The locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
* @param timezone The timezone, or {@code null} for UTC.
@@ -482,16 +497,26 @@ public class WKTFormat extends CompoundF
*/
@Override
public Object parse(final CharSequence text, final ParsePosition pos) throws ParseException {
+ warnings = null;
+ ArgumentChecks.ensureNonNull("text", text);
+ ArgumentChecks.ensureNonNull("pos", pos);
+ AbstractParser parser = this.parser;
if (parser == null) {
if (factories == null) {
factories = new HashMap<Class<?>,Factory>();
}
- parser = new GeodeticObjectParser(symbols,
+ this.parser = parser = new GeodeticObjectParser(symbols,
(NumberFormat) getFormat(Number.class),
(DateFormat) getFormat(Date.class),
- convention, false, getLocale(), factories);
+ (UnitFormat) getFormat(Unit.class),
+ convention, getLocale(), factories);
+ }
+ Object object = null;
+ try {
+ return object = parser.parseObject(text.toString(), pos);
+ } finally {
+ warnings = parser.getAndClearWarnings(object);
}
- return parser.parseObject(text.toString(), pos);
}
/**
@@ -507,10 +532,11 @@ public class WKTFormat extends CompoundF
* @param toAppendTo Where the text is to be appended.
* @throws IOException If an error occurred while writing to {@code toAppendTo}.
*
- * @see #getWarning()
+ * @see FormattableObject#toWKT()
*/
@Override
public void format(final Object object, final Appendable toAppendTo) throws IOException {
+ warnings = null;
ArgumentChecks.ensureNonNull("object", object);
ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
/*
@@ -538,13 +564,20 @@ public class WKTFormat extends CompoundF
this.formatter = formatter;
}
final boolean valid;
+ final InternationalString warning;
try {
formatter.setBuffer(buffer);
valid = formatter.appendElement(object) || formatter.appendValue(object);
} finally {
+ warning = formatter.getErrorMessage(); // Must be saved before formatter.clear() is invoked.
formatter.setBuffer(null);
formatter.clear();
}
+ if (warning != null) {
+ warnings = new Warnings(getLocale(), (byte) 0, Collections.<String, List<String>>emptyMap());
+ warnings.add(warning, formatter.getErrorCause(), null);
+ warnings.setRoot(object);
+ }
if (!valid) {
throw new ClassCastException(Errors.format(
Errors.Keys.IllegalArgumentClass_2, "object", object.getClass()));
@@ -579,13 +612,34 @@ public class WKTFormat extends CompoundF
}
/**
- * If a warning occurred during the last WKT {@linkplain #format(Object, Appendable) formatting}, returns
- * the warning. Otherwise returns {@code null}. The warning is cleared every time a new object is formatted.
+ * If warnings occurred during the last WKT {@linkplain #parse(CharSequence, ParsePosition) parsing} or
+ * {@linkplain #format(Object, Appendable) formatting}, returns the warnings. Otherwise returns {@code null}.
+ * The warnings are cleared every time a new object is parsed or formatted.
+ *
+ * @return The warnings of the last parsing of formatting operation, or {@code null} if none.
+ *
+ * @since 0.6
+ */
+ public Warnings getWarnings() {
+ final Warnings w = warnings;
+ if (w != null) {
+ w.publish();
+ }
+ return w;
+ }
+
+ /**
+ * If a warning occurred during the last WKT {@linkplain #parse(CharSequence, ParsePosition) parsing} or
+ * {@linkplain #format(Object, Appendable) formatting}, returns the warning. Otherwise returns {@code null}.
+ * The warning is cleared every time a new object is parsed or formatted.
*
* @return The last warning, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #getWarnings()}.
*/
+ @Deprecated
public String getWarning() {
- return (formatter != null) ? formatter.getErrorMessage() : null;
+ return (warnings != null) ? warnings.toString() : null;
}
/**
@@ -597,6 +651,8 @@ public class WKTFormat extends CompoundF
public WKTFormat clone() {
final WKTFormat clone = (WKTFormat) super.clone();
clone.formatter = null; // Do not share the formatter.
+ clone.parser = null;
+ clone.warnings = null;
return clone;
}
}
Copied: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java (from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java?p2=sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java&p1=sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java&r1=1686269&r2=1686280&rev=1686280&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -36,6 +36,9 @@ import org.apache.sis.util.resources.Err
import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.resources.Vocabulary;
+// Branch-specific imports
+import org.apache.sis.internal.jdk7.JDK7;
+
/**
* Warnings that occurred during a <cite>Well Known Text</cite> (WKT) parsing or formatting.
@@ -184,13 +187,13 @@ public final class Warnings implements L
final void add(final InternationalString message, final Exception cause, final String[] source) {
assert (message != null) || (cause != null);
if (messages == null) {
- messages = new ArrayList<>(4); // We expect few items.
+ messages = new ArrayList<Object>(4); // We expect few items.
}
messages.add(message);
messages.add(cause);
if (cause != null) {
if (exceptionSources == null) {
- exceptionSources = new LinkedHashMap<>(4); // We expect few items.
+ exceptionSources = new LinkedHashMap<Exception, String[]>(4); // We expect few items.
}
exceptionSources.put(cause, source);
}
@@ -204,7 +207,7 @@ public final class Warnings implements L
if (!published) {
ignoredElements = ignoredElements.isEmpty()
? Collections.<String, List<String>>emptyMap()
- : new LinkedHashMap<>(ignoredElements);
+ : new LinkedHashMap<String, List<String>>(ignoredElements);
published = true;
}
}
@@ -304,7 +307,7 @@ public final class Warnings implements L
*/
public String toString(final Locale locale) {
final StringBuilder buffer = new StringBuilder(250);
- final String lineSeparator = System.lineSeparator();
+ final String lineSeparator = JDK7.lineSeparator();
final Messages resources = Messages.getResources(locale);
buffer.append(resources.getString(Messages.Keys.IncompleteFormattingOrParsing_2, operation, root))
.append(lineSeparator);
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -17,21 +17,30 @@
/**
* <cite>Well Known Text</cite> (WKT) parsing and formatting.
- * This package implements the services provided by the {@link org.apache.sis.referencing.CRS#parseWKT(String)}
- * and {@link org.opengis.referencing.IdentifiedObject#toWKT()} convenience methods, with more control.
+ * This package implements the services provided by various convenience methods:
+ *
+ * <ul>
+ * <li>{@link org.apache.sis.referencing.CRS#fromWKT(String)} (SIS parsing static method)</li>
+ * <li>{@link org.opengis.referencing.crs.CRSFactory#createFromWKT(String)} (GeoAPI parsing method)</li>
+ * <li>{@link org.opengis.referencing.operation.MathTransformFactory#createFromWKT(String)} (GeoAPI parsing method)</li>
+ * <li>{@link org.opengis.referencing.IdentifiedObject#toWKT()} (GeoAPI formatting method)</li>
+ * </ul>
+ *
+ * However the {@link org.apache.sis.io.wkt.WKTFormat} class provided in this package gives more control.
* For example this package allows to:
*
* <ul>
- * <li>Format projection and parameters using the names of a chosen authority. For example the
- * <cite>"Mercator (variant A)"</cite> projection is named {@code "Mercator_1SP"} by OGC 01-009
- * and {@code "CT_Mercator"} by GeoTIFF.</li>
- * <li>Format the elements with curly brackets instead than square ones.
+ * <li>Format projection and parameters using the names of a chosen authority.
+ * For example the <cite>"Mercator (variant A)"</cite> projection is named
+ * {@code "Mercator_1SP"} by OGC 01-009 and {@code "CT_Mercator"} by GeoTIFF.</li>
+ * <li>Format the elements with different quote characters or brackets style.
* For example both {@code ID["EPSG",4326]} and {@code ID("EPSG",4326)} are legal WKT.</li>
* <li>Format with a different indentation or format the whole WKT on a single line.</li>
* <li>Apply syntactic coloring on terminal supporting <cite>ANSI escape codes</cite>
* (a.k.a. ECMA-48, ISO/IEC 6429 and X3.64).</li>
- * <li>Ignore the {@code AXIS[…]} elements at parsing time. This approach can be used as a way to force
- * the (<var>longitude</var>, <var>latitude</var>) axes order.</li>
+ * <li>Alter the parsing in a way compatible with non-standard (but commonly used) WKT.
+ * For example some others softwares ignore the {@code AXIS[…]} elements at parsing time.</li>
+ * <li>Report warnings that occurred during parsing or formatting.</li>
* </ul>
*
* <div class="section">Referencing WKT</div>
@@ -56,11 +65,25 @@
* provide their own, limited, WKT parsing and formatting services for the {@code BOX} and {@code POINT} elements.
* A description for this WKT format can be found on <a href="http://en.wikipedia.org/wiki/Well-known_text">Wikipedia</a>.
*
+ * <div class="section">Where to find WKT examples</div>
+ * An excellent source of well-formed WKT is the online <cite>EPSG Geodetic Parameter Registry</cite>.
+ * The WKT of many Coordinate Reference System object can be viewed using the pattern below
+ * (replace {@code 3395} by the EPSG code of the desired CRS):
+ *
+ * <blockquote><b>Example</b>: <cite>"WGS 84 / World Mercator"</cite>:
+ * <a href="http://epsg-registry.org/export.htm?wkt=urn:ogc:def:crs:EPSG::3395">http://epsg-registry.org/export.htm?wkt=urn:ogc:def:crs:EPSG::3395</a>
+ * </blockquote>
+ *
+ * Readers should be aware that some popular other sources of WKT are actually invalid,
+ * since many of them do not comply with EPSG definitions (especially on axis order).
+ * The above-cited EPSG registry is <strong>the</strong> authoritative source
+ * of CRS definitions in the EPSG namespace.
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Rémi Eve (IRD)
* @author Rueben Schulz (UBC)
* @since 0.4
- * @version 0.4
+ * @version 0.6
* @module
*
* @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlRoot
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.util.InternationalString;
+import org.apache.sis.internal.util.Citations;
/**
@@ -76,7 +77,7 @@ import org.opengis.util.InternationalStr
* @author Touraïvane (IRD)
* @author Cédric Briançon (Geomatys)
* @since 0.3
- * @version 0.5
+ * @version 0.6
* @module
*
* @see ImmutableIdentifier
@@ -139,15 +140,32 @@ public class DefaultIdentifier extends I
/**
* Creates an identifier initialized to the given authority and code.
+ * This constructor automatically initializes the {@linkplain #getCodeSpace() code space} to a value inferred
+ * from the given {@code authority}, if a suitable value can be found. This constructor proceeds by searching
+ * for the first suitable property in the following list:
+ *
+ * <ol>
+ * <li>The value of {@link org.apache.sis.xml.IdentifierSpace#getName()}.</li>
+ * <li>A {@linkplain org.apache.sis.metadata.iso.citation.DefaultCitation#getIdentifiers() citation identifier}
+ * which is a valid
+ * {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence) unicode identifier}.</li>
+ * <li>Only if the citation has no identifier, a citation title or
+ * {@linkplain org.apache.sis.metadata.iso.citation.DefaultCitation#getAlternateTitles() alternate title}
+ * which is a valid
+ * {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence) unicode identifier}.</li>
+ * </ol>
*
* @param authority The organization or party responsible for definition and maintenance
* of the code, or {@code null} if none.
* @param code The alphanumeric value identifying an instance in the namespace,
* or {@code null} if none.
+ *
+ * @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
*/
public DefaultIdentifier(final Citation authority, final String code) {
this.authority = authority;
this.code = code;
+ codeSpace = Citations.getCodeSpace(authority);
}
/**
@@ -197,6 +215,12 @@ public class DefaultIdentifier extends I
/**
* Returns the alphanumeric value identifying an instance in the namespace.
+ * The code is optionally from a controlled list or pattern.
+ *
+ * <div class="note"><b>Example:</b> {@code "4326"}.</div>
+ *
+ * The code is mandatory according ISO specification, but this {@code DefaultIdentifier}
+ * implementation does not enforce this restriction.
*
* @return Value identifying an instance in the namespace.
*/
@@ -218,6 +242,9 @@ public class DefaultIdentifier extends I
/**
* Returns the identifier or namespace in which the code is valid.
+ * This is often the {@linkplain #getAuthority() authority}'s abbreviation, but not necessarily.
+ *
+ * <div class="note"><b>Example:</b> {@code "EPSG"}.</div>
*
* @return The identifier code space, or {@code null} if none.
*
@@ -246,6 +273,8 @@ public class DefaultIdentifier extends I
* uses versions. When appropriate, the edition is identified by the effective date,
* coded using ISO 8601 date format.
*
+ * <div class="note"><b>Example:</b> the version of the underlying EPSG database.</div>
+ *
* @return The version, or {@code null} if not available.
*/
@Override
@@ -266,6 +295,8 @@ public class DefaultIdentifier extends I
/**
* Returns the natural language description of the meaning of the code value.
*
+ * <div class="note"><b>Example:</b> "World Geodetic System 1984".</div>
+ *
* @return The natural language description, or {@code null} if none.
*
* @since 0.5
@@ -288,8 +319,9 @@ public class DefaultIdentifier extends I
}
/**
- * Organization or party responsible for definition and maintenance of the
- * {@linkplain #getCode() code}.
+ * Organization or party responsible for definition and maintenance of the {@linkplain #getCode() code}.
+ * The organization's abbreviation is often the same than this identifier {@linkplain #getCodeSpace() code space},
+ * but not necessarily.
*
* @return The authority, or {@code null} if not available.
*/
@@ -300,8 +332,7 @@ public class DefaultIdentifier extends I
}
/**
- * Sets the organization or party responsible for definition and maintenance of the
- * {@linkplain #getCode() code}.
+ * Sets the organization or party responsible for definition and maintenance of the {@linkplain #getCode() code}.
*
* @param newValue The new authority.
*/
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -19,14 +19,26 @@ package org.apache.sis.metadata.iso.exte
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.InternationalString;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.extent.GeographicDescription;
import org.apache.sis.metadata.iso.DefaultIdentifier;
+import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.iso.Types;
/**
* Description of the geographic area using identifiers.
+ * The area is given by a {@linkplain #getGeographicIdentifier() geographic identifier},
+ * which may be a code in the codespace of some authority (for example an EPSG code).
+ * In addition, the geographic identifier can optionally have a
+ * {@linkplain DefaultIdentifier#getDescription() natural language description}.
+ *
+ * <div class="note"><b>Example:</b>
+ * a geographic area may be identified by the {@code 1731} code in the {@code EPSG} codespace.
+ * The natural language description for {@code EPSG:1731} can be <cite>“France – mainland north of 48.15°N”</cite>.
+ * </div>
*
* <p><b>Limitations:</b></p>
* <ul>
@@ -41,7 +53,7 @@ import org.apache.sis.metadata.iso.Defau
* @author Touraïvane (IRD)
* @author Cédric Briançon (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.6
* @module
*/
@XmlType(name = "EX_GeographicDescription_Type")
@@ -64,16 +76,57 @@ public class DefaultGeographicDescriptio
}
/**
- * Creates an inclusive geographic description initialized to the specified value.
+ * Creates an inclusive geographic description initialized to the given identifier.
* This constructor sets the {@linkplain #getInclusion() inclusion} property to {@code true}.
*
+ * <p><b>Usage note:</b> if the description is a sentence like “Netherlands offshore”, it may not be suitable
+ * for the {@code code} argument. Callers may consider using the {@linkplain DefaultIdentifier#getDescription()
+ * identifier description} as an alternative and keep the code for a more compact string (often a primary key).</p>
+ *
+ * <div class="note"><b>Example:</b>
+ * <code>new DefaultGeographicDescription({@link org.apache.sis.metadata.iso.citation.Citations#EPSG}, "1731")</code>
+ * can stand for <cite>“France – mainland north of 48.15°N”</cite>.</div>
+ *
* @param authority The authority of the identifier code, or {@code null} if none.
* @param code The identifier code used to represent a geographic area, or {@code null} if none.
*/
public DefaultGeographicDescription(final Citation authority, final String code) {
super(true);
if (authority != null || code != null) {
- this.geographicIdentifier = new DefaultIdentifier(authority, code);
+ geographicIdentifier = new DefaultIdentifier(authority, code);
+ }
+ }
+
+ /**
+ * Creates an inclusive geographic description initialized to the given natural language description.
+ * This constructor sets the {@linkplain #getInclusion() inclusion} property to {@code true} and the
+ * {@linkplain DefaultIdentifier#getCode() identifier code} to one of the following choices:
+ *
+ * <ul>
+ * <li>the given {@code description} string if it is a valid
+ * {@linkplain CharSequences#isUnicodeIdentifier(CharSequence) Unicode identifier},</li>
+ * <li>otherwise an {@linkplain CharSequences#camelCaseToAcronym(CharSequence) acronym}
+ * of the given {@code description}.</li>
+ * </ul>
+ *
+ * @param description The natural language description of the meaning of the code value, or {@code null} if none.
+ *
+ * @since 0.6
+ */
+ public DefaultGeographicDescription(final CharSequence description) {
+ super(true);
+ if (description != null) {
+ final DefaultIdentifier id = new DefaultIdentifier();
+ if (CharSequences.isUnicodeIdentifier(description)) {
+ id.setCode(description.toString());
+ if (description instanceof InternationalString) {
+ id.setDescription((InternationalString) description);
+ }
+ } else {
+ id.setCode(CharSequences.camelCaseToAcronym(description).toString());
+ id.setDescription(Types.toInternationalString(description));
+ }
+ geographicIdentifier = id;
}
}
@@ -121,6 +174,14 @@ public class DefaultGeographicDescriptio
/**
* Returns the identifier used to represent a geographic area.
*
+ * <div class="note"><b>Example:</b>
+ * an identifier with the following properties:
+ * <ul>
+ * <li>the {@code "EPSG"} code space,</li>
+ * <li>the {@code "1731"} code, and</li>
+ * <li>the <cite>“France – mainland north of 48.15°N”</cite> description.</li>
+ * </ul></div>
+ *
* @return The identifier used to represent a geographic area, or {@code null}.
*/
@Override
Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -28,6 +28,8 @@ import org.opengis.metadata.extent.Geogr
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.referencing.datum.VerticalDatumType;
import org.apache.sis.measure.Longitude;
import org.apache.sis.measure.MeasurementRange;
import org.apache.sis.measure.Range;
@@ -54,7 +56,7 @@ import static org.apache.sis.internal.me
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.6
* @module
*
* @see org.apache.sis.geometry.Envelopes
@@ -132,32 +134,60 @@ public final class Extents extends Stati
}
/**
- * Returns the union of all vertical ranges found in the given extent, or {@code null} if none.
- * Depths have negative height values: if the {@linkplain CoordinateSystemAxis#getDirection() axis direction}
+ * Returns the union of chosen vertical ranges found in the given extent, or {@code null} if none.
+ * This method gives preference to heights above the Mean Sea Level when possible.
+ * Depths have negative height values: if the
+ * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getDirection() axis direction}
* is toward down, then this method reverses the sign of minimum and maximum values.
*
* <div class="section">Multi-occurrences</div>
* If the given {@code Extent} object contains more than one vertical extent, then this method
- * performs the following choices:
+ * performs a choice based on the vertical datum and the unit of measurement:
*
* <ul>
- * <li>If no range specify a unit of measurement, return the first range and ignore all others.</li>
- * <li>Otherwise take the first range having a unit of measurement. Then:<ul>
- * <li>All other ranges having an incompatible unit of measurement will be ignored.</li>
- * <li>All other ranges having a compatible unit of measurement will be converted to
- * the unit of the first retained range, and their union will be computed.</li>
- * </ul></li>
+ * <li><p><b>Choice based on vertical datum</b><br>
+ * Only the extents associated (indirectly, through their CRS) to the same non-null {@link VerticalDatumType}
+ * will be taken in account. If all datum types are null, then this method conservatively uses only the first
+ * vertical extent. Otherwise the datum type used for filtering the vertical extents is:</p>
+ *
+ * <ul>
+ * <li>{@link VerticalDatumType#GEOIDAL} or {@link VerticalDatumType#DEPTH DEPTH} if at least one extent
+ * uses those datum types. For this method, {@code DEPTH} is considered as equivalent to {@code GEOIDAL}
+ * except for the axis direction.</li>
+ * <li>Otherwise, the first non-null datum type found in iteration order.</li>
+ * </ul>
+ *
+ * <div class="note"><b>Rational:</b> like {@linkplain #getGeographicBoundingBox(Extent) geographic bounding box},
+ * the vertical range is an approximative information; the range returned by this method does not carry any
+ * information about the vertical CRS and this method does not attempt to perform coordinate transformation.
+ * But this method is more useful if the returned ranges are close to a frequently used surface, like the
+ * Mean Sea Level. The same simplification is applied in the
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#31">{@code VerticalExtent} element of
+ * Well Known Text (WKT) format</a>, which specifies that <cite>“Vertical extent is an approximate description
+ * of location; heights are relative to an unspecified mean sea level.”</cite></div></li>
+ *
+ * <li><p><b>Choice based on units of measurement</b><br>
+ * If, after the choice based on the vertical datum described above, there is still more than one vertical
+ * extent to consider, then the next criterion checks for the units of measurement.</p>
+ * <ul>
+ * <li>If no range specify a unit of measurement, return the first range and ignore all others.</li>
+ * <li>Otherwise take the first range having a unit of measurement. Then:<ul>
+ * <li>All other ranges having an incompatible unit of measurement will be ignored.</li>
+ * <li>All other ranges having a compatible unit of measurement will be converted to
+ * the unit of the first retained range, and their union will be computed.</li>
+ * </ul></li>
+ * </ul>
+ *
+ * <div class="note"><b>Example:</b>
+ * Heights or depths are often measured using some pressure units, for example hectopascals (hPa).
+ * An {@code Extent} could contain two vertical elements: one with the height measurements in hPa,
+ * and the other element with heights transformed to metres using an empirical formula.
+ * In such case this method will select the first vertical element on the assumption that it is
+ * the "main" one that the metadata producer intended to show. Next, this method will search for
+ * other vertical elements using pressure unit. In our example there is none, but if such elements
+ * were found, this method would compute their union.</div></li>
* </ul>
*
- * <div class="note"><b>Example:</b>
- * Heights or depths are often measured using some pressure units, for example hectopascals (hPa).
- * An {@code Extent} could contain two vertical elements: one with the height measurements in hPa,
- * and the other element with heights transformed to metres using an empirical formula.
- * In such case this method will select the first vertical element on the assumption that it is
- * the "main" one that the metadata producer intended to show. Next, this method will search for
- * other vertical elements using pressure unit. In our example there is none, but if such elements
- * were found, this method would compute their union.</div>
- *
* @param extent The extent to convert to a vertical measurement range, or {@code null}.
* @return A vertical measurement range created from the given extent, or {@code null} if none.
*
@@ -165,13 +195,22 @@ public final class Extents extends Stati
*/
public static MeasurementRange<Double> getVerticalRange(final Extent extent) {
MeasurementRange<Double> range = null;
+ VerticalDatumType selectedType = null;
if (extent != null) {
for (final VerticalExtent element : extent.getVerticalElements()) {
double min = element.getMinimumValue();
double max = element.getMaximumValue();
final VerticalCRS crs = element.getVerticalCRS();
+ VerticalDatumType type = null;
Unit<?> unit = null;
if (crs != null) {
+ final VerticalDatum datum = crs.getDatum();
+ if (datum != null) {
+ type = datum.getVerticalDatumType();
+ if (VerticalDatumType.DEPTH.equals(type)) {
+ type = VerticalDatumType.GEOIDAL;
+ }
+ }
final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(0);
unit = axis.getUnit();
if (AxisDirection.DOWN.equals(axis.getDirection())) {
@@ -182,27 +221,39 @@ public final class Extents extends Stati
}
if (range != null) {
/*
- * If the new range does not specify any unit, then we do not know how to convert
- * the values before to perform the union operation. Conservatively do nothing.
+ * If the new range does not specify any datum type or unit, then we do not know how to
+ * convert the values before to perform the union operation. Conservatively do nothing.
*/
- if (unit == null) {
+ if (type == null || unit == null) {
continue;
}
/*
- * If previous range did not specify any unit, then unconditionally replace it by
- * the new range since it provides more information. If both ranges specify units,
- * then we will compute the union if we can, or ignore the new range otherwise.
+ * If the new range is not measured relative to the same kind of surface than the previous range,
+ * then we do not know how to combine those ranges. Do nothing, unless the new range is a Mean Sea
+ * Level Height in which case we forget all previous ranges and use the new one instead.
*/
- final Unit<?> previous = range.unit();
- if (previous != null) {
- if (previous.isCompatible(unit)) {
- range = (MeasurementRange<Double>) range.union(
- MeasurementRange.create(min, true, max, true, unit));
+ if (!type.equals(selectedType)) {
+ if (!type.equals(VerticalDatumType.GEOIDAL)) {
+ continue;
+ }
+ } else if (selectedType != null) {
+ /*
+ * If previous range did not specify any unit, then unconditionally replace it by
+ * the new range since it provides more information. If both ranges specify units,
+ * then we will compute the union if we can, or ignore the new range otherwise.
+ */
+ final Unit<?> previous = range.unit();
+ if (previous != null) {
+ if (previous.isCompatible(unit)) {
+ range = (MeasurementRange<Double>) range.union(
+ MeasurementRange.create(min, true, max, true, unit));
+ }
+ continue;
}
- continue;
}
}
range = MeasurementRange.create(min, true, max, true, unit);
+ selectedType = type;
}
}
return range;
Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -40,7 +40,7 @@ public final strictfp class ElementTest
/**
* A dummy parser to be given to the {@link Element} constructor.
*/
- private final Parser parser = new Parser(Symbols.SQUARE_BRACKETS, null, null, Locale.ENGLISH) {
+ private final AbstractParser parser = new AbstractParser(Symbols.SQUARE_BRACKETS, null, null, null, Locale.ENGLISH) {
@Override Object parseObject(Element element) throws ParseException {
throw new UnsupportedOperationException();
}
@@ -223,7 +223,7 @@ public final strictfp class ElementTest
Element element = parse("TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17T00:00:00.0Z]]");
assertEquals("keyword", "TimeDatum", element.keyword);
assertEquals("name", "Modified Julian", element.pullString("name"));
- Element inner = element.pullElement("TimeOrigin");
+ Element inner = element.pullElement(AbstractParser.MANDATORY, "TimeOrigin");
assertEquals("keyword", "TimeOrigin", inner.keyword);
assertEquals("date", TestUtilities.date("1858-11-17 00:00:00"), inner.pullDate("date"));
inner.close(null);
Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -16,13 +16,20 @@
*/
package org.apache.sis.metadata.iso.extent;
+import java.util.List;
import java.util.Arrays;
+import java.util.Collections;
import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+import javax.measure.converter.UnitConverter;
+import javax.measure.converter.ConversionException;
import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.apache.sis.measure.Units;
import org.apache.sis.measure.MeasurementRange;
import org.apache.sis.test.mock.VerticalCRSMock;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
+import org.apache.sis.test.TestUtilities;
import org.junit.Test;
import static org.apache.sis.internal.metadata.ReferencingServices.NAUTICAL_MILE;
@@ -34,7 +41,7 @@ import static org.junit.Assert.*;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
- * @version 0.4
+ * @version 0.6
* @module
*/
@DependsOn(DefaultGeographicBoundingBoxTest.class)
@@ -46,22 +53,41 @@ public final strictfp class ExtentsTest
/**
* Tests {@link Extents#getVerticalRange(Extent)}.
+ *
+ * @throws ConversionException should never happen in this test.
*/
@Test
- public void testGetVerticalRange() {
- final DefaultExtent extent = new DefaultExtent();
- extent.setVerticalElements(Arrays.asList(
+ @SuppressWarnings("null")
+ public void testGetVerticalRange() throws ConversionException {
+ final List<DefaultVerticalExtent> extents = Arrays.asList(
new DefaultVerticalExtent( -200, -100, VerticalCRSMock.HEIGHT),
new DefaultVerticalExtent( 150, 300, VerticalCRSMock.DEPTH),
new DefaultVerticalExtent( 0.1, 0.2, VerticalCRSMock.SIGMA_LEVEL),
- new DefaultVerticalExtent( -600, -300, VerticalCRSMock.HEIGHT_ft), // [91.44 182.88] metres
+ new DefaultVerticalExtent( -600, -300, VerticalCRSMock.HEIGHT_ft), // [91.44 … 182.88] metres
new DefaultVerticalExtent(10130, 20260, VerticalCRSMock.BAROMETRIC_HEIGHT)
- ));
+ );
+ Collections.shuffle(extents, TestUtilities.createRandomNumberGenerator());
+ /*
+ * Since we have shuffled the vertical extents in random order, the range that we will
+ * test may be either in metres or in feet depending on which vertical extent is first.
+ * So we need to check which linear unit is first.
+ */
+ Unit<?> unit = null;
+ for (final DefaultVerticalExtent e : extents) {
+ unit = e.getVerticalCRS().getCoordinateSystem().getAxis(0).getUnit();
+ if (Units.isLinear(unit)) break;
+ }
+ final UnitConverter c = unit.getConverterToAny(SI.METRE);
+ /*
+ * The actual test. Arbitrarily compare the heights in metres, converting them if needed.
+ */
+ final DefaultExtent extent = new DefaultExtent();
+ extent.setVerticalElements(extents);
final MeasurementRange<Double> range = Extents.getVerticalRange(extent);
assertNotNull("getVerticalRange", range);
- assertEquals("unit", SI.METRE, range.unit());
- assertEquals("minimum", -300, range.getMinDouble(), 0.001);
- assertEquals("maximum", -91.44, range.getMaxDouble(), 0.001);
+ assertSame ("unit", unit, range.unit());
+ assertEquals ("minimum", -300, c.convert(range.getMinDouble()), 0.001);
+ assertEquals ("maximum", -91.44, c.convert(range.getMaxDouble()), 0.001);
}
/**
Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -36,7 +36,7 @@ import org.opengis.util.InternationalStr
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
- * @version 0.4
+ * @version 0.6
* @module
*/
@SuppressWarnings("serial")
@@ -47,31 +47,36 @@ public final strictfp class VerticalCRSM
* Height in metres.
*/
public static final VerticalCRS HEIGHT = new VerticalCRSMock("Height",
- Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true);
+ VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true);
/**
* Height in feet.
*/
public static final VerticalCRS HEIGHT_ft = new VerticalCRSMock("Height",
- Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, NonSI.FOOT, true);
+ VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, NonSI.FOOT, true);
/**
* Height estimated from hPa.
*/
public static final VerticalCRS BAROMETRIC_HEIGHT = new VerticalCRSMock("Barometric height",
- 0, Double.POSITIVE_INFINITY, SI.MetricPrefix.HECTO(SI.PASCAL), true);
+ VerticalDatumType.BAROMETRIC, 0, Double.POSITIVE_INFINITY, SI.MetricPrefix.HECTO(SI.PASCAL), true);
/**
* Depth in metres.
*/
public static final VerticalCRS DEPTH = new VerticalCRSMock("Depth",
- 0, Double.POSITIVE_INFINITY, SI.METRE, false);
+ VerticalDatumType.DEPTH, 0, Double.POSITIVE_INFINITY, SI.METRE, false);
/**
* Depth as a fraction of the sea floor depth at the location of the point for which the depth is evaluated.
*/
public static final VerticalCRS SIGMA_LEVEL = new VerticalCRSMock("Sigma level",
- 0, 1, Unit.ONE, false);
+ VerticalDatumType.OTHER_SURFACE, 0, 1, Unit.ONE, false);
+
+ /**
+ * The datum type (geoidal, barometric, etc.).
+ */
+ private final VerticalDatumType type;
/**
* The minimum and maximum values.
@@ -97,10 +102,11 @@ public final strictfp class VerticalCRSM
* @param minimumValue The minium value.
* @param maximumValue The maximum value.
*/
- private VerticalCRSMock(final String name, final double minimumValue, final double maximumValue,
- final Unit<?> unit, final boolean up)
+ private VerticalCRSMock(final String name, VerticalDatumType type,
+ final double minimumValue, final double maximumValue, final Unit<?> unit, final boolean up)
{
super(name);
+ this.type = type;
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
this.unit = unit;
@@ -120,7 +126,7 @@ public final strictfp class VerticalCRSM
@Override public InternationalString getAnchorPoint() {return null;}
@Override public Date getRealizationEpoch() {return null;}
@Override public Extent getDomainOfValidity() {return null;}
- @Override public VerticalDatumType getVerticalDatumType() {return VerticalDatumType.GEOIDAL;}
+ @Override public VerticalDatumType getVerticalDatumType() {return type;}
@Override public VerticalDatum getDatum() {return this;}
@Override public VerticalCS getCoordinateSystem() {return this;}
@Override public int getDimension() {return 1;}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -446,6 +446,18 @@ public final class ServicesForMetadata e
///////////////////////////////////////////////////////////////////////////////////////
/**
+ * Returns a coordinate reference system for heights above the mean seal level.
+ *
+ * @return The "Mean Seal Level (MSL) height" coordinate reference system.
+ *
+ * @since 0.6
+ */
+ @Override
+ public VerticalCRS getMSLH() {
+ return CommonCRS.Vertical.MEAN_SEA_LEVEL.crs();
+ }
+
+ /**
* Returns the Greenwich prime meridian.
*
* @return The Greenwich prime meridian.
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -779,7 +779,9 @@ public class AbstractIdentifiedObject ex
* </ul>
*
* <div class="section">Future evolutions</div>
- * This method implements heuristic rules learned from experience while trying to provide inter-operability
+ * This method implements recommendations from the
+ * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#139">§B.5.2 of WKT 2 specification</a>,
+ * together with heuristic rules learned from experience while trying to provide inter-operability
* with different data producers. Those rules may be adjusted in any future SIS version according experience
* gained while working with more data producers.
*
@@ -787,6 +789,7 @@ public class AbstractIdentifiedObject ex
* @return {@code true} if the primary name of at least one alias matches the specified {@code name}.
*
* @see IdentifiedObjects#isHeuristicMatchForName(IdentifiedObject, String)
+ * @see org.apache.sis.util.Characters.Filter#LETTERS_AND_DIGITS
*/
public boolean isHeuristicMatchForName(final String name) {
return NameToIdentifier.isHeuristicMatchForName(this.name, alias, name);
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -28,6 +28,7 @@ import org.opengis.referencing.cs.Ellips
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.CompoundCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -42,6 +43,7 @@ import org.opengis.metadata.extent.Geogr
import org.apache.sis.internal.util.DefinitionURI;
import org.apache.sis.internal.referencing.AxisDirections;
import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.referencing.cs.DefaultVerticalCS;
import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
import org.apache.sis.referencing.crs.DefaultGeographicCRS;
@@ -82,7 +84,7 @@ import static java.util.Collections.sing
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3
- * @version 0.5
+ * @version 0.6
* @module
*/
public final class CRS extends Static {
@@ -164,7 +166,7 @@ public final class CRS extends Static {
* that CommonCRS is not expected to succeed if the real EPSG factory threw an exception,
* so we will log a message at the warning level in such case.
*/
- CRSAuthorityFactory factory = null; // TODO
+ final CRSAuthorityFactory factory = DefaultFactories.forClass(CRSAuthorityFactory.class);
if (factory != null) try {
return factory.createCoordinateReferenceSystem(value);
} catch (FactoryException failure) {
@@ -177,6 +179,62 @@ public final class CRS extends Static {
}
/**
+ * Creates a Coordinate Reference System object from a <cite>Well Known Text</cite> (WKT).
+ * The default {@linkplain org.apache.sis.io.wkt Apache SIS parser} understands both
+ * version 1 (a.k.a. OGC 01-009) and version 2 (a.k.a. ISO 19162) of the WKT format.
+ *
+ * <div class="note"><b>Example:</b> below is a slightly simplified WKT 2 string for a Mercator projection.
+ * For making this example smaller, some optional {@code UNIT[…]} and {@code ORDER[…]} elements have been omitted.
+ *
+ * {@preformat wkt
+ * ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
+ * BaseGeodCRS["SIRGAS 2000",
+ * Datum["Sistema de Referencia Geocentrico para las Americas 2000",
+ * Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
+ * Conversion["Petrobras Mercator",
+ * Method["Mercator (variant B)", Id["EPSG",9805]],
+ * Parameter["Latitude of 1st standard parallel", -2],
+ * Parameter["Longitude of natural origin", -43],
+ * Parameter["False easting", 5000000],
+ * Parameter["False northing", 10000000]],
+ * CS[cartesian,2],
+ * Axis["easting (E)", east],
+ * Axis["northing (N)", north],
+ * LengthUnit["metre", 1],
+ * Id["EPSG",5641]]
+ * }
+ * </div>
+ *
+ * <div class="section">Usage and performance considerations</div>
+ * This convenience method delegates to
+ * {@link org.apache.sis.referencing.factory.GeodeticObjectFactory#createFromWKT(String)}
+ * using a default factory instance. This is okay for occasional use, but has the following limitations:
+ *
+ * <ul>
+ * <li>Performance may be sub-optimal in a multi-thread environment.</li>
+ * <li>No control on the WKT {@linkplain org.apache.sis.io.wkt.Convention conventions} in use.</li>
+ * <li>No control on the handling of {@linkplain org.apache.sis.io.wkt.Warnings warnings}.</li>
+ * </ul>
+ *
+ * Applications which need to parse a large amount of WKT strings should consider to use
+ * the {@link org.apache.sis.io.wkt.WKTFormat} class instead than this method.
+ *
+ * @param text Coordinate system encoded in Well-Known Text format (version 1 or 2).
+ * @return The parsed Coordinate Reference System.
+ * @throws FactoryException if the given WKT can not be parsed.
+ *
+ * @see org.apache.sis.io.wkt
+ * @see org.apache.sis.geometry.Envelopes#fromWKT(CharSequence)
+ * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
+ *
+ * @since 0.6
+ */
+ public static CoordinateReferenceSystem fromWKT(final String text) throws FactoryException {
+ ArgumentChecks.ensureNonNull("text", text);
+ return DefaultFactories.forBuildin(CRSFactory.class).createFromWKT(text);
+ }
+
+ /**
* Returns the valid geographic area for the given coordinate reference system, or {@code null} if unknown.
* This method explores the {@linkplain CoordinateReferenceSystem#getDomainOfValidity() domain of validity}
* associated with the given CRS. If more than one geographic bounding box is found, then they will be
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -36,6 +36,7 @@ import org.apache.sis.referencing.Identi
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.cs.AbstractCS;
import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.io.wkt.Convention;
import org.apache.sis.io.wkt.Formatter;
import static org.apache.sis.util.Utilities.deepEquals;
@@ -520,10 +521,12 @@ public class AbstractCRS extends Abstrac
formatter.append(toFormattable(cs)); // WKT2 only, since the concept of CoordinateSystem was not explicit in WKT 1.
formatter.indent(+1);
}
- final int dimension = cs.getDimension();
- for (int i=0; i<dimension; i++) {
- formatter.newLine();
- formatter.append(toFormattable(cs.getAxis(i)));
+ if (!isWKT1 || formatter.getConvention() != Convention.WKT1_IGNORE_AXES) {
+ final int dimension = cs.getDimension();
+ for (int i=0; i<dimension; i++) {
+ formatter.newLine();
+ formatter.append(toFormattable(cs.getAxis(i)));
+ }
}
if (!isWKT1) { // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
formatter.newLine();
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -143,8 +143,8 @@ public enum AxesConvention implements Ax
* changes are more difficult to handle by coordinate operation factories.
* </div>
*
- * @see CoordinateSystems#normalize(CoordinateSystem)
* @see org.apache.sis.referencing.CommonCRS#normalizedGeographic()
+ * @see CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)
*/
NORMALIZED {
@Override
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -43,12 +43,12 @@ import org.apache.sis.referencing.datum.
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.referencing.MergedProperties;
import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.metadata.WKTParser;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.util.iso.AbstractFactory;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.io.wkt.Parser;
import org.apache.sis.xml.XML;
@@ -180,14 +180,14 @@ import org.apache.sis.xml.XML;
* @version 0.6
* @module
*/
-public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory {
+public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser {
/**
* The constructor for WKT parsers, fetched when first needed. The WKT parser is defined in the
* same module than this class, so we will hopefully not have security issues. But we have to
* use reflection because the parser class is not yet public (because we do not want to commit
* its API yet).
*/
- private static volatile Constructor<? extends WKTParser> parserConstructor;
+ private static volatile Constructor<? extends Parser> parserConstructor;
/**
* The default properties, or an empty map if none. This map shall not change after construction in
@@ -214,7 +214,7 @@ public class GeodeticObjectFactory exten
* The <cite>Well Known Text</cite> parser for {@code CoordinateReferenceSystem} instances.
* This parser is not thread-safe, so we need to prevent two threads from using the same instance in same time.
*/
- private final AtomicReference<WKTParser> parser;
+ private final AtomicReference<Parser> parser;
/**
* Constructs a factory with no default properties.
@@ -238,7 +238,7 @@ public class GeodeticObjectFactory exten
}
defaultProperties = properties;
pool = new WeakHashSet<IdentifiedObject>(IdentifiedObject.class);
- parser = new AtomicReference<WKTParser>();
+ parser = new AtomicReference<Parser>();
}
/**
@@ -1340,18 +1340,55 @@ public class GeodeticObjectFactory exten
}
/**
- * Creates a coordinate reference system object from a string.
+ * Creates a Coordinate Reference System object from a <cite>Well Known Text</cite> (WKT).
+ * This method understands both version 1 (a.k.a. OGC 01-009) and version 2 (a.k.a. ISO 19162)
+ * of the WKT format.
+ *
+ * <div class="note"><b>Example:</b> below is a slightly simplified WKT 2 string for a Mercator projection.
+ * For making this example smaller, some optional {@code UNIT[…]} and {@code ORDER[…]} elements have been omitted.
+ *
+ * {@preformat wkt
+ * ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
+ * BaseGeodCRS["SIRGAS 2000",
+ * Datum["Sistema de Referencia Geocentrico para las Americas 2000",
+ * Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
+ * Conversion["Petrobras Mercator",
+ * Method["Mercator (variant B)", Id["EPSG",9805]],
+ * Parameter["Latitude of 1st standard parallel", -2],
+ * Parameter["Longitude of natural origin", -43],
+ * Parameter["False easting", 5000000],
+ * Parameter["False northing", 10000000]],
+ * CS[cartesian,2],
+ * Axis["easting (E)", east],
+ * Axis["northing (N)", north],
+ * LengthUnit["metre", 1],
+ * Id["EPSG",5641]]
+ * }
+ * </div>
+ *
+ * <div class="section">Usage and performance considerations</div>
+ * The default implementation uses a shared instance of {@link org.apache.sis.io.wkt.WKTFormat}
+ * with the addition of thread-safety. This is okay for occasional use,
+ * but is sub-optimal if this method is extensively used in a multi-thread environment.
+ * Furthermore this method offers no control on the WKT {@linkplain org.apache.sis.io.wkt.Convention conventions}
+ * in use and on the handling of {@linkplain org.apache.sis.io.wkt.Warnings warnings}.
+ * Applications which need to parse a large amount of WKT strings should consider to use
+ * the {@link org.apache.sis.io.wkt.WKTFormat} class instead than this method.
*
* @param text Coordinate system encoded in Well-Known Text format (version 1 or 2).
* @throws FactoryException if the object creation failed.
+ *
+ * @see org.apache.sis.io.wkt
+ * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
+ * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
*/
@Override
public CoordinateReferenceSystem createFromWKT(final String text) throws FactoryException {
- WKTParser p = parser.getAndSet(null);
+ Parser p = parser.getAndSet(null);
if (p == null) try {
- Constructor<? extends WKTParser> c = parserConstructor;
+ Constructor<? extends Parser> c = parserConstructor;
if (c == null) {
- c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(WKTParser.class)
+ c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(Parser.class)
.getConstructor(Map.class, ObjectFactory.class, MathTransformFactory.class);
c.setAccessible(true);
parserConstructor = c;
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -46,9 +46,9 @@ import org.opengis.referencing.operation
import org.opengis.util.FactoryException;
import org.opengis.util.NoSuchIdentifierException;
+import org.apache.sis.io.wkt.Parser;
import org.apache.sis.internal.util.LazySet;
import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.metadata.WKTParser;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.referencing.ReferencingUtilities;
@@ -155,7 +155,7 @@ import org.apache.sis.internal.jdk8.JDK8
* @see MathTransformProvider
* @see AbstractMathTransform
*/
-public class DefaultMathTransformFactory extends AbstractFactory implements MathTransformFactory {
+public class DefaultMathTransformFactory extends AbstractFactory implements MathTransformFactory, Parser {
/*
* NOTE FOR JAVADOC WRITER:
* The "method" word is ambiguous here, because it can be "Java method" or "coordinate operation method".
@@ -177,7 +177,7 @@ public class DefaultMathTransformFactory
* use reflection because the parser class is not yet public (because we do not want to commit
* its API yet).
*/
- private static volatile Constructor<? extends WKTParser> parserConstructor;
+ private static volatile Constructor<? extends Parser> parserConstructor;
/**
* All methods specified at construction time or found on the classpath.
@@ -221,7 +221,7 @@ public class DefaultMathTransformFactory
* This parser is not thread-safe, so we need to prevent two threads from using
* the same instance in same time.
*/
- private final AtomicReference<WKTParser> parser;
+ private final AtomicReference<Parser> parser;
/**
* Creates a new factory which will discover operation methods with a {@link ServiceLoader}.
@@ -293,7 +293,7 @@ public class DefaultMathTransformFactory
methodsByType = new IdentityHashMap<Class<?>, OperationMethodSet>();
lastMethod = new ThreadLocal<OperationMethod>();
pool = new WeakHashSet<MathTransform>(MathTransform.class);
- parser = new AtomicReference<WKTParser>();
+ parser = new AtomicReference<Parser>();
}
/**
@@ -823,11 +823,11 @@ public class DefaultMathTransformFactory
@Override
public MathTransform createFromWKT(final String text) throws FactoryException {
lastMethod.remove();
- WKTParser p = parser.getAndSet(null);
+ Parser p = parser.getAndSet(null);
if (p == null) try {
- Constructor<? extends WKTParser> c = parserConstructor;
+ Constructor<? extends Parser> c = parserConstructor;
if (c == null) {
- c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(WKTParser.class)
+ c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(Parser.class)
.getConstructor(MathTransformFactory.class);
c.setAccessible(true);
parserConstructor = c;
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -18,6 +18,7 @@ package org.apache.sis.io.wkt;
import java.util.Date;
import java.util.Iterator;
+import java.util.Locale;
import java.text.ParsePosition;
import java.text.ParseException;
import javax.measure.unit.SI;
@@ -68,6 +69,9 @@ public final strictfp class GeodeticObje
/**
* Parses the given text.
*
+ * @param type The expected object type.
+ * @param text The WKT string to parse.
+ * @return The parsed object.
* @throws ParseException if an error occurred during the parsing.
*/
private <T> T parse(final Class<T> type, final String text) throws ParseException {
@@ -78,6 +82,8 @@ public final strictfp class GeodeticObje
final Object obj = parser.parseObject(text, position);
assertEquals("errorIndex", -1, position.getErrorIndex());
assertEquals("index", text.length(), position.getIndex());
+ assertNull("warnings", parser.getAndClearWarnings(obj));
+ assertTrue("ignoredElements", parser.ignoredElements.isEmpty());
assertInstanceOf("GeodeticObjectParser.parseObject", type, obj);
return type.cast(obj);
}
@@ -85,9 +91,9 @@ public final strictfp class GeodeticObje
/**
* Uses a new parser for the given convention.
*/
- private void setConvention(final Convention convention, final boolean isAxisIgnored) {
+ private void setConvention(final Convention convention) {
final GeodeticObjectParser p = parser;
- parser = new GeodeticObjectParser(p.symbols, null, null, convention, isAxisIgnored, p.errorLocale, null);
+ parser = new GeodeticObjectParser(p.symbols, null, null, null, convention, p.errorLocale, null);
}
/**
@@ -343,7 +349,7 @@ public final strictfp class GeodeticObje
* So we allow this interpretation in Convention.WKT1_COMMON_UNITS for compatibility reasons.
*/
wkt = wkt.replace("2.5969213", "2.33722917"); // Convert unit in prime meridian.
- setConvention(Convention.WKT1_COMMON_UNITS, true);
+ setConvention(Convention.WKT1_IGNORE_AXES);
crs = parse(GeographicCRS.class, wkt);
assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
pm = verifyNTF(crs.getDatum(), false);
@@ -397,7 +403,7 @@ public final strictfp class GeodeticObje
wkt = wkt.replace("52.0", "46.8"); // Convert unit in “latitude_of_origin” parameter.
wkt = wkt.replace("600.0", "600000"); // Convert unit in “false_easting” parameter.
wkt = wkt.replace("2200.0", "2200000"); // Convert unit in “false_northing” parameter.
- setConvention(Convention.WKT1_COMMON_UNITS, true);
+ setConvention(Convention.WKT1_IGNORE_AXES);
crs = parse(ProjectedCRS.class, wkt);
assertNameAndIdentifierEqual("NTF (Paris) / Lambert zone II", 0, crs);
verifyProjectedCS(crs.getCoordinateSystem(), SI.KILOMETRE);
@@ -620,4 +626,61 @@ public final strictfp class GeodeticObje
assertEquals("false_easting", 600000.0, param.parameter("false_easting" ).doubleValue(SI .METRE), STRICT);
assertEquals("false_northing", 200000.0, param.parameter("false_northing" ).doubleValue(SI .METRE), STRICT);
}
+
+ /**
+ * Tests the production of a warning messages when the WKT contains unknown elements.
+ *
+ * @throws ParseException if the parsing failed.
+ */
+ @Test
+ @DependsOnMethod("testWithImplicitAxes")
+ public void testWarnings() throws ParseException {
+ parser = new GeodeticObjectParser();
+ final ParsePosition position = new ParsePosition(0);
+ final GeographicCRS crs = (GeographicCRS) parser.parseObject(
+ " GEOGCS[“WGS 84”,\n" +
+ " DATUM[“World Geodetic System 1984”,\n" +
+ " SPHEROID[“WGS84”, 6378137.0, 298.257223563, Ext1[“foo”], Ext2[“bla”]]],\n" +
+ " PRIMEM[“Greenwich”, 0.0, Intruder[“unknown”]],\n" +
+ " UNIT[“degree”, 0.017453292519943295], Intruder[“foo”]]", position);
+
+ verifyGeographicCRS(0, crs);
+ assertEquals("errorIndex", -1, position.getErrorIndex());
+ final Warnings warnings = parser.getAndClearWarnings(crs);
+ assertNotNull("warnings", warnings);
+
+ assertTrue("warnings.getExceptions()",
+ warnings.getExceptions().isEmpty());
+
+ assertEquals("warnings.getRootElement()", "WGS 84",
+ warnings.getRootElement());
+
+ assertArrayEquals("warnings.getUnknownElements()",
+ new String[] {"Intruder", "Ext1", "Ext2"},
+ warnings.getUnknownElements().toArray());
+
+ assertArrayEquals("warnings.getUnknownElementLocations(…)",
+ new String[] {"PRIMEM", "GEOGCS"},
+ warnings.getUnknownElementLocations("Intruder").toArray());
+
+ assertArrayEquals("warnings.getUnknownElementLocations(…)",
+ new String[] {"SPHEROID"},
+ warnings.getUnknownElementLocations("Ext1").toArray());
+
+ assertArrayEquals("warnings.getUnknownElementLocations(…)",
+ new String[] {"SPHEROID"},
+ warnings.getUnknownElementLocations("Ext2").toArray());
+
+ assertMultilinesEquals("Parsing of “WGS 84” done, but some elements were ignored.\n" +
+ " • The text contains unknown elements:\n" +
+ " ‣ “Intruder” in PRIMEM, GEOGCS.\n" +
+ " ‣ “Ext1” in SPHEROID.\n" +
+ " ‣ “Ext2” in SPHEROID.\n", warnings.toString(Locale.US));
+
+ assertMultilinesEquals("La lecture de « WGS 84 » a été faite, mais en ignorant certains éléments.\n" +
+ " • Le texte contient des éléments inconnus :\n" +
+ " ‣ « Intruder » dans PRIMEM, GEOGCS.\n" +
+ " ‣ « Ext1 » dans SPHEROID.\n" +
+ " ‣ « Ext2 » dans SPHEROID.\n", warnings.toString(Locale.FRANCE));
+ }
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -123,7 +123,7 @@ public final strictfp class AbstractRefe
" BBox[51.43, 2.54, 55.77, 6.40],\n" +
" VerticalExtent[-1000, -10, LengthUnit[“metre”, 1]],\n" +
" Id[“EPSG”, 4326, “8.2”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
- " Remarks[“注です。”]]",
+ " Remark[“注です。”]]",
object);
assertWktEquals(Convention.WKT2_SIMPLIFIED,
@@ -133,7 +133,7 @@ public final strictfp class AbstractRefe
" BBox[51.43, 2.54, 55.77, 6.40],\n" +
" VerticalExtent[-1000, -10],\n" +
" Id[“EPSG”, 4326, “8.2”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
- " Remarks[“注です。”]]",
+ " Remark[“注です。”]]",
object);
assertWktEquals(Convention.INTERNAL,
@@ -143,7 +143,7 @@ public final strictfp class AbstractRefe
" BBox[51.43, 2.54, 55.77, 6.40],\n" +
" VerticalExtent[-1000, -10],\n" +
" Id[“EPSG”, 4326, “8.2”],\n" +
- " Remarks[“注です。”]]",
+ " Remark[“注です。”]]",
object);
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -158,7 +158,7 @@ public final strictfp class DefaultCompo
" AXIS[“Gravity-related height”, UP]],\n" +
" TIMECRS[“Time”,\n" +
" TIMEDATUM[“Modified Julian”, TIMEORIGIN[1858-11-17T00:00:00.0Z]],\n" +
- " UNIT[“day”, 86400],\n" +
+ " TIMEUNIT[“day”, 86400],\n" +
" AXIS[“Time”, FUTURE]]]",
HardCodedCRS.GEOID_4D);
}