001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/AggregateImpl.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    import java.util.ArrayList;
048    import java.util.Iterator;
049    
050    import org.deegree.framework.log.ILogger;
051    import org.deegree.framework.log.LoggerFactory;
052    import org.deegree.model.crs.CoordinateSystem;
053    
054    
055    
056    /**
057    * default implementierung of the Aggregate interface 
058    *
059    * ------------------------------------------------------------
060    * @version 8.6.2001
061    * @author Andreas Poth href="mailto:poth@lat-lon.de"
062    */
063    abstract class AggregateImpl extends GeometryImpl implements Aggregate, Serializable {
064        
065        private static ILogger LOG = LoggerFactory.getLogger( AggregateImpl.class );
066        
067        /** Use serialVersionUID for interoperability. */
068        private final static long serialVersionUID = 1161164609227432958L;
069        protected ArrayList<Geometry> aggregate = new ArrayList<Geometry>( 500 );
070        
071    
072        /**
073         * Creates a new AggregateImpl object.
074         *
075         * @param crs 
076         */
077        public AggregateImpl( CoordinateSystem crs ) {
078            super( crs );
079        }
080    
081        /**
082         * Creates a new AggregateImpl object.
083         */
084        private AggregateImpl() {
085            super( null );
086        }        
087    
088        /**
089         * returns the number of Geometry within the aggregation
090         */
091        public int getSize() {
092            return aggregate.size();
093        }
094    
095        /**
096         * merges this aggregation with another one 
097         *
098         * @exception GeometryException a GeometryException will be thrown if the submitted
099         *             isn't the same type as the recieving one.
100         */
101        public void merge( Aggregate aggregate ) throws GeometryException {
102            if ( !this.getClass().getName().equals( aggregate.getClass().getName() ) ) {
103                throw new GeometryException( "Aggregations are not of the same type!" );
104            }
105    
106            for ( int i = 0; i < this.getSize(); i++ ) {
107                this.add( aggregate.getObjectAt( i ) );
108            }
109    
110            setValid( false );
111        }
112    
113        /**
114         * adds an Geometry to the aggregation 
115         */
116        public void add( Geometry gmo ) {
117            aggregate.add( gmo );
118    
119            setValid( false );
120        }
121    
122        /**
123         * inserts a Geometry in the aggregation. all elements with an index 
124         * equal or larger index will be moved. if index is
125         * larger then getSize() - 1 or smaller then 0 or gmo equals null 
126         * an exception will be thrown.
127         *
128         * @param gmo Geometry to insert.     
129         * @param index position where to insert the new Geometry
130         */
131        public void insertObjectAt( Geometry gmo, int index ) throws GeometryException {
132            if ( ( index < 0 ) || ( index > this.getSize() - 1 ) ) {
133                    throw new GeometryException( "invalid index/position: " + index +
134                                                                    " to insert a geometry!" );
135            } 
136    
137            if ( gmo == null ) {
138                throw new GeometryException( "gmo == null. it isn't possible to insert a value" + 
139                                        " that equals null!" );
140            }
141    
142            aggregate.add( index, gmo );
143    
144            setValid( false );
145        }
146    
147        /**
148         * sets the submitted Geometry at the submitted index. the element
149         * at the position <code>index</code> will be removed. if index is
150         * larger then getSize() - 1 or smaller then 0 or gmo equals null 
151         * an exception will be thrown.
152         *
153         * @param gmo Geometry to set.     
154         * @param index position where to set the new Geometry
155         */
156        public void setObjectAt( Geometry gmo, int index ) throws GeometryException {
157            if ( ( index < 0 ) || ( index > this.getSize() - 1 ) ) {
158                    throw new GeometryException( "invalid index/position: " + index +
159                                                                    " to set a geometry!" );
160            }
161    
162            if ( gmo == null ) {
163                throw new GeometryException( "gmo == null. it isn't possible to set a value" + 
164                                        " that equals null!" );
165            }
166    
167            aggregate.set( index, gmo );
168    
169            setValid( false );
170        }
171    
172        /**
173         * removes the submitted Geometry from the aggregation
174         *
175         * @return the removed Geometry
176         */
177        public Geometry removeObject( Geometry gmo ) {
178            if ( gmo == null ) {
179                return null;
180            }
181    
182            int i = aggregate.indexOf( gmo );
183    
184            Geometry gmo_ = null;
185    
186            try {
187                gmo_ = removeObjectAt( i );
188            } catch ( GeometryException e ) {
189                LOG.logError( e.getMessage(), e );
190            }
191    
192            setValid( false );
193    
194            return gmo_;
195        }
196    
197        /**
198         * removes the Geometry at the submitted index from the aggregation.
199         * if index is larger then getSize() - 1 or smaller then 0 
200         * an exception will be thrown.
201         *
202         * @return the removed Geometry
203         */
204        public Geometry removeObjectAt( int index ) throws GeometryException {
205            if ( index < 0 ) {
206                return null;
207            }
208    
209            if ( index > ( this.getSize() - 1 ) ) {
210                throw new GeometryException( "invalid index/position: " + index +
211                                                            " to remove a geometry!" );
212            }
213    
214            Geometry gmo = aggregate.remove( index );
215    
216            setValid( false );
217    
218            return gmo;
219        }
220    
221        /**
222         * removes all Geometry from the aggregation. 
223         */
224        public void removeAll() {
225            aggregate.clear();
226            envelope = null;
227            setValid( false );
228        }
229    
230        /**
231         * returns the Geometry at the submitted index. if index is
232         * larger then getSize() - 1 or smaller then 0 
233         * an exception will be thrown.
234         */
235        public Geometry getObjectAt( int index ) {
236            return aggregate.get( index );
237        }
238    
239        /**
240         * returns all Geometries as array
241         */
242        public Geometry[] getAll() {
243            Geometry[] gmos = new Geometry[this.getSize()];
244    
245            return aggregate.toArray( gmos );
246        }
247    
248        /**
249         * returns true if the submitted Geometry is within the aggregation
250         */
251        public boolean isMember( Geometry gmo ) {
252            return aggregate.contains( gmo );
253        }
254    
255        /**
256         * returns the aggregation as an iterator
257         */
258        public Iterator getIterator() {
259            return aggregate.iterator();
260        }
261    
262        /**
263         * returns true if no geometry stored
264         * within the collection.
265         */
266        public boolean isEmpty() {
267            return ( getSize() == 0 );
268        }
269    
270        /**
271         * sets the spatial reference system
272         *
273         * @param crs new spatial reference system
274         */
275        public void setCoordinateSystem( CoordinateSystem crs ) {
276            super.setCoordinateSystem( crs );
277    
278            if ( aggregate != null ) {
279                for ( int i = 0; i < aggregate.size(); i++ ) {
280                    ( (GeometryImpl)getObjectAt( i ) ).setCoordinateSystem( crs );
281                }
282                setValid( false );
283            }
284        }    
285    
286        /**
287         * translate the point by the submitted values. the <code>dz</code>-
288         * value will be ignored.
289         */
290        public void translate( double[] d ) {
291            try {
292                for ( int i = 0; i < getSize(); i++ ) {
293                    Geometry gmo = getObjectAt( i );
294                    gmo.translate( d );
295                }
296                setValid( false );
297            } catch ( Exception e ) {
298                LOG.logError( e.getMessage(), e );
299            }
300            setValid( false );
301        }
302    
303        /**
304         *
305         *
306         * @param other 
307         *
308         * @return 
309         */
310        public boolean equals( Object other ) {
311            if ( envelope == null ) {
312                    calculateParam();
313            }
314            if ( !super.equals( other ) || !( other instanceof AggregateImpl ) || 
315                     !envelope.equals( ( (Geometry)other ).getEnvelope() ) || 
316                     ( getSize() != ( (Aggregate)other ).getSize() ) ) {
317                return false;
318            }
319    
320            try {
321                for ( int i = 0; i < getSize(); i++ ) {
322                    Object o1 = getObjectAt( i );
323                    Object o2 = ( (Aggregate)other ).getObjectAt( i );
324    
325                    if ( !o1.equals( o2 ) ) {
326                        return false;
327                    }
328                }
329            } catch ( Exception ex ) {
330                return false;
331            }
332    
333            return true;
334        }
335    
336        /**
337         * The Boolean valued operation "intersects" shall return TRUE if this Geometry
338         * intersects another Geometry. Within a Complex, the Primitives do not
339         * intersect one another. In general, topologically structured data uses shared
340         * geometric objects to capture intersection information.
341         */
342        public boolean intersects( Geometry gmo ) {
343            boolean inter = false;
344    
345            try {
346                for ( int i = 0; i < aggregate.size(); i++ ) {
347                    if ( this.getObjectAt( i ).intersects( gmo ) ) {
348                        inter = true;
349                        break;
350                    }
351                }
352            } catch ( Exception e ) {
353            }
354    
355            return inter;
356        }
357    
358        /**
359         *
360         *
361         * @return 
362         */
363        public String toString() {
364            String ret = null;
365            ret = "aggregate = " + aggregate + "\n";
366            ret += ( "envelope = " + envelope + "\n" );
367            return ret;
368        }
369    }/* ********************************************************************
370    Changes to this class. What the people have been up to:
371    $Log$
372    Revision 1.7  2006/11/27 09:07:51  poth
373    JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
374    
375    Revision 1.6  2006/07/12 14:46:15  poth
376    comment footer added
377    
378    ********************************************************************** */