/*
* Geotools 2 - OpenSource mapping toolkit
* (C) 2003, Geotools Project Managment Committee (PMC)
* (C) 2001, Institut de Recherche pour le Développement
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* This package contains documentation from OpenGIS specifications.
* OpenGIS consortium's work is fully acknowledged here.
*/
package org.geotools.cs;
// OpenGIS dependencies
import java.rmi.RemoteException;
import javax.media.jai.ParameterList;
import org.geotools.ct.MissingParameterException;
import org.geotools.resources.i18n.ErrorKeys;
import org.geotools.resources.i18n.Errors;
import org.geotools.units.Unit;
import org.opengis.cs.CS_GeographicCoordinateSystem;
import org.opengis.cs.CS_LinearUnit;
import org.opengis.cs.CS_ProjectedCoordinateSystem;
import org.opengis.cs.CS_Projection;
/**
* A 2D cartographic coordinate system. Projected coordinates are the
* two-dimensional cartesian coordinates typically found on maps and computer
* displays. The cartesian axes are often called "paper coordinates" or
* "display coordinates." The conversions from a three-dimensional curvilinear
* coordinate system (whether ellipsoidal or spherical) to projected
* coordinates may be assumed to be well known. Examples of projected
* coordinate systems are: Lambert, Mercator, and transverse Mercator.
* Conversions to, and conversions between, projected spatial coordinate
* systems often do not preserve distances, areas and angles.
*
* @source $URL$
* @version $Id$
* @author OpenGIS (www.opengis.org)
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem
*
* @deprecated Replaced by {@link org.geotools.referencing.crs.DefaultProjectedCRS}.
*/
public class ProjectedCoordinateSystem extends HorizontalCoordinateSystem {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 5412822472156531329L;
/**
* Small value for comparaison of double
types.
*/
private static final double EPS = 1E-6;
/**
* The linear unit.
*/
private final Unit unit;
/**
* Geographic coordinate system to base projection on.
*/
private final GeographicCoordinateSystem gcs;
/**
* Projection from geographic to projected coordinate system.
*/
private final Projection projection;
/**
* Creates a projected coordinate system using the specified geographic
* system. Projected coordinates will be in meters, x values
* increasing east and y values increasing north.
*
* @param name Name to give new object.
* @param gcs Geographic coordinate system to base projection on.
* @param projection Projection from geographic to projected coordinate system.
*/
public ProjectedCoordinateSystem(final CharSequence name,
final GeographicCoordinateSystem gcs,
final Projection projection)
{
this(name, gcs, projection, Unit.METRE, AxisInfo.X, AxisInfo.Y);
}
/**
* Creates a projected coordinate system using a projection object.
*
* @param name Name to give new object.
* @param gcs Geographic coordinate system to base projection on.
* @param projection Projection from geographic to projected coordinate system.
* @param unit Linear units of created PCS.
* @param axis0 Details of 0th ordinates in created PCS coordinates.
* @param axis1 Details of 1st ordinates in created PCS coordinates.
*
* @see org.opengis.cs.CS_CoordinateSystemFactory#createProjectedCoordinateSystem
*/
public ProjectedCoordinateSystem(final CharSequence name,
final GeographicCoordinateSystem gcs,
Projection projection,
final Unit unit,
final AxisInfo axis0,
final AxisInfo axis1)
{
super(name, gcs.getHorizontalDatum(), axis0, axis1);
ensureNonNull("gcs", gcs);
ensureNonNull("projection", projection);
ensureNonNull("unit", unit);
ensureLinearUnit(unit);
final Ellipsoid ellipsoid = getHorizontalDatum().getEllipsoid();
final Unit ellipsoidUnit = ellipsoid.getAxisUnit();
final double semiMajor = Unit.METRE.convert(ellipsoid.getSemiMajorAxis(), ellipsoidUnit);
final double semiMinor = Unit.METRE.convert(ellipsoid.getSemiMinorAxis(), ellipsoidUnit);
String invalidParameter = null;
boolean resetAxisLength = false;
try {
// Use '!(...) <= EPS' in order to reject NaN values.
if (!(Math.abs(semiMinor - projection.getValue("semi_minor")) <= EPS)) {
invalidParameter = "semi_minor";
}
} catch (MissingParameterException exception) {
// Axis length not set.
resetAxisLength = true;
}
try {
// Use '!(...) <= EPS' in order to reject NaN values.
if (!(Math.abs(semiMajor - projection.getValue("semi_major")) <= EPS)) {
invalidParameter = "semi_major";
}
} catch (MissingParameterException exception) {
// Axis length not set.
resetAxisLength = true;
}
if (invalidParameter != null) {
throw new IllegalArgumentException(Errors.format(
ErrorKeys.INCOMPATIBLE_ELLIPSOID_$2,
invalidParameter, ellipsoid.getName().getCode()));
}
if (resetAxisLength) {
final ParameterList parameters = projection.getParameters();
parameters.setParameter("semi_major", semiMajor);
parameters.setParameter("semi_minor", semiMinor);
projection = new Projection(projection.getName().getCode(),
projection.getClassName(),
parameters);
}
this.gcs = gcs;
this.projection = projection;
this.unit = unit;
}
/**
* Returns the geographic coordinate system.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getGeographicCoordinateSystem()
*
* @deprecated Replaced by {@link org.geotools.referencing.crs.DefaultProjectedCRS#getBaseCRS}.
*/
public GeographicCoordinateSystem getGeographicCoordinateSystem() {
return gcs;
}
/**
* Gets the projection.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getProjection()
*
* @deprecated Replaced by {@link org.geotools.referencing.crs.DefaultProjectedCRS#getConversionFromBase}.
*/
public Projection getProjection() {
return projection;
}
/**
* Gets units for dimension within coordinate system.
* This linear unit is the same for all axes.
*
* @param dimension Zero based index of axis.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getUnits(int)
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getLinearUnit()
*
* @deprecated Replaced by {@link org.geotools.referencing.cs.DefaultCoordinateSystemAxis#getUnit}.
*/
public Unit getUnits(final int dimension) {
if (dimension>=0 && dimensionthis.
* @param compareNames true
to comparare the {@linkplain #getName name},
* {@linkplain #getAlias alias}, {@linkplain #getAuthorityCode authority
* code}, etc. as well, or false
to compare only properties
* relevant to transformations.
* @return true
if both objects are equal.
*/
public boolean equals(final Info object, final boolean compareNames) {
if (object == this) {
return true;
}
if (super.equals(object, compareNames)) {
final ProjectedCoordinateSystem that = (ProjectedCoordinateSystem) object;
return equals(this.gcs, that.gcs, compareNames) &&
equals(this.projection, that.projection, compareNames) &&
equals(this.unit, that.unit );
}
return false;
}
/**
* Returns a hash value for this coordinate system. {@linkplain #getName Name},
* {@linkplain #getAlias alias}, {@linkplain #getAuthorityCode authority code}
* and the like are not taken in account. In other words, two coordinate systems
* will return the same hash value if they are equal in the sense of
* {@link #equals equals}(Info, false)
.
*
* @return The hash code value. This value doesn't need to be the same
* in past or future versions of this class.
*/
public int hashCode() {
return (int)serialVersionUID +
37*(gcs .hashCode() +
37*(projection.hashCode() +
37*(unit .hashCode())));
}
/**
* Fills the part inside "[...]".
* Used for formatting Well Known Text (WKT).
*/
String addString(final StringBuffer buffer, final Unit context) {
buffer.append(", ");
buffer.append(gcs);
buffer.append(", ");
buffer.append(projection);
buffer.append(", ");
projection.addParameters(buffer, unit);
addUnit(buffer, unit);
buffer.append(", ");
buffer.append(getAxis(0));
buffer.append(", ");
buffer.append(getAxis(1));
return "PROJCS";
}
/**
* Returns an OpenGIS interface for this projected coordinate
* system. The returned object is suitable for RMI use.
*
* Note: The returned type is a generic {@link Object} in order
* to avoid premature class loading of OpenGIS interface.
*/
final Object toOpenGIS(final Object adapters) throws RemoteException {
return new Export(adapters);
}
/////////////////////////////////////////////////////////////////////////
//////////////// ////////////////
//////////////// OPENGIS ADAPTER ////////////////
//////////////// ////////////////
/////////////////////////////////////////////////////////////////////////
/**
* Wraps a {@link ProjectedCoordinateSystem} object for use with OpenGIS.
* This class is suitable for RMI use.
*/
private final class Export extends HorizontalCoordinateSystem.Export implements CS_ProjectedCoordinateSystem {
/**
* Constructs a remote object.
*/
protected Export(final Object adapters) throws RemoteException {
super(adapters);
}
/**
* Returns the GeographicCoordinateSystem.
*/
public CS_GeographicCoordinateSystem getGeographicCoordinateSystem() throws RemoteException {
return adapters.export(ProjectedCoordinateSystem.this.getGeographicCoordinateSystem());
}
/**
* Returns the LinearUnits.
*/
public CS_LinearUnit getLinearUnit() throws RemoteException {
return (CS_LinearUnit) adapters.export(ProjectedCoordinateSystem.this.getUnits());
}
/**
* Gets the projection.
*/
public CS_Projection getProjection() throws RemoteException {
return adapters.export(ProjectedCoordinateSystem.this.getProjection());
}
}
}