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 }