001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/model/spatialschema/MultiCurveImpl.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 MultiCurve interface from package deegree.model.spatialschema.
046     *
047     * ------------------------------------------------------------
048     *
049     * @version 12.6.2001
050     * @author Andreas Poth
051     */
052    public class MultiCurveImpl extends MultiPrimitiveImpl implements MultiCurve, Serializable {
053        /** Use serialVersionUID for interoperability. */
054        private final static long serialVersionUID = 2730942874409216686L;
055    
056        private static final ILogger LOG = LoggerFactory.getLogger( MultiCurveImpl.class );
057    
058        /**
059         * Creates a new MultiCurveImpl object.
060         *
061         * @param crs
062         */
063        protected MultiCurveImpl( CoordinateSystem crs ) {
064            super( crs );
065        }
066    
067        /**
068         * Creates a new MultiCurveImpl object.
069         *
070         * @param curve
071         */
072        protected MultiCurveImpl( Curve[] curve ) {
073            super( curve[0].getCoordinateSystem() );
074    
075            for ( int i = 0; i < curve.length; i++ ) {
076                aggregate.add( curve[i] );
077            }
078    
079        }
080    
081        /**
082         * Creates a new MultiCurveImpl object.
083         *
084         * @param curve
085         * @param crs
086         */
087        protected MultiCurveImpl( Curve[] curve, CoordinateSystem crs ) {
088            super( crs );
089    
090            for ( int i = 0; i < curve.length; i++ ) {
091                aggregate.add( curve[i] );
092            }
093    
094        }
095    
096        /**
097         * adds a Curve to the aggregation
098         */
099        public void addCurve( Curve curve ) {
100            super.add( curve );
101        }
102    
103        /**
104         * inserts a Curve in the aggregation. all elements with an index equal or larger index will be moved. if index is
105         * larger then getSize() - 1 or smaller then 0 or curve equals null an exception will be thrown.
106         *
107         * @param curve
108         *            Curve to insert.
109         * @param index
110         *            position where to insert the new Curve
111         */
112        public void insertCurveAt( Curve curve, int index )
113                                throws GeometryException {
114            super.insertObjectAt( curve, index );
115        }
116    
117        /**
118         * sets the submitted Curve at the submitted index. the element at the position <code>index</code> will be
119         * removed. if index is larger then getSize() - 1 or smaller then 0 or curve equals null an exception will be
120         * thrown.
121         *
122         * @param curve
123         *            Curve to set.
124         * @param index
125         *            position where to set the new Curve
126         */
127        public void setCurveAt( Curve curve, int index )
128                                throws GeometryException {
129            setObjectAt( curve, index );
130        }
131    
132        /**
133         * removes the submitted Curve from the aggregation
134         *
135         * @return the removed Curve
136         */
137        public Curve removeCurve( Curve curve ) {
138            return (Curve) super.removeObject( curve );
139        }
140    
141        /**
142         * removes the Curve at the submitted index from the aggregation. if index is larger then getSize() - 1 or smaller
143         * then 0 an exception will be thrown.
144         *
145         * @return the removed Curve
146         */
147        public Curve removeCurveAt( int index )
148                                throws GeometryException {
149            return (Curve) super.removeObjectAt( index );
150        }
151    
152        /**
153         * removes all Curve from the aggregation.
154         */
155        @Override
156        public void removeAll() {
157            super.removeAll();
158        }
159    
160        /**
161         * returns the Curve at the submitted index.
162         */
163        public Curve getCurveAt( int index ) {
164            return (Curve) super.getPrimitiveAt( index );
165        }
166    
167        /**
168         * returns all Curves as array
169         */
170        public Curve[] getAllCurves() {
171            return aggregate.toArray( new Curve[getSize()] );
172        }
173    
174        /**
175         * returns true if the submitted Curve is within the aggregation
176         *
177         * @param curve
178         * @return true if the submitted Curve is within the aggregation
179         */
180        public boolean isMember( Curve curve ) {
181            return super.isMember( curve );
182        }
183    
184        /**
185         * returns the boundary of the MultiCurve
186         * <p>
187         * not implemented yet
188         *
189         * @return <code>null</code>
190         */
191        @Override
192        public Boundary getBoundary() {
193            return null;
194        }
195    
196        /**
197         * calculates the bounding box / envelope of the aggregation
198         */
199        protected void calculateEnvelope() {
200            Envelope bb = getCurveAt( 0 ).getEnvelope();
201    
202            double[] min = bb.getMin().getAsArray().clone();
203            double[] max = bb.getMax().getAsArray().clone();
204    
205            for ( int i = 1; i < getSize(); i++ ) {
206                double[] pos1 = getCurveAt( i ).getEnvelope().getMin().getAsArray();
207                double[] pos2 = getCurveAt( i ).getEnvelope().getMax().getAsArray();
208    
209                for ( int j = 0; j < pos1.length; j++ ) {
210                    if ( pos1[j] < min[j] ) {
211                        min[j] = pos1[j];
212                    } else if ( pos1[j] > max[j] ) {
213                        max[j] = pos1[j];
214                    }
215    
216                    if ( pos2[j] < min[j] ) {
217                        min[j] = pos2[j];
218                    } else if ( pos2[j] > max[j] ) {
219                        max[j] = pos2[j];
220                    }
221                }
222            }
223    
224            envelope = new EnvelopeImpl( new PositionImpl( min ), new PositionImpl( max ), this.crs );
225        }
226    
227        /**
228         * calculates the centroid of the aggregation
229         */
230        protected void calculateCentroid() {
231            try {
232                double cnt = 0;
233                Point gmp = getCurveAt( 0 ).getCentroid();
234    
235                double[] cen = new double[gmp.getAsArray().length];
236    
237                for ( int i = 0; i < getSize(); i++ ) {
238                    cnt += getCurveAt( i ).getNumberOfCurveSegments();
239    
240                    double[] pos = getCurveAt( i ).getCentroid().getAsArray();
241    
242                    for ( int j = 0; j < getCoordinateDimension(); j++ ) {
243                        cen[j] += pos[j];
244                    }
245                }
246    
247                for ( int j = 0; j < getCoordinateDimension(); j++ ) {
248                    cen[j] = cen[j] / cnt / getSize();
249                }
250    
251                centroid = new PointImpl( new PositionImpl( cen ), null );
252            } catch ( Exception ex ) {
253                LOG.logError( "", ex );
254            }
255        }
256    
257        /**
258         * calculates the centroid and envelope of the aggregation
259         */
260        @Override
261        protected void calculateParam() {
262            calculateCentroid();
263            calculateEnvelope();
264            setValid( true );
265        }
266    
267        @Override
268        public int getDimension() {
269            return 1;
270        }
271    
272        @Override
273        public int getCoordinateDimension() {
274            return getCurveAt( 0 ).getCoordinateDimension();
275        }
276    
277        @Override
278        public Object clone() {
279            MultiCurve mc = null;
280    
281            try {
282                mc = new MultiCurveImpl( getCoordinateSystem() );
283    
284                for ( int i = 0; i < this.getSize(); i++ ) {
285                    CurveImpl ci = (CurveImpl) getCurveAt( i );
286                    mc.addCurve( (Curve) ci.clone() );
287                }
288            } catch ( Exception ex ) {
289                LOG.logError( "MultiCurve_Impl.clone: ", ex );
290            }
291    
292            return mc;
293        }
294    }