001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/PointImpl.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2006 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 org.deegree.model.crs.CoordinateSystem;
049    
050    /**
051     * default implementation of the Point interface.
052     * 
053     * <p>
054     * ------------------------------------------------------------
055     * </p>
056     * 
057     * @version 5.6.2001
058     * @author Andreas Poth
059     *         <p>
060     */
061    
062    final class PointImpl extends PrimitiveImpl implements Point, Serializable {
063        /** Use serialVersionUID for interoperability. */
064        private final static long serialVersionUID = 6106017748940535740L;
065    
066        private Position position = null;
067    
068        /**
069         * constructor. initializes a point to the coordinate 0/0
070         * 
071         * @param crs
072         *            spatial reference system of the point
073         */
074        public PointImpl( CoordinateSystem crs ) {
075            super( crs );
076            position = new PositionImpl();
077            empty = true;
078            centroid = this;
079        }
080    
081        /**
082         * constructor for initializing a point within a two-dimensional coordinate system
083         * 
084         * @param x
085         *            x-value of the point
086         * @param y
087         *            y-value of the point
088         * @param crs
089         *            spatial reference system of the point
090         */
091        public PointImpl( double x, double y, CoordinateSystem crs ) {
092            super( crs );
093            position = new PositionImpl( x, y );
094            empty = false;
095            centroid = this;
096        }
097    
098        /**
099         * constructor for initializing a point within a three-dimensional coordinate system
100         * 
101         * @param x
102         *            x-value of the point
103         * @param y
104         *            y-value of the point
105         * @param z
106         *            z-value of the point
107         * @param crs
108         *            spatial reference system of the point
109         */
110        public PointImpl( double x, double y, double z, CoordinateSystem crs ) {
111            super( crs );
112            position = new PositionImpl( x, y, z );
113            empty = false;
114            centroid = this;
115        }
116    
117        /**
118         * constructor
119         * 
120         * @param gmo
121         *            existing GM_Point
122         */
123        public PointImpl( Point gmo ) {
124            super( gmo.getCoordinateSystem() );
125            position = new PositionImpl( gmo.getAsArray() );
126            empty = false;
127            centroid = this;
128        }
129    
130        /**
131         * constructor
132         * 
133         * @param gmo
134         *            existing GM_Point
135         * @param crs
136         *            spatial reference system of the point
137         */
138        public PointImpl( Position gmo, CoordinateSystem crs ) {
139            super( crs );
140            position = gmo;
141            empty = false;
142            centroid = this;
143        }
144    
145        /**
146         * checks if this point is completly equal to the submitted geometry
147         */
148        @Override
149        public boolean equals( Object other ) {
150            if ( super.equals( other ) && ( other instanceof Point ) ) {
151                Point p = (Point) other;
152                boolean flagEq = Math.abs( getX() - p.getX() ) < mute
153                                 && Math.abs( getY() - p.getY() ) < mute;
154                if ( getCoordinateDimension() == 3 ) {
155                    flagEq = flagEq && Math.abs( getZ() - p.getZ() ) < mute;
156                }
157                return flagEq;
158            }
159    
160            return false;
161        }
162    
163        /**
164         * The operation "dimension" shall return the inherent dimension of this Geometry, which shall
165         * be less than or equal to the coordinate dimension. The dimension of a collection of geometric
166         * objects shall be the largest dimension of any of its pieces. Points are 0-dimensional, curves
167         * are 1-dimensional, surfaces are 2-dimensional, and solids are 3-dimensional.
168         */
169        public int getDimension() {
170            return 0;
171        }
172    
173        /**
174         * The operation "coordinateDimension" shall return the dimension of the coordinates that define
175         * this Geometry, which must be the same as the coordinate dimension of the coordinate reference
176         * system for this Geometry.
177         */
178        public int getCoordinateDimension() {
179            return getPosition().getCoordinateDimension();
180        }
181    
182        /**
183         * returns a shallow copy of the geometry.
184         */
185        @Override
186        public Object clone() {
187            return new PointImpl( this );
188        }
189    
190        /**
191         * returns the x-value of this point
192         */
193        public double getX() {
194            return position.getX();
195        }
196    
197        /**
198         * returns the y-value of this point
199         */
200        public double getY() {
201            return position.getY();
202        }
203    
204        /**
205         * returns the y-value of this point
206         */
207        public double getZ() {
208            return position.getZ();
209        }
210    
211        /**
212         * returns the x- and y-value of the point as a two dimensional array the first field contains
213         * the x- the second field the y-value.
214         */
215        public double[] getAsArray() {
216            return position.getAsArray();
217        }
218    
219        /**
220         * translate the point by the submitted values. the <code>dz</code>- value will be ignored.
221         */
222        @Override
223        public void translate( double[] d ) {
224            setValid( false );
225            position.translate( d );
226        }
227    
228        /**
229         * @return position
230         * 
231         */
232        public Position getPosition() {
233            return position;
234        }
235    
236        /**
237         * The Boolean valued operation "intersects" shall return TRUE if this Geometry intersects
238         * another Geometry. Within a Complex, the Primitives do not intersect one another. In general,
239         * topologically structured data uses shared geometric objects to capture intersection
240         * information.
241         * <p>
242         * </p>
243         * dummy implementation
244         */
245        @Override
246        public boolean intersects( Geometry gmo ) {
247            boolean inter = false;
248    
249            try {
250                if ( gmo instanceof Point ) {
251                    inter = LinearIntersects.intersects( (Point) gmo, this );
252                } else if ( gmo instanceof Curve ) {
253                    inter = LinearIntersects.intersects( this, (Curve) gmo );
254                } else if ( gmo instanceof Surface ) {
255                    inter = LinearIntersects.intersects( this, (Surface) gmo );
256                } else if ( gmo instanceof Aggregate ) {
257                    inter = intersectsAggregate( (Aggregate) gmo );
258                }
259            } catch ( Exception e ) {
260                // ignore
261            }
262    
263            return inter;
264        }
265    
266        /**
267         * the operations returns true if the submitted multi primitive intersects with the curve
268         * segment
269         */
270        private boolean intersectsAggregate( Aggregate mprim )
271                                throws Exception {
272            boolean inter = false;
273    
274            int cnt = mprim.getSize();
275    
276            for ( int i = 0; i < cnt; i++ ) {
277                if ( intersects( mprim.getObjectAt( i ) ) ) {
278                    inter = true;
279                    break;
280                }
281            }
282    
283            return inter;
284        }
285    
286        /**
287         * The Boolean valued operation "contains" shall return TRUE if this Geometry contains another
288         * Geometry.
289         * <p>
290         * </p>
291         */
292        @Override
293        public boolean contains( Geometry gmo ) {
294            throw new NoSuchMethodError( "the contains operation for points "
295                                         + "isn't supported at the moment." );
296        }
297    
298        /**
299         * recalculates internal parameters
300         */
301        @Override
302        protected void calculateParam() {
303            setValid( true );
304        }
305    
306        @Override
307        public String toString() {
308            StringBuffer ret = new StringBuffer( 30 );
309            ret.append( this.getClass().getName() ).append( ": " );
310    
311            for ( int i = 0; i < getAsArray().length; i++ ) {
312                ret.append( getAsArray()[i] ).append( ' ' );
313            }
314    
315            return ret.toString();
316        }
317    
318    }