001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/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: import javax.vecmath.Point3d;
049:
050: /**
051: * A sequence of decimals numbers which when written on a width are a sequence of coordinate positions. The width is
052: * derived from the CRS or coordinate dimension of the container.
053: *
054: * <p>
055: * -----------------------------------------------------------------------
056: * </p>
057: *
058: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
059: * @author last edited by: $Author: rbezema $
060: * @version $Revision: 10288 $ $Date: 2008-02-25 09:00:39 -0800 (Mon, 25 Feb 2008) $
061: */
062: class PositionImpl implements Position, Serializable {
063: /** Use serialVersionUID for interoperability. */
064: private final static long serialVersionUID = -3780255674921824356L;
065:
066: // private double[] point = null;
067: private final Point3d point;
068:
069: private double accuracy = 0.000001;
070:
071: private final int dimension;
072:
073: /**
074: * constructor. initializes a point to the coordinate 0/0
075: */
076: PositionImpl() {
077: // point = new double[] { 0, 0, 0 };
078: point = new Point3d();
079: dimension = 3;
080: }
081:
082: /**
083: * constructor
084: *
085: * @param x
086: * x-value of the point
087: * @param y
088: * y-value of the point
089: */
090: PositionImpl(double x, double y) {
091: // point = new double[] { x, y, Double.NaN };
092: point = new Point3d(x, y, Double.NaN);
093: dimension = 2;
094: }
095:
096: /**
097: * constructor
098: *
099: * @param x
100: * x-value of the point
101: * @param y
102: * y-value of the point
103: * @param z
104: * z-value of the point
105: */
106: PositionImpl(double x, double y, double z) {
107: // point = new double[] { x, y, z };
108: point = new Point3d(x, y, z);
109: if (Double.isNaN(z)) {
110: dimension = 2;
111: } else {
112: dimension = 3;
113: }
114: }
115:
116: /**
117: * constructor.
118: *
119: * @param coords
120: * the Coordinates from which the position is build.
121: */
122: PositionImpl(double[] coords) {
123: if (coords.length == 3 && !Double.isNaN(coords[2])) {
124: dimension = 3;
125: } else {
126: if (coords.length == 2) {
127: coords = new double[] { coords[0], coords[1],
128: Double.NaN };
129: }
130: dimension = 2;
131: }
132: point = new Point3d(coords);
133: }
134:
135: /**
136: * Constructor from another point3d
137: *
138: * @param other
139: * the Coordinates from which the position is build if <code>null</code> the default values 0,0,0 with
140: * a dim of 3 is assumed.
141: */
142: PositionImpl(final Point3d other) {
143: if (other != null) {
144: dimension = Double.isNaN(other.z) ? 2 : 3;
145: point = new Point3d(other);
146: } else {
147: dimension = 3;
148: point = new Point3d();
149: }
150: }
151:
152: /**
153: * @return the coordinate dimension of the position
154: */
155: public int getCoordinateDimension() {
156: return dimension;
157: }
158:
159: /**
160: * @return a shallow copy of the geometry.
161: */
162: @Override
163: public Object clone() {
164: return new PositionImpl((Point3d) point.clone());
165: }
166:
167: /**
168: * @return the x-value of this point
169: */
170: public double getX() {
171: // return point[0];
172: return point.x;
173: }
174:
175: /**
176: * @return the y-value of this point
177: */
178: public double getY() {
179: // return point[1];
180: return point.y;
181: }
182:
183: /**
184: * @return the z-value of this point, if dimension is 2, this value will be Double.NaN
185: */
186: public double getZ() {
187: // return point[2];
188: return point.z;
189: }
190:
191: /**
192: * @return the position as a array the first field contains the x- the second field the y-value etc.
193: *
194: * NOTE: The returned array always has a length of 3, regardless of the dimension. This is due to a limitation in
195: * the coordinate transformation package (proj4), which expects coordinates to have 3 dimensions.
196: */
197: public double[] getAsArray() {
198: return new double[] { point.x, point.y, point.z };
199: }
200:
201: /**
202: * translate the point by the submitted values.
203: *
204: * @param d
205: */
206: public void translate(double[] d) {
207: if (d != null && d.length >= 2) {
208: point.x += d[0];
209: point.y += d[1];
210: if (dimension == 3) {
211: if (d.length == 3) {
212: point.z += d[2];
213: }
214: }
215: }
216: }
217:
218: @Override
219: public boolean equals(Object other) {
220: if (other != null && other instanceof Position) {
221: final Position that = (Position) other;
222: return dimension == that.getCoordinateDimension()
223: && Math.abs(point.x - that.getX()) < accuracy
224: && Math.abs(point.y - that.getY()) < accuracy
225: && ((dimension == 3) ? Math.abs(point.z
226: - that.getZ()) < accuracy : true);
227: }
228: return false;
229: }
230:
231: // /**
232: // * compares if all field of other are equal to the corresponding fields of this position
233: // */
234: // @Override
235: // public boolean equals( Object other ) {
236: // boolean eq = true;
237: // double[] other_ = ( (Position) other ).getAsArray();
238: //
239: // if ( eq ) {
240: // for ( int i = 0; i < dimension; i++ ) {
241: // if ( Math.abs( point[i] - other_[i] ) > accuracy ) {
242: // eq = false;
243: // break;
244: // }
245: // }
246: // }
247: //
248: // return eq;
249: // }
250:
251: /**
252: * @return the accuracy the position is defined. The accuracy is measured in values of the CRS the positions
253: * coordinates are stored
254: */
255: public double getAccuracy() {
256: return accuracy;
257: }
258:
259: /**
260: * @param accuracy
261: */
262: public void setAccuracy(double accuracy) {
263: this .accuracy = accuracy;
264: }
265:
266: @Override
267: public String toString() {
268: StringBuilder ret = new StringBuilder("Position: ");
269: ret.append(point.x).append(" ");
270: ret.append(point.y);
271: if (dimension == 3) {
272: ret.append(" ");
273: ret.append(point.z);
274: }
275: return ret.toString();
276: }
277:
278: public final Point3d getAsPoint3d() {
279: return point;
280: }
281: }
|