    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }