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