/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/exse/
lat/lon GmbH
http://www.lat-lon.de
It has been implemented within SEAGIS - An OpenSource implementation of OpenGIS specification
(C) 2001, Institut de Recherche pour le D�veloppement (http://sourceforge.net/projects/seagis/)
SEAGIS Contacts: Surveillance de l'Environnement Assist�e par Satellite
Institut de Recherche pour le D�veloppement / US-Espace
mailto:seasnet@teledetection.fr
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
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: klaus.greve@uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.model.csct.cs;
// OpenGIS dependencies
import java.util.Map;
import javax.media.jai.ParameterList;
import org.deegree.model.csct.ct.MissingParameterException;
import org.deegree.model.csct.resources.Utilities;
import org.deegree.model.csct.resources.css.ResourceKeys;
import org.deegree.model.csct.resources.css.Resources;
import org.deegree.model.csct.units.Unit;
/**
* 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.
*
* @version 1.00
* @author OpenGIS (www.opengis.org)
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem
*/
public class ProjectedCoordinateSystem extends HorizontalCoordinateSystem {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 5412822472156531329L;
/**
* The angular unit.
*/
private final Unit unit;
/**
* Geographic coordinate system to base projection on.
*/
private final GeographicCoordinateSystem gcs;
/**
* projection 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, <var>x</var> values
* increasing east and <var>y</var> 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 String 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.
*
*/
public ProjectedCoordinateSystem( final String 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 double semiMajor = ellipsoid.getSemiMajorAxis();
final double semiMinor = ellipsoid.getSemiMinorAxis();
String invalidParameter = null;
boolean resetAxisLength = false;
try {
if ( semiMinor != projection.getValue( "semi_minor" ) )
invalidParameter = "semi_minor";
} catch ( MissingParameterException exception ) {
// Axis length not set.
resetAxisLength = true;
}
try {
if ( semiMajor != projection.getValue( "semi_major" ) )
invalidParameter = "semi_major";
} catch ( MissingParameterException exception ) {
// Axis length not set.
resetAxisLength = true;
}
if ( invalidParameter != null ) {
throw new IllegalArgumentException(
Resources.format(
ResourceKeys.ERROR_INCOMPATIBLE_ELLIPSOID_$2,
invalidParameter,
ellipsoid.getName( null ) ) );
}
if ( resetAxisLength ) {
final ParameterList parameters = projection.getParameters();
parameters.setParameter( "semi_major", semiMajor );
parameters.setParameter( "semi_minor", semiMinor );
projection = new Projection( projection.getName( null ), projection.getClassName(),
parameters );
}
this.gcs = gcs;
this.projection = projection;
this.unit = unit;
}
/**
* Creates a projected coordinate system using a projection object.
*
* @param properties The set of properties (see {@link Info}).
* @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.
*/
ProjectedCoordinateSystem( final Map properties, final GeographicCoordinateSystem gcs,
final Projection projection, final Unit unit, final AxisInfo axis0,
final AxisInfo axis1 ) {
super( properties, gcs.getHorizontalDatum(), axis0, axis1 );
this.gcs = gcs;
this.projection = projection;
this.unit = unit;
// Accept null values.
}
/**
* Returns the geographic coordinate system.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getGeographicCoordinateSystem()
*/
public GeographicCoordinateSystem getGeographicCoordinateSystem() {
return gcs;
}
/**
* Gets the projection.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getProjection()
*/
public Projection getProjection() {
return projection;
}
/**
* Gets units for dimension within coordinate system.
* This linear unit is the same for all axis.
*
* @param dimension Zero based index of axis.
*
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getUnits(int)
* @see org.opengis.cs.CS_ProjectedCoordinateSystem#getLinearUnit()
*/
public Unit getUnits( final int dimension ) {
if ( dimension >= 0 && dimension < getDimension() )
return unit;
throw new IndexOutOfBoundsException(
Resources.format(
ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1,
new Integer( dimension ) ) );
}
/**
* Returns <code>true</code> if this coordinate system is equivalents to
* the specified coordinate system. Two coordinate systems are considered
* equivalent if the {@link org.deegree.model.csct.ct.CoordinateTransformation} from
* <code>this</code> to <code>cs</code> would be the identity transform.
* The default implementation compare datum, units and axis, but ignore
* name, alias and other meta-data informations.
*
* @param cs The coordinate system (may be <code>null</code>).
* @return <code>true</code> if both coordinate systems are equivalent.
*/
public boolean equivalents( final CoordinateSystem cs ) {
if ( cs == this )
return true;
if ( super.equivalents( cs ) ) {
final ProjectedCoordinateSystem that = (ProjectedCoordinateSystem) cs;
return Utilities.equals( this.gcs, that.gcs )
&& Utilities.equals( this.projection, that.projection )
&& Utilities.equals( this.unit, that.unit );
}
return false;
}
/**
* Fill the part inside "[...]".
* Used for formatting Well Know Text (WKT).
*/
String addString( final StringBuffer buffer ) {
buffer.append( ", " );
buffer.append( gcs );
buffer.append( ", " );
buffer.append( projection );
buffer.append( ", " );
addUnit( buffer, unit );
buffer.append( ", " );
buffer.append( getAxis( 0 ) );
buffer.append( ", " );
buffer.append( getAxis( 1 ) );
return "PROJCS";
}
}