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