001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }