/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.imageio.metadata; import org.geotools.coverage.io.util.Utilities; /** * A BaseCRS mainly represents a SpatialCRS (as an instance, a * GeographicCRS/3DGeographicCRS) which should also be used to defined a * conversion to a DerivedCRS/ProjectedCRS. * * @author Daniele Romagnoli, GeoSolutions * @author Alessio Fabiani, GeoSolutions * * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/coverage-experiment/coverage-core/src/main/java/org/geotools/imageio/metadata/BaseCRS.java $ */ public class BaseCRS extends AbstractCoordinateReferenceSystem { /** * PrimeMeridian element node. It is valid only for Geodetic Datums. */ private IdentifiableMetadataAccessor primeMeridian = null; /** * Ellipsoid element node. It is valid only for Geodetic Datums. */ private IdentifiableMetadataAccessor ellipsoid = null; /** * SemiMajorAxis node. */ private MetadataAccessor semiMajorAxis = null; private MetadataAccessor secondDefiningParameter = null; protected String crsType; protected BaseCRS(SpatioTemporalMetadata metadata, final String crsType, final String parentPath) { super(metadata, parentPath); } /** * This constructor should only be invoked by ProjectedCRS/DerivedCRS to * define the BaseCRS */ protected BaseCRS(final SpatioTemporalMetadata metadata) { super(metadata, SpatioTemporalMetadataFormat.MD_CRS + "/" + SpatioTemporalMetadataFormat.MD_SCRS_BASE_CRS, null); } /** * Sets the {@linkplain Identification identification} of the CoordinateReferenceSystem */ public void setCRS(final Identification identification) { setIdentification(identification); } /** * Returns the {@linkplain Identification identification} */ public Identification getCRS() { return getIdentification(); } /** * <p> * A prime meridian defines the origin from which longitude values are * determined. Note: Default value for prime meridian name is "Greenwich". * When default applies, value for greenwichLongitude shall be 0 (degrees). * </p> * <ul> * <li>Prime meridian Greenwich longitude: Longitude of the prime meridian * measured from the Greenwich meridian, positive eastward. * <ul> * <li>Default value: 0 degrees. </li> * <li>Note: If the value of the prime meridian name is "Greenwich" then * the value of greenwichLongitude shall be 0 degrees.</li> * </ul> * </li> * </ul> */ public void addPrimeMeridian(final String greenwichLon, Identification primeMeridianId) { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM) { primeMeridian = new IdentifiableMetadataAccessor(datum.getChild(), SpatioTemporalMetadataFormat.MD_DTM_GEODETIC_PRIMEMERIDIAN, null, primeMeridianId); primeMeridian.setString(SpatioTemporalMetadataFormat.MD_DTM_GD_PM_GREENWICHLONGITUDE, greenwichLon); } else throw new IllegalArgumentException("Could not set Prime Meridian for non-Geodetic Datum type"); } /** * <p> * An ellipsoid is a geometric figure that can be used to describe the * approximate shape of the earth. In mathematical terms, it is a surface * formed by the rotation of an ellipse about its minor axis. * </p> * <p> * <ul> * <li>semiMajorAxis: Length of the semi-major axis of the ellipsoid.</li> * <li>secondDefiningParameter: Definition of the second parameter that * describes the shape of this ellipsoid. * <ul> * <li>Inverse flattening: Inverse flattening value of the ellipsoid.</li> * <li>Length of semi-minor axis: Length of the semi-minor axis of the * ellipsoid.</li> * <li>�Ellipsoid = Sphere� indicator: The ellipsoid is degenerate and is * actually a sphere. The sphere is completely defined by the semi-major * axis, which is the radius of the sphere. This attribute has the fixed * text value "sphere".</li> * </ul> * </li> * </ul> * </p> */ public void addEllipsoid(final String semiMajorAxis, final String semiMinorAxis, final String invFlattening, final String unit, Identification ellipsoidId) { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM) { ellipsoid = new IdentifiableMetadataAccessor(datum.getChild(), SpatioTemporalMetadataFormat.MD_DTM_GD_ELLIPSOID, null, ellipsoidId); this.semiMajorAxis = new MetadataAccessor(ellipsoid, SpatioTemporalMetadataFormat.MD_DTM_GD_EL_SEMIMAJORAXIS, null); this.semiMajorAxis.setString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTEVALUE, semiMajorAxis); ellipsoid.setString(SpatioTemporalMetadataFormat.MD_DTM_GD_EL_UNIT, unit); this.secondDefiningParameter = new MetadataAccessor(ellipsoid, SpatioTemporalMetadataFormat.MD_DTM_GD_EL_SECONDDEFPARAM, null); if (Utilities.ensureValidString(semiMajorAxis, semiMinorAxis) && semiMajorAxis.equals(semiMinorAxis)) { this.secondDefiningParameter.setString(SpatioTemporalMetadataFormat.MD_DTM_GD_EL_SPHERE, "true"); } else if (Utilities.ensureValidString(semiMinorAxis)) { this.secondDefiningParameter.setString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTETYPE, SpatioTemporalMetadataFormat.MD_DTM_GD_EL_SEMIMINORAXIS); this.secondDefiningParameter.setString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTEVALUE, semiMinorAxis); } else if (Utilities.ensureValidString(invFlattening)) { this.secondDefiningParameter.setString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTETYPE, SpatioTemporalMetadataFormat.MD_DTM_GD_EL_INVERSEFLATTENING); this.secondDefiningParameter.setString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTEVALUE, invFlattening); } else { throw new IllegalArgumentException("Second Defining Parameter is mandatory for Geodetic Datum Ellipsoid!"); } } else throw new IllegalArgumentException("Could not set Prime Meridian for non-Geodetic Datum type"); } /** * See {@link #addPrimeMeridian(String, Identification)}. * * @return GreenwichLongitude {@link String} */ public String getGreenwichLongitude() { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM && primeMeridian != null) { return primeMeridian.getString(SpatioTemporalMetadataFormat.MD_DTM_GD_PM_GREENWICHLONGITUDE); } else throw new IllegalArgumentException("Prime Meridian not set or non-Geodetic Datum type selected"); } /** * See {@link #addEllipsoid(String, String, String, String, Identification)}. * * @return ellipsoid unit {@link String} */ public String getEllipsoidUnit() { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM&& ellipsoid != null) { return ellipsoid.getString(SpatioTemporalMetadataFormat.MD_DTM_GD_EL_UNIT); } else throw new IllegalArgumentException("Ellipsoid not set or non-Geodetic Datum type selected"); } /** * See {@link #addEllipsoid(String, String, String, String, Identification)}. * * @return SemiMajorAxis {@link String} */ public String getSemiMajorAxis() { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM && semiMajorAxis != null) { return semiMajorAxis.getString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTEVALUE); } else throw new IllegalArgumentException("Ellipsoid not set or non-Geodetic Datum type selected"); } /** * See {@link #addEllipsoid(String, String, String, String, Identification)}. * * @return SecondDefinigParameterType {@link String} */ public String getSecondDefinigParameterType() { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM && secondDefiningParameter != null) { return secondDefiningParameter.getString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTETYPE); } else throw new IllegalArgumentException("Ellipsoid not set or non-Geodetic Datum type selected"); } /** * See {@link #addEllipsoid(String, String, String, String, Identification)}. * * @return SecondDefinigParameterValue {@link String} */ public String getSecondDefinigParameterValue() { if (datum.getSelectedChoice() == Datum.GEODETIC_DATUM && secondDefiningParameter != null) { return secondDefiningParameter.getString(SpatioTemporalMetadataFormat.MD_COMM_ATTRIBUTEVALUE); } else throw new IllegalArgumentException("Ellipsoid not set or non-Geodetic Datum type selected"); } /** * See {@link #addPrimeMeridian(String, Identification)}. * * @return PrimeMeridian {@link String} */ public Identification getPrimeMeridian() { if (primeMeridian != null) return new Identification(primeMeridian); else throw new IllegalArgumentException("Prime Meridian not set or non-Geodetic Datum type selected"); } /** * See {@link #setDatum(int, Identification)}. * * @param value * PixelInCell {@link String} */ public void addPixelInCell(String value) { if (datum.getSelectedChoice() == Datum.IMAGE_DATUM) if ("cell_corner".equals(value) || "cell_center".equals(value)) datum.getChild().setString(SpatioTemporalMetadataFormat.MD_DTM_ID_PIXELINCELL, value); else throw new IllegalArgumentException("Pixel in Cell must be one of the {cell_corner; cell_center}"); else throw new IllegalArgumentException("Could not set Pixel in Cell for non-Image Datum type"); } /** * See {@link #setDatum(int, Identification)}. * * @return value {@link String} */ public String getPixelInCell() { if (datum.getSelectedChoice() == Datum.IMAGE_DATUM) return datum.getChild().getString(SpatioTemporalMetadataFormat.MD_DTM_ID_PIXELINCELL); else throw new IllegalArgumentException("Could not get Pixel in Cell for non-Image Datum type"); } /** * Returns the * {@linkplain AbstractCoordinateReferenceSystem coordinate reference system} in <A * HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well * Known Text</cite> format</A>, or {@code null} if none. */ public String getWKT() { return getString("WKT"); } /** * Sets the * {@linkplain AbstractCoordinateReferenceSystem coordinate reference system} in <A * HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well * Known Text</cite> format</A>. */ public void setWKT(final String wkt) { setString("WKT", wkt); } /** * See {@link #addEllipsoid(String, Identification)}. * * @return Ellipsoid {@link String} */ public Identification getEllipsoid() { if (ellipsoid != null) return new Identification(ellipsoid); else throw new IllegalArgumentException("Ellipsoid no set!"); } /** * Sets the CoordinateReferenceSystem/Datum. * * @param datumType * {@link int} One of the available Datums (see * {@link Datum Datum} for details) * @param identification * {@link Identification} Specifies the name, aliases, * identifiers and remarks for this Object. */ public void setDatum(final int datumType, final Identification identification) { if (datumType == Datum.TEMPORAL_DATUM || datumType == Datum.VERTICAL_DATUM) throw new IllegalArgumentException("Use a TemporalCRS/VerticalCRS to set Temporal/Vertical datums"); super.setDatum(datumType, identification); } public String getCrsType() { return crsType; } }