001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/model/spatialschema/CurveBoundaryImpl.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.model.spatialschema;
037    
038    import java.io.Serializable;
039    
040    import org.deegree.framework.log.ILogger;
041    import org.deegree.framework.log.LoggerFactory;
042    import org.deegree.model.crs.CoordinateSystem;
043    
044    /**
045     * default implementation of the CurveBoundary interface from package deegree.model.spatialschema.
046     *
047     * <p>
048     * ------------------------------------------------------------
049     * </p>
050     *
051     * @version 10.6.2001
052     * @author Andreas Poth
053     */
054    
055    public class CurveBoundaryImpl extends PrimitiveBoundaryImpl implements CurveBoundary, Serializable {
056    
057        private ILogger LOG = LoggerFactory.getLogger( CurveBoundaryImpl.class );
058    
059        /** Use serialVersionUID for interoperability. */
060        private final static long serialVersionUID = 4226497939552424434L;
061    
062        private Position ep = null;
063    
064        private Position sp = null;
065    
066        /**
067         * constructor of curve_boundary with CS_CoordinateSystem and startpoint and endpoint
068         *
069         * @param crs
070         * @param sp
071         * @param ep
072         */
073        protected CurveBoundaryImpl( CoordinateSystem crs, Position sp, Position ep ) {
074            super( crs );
075    
076            this.sp = sp;
077            this.ep = ep;
078    
079            setValid( false );
080        }
081    
082        /**
083         * The operation "dimension" shall return the inherent dimension of this Geometry, which shall be less than or equal
084         * to the coordinate dimension. The dimension of a collection of geometric objects shall be the largest dimension of
085         * any of its pieces. Points are 0-dimensional, curves are 1-dimensional, surfaces are 2-dimensional, and solids are
086         * 3-dimensional.
087         */
088        public int getDimension() {
089            return 1;
090        }
091    
092        /**
093         * The operation "coordinateDimension" shall return the dimension of the coordinates that define this Geometry,
094         * which must be the same as the coordinate dimension of the coordinate reference system for this Geometry.
095         */
096        public int getCoordinateDimension() {
097            return getStartPoint().getCoordinateDimension();
098        }
099    
100        /**
101         * @return a shallow copy of the geometry
102         */
103        @Override
104        public Object clone() {
105            CurveBoundary cb = null;
106    
107            try {
108                cb = new CurveBoundaryImpl( getCoordinateSystem(), sp, ep );
109            } catch ( Exception ex ) {
110                LOG.logError( ex.getMessage(), ex );
111            }
112    
113            return cb;
114        }
115    
116        /**
117         * returns the StartPoint of the boundary
118         */
119        public Position getStartPoint() {
120            return sp;
121        }
122    
123        /**
124         * returns the EndPoint of the boundary
125         */
126        public Position getEndPoint() {
127            return ep;
128        }
129    
130        /**
131         * checks if this curve is completely equal to the submitted geometry
132         *
133         * @param other
134         *            object to compare to
135         */
136        @Override
137        public boolean equals( Object other ) {
138            if ( !super.equals( other ) || !( other instanceof CurveBoundaryImpl ) ) {
139                return false;
140            }
141    
142            if ( !ep.equals( ( (CurveBoundary) other ).getEndPoint() )
143                 || !sp.equals( ( (CurveBoundary) other ).getStartPoint() ) ) {
144                return false;
145            }
146    
147            return true;
148        }
149    
150        /**
151         * The Boolean valued operation "intersects" shall return TRUE if this Geometry intersects another Geometry. Within
152         * a Complex, the Primitives do not intersect one another. In general, topologically structured data uses shared
153         * geometric objects to capture intersection information.
154         */
155        @Override
156        public boolean intersects( Geometry gmo ) {
157            boolean inter = false;
158            Point p1 = new PointImpl( sp, crs );
159            Point p2 = new PointImpl( ep, crs );
160    
161            try {
162                if ( gmo instanceof Point ) {
163                    inter = LinearIntersects.intersects( p1, (Point) gmo );
164    
165                    if ( !inter ) {
166                        inter = LinearIntersects.intersects( p2, (Point) gmo );
167                    }
168                } else if ( gmo instanceof Curve ) {
169                    inter = LinearIntersects.intersects( p1, (Curve) gmo );
170    
171                    if ( !inter ) {
172                        inter = LinearIntersects.intersects( p2, (Curve) gmo );
173                    }
174                } else if ( gmo instanceof Surface ) {
175                    inter = LinearIntersects.intersects( p1, (Surface) gmo );
176    
177                    if ( !inter ) {
178                        inter = LinearIntersects.intersects( p2, (Surface) gmo );
179                    }
180                } else if ( gmo instanceof MultiPrimitive ) {
181                    inter = intersectsMultiPrimitive( (MultiPrimitive) gmo );
182                }
183            } catch ( Exception e ) {
184                // do nothing
185            }
186    
187            return inter;
188        }
189    
190        /**
191         * the operations returns true if the submitted multi primitive intersects with the curve segment
192         */
193        private boolean intersectsMultiPrimitive( MultiPrimitive mprim )
194                                throws Exception {
195            boolean inter = false;
196    
197            int cnt = mprim.getSize();
198    
199            for ( int i = 0; i < cnt; i++ ) {
200                if ( intersects( mprim.getPrimitiveAt( i ) ) ) {
201                    inter = true;
202                    break;
203                }
204            }
205    
206            return inter;
207        }
208    
209        /**
210         * calculates the envelope of the curve boundary
211         */
212        private void calculateEnvelope() {
213            double[] min = sp.getAsArray().clone();
214            double[] max = ep.getAsArray().clone();
215    
216            for ( int i = 0; i < min.length; i++ ) {
217                if ( min[i] > max[i] ) {
218                    double d = min[i];
219                    min[i] = max[i];
220                    max[i] = d;
221                }
222            }
223    
224            envelope = new EnvelopeImpl( new PositionImpl( min ), new PositionImpl( max ), this.crs );
225        }
226    
227        /**
228         * calculates the envelope of the curve boundary
229         */
230        @Override
231        protected void calculateParam() {
232            calculateEnvelope();
233            setValid( true );
234        }
235    
236        @Override
237        public String toString() {
238            return "point1: [" + sp + "] - point2: [" + ep + "]";
239        }
240    }