001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/rtree/HyperBoundingBox.java $
002 //----------------------------------------
003 //RTree implementation.
004 //Copyright (C) 2002-2004 Wolfgang Baer - WBaer@gmx.de
005 //
006 //This library is free software; you can redistribute it and/or
007 //modify it under the terms of the GNU Lesser General Public
008 //License as published by the Free Software Foundation; either
009 //version 2.1 of the License, or (at your option) any later version.
010 //
011 //This library is distributed in the hope that it will be useful,
012 //but WITHOUT ANY WARRANTY; without even the implied warranty of
013 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 //Lesser General Public License for more details.
015 //
016 //You should have received a copy of the GNU Lesser General Public
017 //License along with this library; if not, write to the Free Software
018 //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019 //----------------------------------------
020
021 package org.deegree.io.rtree;
022
023 import java.io.Serializable;
024
025 /**
026 * <p>
027 * HyperBoundingBox implementing a bounding box object in the multidimensional space.
028 * </p>
029 *
030 * @author Wolfgang Baer - WBaer@gmx.de
031 */
032
033 public class HyperBoundingBox implements Serializable {
034
035 private HyperPoint pMin;
036
037 private HyperPoint pMax;
038
039 /**
040 * Constructor.<br>
041 * Creates a HyperBoundingBox for given HyperPoints.
042 *
043 * @param pMin -
044 * min point
045 * @param pMax -
046 * max point
047 */
048 public HyperBoundingBox( HyperPoint pMin, HyperPoint pMax ) {
049 if ( pMin.getDimension() != pMax.getDimension() )
050 throw new IllegalArgumentException( "HyperPoints need same dimension: " + pMin.getDimension() + " != "
051 + pMax.getDimension() );
052
053 this.pMin = pMin;
054 this.pMax = pMax;
055 }
056
057 /**
058 * Creates a null HyperBoundingBox with null HyperPoints. Mostly used internal.
059 *
060 * @param dimension -
061 * int for dimension of point
062 * @return HyperBoundingBox
063 */
064 protected static HyperBoundingBox getNullHyperBoundingBox( int dimension ) {
065 return new HyperBoundingBox( HyperPoint.getNullHyperPoint( dimension ),
066 HyperPoint.getNullHyperPoint( dimension ) );
067 }
068
069 /**
070 * Returns the minimum HyperPoint
071 *
072 * @return HyperPoint
073 *
074 */
075 public HyperPoint getPMin() {
076 return pMin;
077 }
078
079 /**
080 * Returns the maximum HyperPoint
081 *
082 * @return HyperPoint
083 *
084 */
085 public HyperPoint getPMax() {
086 return pMax;
087 }
088
089 /**
090 * Returns the dimension of this HyperBoundingBox.
091 *
092 * @return int
093 */
094 public int getDimension() {
095 return pMin.getDimension();
096 }
097
098 /**
099 * Tests if this and the given HyperBoundingBox overlaps.
100 *
101 * @param box -
102 * HyperBoundingBox to test
103 * @return boolean
104 */
105 public boolean overlaps( HyperBoundingBox box ) {
106 boolean intersect = true;
107
108 for ( int i = 0; i < getDimension(); i++ ) {
109 if ( ( pMin.getCoord( i ) > box.getPMax().getCoord( i ) )
110 || ( pMax.getCoord( i ) < box.getPMin().getCoord( i ) ) ) {
111 intersect = false;
112 break;
113 }
114 }
115
116 return intersect;
117 }
118
119 /**
120 * Tests if this contains the given HyperBoundingBox overlaps.
121 *
122 * @param box -
123 * HyperBoundingBox to test
124 * @return boolean
125 */
126 public boolean contains( HyperBoundingBox box ) {
127 boolean contains = true;
128
129 for ( int i = 0; i < getDimension(); i++ ) {
130 if ( ( pMin.getCoord( i ) > box.getPMin().getCoord( i ) )
131 || ( pMax.getCoord( i ) < box.getPMax().getCoord( i ) ) ) {
132 contains = false;
133 break;
134 }
135 }
136
137 return contains;
138 }
139
140 /**
141 * Computes the area (over all dimension) of this.
142 *
143 * @return double
144 */
145 public double getArea() {
146 double area = 1;
147
148 for ( int i = 0; i < pMin.getDimension(); i++ )
149 area = area * ( pMax.getCoord( i ) - pMin.getCoord( i ) );
150
151 return area;
152 }
153
154 /**
155 * Computes the union of this with the given HyperBoundingBox.
156 *
157 * @param box -
158 * given HyperBoundingBox
159 * @return HyperBoundingBox
160 */
161 public HyperBoundingBox unionBoundingBox( HyperBoundingBox box ) {
162
163 if ( this.getDimension() != box.getDimension() )
164 throw new IllegalArgumentException( "HyperBoundingBoxes need same dimension " + this.getDimension()
165 + " != " + box.getDimension() );
166
167 if ( this.equals( HyperBoundingBox.getNullHyperBoundingBox( this.getDimension() ) ) )
168 return box;
169 if ( box.equals( HyperBoundingBox.getNullHyperBoundingBox( this.getDimension() ) ) )
170 return this;
171
172 double[] min = new double[this.getDimension()];
173 double[] max = new double[this.getDimension()];
174
175 for ( int i = 0; i < this.getDimension(); i++ ) {
176
177 if ( this.getPMin().getCoord( i ) <= box.getPMin().getCoord( i ) ) {
178 min[i] = this.getPMin().getCoord( i );
179 } else {
180 min[i] = box.getPMin().getCoord( i );
181 }
182 if ( this.getPMax().getCoord( i ) >= box.getPMax().getCoord( i ) ) {
183 max[i] = this.getPMax().getCoord( i );
184 } else {
185 max[i] = box.getPMax().getCoord( i );
186 }
187 }
188 return new HyperBoundingBox( new HyperPoint( min ), new HyperPoint( max ) );
189 }
190
191 /**
192 * Computes the minimal distance square of this to the given HyperPoint. After Roussopoulos
193 * Nick: Nearest Neighbor Queries - MINDIST
194 *
195 * @param point -
196 * HyperPoint
197 * @return double
198 */
199 public double minDist( HyperPoint point ) {
200 double min = 0;
201 double ri = 0;
202
203 for ( int i = 0; i < point.getDimension(); i++ ) {
204 if ( point.getCoord( i ) < this.pMin.getCoord( i ) ) {
205 ri = this.pMin.getCoord( i );
206 } else {
207 if ( point.getCoord( i ) > this.pMax.getCoord( i ) ) {
208 ri = this.pMax.getCoord( i );
209 } else {
210 ri = point.getCoord( i );
211 }
212 }
213 min = min + Math.pow( point.getCoord( i ) - ri, 2 );
214 }
215 return min;
216 }
217
218 /**
219 * Deep copy.
220 *
221 * @see java.lang.Object#clone()
222 */
223 protected Object clone() {
224 return new HyperBoundingBox( (HyperPoint) pMin.clone(), (HyperPoint) pMax.clone() );
225 }
226
227 /**
228 * Builds a String representation of the HyperBoundingBox.
229 *
230 * @return String
231 */
232 public String toString() {
233 return "BOX: P-Min (" + pMin.toString() + "), P-Max (" + pMax.toString() + ")";
234 }
235
236 /**
237 * Implements equals
238 *
239 * @see java.lang.Object#equals(java.lang.Object)
240 */
241 public boolean equals( Object obj ) {
242 HyperBoundingBox box = (HyperBoundingBox) obj;
243 return ( this.pMin.equals( box.pMin ) && this.pMax.equals( box.pMax ) );
244 }
245 }