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