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 }