/*---------------- 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.Collections;
import java.util.Map;
import java.util.Set;
import org.deegree.model.csct.pt.CoordinatePoint;
import org.deegree.model.csct.pt.Envelope;
import org.deegree.model.csct.pt.Latitude;
import org.deegree.model.csct.pt.Longitude;
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 coordinate system based on latitude and longitude.
* Some geographic coordinate systems are <var>latitude</var>/<var>longiude</var>,
* and some are <var>longitude</var>/<var>latitude</var>. You can find out
* which this is by examining the axes. You should also check the angular
* units, since not all geographic coordinate systems use degrees.
*
* @version 1.00
* @author OpenGIS (www.opengis.org)
* @author Martin Desruisseaux
*
* @see org.opengis.cs.CS_GeographicCoordinateSystem
*/
public class GeographicCoordinateSystem extends HorizontalCoordinateSystem {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = -2024367470686889008L;
/**
* A geographic coordinate system using WGS84 datum.
* This coordinate system use <var>longitude</var>/<var>latitude</var> ordinates
* with longitude values increasing north and latitude values increasing east.
* Angular units are degrees and prime meridian is Greenwich.
*/
public static final GeographicCoordinateSystem WGS84 = (GeographicCoordinateSystem) pool.intern( new GeographicCoordinateSystem(
"WGS84",
HorizontalDatum.WGS84 ) );
/**
* The angular unit.
*/
private final Unit unit;
/**
* The prime meridian.
*/
private final PrimeMeridian meridian;
/**
* Creates a geographic coordinate system. This coordinate system will use
* <var>longitude</var>/<var>latitude</var> ordinates with longitude values
* increasing east and latitude values increasing north. Angular units are
* degrees and prime meridian is Greenwich.
*
* @param name Name to give new object.
* @param datum Horizontal datum for created coordinate system.
*/
public GeographicCoordinateSystem( final String name, final HorizontalDatum datum ) {
this( name, Unit.DEGREE, datum, PrimeMeridian.GREENWICH, AxisInfo.LONGITUDE,
AxisInfo.LATITUDE );
}
/**
* Creates a geographic coordinate system, which could be <var>latitude</var>/<var>longiude</var>
* or <var>longitude</var>/<var>latitude</var>.
*
* @param name Name to give new object.
* @param unit Angular units for created coordinate system.
* @param datum Horizontal datum for created coordinate system.
* @param meridian Prime Meridian for created coordinate system.
* @param axis0 Details of 0th ordinates.
* @param axis1 Details of 1st ordinates.
*
*/
public GeographicCoordinateSystem( final String name, final Unit unit,
final HorizontalDatum datum, final PrimeMeridian meridian,
final AxisInfo axis0, final AxisInfo axis1 ) {
super( name, datum, axis0, axis1 );
ensureNonNull( "unit", unit );
ensureNonNull( "meridian", meridian );
ensureAngularUnit( unit );
this.unit = unit;
this.meridian = meridian;
}
/**
* Creates a geographic coordinate system, which could be <var>latitude</var>/<var>longiude</var>
* or <var>longitude</var>/<var>latitude</var>.
*
* @param properties The set of properties (see {@link Info}).
* @param unit Angular units for created coordinate system.
* @param datum Horizontal datum for created coordinate system.
* @param meridian Prime Meridian for created coordinate system.
* @param axis0 Details of 0th ordinates.
* @param axis1 Details of 1st ordinates.
*/
GeographicCoordinateSystem( final Map properties, final Unit unit, final HorizontalDatum datum,
final PrimeMeridian meridian, final AxisInfo axis0,
final AxisInfo axis1 ) {
super( properties, datum, axis0, axis1 );
this.unit = unit;
this.meridian = meridian;
// Accept null values.
}
/**
* Gets units for dimension within coordinate system.
* This angular unit is the same for all axis.
*
* @param dimension Zero based index of axis.
*
* @see org.opengis.cs.CS_GeographicCoordinateSystem#getUnits(int)
*/
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 the prime meridian.
*
* @see org.opengis.cs.CS_GeographicCoordinateSystem#getPrimeMeridian()
*/
public PrimeMeridian getPrimeMeridian() {
return meridian;
}
/**
* Gets default envelope of coordinate system.
*
* @see org.opengis.cs.CS_GeographicCoordinateSystem#getDefaultEnvelope()
*/
public Envelope getDefaultEnvelope() {
final int dimension = getDimension();
final CoordinatePoint minCP = new CoordinatePoint( dimension );
final CoordinatePoint maxCP = new CoordinatePoint( dimension );
for ( int i = 0; i < dimension; i++ ) {
double min, max;
final Unit unit = getUnits( i );
final AxisOrientation orientation = getAxis( i ).orientation;
if ( AxisOrientation.NORTH.equals( orientation.absolute() ) ) {
min = Latitude.MIN_VALUE;
max = Latitude.MAX_VALUE;
} else if ( AxisOrientation.EAST.equals( orientation.absolute() ) ) {
min = Longitude.MIN_VALUE;
max = Longitude.MAX_VALUE;
} else {
min = Double.NEGATIVE_INFINITY;
max = Double.POSITIVE_INFINITY;
}
min = unit.convert( min, Unit.DEGREE );
max = unit.convert( max, Unit.DEGREE );
minCP.ord[i] = Math.min( min, max );
maxCP.ord[i] = Math.max( min, max );
}
return new Envelope( minCP, maxCP );
}
/**
* Gets details on conversions to WGS84. Some geographic coordinate systems
* provide several transformations into WGS84, which are designed to provide
* good accuracy in different areas of interest. The first conversion should
* provide acceptable accuracy over the largest possible area of interest.
*
* @return A set of conversions info to WGS84. The default
* implementation returns an empty set.
*
* @see org.opengis.cs.CS_GeographicCoordinateSystem#getNumConversionToWGS84()
* @see org.opengis.cs.CS_GeographicCoordinateSystem#getWGS84ConversionInfo(int)
*/
public Set getWGS84ConversionInfos() {
return Collections.EMPTY_SET;
}
/**
* 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 GeographicCoordinateSystem that = (GeographicCoordinateSystem) cs;
return Utilities.equals( this.unit, that.unit )
&& Utilities.equals( this.meridian, that.meridian );
}
return false;
}
/**
* Fill the part inside "[...]".
* Used for formatting Well Know Text (WKT).
*/
String addString( final StringBuffer buffer ) {
buffer.append( ", " );
buffer.append( getDatum() );
buffer.append( ", " );
buffer.append( meridian );
buffer.append( ", " );
addUnit( buffer, unit );
buffer.append( ", " );
buffer.append( getAxis( 0 ) );
buffer.append( ", " );
buffer.append( getAxis( 1 ) );
return "GEOGCS";
}
}