001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/model/spatialschema/CurveBoundaryImpl.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 org.deegree.framework.log.ILogger;
049    import org.deegree.framework.log.LoggerFactory;
050    import org.deegree.model.crs.CoordinateSystem;
051    
052    /**
053     * default implementation of the CurveBoundary interface from package jago.model.
054     * 
055     * <p>
056     * ------------------------------------------------------------
057     * </p>
058     * 
059     * @version 10.6.2001
060     * @author Andreas Poth
061     */
062    
063    class CurveBoundaryImpl extends PrimitiveBoundaryImpl implements CurveBoundary, Serializable {
064    
065        private ILogger LOG = LoggerFactory.getLogger( CurveBoundaryImpl.class );
066    
067        /** Use serialVersionUID for interoperability. */
068        private final static long serialVersionUID = 4226497939552424434L;
069    
070        private Position ep = null;
071    
072        private Position sp = null;
073    
074        /**
075         * constructor of curve_boundary with CS_CoordinateSystem and startpoint and endpoint
076         */
077        public CurveBoundaryImpl( CoordinateSystem crs, Position sp, Position ep ) {
078            super( crs );
079    
080            this.sp = sp;
081            this.ep = ep;
082    
083            setValid( false );
084        }
085    
086        /**
087         * The operation "dimension" shall return the inherent dimension of this Geometry, which shall
088         * be less than or equal to the coordinate dimension. The dimension of a collection of geometric
089         * objects shall be the largest dimension of any of its pieces. Points are 0-dimensional, curves
090         * are 1-dimensional, surfaces are 2-dimensional, and solids are 3-dimensional.
091         */
092        public int getDimension() {
093            return 1;
094        }
095    
096        /**
097         * The operation "coordinateDimension" shall return the dimension of the coordinates that define
098         * this Geometry, which must be the same as the coordinate dimension of the coordinate reference
099         * system for this Geometry.
100         */
101        public int getCoordinateDimension() {
102            return getStartPoint().getCoordinateDimension();
103        }
104    
105        /**
106         * returns a shallow copy of the geometry
107         */
108        public Object clone() {
109            CurveBoundary cb = null;
110    
111            try {
112                cb = new CurveBoundaryImpl( getCoordinateSystem(), sp, ep );
113            } catch ( Exception ex ) {
114                LOG.logError( ex.getMessage(), ex );
115            }
116    
117            return cb;
118        }
119    
120        /**
121         * returns the StartPoint of the boundary
122         */
123        public Position getStartPoint() {
124            return sp;
125        }
126    
127        /**
128         * returns the EndPoint of the boundary
129         */
130        public Position getEndPoint() {
131            return ep;
132        }
133    
134        /**
135         * checks if this curve is completly equal to the submitted geometry
136         * 
137         * @param other
138         *            object to compare to
139         */
140        public boolean equals( Object other ) {
141            if ( !super.equals( other ) || !( other instanceof CurveBoundaryImpl ) ) {
142                return false;
143            }
144    
145            if ( !ep.equals( ( (CurveBoundary) other ).getEndPoint() )
146                 || !sp.equals( ( (CurveBoundary) other ).getStartPoint() ) ) {
147                return false;
148            }
149    
150            return true;
151        }
152    
153        /**
154         * The Boolean valued operation "intersects" shall return TRUE if this Geometry intersects
155         * another Geometry. Within a Complex, the Primitives do not intersect one another. In general,
156         * topologically structured data uses shared geometric objects to capture intersection
157         * information.
158         */
159        public boolean intersects( Geometry gmo ) {
160            boolean inter = false;
161            Point p1 = new PointImpl( sp, crs );
162            Point p2 = new PointImpl( ep, crs );
163    
164            try {
165                if ( gmo instanceof Point ) {
166                    inter = LinearIntersects.intersects( p1, (Point) gmo );
167    
168                    if ( !inter ) {
169                        inter = LinearIntersects.intersects( p2, (Point) gmo );
170                    }
171                } else if ( gmo instanceof Curve ) {
172                    inter = LinearIntersects.intersects( p1, (Curve) gmo );
173    
174                    if ( !inter ) {
175                        inter = LinearIntersects.intersects( p2, (Curve) gmo );
176                    }
177                } else if ( gmo instanceof Surface ) {
178                    inter = LinearIntersects.intersects( p1, (Surface) gmo );
179    
180                    if ( !inter ) {
181                        inter = LinearIntersects.intersects( p2, (Surface) gmo );
182                    }
183                } else if ( gmo instanceof MultiPrimitive ) {
184                    inter = intersectsMultiPrimitive( (MultiPrimitive) gmo );
185                }
186            } catch ( Exception e ) {
187            }
188    
189            return inter;
190        }
191    
192        /**
193         * the operations returns true if the submitted multi primitive intersects with the curve
194         * segment
195         */
196        private boolean intersectsMultiPrimitive( MultiPrimitive mprim )
197                                throws Exception {
198            boolean inter = false;
199    
200            int cnt = mprim.getSize();
201    
202            for ( int i = 0; i < cnt; i++ ) {
203                if ( intersects( mprim.getPrimitiveAt( i ) ) ) {
204                    inter = true;
205                    break;
206                }
207            }
208    
209            return inter;
210        }
211    
212        /**
213         * calculates the envelope of the curve boundary
214         */
215        private void calculateEnvelope() {
216            double[] min = sp.getAsArray().clone();
217            double[] max = ep.getAsArray().clone();
218    
219            for ( int i = 0; i < min.length; i++ ) {
220                if ( min[i] > max[i] ) {
221                    double d = min[i];
222                    min[i] = max[i];
223                    max[i] = d;
224                }
225            }
226    
227            envelope = new EnvelopeImpl( new PositionImpl( min ), new PositionImpl( max ), this.crs );
228        }
229    
230        /**
231         * calculates the envelope of the curve boundary
232         */
233        protected void calculateParam() {
234            calculateEnvelope();
235            setValid( true );
236        }
237    
238        /**
239         * 
240         * 
241         * @return
242         */
243        public String toString() {
244            return "point1: [" + sp + "] - point2: [" + ep + "]";
245        }
246    }