001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/model/spatialschema/MultiCurveImpl.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 048 import org.deegree.framework.log.ILogger; 049 import org.deegree.framework.log.LoggerFactory; 050 import org.deegree.model.crs.CoordinateSystem; 051 052 /** 053 * default implementation of the MultiCurve interface from package jago.model. 054 * 055 * ------------------------------------------------------------ 056 * 057 * @version 12.6.2001 058 * @author Andreas Poth 059 */ 060 final class MultiCurveImpl extends MultiPrimitiveImpl implements MultiCurve, Serializable { 061 /** Use serialVersionUID for interoperability. */ 062 private final static long serialVersionUID = 2730942874409216686L; 063 064 private static final ILogger LOG = LoggerFactory.getLogger( MultiCurveImpl.class ); 065 066 /** 067 * Creates a new MultiCurveImpl object. 068 * 069 * @param crs 070 */ 071 public MultiCurveImpl( CoordinateSystem crs ) { 072 super( crs ); 073 } 074 075 /** 076 * Creates a new MultiCurveImpl object. 077 * 078 * @param gmc 079 */ 080 public MultiCurveImpl( Curve[] gmc ) { 081 super( gmc[0].getCoordinateSystem() ); 082 083 for ( int i = 0; i < gmc.length; i++ ) { 084 aggregate.add( gmc[i] ); 085 } 086 087 } 088 089 /** 090 * Creates a new MultiCurveImpl object. 091 * 092 * @param gmc 093 * @param crs 094 */ 095 public MultiCurveImpl( Curve[] gmc, CoordinateSystem crs ) { 096 super( crs ); 097 098 for ( int i = 0; i < gmc.length; i++ ) { 099 aggregate.add( gmc[i] ); 100 } 101 102 } 103 104 /** 105 * adds a Curve to the aggregation 106 */ 107 public void addCurve( Curve gmc ) { 108 super.add( gmc ); 109 } 110 111 /** 112 * inserts a Curve in the aggregation. all elements with an index equal or larger index will be 113 * moved. if index is larger then getSize() - 1 or smaller then 0 or gmc equals null an 114 * exception will be thrown. 115 * 116 * @param gmc 117 * Curve to insert. 118 * @param index 119 * position where to insert the new Curve 120 */ 121 public void insertCurveAt( Curve gmc, int index ) 122 throws GeometryException { 123 super.insertObjectAt( gmc, index ); 124 } 125 126 /** 127 * sets the submitted Curve at the submitted index. the element at the position 128 * <code>index</code> will be removed. if index is larger then getSize() - 1 or smaller then 0 129 * or gmc equals null an exception will be thrown. 130 * 131 * @param gmc 132 * Curve to set. 133 * @param index 134 * position where to set the new Curve 135 */ 136 public void setCurveAt( Curve gmc, int index ) 137 throws GeometryException { 138 setObjectAt( gmc, index ); 139 } 140 141 /** 142 * removes the submitted Curve from the aggregation 143 * 144 * @return the removed Curve 145 */ 146 public Curve removeCurve( Curve gmc ) { 147 return (Curve) super.removeObject( gmc ); 148 } 149 150 /** 151 * removes the Curve at the submitted index from the aggregation. if index is larger then 152 * getSize() - 1 or smaller then 0 an exception will be thrown. 153 * 154 * @return the removed Curve 155 */ 156 public Curve removeCurveAt( int index ) 157 throws GeometryException { 158 return (Curve) super.removeObjectAt( index ); 159 } 160 161 /** 162 * removes all Curve from the aggregation. 163 */ 164 public void removeAll() { 165 super.removeAll(); 166 } 167 168 /** 169 * returns the Curve at the submitted index. 170 */ 171 public Curve getCurveAt( int index ) { 172 return (Curve) super.getPrimitiveAt( index ); 173 } 174 175 /** 176 * returns all Curves as array 177 */ 178 public Curve[] getAllCurves() { 179 return aggregate.toArray( new Curve[getSize()] ); 180 } 181 182 /** 183 * returns true if the submitted Curve is within the aggregation 184 */ 185 public boolean isMember( Curve gmc ) { 186 return super.isMember( gmc ); 187 } 188 189 /** 190 * returns the boundary of the MultiCurve 191 * <p> 192 * not implemented yet 193 */ 194 public Boundary getBoundary() { 195 return null; 196 } 197 198 /** 199 * calculates the bounding box / envelope of the aggregation 200 */ 201 protected void calculateEnvelope() { 202 Envelope bb = getCurveAt( 0 ).getEnvelope(); 203 204 double[] min = bb.getMin().getAsArray().clone(); 205 double[] max = bb.getMax().getAsArray().clone(); 206 207 for ( int i = 1; i < getSize(); i++ ) { 208 double[] pos1 = getCurveAt( i ).getEnvelope().getMin().getAsArray(); 209 double[] pos2 = getCurveAt( i ).getEnvelope().getMax().getAsArray(); 210 211 for ( int j = 0; j < pos1.length; j++ ) { 212 if ( pos1[j] < min[j] ) { 213 min[j] = pos1[j]; 214 } else if ( pos1[j] > max[j] ) { 215 max[j] = pos1[j]; 216 } 217 218 if ( pos2[j] < min[j] ) { 219 min[j] = pos2[j]; 220 } else if ( pos2[j] > max[j] ) { 221 max[j] = pos2[j]; 222 } 223 } 224 } 225 226 envelope = new EnvelopeImpl( new PositionImpl( min ), new PositionImpl( max ), this.crs ); 227 } 228 229 /** 230 * calculates the centroid of the aggregation 231 */ 232 protected void calculateCentroid() { 233 try { 234 double cnt = 0; 235 Point gmp = getCurveAt( 0 ).getCentroid(); 236 237 double[] cen = new double[gmp.getAsArray().length]; 238 239 for ( int i = 0; i < getSize(); i++ ) { 240 cnt += getCurveAt( i ).getNumberOfCurveSegments(); 241 242 double[] pos = getCurveAt( i ).getCentroid().getAsArray(); 243 244 for ( int j = 0; j < getCoordinateDimension(); j++ ) { 245 cen[j] += pos[j]; 246 } 247 } 248 249 for ( int j = 0; j < getCoordinateDimension(); j++ ) { 250 cen[j] = cen[j] / cnt / getSize(); 251 } 252 253 centroid = new PointImpl( new PositionImpl( cen ), null ); 254 } catch ( Exception ex ) { 255 LOG.logError( "", ex ); 256 } 257 } 258 259 /** 260 * calculates the centroid and envelope of the aggregation 261 */ 262 protected void calculateParam() { 263 calculateCentroid(); 264 calculateEnvelope(); 265 setValid( true ); 266 } 267 268 /** 269 * The operation "dimension" shall return the inherent dimension of this Geometry, which shall 270 * be less than or equal to the coordinate dimension. The dimension of a collection of geometric 271 * objects shall be the largest dimension of any of its pieces. Points are 0-dimensional, curves 272 * are 1-dimensional, surfaces are 2-dimensional, and solids are 3-dimensional. 273 */ 274 public int getDimension() { 275 return 1; 276 } 277 278 /** 279 * The operation "coordinateDimension" shall return the dimension of the coordinates that define 280 * this Geometry, which must be the same as the coordinate dimension of the coordinate reference 281 * system for this Geometry. 282 */ 283 public int getCoordinateDimension() { 284 return getCurveAt( 0 ).getCoordinateDimension(); 285 } 286 287 /** 288 * returns a shallow copy of the geometry 289 */ 290 public Object clone() { 291 MultiCurve mc = null; 292 293 try { 294 mc = new MultiCurveImpl( getCoordinateSystem() ); 295 296 for ( int i = 0; i < this.getSize(); i++ ) { 297 CurveImpl ci = (CurveImpl) getCurveAt( i ); 298 mc.addCurve( (Curve) ci.clone() ); 299 } 300 } catch ( Exception ex ) { 301 LOG.logError( "MultiCurve_Impl.clone: ", ex ); 302 } 303 304 return mc; 305 } 306 }