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