001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/cs/GeographicCoordinateSystem.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/exse/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 It has been implemented within SEAGIS - An OpenSource implementation of OpenGIS specification 012 (C) 2001, Institut de Recherche pour le D�veloppement (http://sourceforge.net/projects/seagis/) 013 SEAGIS Contacts: Surveillance de l'Environnement Assist�e par Satellite 014 Institut de Recherche pour le D�veloppement / US-Espace 015 mailto:seasnet@teledetection.fr 016 017 018 This library is free software; you can redistribute it and/or 019 modify it under the terms of the GNU Lesser General Public 020 License as published by the Free Software Foundation; either 021 version 2.1 of the License, or (at your option) any later version. 022 023 This library is distributed in the hope that it will be useful, 024 but WITHOUT ANY WARRANTY; without even the implied warranty of 025 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 026 Lesser General Public License for more details. 027 028 You should have received a copy of the GNU Lesser General Public 029 License along with this library; if not, write to the Free Software 030 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 031 032 Contact: 033 034 Andreas Poth 035 lat/lon GmbH 036 Aennchenstr. 19 037 53115 Bonn 038 Germany 039 E-Mail: poth@lat-lon.de 040 041 Klaus Greve 042 Department of Geography 043 University of Bonn 044 Meckenheimer Allee 166 045 53115 Bonn 046 Germany 047 E-Mail: klaus.greve@uni-bonn.de 048 049 050 ---------------------------------------------------------------------------*/ 051 package org.deegree.model.csct.cs; 052 053 // OpenGIS dependencies 054 import java.util.Collections; 055 import java.util.Map; 056 import java.util.Set; 057 058 import org.deegree.model.csct.pt.CoordinatePoint; 059 import org.deegree.model.csct.pt.Envelope; 060 import org.deegree.model.csct.pt.Latitude; 061 import org.deegree.model.csct.pt.Longitude; 062 import org.deegree.model.csct.resources.Utilities; 063 import org.deegree.model.csct.resources.css.ResourceKeys; 064 import org.deegree.model.csct.resources.css.Resources; 065 import org.deegree.model.csct.units.Unit; 066 067 /** 068 * A coordinate system based on latitude and longitude. Some geographic coordinate systems are 069 * <var>latitude</var>/<var>longiude</var>, and some are <var>longitude</var>/<var>latitude</var>. 070 * You can find out which this is by examining the axes. You should also check the angular units, 071 * since not all geographic coordinate systems use degrees. 072 * 073 * @version 1.00 074 * @author OpenGIS (www.opengis.org) 075 * @author Martin Desruisseaux 076 * 077 * @author last edited by: $Author: bezema $ 078 * 079 * @version $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $ 080 * 081 * @see "org.opengis.cs.CS_GeographicCoordinateSystem" 082 */ 083 public class GeographicCoordinateSystem extends HorizontalCoordinateSystem { 084 /** 085 * Serial number for interoperability with different versions. 086 */ 087 private static final long serialVersionUID = -2024367470686889008L; 088 089 /** 090 * A geographic coordinate system using WGS84 datum. This coordinate system use <var>longitude</var>/<var>latitude</var> 091 * ordinates with longitude values increasing north and latitude values increasing east. Angular 092 * units are degrees and prime meridian is Greenwich. 093 */ 094 public static final GeographicCoordinateSystem WGS84 = (GeographicCoordinateSystem) pool.intern( new GeographicCoordinateSystem( 095 "WGS84", 096 HorizontalDatum.WGS84 ) ); 097 098 /** 099 * The angular unit. 100 */ 101 private final Unit unit; 102 103 /** 104 * The prime meridian. 105 */ 106 private final PrimeMeridian meridian; 107 108 /** 109 * Creates a geographic coordinate system. This coordinate system will use <var>longitude</var>/<var>latitude</var> 110 * ordinates with longitude values increasing east and latitude values increasing north. Angular 111 * units are degrees and prime meridian is Greenwich. 112 * 113 * @param name 114 * Name to give new object. 115 * @param datum 116 * Horizontal datum for created coordinate system. 117 */ 118 public GeographicCoordinateSystem( final String name, final HorizontalDatum datum ) { 119 this( name, Unit.DEGREE, datum, PrimeMeridian.GREENWICH, AxisInfo.LONGITUDE, 120 AxisInfo.LATITUDE ); 121 } 122 123 /** 124 * Creates a geographic coordinate system, which could be <var>latitude</var>/<var>longiude</var> 125 * or <var>longitude</var>/<var>latitude</var>. 126 * 127 * @param name 128 * Name to give new object. 129 * @param unit 130 * Angular units for created coordinate system. 131 * @param datum 132 * Horizontal datum for created coordinate system. 133 * @param meridian 134 * Prime Meridian for created coordinate system. 135 * @param axis0 136 * Details of 0th ordinates. 137 * @param axis1 138 * Details of 1st ordinates. 139 * 140 */ 141 public GeographicCoordinateSystem( final String name, final Unit unit, 142 final HorizontalDatum datum, final PrimeMeridian meridian, 143 final AxisInfo axis0, final AxisInfo axis1 ) { 144 super( name, datum, axis0, axis1 ); 145 ensureNonNull( "unit", unit ); 146 ensureNonNull( "meridian", meridian ); 147 ensureAngularUnit( unit ); 148 this.unit = unit; 149 this.meridian = meridian; 150 } 151 152 /** 153 * Creates a geographic coordinate system, which could be <var>latitude</var>/<var>longiude</var> 154 * or <var>longitude</var>/<var>latitude</var>. 155 * 156 * @param properties 157 * The set of properties (see {@link Info}). 158 * @param unit 159 * Angular units for created coordinate system. 160 * @param datum 161 * Horizontal datum for created coordinate system. 162 * @param meridian 163 * Prime Meridian for created coordinate system. 164 * @param axis0 165 * Details of 0th ordinates. 166 * @param axis1 167 * Details of 1st ordinates. 168 */ 169 GeographicCoordinateSystem( final Map properties, final Unit unit, final HorizontalDatum datum, 170 final PrimeMeridian meridian, final AxisInfo axis0, 171 final AxisInfo axis1 ) { 172 super( properties, datum, axis0, axis1 ); 173 this.unit = unit; 174 this.meridian = meridian; 175 // Accept null values. 176 } 177 178 /** 179 * Gets units for dimension within coordinate system. This angular unit is the same for all 180 * axis. 181 * 182 * @param dimension 183 * Zero based index of axis. 184 * @return units for dimension within coordinate system. This angular unit is the same for all 185 * axis. 186 * 187 * @see "org.opengis.cs.CS_GeographicCoordinateSystem#getUnits(int)" 188 */ 189 public Unit getUnits( final int dimension ) { 190 if ( dimension >= 0 && dimension < getDimension() ) 191 return unit; 192 throw new IndexOutOfBoundsException( 193 Resources.format( 194 ResourceKeys.ERROR_INDEX_OUT_OF_BOUNDS_$1, 195 new Integer( dimension ) ) ); 196 } 197 198 /** 199 * Returns the prime meridian. 200 * 201 * @return the prime meridian. 202 * 203 * @see "org.opengis.cs.CS_GeographicCoordinateSystem#getPrimeMeridian()" 204 */ 205 public PrimeMeridian getPrimeMeridian() { 206 return meridian; 207 } 208 209 /** 210 * Gets default envelope of coordinate system. 211 * 212 * @return default envelope of coordinate system. 213 * 214 * @see "org.opengis.cs.CS_GeographicCoordinateSystem#getDefaultEnvelope()" 215 */ 216 public Envelope getDefaultEnvelope() { 217 final int dimension = getDimension(); 218 final CoordinatePoint minCP = new CoordinatePoint( dimension ); 219 final CoordinatePoint maxCP = new CoordinatePoint( dimension ); 220 for ( int i = 0; i < dimension; i++ ) { 221 double min, max; 222 final Unit unit = getUnits( i ); 223 final AxisOrientation orientation = getAxis( i ).orientation; 224 if ( AxisOrientation.NORTH.equals( orientation.absolute() ) ) { 225 min = Latitude.MIN_VALUE; 226 max = Latitude.MAX_VALUE; 227 } else if ( AxisOrientation.EAST.equals( orientation.absolute() ) ) { 228 min = Longitude.MIN_VALUE; 229 max = Longitude.MAX_VALUE; 230 } else { 231 min = Double.NEGATIVE_INFINITY; 232 max = Double.POSITIVE_INFINITY; 233 } 234 min = unit.convert( min, Unit.DEGREE ); 235 max = unit.convert( max, Unit.DEGREE ); 236 minCP.ord[i] = Math.min( min, max ); 237 maxCP.ord[i] = Math.max( min, max ); 238 } 239 return new Envelope( minCP, maxCP ); 240 } 241 242 /** 243 * Gets details on conversions to WGS84. Some geographic coordinate systems provide several 244 * transformations into WGS84, which are designed to provide good accuracy in different areas of 245 * interest. The first conversion should provide acceptable accuracy over the largest possible 246 * area of interest. 247 * 248 * @return A set of conversions info to WGS84. The default implementation returns an empty set. 249 * 250 * @see "org.opengis.cs.CS_GeographicCoordinateSystem#getNumConversionToWGS84()" 251 * @see "org.opengis.cs.CS_GeographicCoordinateSystem#getWGS84ConversionInfo(int)" 252 */ 253 public Set getWGS84ConversionInfos() { 254 return Collections.EMPTY_SET; 255 } 256 257 /** 258 * Returns <code>true</code> if this coordinate system is equivalents to the specified 259 * coordinate system. Two coordinate systems are considered equivalent if the 260 * {@link org.deegree.model.csct.ct.CoordinateTransformation} from <code>this</code> to 261 * <code>cs</code> would be the identity transform. The default implementation compare datum, 262 * units and axis, but ignore name, alias and other meta-data informations. 263 * 264 * @param cs 265 * The coordinate system (may be <code>null</code>). 266 * @return <code>true</code> if both coordinate systems are equivalent. 267 */ 268 public boolean equivalents( final CoordinateSystem cs ) { 269 if ( cs == this ) 270 return true; 271 if ( super.equivalents( cs ) ) { 272 final GeographicCoordinateSystem that = (GeographicCoordinateSystem) cs; 273 return Utilities.equals( this.unit, that.unit ) 274 && Utilities.equals( this.meridian, that.meridian ); 275 } 276 return false; 277 } 278 279 /** 280 * Fill the part inside "[...]". Used for formatting Well Know Text (WKT). 281 * 282 * @param buffer 283 * @return 284 */ 285 String addString( final StringBuffer buffer ) { 286 buffer.append( ", " ); 287 buffer.append( getDatum() ); 288 buffer.append( ", " ); 289 buffer.append( meridian ); 290 buffer.append( ", " ); 291 addUnit( buffer, unit ); 292 buffer.append( ", " ); 293 buffer.append( getAxis( 0 ) ); 294 buffer.append( ", " ); 295 buffer.append( getAxis( 1 ) ); 296 return "GEOGCS"; 297 } 298 299 }