001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/model/spatialschema/MultiPointImpl.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 MultiPoint interface of package deegree.model.spatialschema.
046 *
047 * <p>
048 * ------------------------------------------------------------
049 * </p>
050 *
051 * @version 12.6.2001
052 * @author Andreas Poth href="mailto:poth@lat-lon.de"
053 * <p>
054 */
055 public class MultiPointImpl extends MultiPrimitiveImpl implements MultiPoint, Serializable {
056 /** Use serialVersionUID for interoperability. */
057 private final static long serialVersionUID = -1105623021535230655L;
058
059 private static final ILogger LOG = LoggerFactory.getLogger( MultiPointImpl.class );
060
061 /**
062 * Creates a new MultiPointImpl object.
063 *
064 * @param crs
065 */
066 protected MultiPointImpl( CoordinateSystem crs ) {
067 super( crs );
068 }
069
070 /**
071 * Creates a new MultiPointImpl object.
072 *
073 * @param gmp
074 */
075 protected MultiPointImpl( Point[] gmp ) {
076 super( gmp[0].getCoordinateSystem() );
077
078 for ( int i = 0; i < gmp.length; i++ ) {
079 aggregate.add( gmp[i] );
080 }
081
082 }
083
084 /**
085 * Creates a new MultiPointImpl object.
086 *
087 * @param gmp
088 * @param crs
089 */
090 protected MultiPointImpl( Point[] gmp, CoordinateSystem crs ) {
091 super( crs );
092
093 for ( int i = 0; i < gmp.length; i++ ) {
094 aggregate.add( gmp[i] );
095 }
096
097 }
098
099 /**
100 * adds a Point to the aggregation
101 */
102 public void addPoint( Point gmp ) {
103 super.add( gmp );
104 }
105
106 /**
107 * inserts a Point into the aggregation. all elements with an index equal or larger index will be moved. if index is
108 * larger then getSize() - 1 or smaller then 0 or gmp equals null an exception will be thrown.
109 *
110 * @param gmp
111 * Point to insert.
112 * @param index
113 * position where to insert the new Point
114 */
115 public void insertPointAt( Point gmp, int index )
116 throws GeometryException {
117 super.insertObjectAt( gmp, index );
118 }
119
120 /**
121 * sets the submitted Point at the submitted index. the element at the position <code>index</code> will be
122 * removed. if index is larger then getSize() - 1 or smaller then 0 or gmp equals null an exception will be thrown.
123 *
124 * @param gmp
125 * Point to set.
126 * @param index
127 * position where to set the new Point
128 */
129 public void setPointAt( Point gmp, int index )
130 throws GeometryException {
131 setObjectAt( gmp, index );
132 }
133
134 /**
135 * removes the submitted Point from the aggregation
136 *
137 * @return the removed Point
138 */
139 public Point removePoint( Point gmp ) {
140 return (Point) super.removeObject( gmp );
141 }
142
143 /**
144 * removes the Point at the submitted index from the aggregation. if index is larger then getSize() - 1 or smaller
145 * then 0 an exception will be thrown.
146 *
147 * @return the removed Point
148 */
149 public Point removePointAt( int index )
150 throws GeometryException {
151 return (Point) super.removeObjectAt( index );
152 }
153
154 /**
155 * returns the Point at the submitted index.
156 */
157 public Point getPointAt( int index ) {
158 return (Point) super.getPrimitiveAt( index );
159 }
160
161 /**
162 * returns all Points as array
163 */
164 public Point[] getAllPoints() {
165 return aggregate.toArray( new Point[getSize()] );
166 }
167
168 /**
169 * updates the bounding box of the aggregation
170 */
171 private void calculateEnvelope() {
172 Point gmp = getPointAt( 0 );
173
174 double[] min = gmp.getAsArray().clone();
175 double[] max = min.clone();
176
177 for ( int i = 1; i < getSize(); i++ ) {
178 double[] pos = getPointAt( i ).getAsArray();
179
180 for ( int j = 0; j < pos.length; j++ ) {
181 if ( pos[j] < min[j] ) {
182 min[j] = pos[j];
183 } else if ( pos[j] > max[j] ) {
184 max[j] = pos[j];
185 }
186 }
187 }
188
189 envelope = new EnvelopeImpl( new PositionImpl( min ), new PositionImpl( max ), this.crs );
190 }
191
192 /**
193 * calculates the centroid of the surface
194 */
195 private void calculateCentroid() {
196 try {
197 Point gmp = getPointAt( 0 );
198
199 double[] cen = new double[gmp.getAsArray().length];
200
201 for ( int i = 0; i < getSize(); i++ ) {
202 double[] pos = getPointAt( i ).getAsArray();
203
204 for ( int j = 0; j < pos.length; j++ ) {
205 cen[j] += ( pos[j] / getSize() );
206 }
207 }
208
209 centroid = new PointImpl( new PositionImpl( cen ), null );
210 } catch ( Exception ex ) {
211 LOG.logError( "", ex );
212 }
213 }
214
215 /**
216 * calculates the centroid and envelope of the aggregation
217 */
218 @Override
219 protected void calculateParam() {
220 calculateCentroid();
221 calculateEnvelope();
222 setValid( true );
223 }
224
225 @Override
226 public int getDimension() {
227 return 0;
228 }
229
230 @Override
231 public int getCoordinateDimension() {
232 return getPointAt( 0 ).getCoordinateDimension();
233 }
234
235 @Override
236 public Object clone() {
237 MultiPoint mp = null;
238
239 try {
240 mp = new MultiPointImpl( getCoordinateSystem() );
241
242 for ( int i = 0; i < this.getSize(); i++ ) {
243 PointImpl pi = (PointImpl) getPointAt( i );
244 mp.add( (Point) pi.clone() );
245 }
246 } catch ( Exception ex ) {
247 LOG.logError( "MultiPoint_Impl.clone: ", ex );
248 }
249
250 return mp;
251 }
252 }