001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/io/rtree/NoneLeafNode.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    /**
024     * <p>
025     * Implementation of a NoneLeafNode. Inherits methods from the abstract class Node filling the
026     * defined abstract methods with life.
027     * </p>
028     *
029     * @author Wolfgang Baer - WBaer@gmx.de
030     */
031    class NoneLeafNode extends Node {
032    
033        protected int[] childNodes;
034    
035        /**
036         * Constructor.
037         *
038         * @param pageNumber -
039         *            number of this node in page file
040         * @param file -
041         *            the PageFile of this node
042         */
043        protected NoneLeafNode( int pageNumber, PageFile file ) {
044            super( pageNumber, file );
045            childNodes = new int[file.getCapacity()];
046    
047            for ( int i = 0; i < file.getCapacity(); i++ )
048                childNodes[i] = -1;
049        }
050    
051        /**
052         * @see Node#getData(int)
053         */
054        protected Object getData( int index ) {
055            Object obj = null;
056    
057            try {
058                obj = file.readNode( childNodes[index] );
059            } catch ( PageFileException e ) {
060                // PageFileException NoneLeafNode.getData
061                e.printStackTrace();
062            }
063    
064            return obj;
065        }
066    
067        /**
068         * @see Node#insertData(java.lang.Object, HyperBoundingBox)
069         */
070        protected void insertData( Object node, HyperBoundingBox box ) {
071            childNodes[counter] = ( (Node) node ).getPageNumber();
072            hyperBBs[counter] = box;
073            unionMinBB = unionMinBB.unionBoundingBox( box );
074            ( (Node) node ).parentNode = this.pageNumber;
075            ( (Node) node ).place = this.counter;
076            counter++;
077    
078            try {
079                file.writeNode( (Node) node );
080            } catch ( PageFileException e ) {
081                // PageFileException NoneLeafNode.insertData - at writeNode(Node)
082                e.printStackTrace();
083            }
084        }
085    
086        /**
087         * @see Node#insertData(java.lang.Object, HyperBoundingBox)
088         */
089        protected void deleteData( int index ) {
090    
091            if ( this.getUsedSpace() == 1 ) {
092                // only one element is a special case.
093                hyperBBs[0] = HyperBoundingBox.getNullHyperBoundingBox( file.getDimension() );
094                childNodes[0] = -1;
095                counter--;
096            } else {
097                System.arraycopy( hyperBBs, index + 1, hyperBBs, index, counter - index - 1 );
098                System.arraycopy( childNodes, index + 1, childNodes, index, counter - index - 1 );
099                hyperBBs[counter - 1] = HyperBoundingBox.getNullHyperBoundingBox( file.getDimension() );
100                childNodes[counter - 1] = -1;
101                counter--;
102    
103                for ( int i = 0; i < counter; i++ ) {
104                    Node help = (Node) this.getData( i );
105                    help.place = i;
106    
107                    try {
108                        file.writeNode( help );
109                    } catch ( PageFileException e ) {
110                        // "PageFileException NoneLeafNode.deleteData - at writeNode(Node)
111                        e.printStackTrace();
112                    }
113                }
114            }
115    
116            updateNodeBoundingBox();
117        }
118    
119        /**
120         * Computes the index of the entry with least enlargement if the given HyperBoundingBox would be
121         * added.
122         *
123         * @param box -
124         *            HyperBoundingBox to be added
125         * @return int - index of entry with least enlargement
126         */
127        protected int getLeastEnlargement( HyperBoundingBox box ) {
128    
129            double[] area = new double[counter];
130    
131            for ( int i = 0; i < counter; i++ )
132                area[i] = ( hyperBBs[i].unionBoundingBox( box ) ).getArea() - hyperBBs[i].getArea();
133    
134            double min = area[0];
135            int minnr = 0;
136    
137            for ( int i = 1; i < counter; i++ ) {
138                if ( area[i] < min ) {
139                    min = area[i];
140                    minnr = i;
141                }
142            }
143    
144            return minnr;
145        }
146    
147        /**
148         * @see Node#clone()
149         */
150        protected Object clone() {
151            NoneLeafNode clone = new NoneLeafNode( this.pageNumber, this.file );
152            clone.counter = this.counter;
153            clone.place = this.place;
154            clone.unionMinBB = (HyperBoundingBox) this.unionMinBB.clone();
155            clone.parentNode = this.parentNode;
156    
157            for ( int i = 0; i < file.getCapacity(); i++ )
158                clone.hyperBBs[i] = (HyperBoundingBox) this.hyperBBs[i].clone();
159    
160            return clone;
161        }
162    }