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