    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }