001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/model/spatialschema/PositionImpl.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19 
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     
043     ---------------------------------------------------------------------------*/
044    package org.deegree.model.spatialschema;
045    
046    import java.io.Serializable;
047    
048    /**
049     * A sequence of decimals numbers which when written on a width are a sequence of coordinate
050     * positions. The width is derived from the CRS or coordinate dimension of the container.
051     * 
052     * <p>
053     * -----------------------------------------------------------------------
054     * </p>
055     * 
056     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
057     * @author last edited by: $Author: apoth $
058     * @version $Revision: 9343 $ $Date: 2007-12-27 14:30:32 +0100 (Do, 27 Dez 2007) $
059     */
060    class PositionImpl implements Position, Serializable {
061        /** Use serialVersionUID for interoperability. */
062        private final static long serialVersionUID = -3780255674921824356L;
063    
064        private double[] point = null;
065    
066        private double accuracy = 0.000001;
067    
068        private int dimension = 3;
069    
070        /**
071         * constructor. initializes a point to the coordinate 0/0
072         */
073        PositionImpl() {
074            point = new double[] { 0, 0, 0 };
075        }
076    
077        /**
078         * constructor
079         * 
080         * @param x
081         *            x-value of the point
082         * @param y
083         *            y-value of the point
084         */
085        PositionImpl( double x, double y ) {
086            point = new double[] { x, y, Double.NaN };
087            dimension = 2;
088        }
089    
090        /**
091         * constructor
092         * 
093         * @param x
094         *            x-value of the point
095         * @param y
096         *            y-value of the point
097         * @param z
098         *            z-value of the point
099         */
100        PositionImpl( double x, double y, double z ) {
101            point = new double[] { x, y, z };
102        }
103    
104        /**
105         * constructor.
106         * 
107         * @param coords
108         *            the Coordinates from which the position is build.
109         */
110        PositionImpl( double[] coords ) {
111            if ( coords.length == 3 && !Double.isNaN( coords[2] ) ) {
112                dimension = 3;
113            } else {
114                if ( coords.length == 2 ) {
115                    coords = new double[] { coords[0], coords[1], Double.NaN };
116                }
117                dimension = 2;
118            }
119            point = coords;
120        }
121    
122        /**
123         * @return the coordinate dimension of the position
124         */
125        public int getCoordinateDimension() {
126            return dimension;
127        }
128    
129        /**
130         * @return a shallow copy of the geometry.
131         */
132        @Override
133        public Object clone() {
134            return new PositionImpl( point.clone() );
135        }
136    
137        /**
138         * @return the x-value of this point
139         */
140        public double getX() {
141            return point[0];
142        }
143    
144        /**
145         * @return the y-value of this point
146         */
147        public double getY() {
148            return point[1];
149        }
150    
151        /**
152         * @return the z-value of this point.
153         */
154        public double getZ() {
155            return point[2];
156        }
157    
158        /**
159         * @return the position as a array the first field contains the x- the second field the y-value
160         *         etc.
161         * 
162         * NOTE: The returned array always has a length of 3, regardless of the dimension. This is due
163         * to a limitation in the coordinate transformation package (proj4), which expects coordinates
164         * to have 3 dimensions.
165         */
166        public double[] getAsArray() {
167            return point;
168        }
169    
170        /**
171         * translate the point by the submitted values. the <code>dz</code>- value will be ignored.
172         * 
173         * @param d
174         */
175        public void translate( double[] d ) {
176            for ( int i = 0; i < d.length; i++ ) {
177                point[i] += d[i];
178            }
179        }
180    
181        /**
182         * compares if all field of other are equal to the corresponding fields of this position
183         */
184        @Override
185        public boolean equals( Object other ) {
186            boolean eq = true;
187            double[] other_ = ( (Position) other ).getAsArray();
188    
189            if ( eq ) {
190                for ( int i = 0; i < dimension; i++ ) {
191                    if ( Math.abs( point[i] - other_[i] ) > accuracy ) {
192                        eq = false;
193                        break;
194                    }
195                }
196            }
197    
198            return eq;
199        }
200    
201        /**
202         * @return the accuracy the position is defined. The accuracy is measured in values of the CRS
203         *         the positions coordinates are stored
204         */
205        public double getAccuracy() {
206            return accuracy;
207        }
208    
209        /**
210         * @see #getAccuracy()
211         * @param accuracy
212         */
213        public void setAccuracy( double accuracy ) {
214            this.accuracy = accuracy;
215        }
216    
217        @Override
218        public String toString() {
219            String ret = "Position: ";
220    
221            for ( int i = 0; i < dimension; i++ ) {
222                ret += ( point[i] + " " );
223            }
224    
225            return ret;
226        }
227    }