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