001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/pt/CoordinatePoint.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.pt;
052    
053    // Miscellaneous
054    import java.awt.geom.Point2D;
055    import java.io.Serializable;
056    import java.util.Arrays;
057    
058    import org.deegree.model.csct.resources.Utilities;
059    import org.deegree.model.csct.resources.css.ResourceKeys;
060    import org.deegree.model.csct.resources.css.Resources;
061    
062    /**
063     * A position defined by a list of numbers. The ordinate
064     * values are indexed from <code>0</code> to <code>(numDim-1)</code>,
065     * where <code>numDim</code> is the dimension of the coordinate system
066     * the coordinate point belongs in.
067     *
068     * @version 1.00
069     * @author OpenGIS (www.opengis.org)
070     * @author Martin Desruisseaux
071     *
072     * @see java.awt.geom.Point2D
073     */
074    public class CoordinatePoint implements Dimensioned, Cloneable, Serializable {
075        /**
076         * Serial number for interoperability with different versions.
077         */
078        private static final long serialVersionUID = -6975990652038126533L;
079    
080        /**
081         * The ordinates of the coordinate point.
082         *
083         */
084        public final double[] ord;
085    
086        /**
087         * Construct a coordinate with the
088         * specified number of dimensions.
089         *
090         * @param  numDim Number of dimensions.
091         * @throws NegativeArraySizeException if <code>numDim</code> is negative.
092         */
093        public CoordinatePoint( final int numDim ) throws NegativeArraySizeException {
094            ord = new double[numDim];
095        }
096    
097        /**
098         * Construct a coordinate with the specified ordinates.
099         * The <code>ord</code> array will be copied.
100         */
101        public CoordinatePoint( final double[] ord ) {
102            this.ord = ord.clone();
103        }
104    
105        /**
106         * Construct a 2D coordinate from
107         * the specified ordinates.
108         */
109        public CoordinatePoint( final double x, final double y ) {
110            ord = new double[] { x, y };
111        }
112    
113        /**
114         * Construct a 3D coordinate from
115         * the specified ordinates.
116         */
117        public CoordinatePoint( final double x, final double y, final double z ) {
118            ord = new double[] { x, y, z };
119        }
120    
121        /**
122         * Construct a coordinate from
123         * the specified {@link Point2D}.
124         */
125        public CoordinatePoint( final Point2D point ) {
126            this( point.getX(), point.getY() );
127        }
128    
129        /**
130         * Returns the ordinate value along the specified dimension.
131         * This is equivalent to <code>{@link #ord}[dimension]</code>.
132         */
133        public final double getOrdinate( final int dimension ) {
134            return ord[dimension];
135        }
136    
137        /**
138         * The number of ordinates of a <code>CoordinatePoint</code>.
139         * This is equivalent to <code>{@link #ord}.length</code>.
140         */
141        public final int getDimension() {
142            return ord.length;
143        }
144    
145        /**
146         * Convenience method for checking the point's dimension validity.
147         * This method is usually call for argument checking.
148         *
149         * @param  expectedDimension Expected dimension for this point.
150         * @throws MismatchedDimensionException if this point doesn't have the expected dimension.
151         */
152        final void ensureDimensionMatch( final int expectedDimension )
153                                throws MismatchedDimensionException {
154            final int dimension = getDimension();
155            if ( dimension != expectedDimension ) {
156                throw new MismatchedDimensionException( dimension, expectedDimension );
157            }
158        }
159    
160        /**
161         * Returns a {@link Point2D} with the same coordinate
162         * as this <code>CoordinatePoint</code>. This is a
163         * convenience method for interoperability with Java2D.
164         *
165         * @throws IllegalStateException if this coordinate point is not two-dimensional.
166         */
167        public Point2D toPoint2D()
168                                throws IllegalStateException {
169            if ( ord.length == 2 ) {
170                return new Point2D.Double( ord[0], ord[1] );
171            }
172            throw new IllegalStateException(
173                                             Resources.format(
174                                                               ResourceKeys.ERROR_NOT_TWO_DIMENSIONAL_$1,
175                                                               new Integer( ord.length ) ) );
176        }
177    
178        /**
179         * Returns a hash value for this coordinate.
180         * This value need not remain consistent between
181         * different implementations of the same class.
182         */
183        public int hashCode() {
184            return hashCode( ord );
185        }
186    
187        /**
188         * Returns a hash value for the specified ordinates.
189         */
190        static int hashCode( final double[] ord ) {
191            long code = 78516481;
192            if ( ord != null ) {
193                for ( int i = ord.length; --i >= 0; )
194                    code = code * 31 + Double.doubleToLongBits( ord[i] );
195            }
196            return (int) ( code >>> 32 ) ^ (int) code;
197        }
198    
199        /**
200         * Compares the specified object with
201         * this coordinate for equality.
202         */
203        public boolean equals( final Object object ) {
204            if ( object instanceof CoordinatePoint ) {
205                final CoordinatePoint that = (CoordinatePoint) object;
206                return Arrays.equals( this.ord, that.ord );
207            }
208            return false;
209        }
210    
211        /**
212         * Returns a deep copy of this coordinate.
213         */
214        public Object clone() {
215            return new CoordinatePoint( ord );
216        }
217    
218        /**
219         * Returns a string representation of this coordinate.
220         * The returned string is implementation dependent.
221         * It is usually provided for debugging purposes.
222         */
223        public String toString() {
224            return toString( this, ord );
225        }
226    
227        /**
228         * Returns a string representation of an object.
229         * The returned string is implementation dependent.
230         * It is usually provided for debugging purposes.
231         */
232        static String toString( final Object owner, final double[] ord ) {
233            final StringBuffer buffer = new StringBuffer( Utilities.getShortClassName( owner ) );
234            buffer.append( '[' );
235            for ( int i = 0; i < ord.length; i++ ) {
236                if ( i != 0 )
237                    buffer.append( ", " );
238                buffer.append( ord[i] );
239            }
240            buffer.append( ']' );
241            return buffer.toString();
242        }
243    }