if ("FOO".equals(keyword))
in this method
* and other methods of this class and subclasses, could be optimized with
* a {@code switch} statement.
*/
@Override
protected Object parse(final Element element) throws ParseException {
final Object key = element.peek();
if (key instanceof Element) {
final String keyword = ((Element) key).keyword.trim().toUpperCase(symbols.locale);
Object r = null;
try {
if ( "AXIS".equals(keyword)) return r=parseAxis (element, SI.METER, true);
if ( "PRIMEM".equals(keyword)) return r=parsePrimem (element, NonSI.DEGREE_ANGLE);
if ( "TOWGS84".equals(keyword)) return r=parseToWGS84 (element);
if ( "SPHEROID".equals(keyword)) return r=parseSpheroid (element);
if ( "VERT_DATUM".equals(keyword)) return r=parseVertDatum (element);
if ("LOCAL_DATUM".equals(keyword)) return r=parseLocalDatum(element);
if ( "DATUM".equals(keyword)) return r=parseDatum (element, DefaultPrimeMeridian.GREENWICH);
r = parseMathTransform(element, false);
if (r != null) {
return r;
}
} finally {
// Work around for simulating post-conditions in Java.
assert isValid(r, keyword) : element;
}
}
return parseCoordinateReferenceSystem(element);
}
/**
* Checks if the parsed object is of the expected type. This is also a way to check
* the consistency of the {@link #TYPES} map.
*/
private static boolean isValid(final Object parsed, final String keyword) {
if (parsed == null) {
// Required in order to avoid AssertionError in place of ParseException.
return true;
}
final Class type = getClassOf(keyword);
return type!=null && type.isInstance(parsed);
}
/**
* Returns the properties to be given to the parsed object. This method is invoked
* automatically by the parser for the {@linkplain Element#isRoot root element} only.
* This method expect on input the properties parsed from the {@code AUTHORITY} element,
* and returns on output the properties to give to the object to be created. The default
* implementation returns the {@code properties} map unchanged. Subclasses may override
* this method in order to add or change properties.
*
* Example: if a subclass want to add automatically an authority code when
* no {@code AUTHORITY} element was explicitly set in the WKT, then it may test for the
* {@link IdentifiedObject#IDENTIFIERS_KEY} key and add automatically an entry if this
* key was missing.
*
* @param properties The properties parsed from the WKT file. Entries can be added, removed
* or modified directly in this map.
* @return The properties to be given to the parsed object. This is usually {@code properties}
* (maybe after modifications), but could also be a new map.
*
* @since 2.3
*/
protected Map
* or even
*
* AUTHORITY["<name>", "<code>"]
*
*
* @param parent The parent element.
* @param name The name of the parent object being parsed.
* @return A properties map with the parent name and the optional autority code.
* @throws ParseException if the "AUTHORITY" can't be parsed.
*/
private Map
* AUTHORITY["<name>", <code>]
*
*
* @param parent The parent element.
* @param unit The contextual unit. Usually {@link SI#METRE} or {@link SI#RADIAN}.
* @return The "UNIT" element as an {@link Unit} object.
* @throws ParseException if the "UNIT" can't be parsed.
*
* @todo Authority code is currently ignored. We may consider to create a subclass of
* {@link Unit} which implements {@link IdentifiedObject} in a future version.
*/
private
* UNIT["
*
* Note: there is no AUTHORITY element for AXIS element in OGC specification. However, we
* accept it anyway in order to make the parser more tolerant to non-100% compliant
* WKT. Note that AXIS is really the only element without such AUTHORITY clause and
* the EPSG database provides authority code for all axis.
*
* @param parent The parent element.
* @param unit The contextual unit. Usually {@link NonSI#DEGREE_ANGLE} or {@link SI#METRE}.
* @param required {@code true} if the axis is mandatory,
* or {@code false} if it is optional.
* @return The "AXIS" element as a {@link CoordinateSystemAxis} object, or {@code null}
* if the axis was not required and there is no axis object.
* @throws ParseException if the "AXIS" element can't be parsed.
*/
private CoordinateSystemAxis parseAxis(final Element parent,
final Unit> unit,
final boolean required)
throws ParseException
{
final Element element;
if (required) {
element = parent.pullElement("AXIS");
} else {
element = parent.pullOptionalElement("AXIS");
if (element == null) {
return null;
}
}
final String name = element.pullString ("name");
final Element orientation = element.pullVoidElement("orientation");
final Map
* AXIS["
*
* @param parent The parent element.
* @param angularUnit The contextual unit.
* @return The "PRIMEM" element as a {@link PrimeMeridian} object.
* @throws ParseException if the "PRIMEM" element can't be parsed.
*/
private PrimeMeridian parsePrimem(final Element parent, final Unit
* PRIMEM["
*
* @param parent The parent element.
* @return The "TOWGS84" element as a {@link BursaWolfParameters} object,
* or {@code null} if no "TOWGS84" has been found.
* @throws ParseException if the "TOWGS84" can't be parsed.
*/
private static BursaWolfParameters parseToWGS84(final Element parent)
throws ParseException
{
final Element element = parent.pullOptionalElement("TOWGS84");
if (element == null) {
return null;
}
final BursaWolfParameters info = new BursaWolfParameters(DefaultGeodeticDatum.WGS84);
info.dx = element.pullDouble("dx");
info.dy = element.pullDouble("dy");
info.dz = element.pullDouble("dz");
if (element.peek() != null) {
info.ex = element.pullDouble("ex");
info.ey = element.pullDouble("ey");
info.ez = element.pullDouble("ez");
info.ppm = element.pullDouble("ppm");
}
element.close();
return info;
}
/**
* Parses a "SPHEROID" element. This element has the following pattern:
*
*
* TOWGS84[
*
* @param parent The parent element.
* @return The "SPHEROID" element as an {@link Ellipsoid} object.
* @throws ParseException if the "SPHEROID" element can't be parsed.
*/
private Ellipsoid parseSpheroid(final Element parent) throws ParseException {
Element element = parent.pullElement("SPHEROID");
String name = element.pullString("name");
double semiMajorAxis = element.pullDouble("semiMajorAxis");
double inverseFlattening = element.pullDouble("inverseFlattening");
Map
* SPHEROID["
*
* @param parent The parent element.
* @param ellipsoid The ellipsoid, or {@code null} if none.
* @param linearUnit The linear unit of the parent PROJCS element, or {@code null}.
* @param angularUnit The angular unit of the parent GEOCS element, or {@code null}.
* @return The "PROJECTION" element as a {@link ParameterValueGroup} object.
* @throws ParseException if the "PROJECTION" element can't be parsed.
*/
private ParameterValueGroup parseProjection(final Element parent,
final Ellipsoid ellipsoid,
final Unit
* PROJECTION["
*
* @param parent The parent element.
* @param meridian the prime meridian.
* @return The "DATUM" element as a {@link GeodeticDatum} object.
* @throws ParseException if the "DATUM" element can't be parsed.
*/
private GeodeticDatum parseDatum(final Element parent,
final PrimeMeridian meridian)
throws ParseException
{
Element element = parent.pullElement("DATUM");
String name = element.pullString("name");
Ellipsoid ellipsoid = parseSpheroid(element);
BursaWolfParameters toWGS84 = parseToWGS84(element); // Optional; may be null.
Map
* DATUM["
*
* @param parent The parent element.
* @return The "VERT_DATUM" element as a {@link VerticalDatum} object.
* @throws ParseException if the "VERT_DATUM" element can't be parsed.
*/
private VerticalDatum parseVertDatum(final Element parent) throws ParseException {
final Element element = parent.pullElement("VERT_DATUM");
final String name = element.pullString ("name");
final int datum = element.pullInteger("datum");
final Map
* VERT_DATUM["
*
* @param parent The parent element.
* @return The "LOCAL_DATUM" element as an {@link EngineeringDatum} object.
* @throws ParseException if the "LOCAL_DATUM" element can't be parsed.
*
* @todo The vertical datum type is currently ignored.
*/
private EngineeringDatum parseLocalDatum(final Element parent) throws ParseException {
final Element element = parent.pullElement("LOCAL_DATUM");
final String name = element.pullString ("name");
final int datum = element.pullInteger("datum");
final Map
* LOCAL_DATUM["
*
* @param parent The parent element.
* @return The "LOCAL_CS" element as an {@link EngineeringCRS} object.
* @throws ParseException if the "LOCAL_CS" element can't be parsed.
*
* @todo The coordinate system used is always a Geotools implementation, since we don't
* know which method to invokes in the {@link CSFactory} (is it a cartesian
* coordinate system? a spherical one? etc.).
*/
private EngineeringCRS parseLocalCS(final Element parent) throws ParseException {
Element element = parent.pullElement("LOCAL_CS");
String name = element.pullString("name");
EngineeringDatum datum = parseLocalDatum(element);
Unit
* LOCAL_CS["
*
* @param parent The parent element.
* @return The "GEOCCS" element as a {@link GeocentricCRS} object.
* @throws ParseException if the "GEOCCS" element can't be parsed.
*/
private GeocentricCRS parseGeoCCS(final Element parent) throws ParseException {
final Element element = parent.pullElement("GEOCCS");
final String name = element.pullString("name");
final Map
* GEOCCS["
*
* @param parent The parent element.
* @return The "VERT_CS" element as a {@link VerticalCRS} object.
* @throws ParseException if the "VERT_CS" element can't be parsed.
*/
private VerticalCRS parseVertCS(final Element parent) throws ParseException {
final Element element = parent.pullElement("VERT_CS");
if (element == null) {
return null;
}
String name = element.pullString("name");
VerticalDatum datum = parseVertDatum(element);
Unit
* VERT_CS["
*
* @param parent The parent element.
* @return The "GEOGCS" element as a {@link GeographicCRS} object.
* @throws ParseException if the "GEOGCS" element can't be parsed.
*/
private GeographicCRS parseGeoGCS(final Element parent) throws ParseException {
Element element = parent.pullElement("GEOGCS");
String name = element.pullString("name");
Map
* GEOGCS["
*
* @param parent The parent element.
* @return The "PROJCS" element as a {@link ProjectedCRS} object.
* @throws ParseException if the "GEOGCS" element can't be parsed.
*/
private ProjectedCRS parseProjCS(final Element parent) throws ParseException {
Element element = parent.pullElement("PROJCS");
String name = element.pullString("name");
Map
* PROJCS["
*
* @param parent The parent element.
* @return The "COMPD_CS" element as a {@link CompoundCRS} object.
* @throws ParseException if the "COMPD_CS" element can't be parsed.
*/
private CompoundCRS parseCompdCS(final Element parent) throws ParseException {
final CoordinateReferenceSystem[] CRS = new CoordinateReferenceSystem[2];
Element element = parent.pullElement("COMPD_CS");
String name = element.pullString("name");
Map
* COMPD_CS["
*
* @param parent The parent element.
* @return The "FITTED_CS" element as a {@link CompoundCRS} object.
* @throws ParseException if the "COMPD_CS" element can't be parsed.
*/
private DerivedCRS parseFittedCS(final Element parent) throws ParseException {
Element element = parent.pullElement("FITTED_CS");
String name = element.pullString("name");
Map
* FITTED_CS["
{@linkplain ProjectedCRS}.class
.
*
* @param type The GeoAPI class of the specified element.
* @return The WKT element name, or {@code null} if unknow.
*
* @since 2.4
*/
public static String getNameOf(final Class> type) {
if (type != null) {
for (final Map.Entry
*
*
* @param args The command line arguments.
*/
public static void main(String[] args) {
final Arguments arguments = new Arguments(args);
final Integer indentation = arguments.getOptionalInteger(Formattable.INDENTATION);
final String authority = arguments.getOptionalString("-authority");
args = arguments.getRemainingArguments(0);
if (indentation != null) {
Formattable.setIndentation(indentation.intValue());
}
final BufferedReader in = new BufferedReader(Arguments.getReader(System.in));
try {
final Parser parser = new Parser();
if (authority != null) {
parser.setAuthority(Citations.fromName(authority));
}
parser.reformat(in, arguments.out, arguments.err);
} catch (Exception exception) {
exception.printStackTrace(arguments.err);
}
// Do not close 'in', since it is the standard input stream.
}
}
*
* -authority
<name> The authority to prefer when choosing WKT entities names.
*
* -indentation
<value> Set the indentation (0 for output on a single line)
*
* -encoding
<code> Set the character encoding
*
* -locale
<language> Set the language for the output (e.g. "fr" for French)