001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/io/quadtree/DBQuadtree.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2006 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     53177 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    package org.deegree.io.quadtree;
044    
045    import java.sql.Connection;
046    import java.sql.ResultSet;
047    import java.sql.Statement;
048    import java.util.ArrayList;
049    import java.util.HashMap;
050    import java.util.List;
051    import java.util.Map;
052    
053    import org.deegree.io.DBConnectionPool;
054    import org.deegree.io.JDBCConnection;
055    import org.deegree.model.spatialschema.Envelope;
056    import org.deegree.model.spatialschema.GeometryFactory;
057    import org.deegree.model.spatialschema.Point;
058    
059    /**
060     * 
061     * 
062     *
063     * @version $Revision: 6812 $
064     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
065     * @author last edited by: $Author: apoth $
066     *
067     * @version 1.0. $Revision: 6812 $, $Date: 2007-05-04 15:35:27 +0200 (Fr, 04 Mai 2007) $
068     *
069     * @since 2.0
070     */
071    public class DBQuadtree implements Quadtree  {
072    
073            private String fk_root;
074            private int depth;
075        private int id = 0; 
076        private String indexName = null; 
077        private JDBCConnection jdbc = null;
078        private Map<String,Node> nodeCache = new HashMap<String,Node>(10000);
079        private double accuracyX = 0.0001;
080        private double accuracyY = 0.0001;
081    
082        /**
083         * initializes a quadtree already existing in a database 
084         * @param id  
085         * @param indexName this name will be used to create the table 
086         *                  that stores the nodes of a specific quadtree
087         * @param jdbc description of database connection
088         */
089            public DBQuadtree(int id, String indexName, JDBCConnection jdbc) throws IndexException {
090                this.id = id;
091            this.jdbc = jdbc;
092            this.indexName = indexName;
093            readRootNodeId();
094            }
095        
096        /**
097         * initializes a quadtree already existing in a database 
098         * @param id  
099         * @param indexName this name will be used to create the table 
100         *                  that stores the nodes of a specific quadtree
101         * @param jdbc description of database connection
102         * @param accuracyX
103         * @param accuracyY
104         */
105        public DBQuadtree(int id, String indexName, JDBCConnection jdbc,
106                          double accuracyX, double accuracyY) throws IndexException {
107            this.id = id;
108            this.jdbc = jdbc;
109            this.indexName = indexName;
110            this.accuracyX = accuracyX;
111            this.accuracyY = accuracyY;
112            readRootNodeId();
113        }
114        
115        /**
116         * 
117         * @param id
118         * @return node
119         */
120        Node getFromCache(String id) {
121            return nodeCache.get( id );
122        }
123        
124        /**
125         * 
126         * @param node
127         */
128        void addToCache(Node node) {
129            nodeCache.put( node.getId(), node );
130        }
131       
132        /* (non-Javadoc)
133         * @see org.deegree.io.quadtree.Quadtree#insert(java.lang.Object, org.deegree.model.spatialschema.Envelope)
134         */
135            public void insert(Object item, Envelope envelope) throws IndexException {       
136            Node node = new DBNode( fk_root, null, this, indexName, jdbc, 1 );
137            node.insert( item, envelope );
138        }
139        
140        /**
141         * @param item
142         * @param point
143         */
144        public void insert( Object item, Point point ) throws IndexException {
145            Node node = new DBNode( fk_root, null, this, indexName, jdbc, 1 );
146            Envelope envelope = GeometryFactory.createEnvelope( point.getX() - accuracyX, 
147                                                                point.getY() - accuracyY,
148                                                                point.getX() + accuracyX,
149                                                                point.getY() + accuracyY,
150                                                                null );
151            node.insert( item, envelope );        
152        }
153    
154        /* (non-Javadoc)
155         * @see org.deegree.io.quadtree.Quadtree#query(org.deegree.model.spatialschema.Envelope)
156         */
157        public List<Object> query(Envelope envelope) throws IndexException {
158            List<Object> visitor = new ArrayList<Object>( 1000 );
159            DBNode node = new DBNode( fk_root, null, this, indexName, jdbc, 1 );
160            envelope = envelope.createIntersection( node.getEnvelope() );
161            if ( envelope == null ) {
162                return new ArrayList<Object>();
163            }
164            return node.query( envelope, visitor, 1 );
165        }
166        
167        /* (non-Javadoc)
168         * @see org.deegree.io.quadtree.Quadtree#deleteItem(java.lang.Object)
169         */
170        public void deleteItem(Object item) {
171            
172        }
173        
174        /* (non-Javadoc)
175         * @see org.deegree.io.quadtree.Quadtree#deleteRange(org.deegree.model.spatialschema.Envelope)
176         */
177        public void deleteRange(Envelope envelope) {
178            
179        }
180        
181        /* (non-Javadoc)
182         * @see org.deegree.io.quadtree.Quadtree#getDepth()
183         */
184        public int getDepth() {
185            return depth;
186        }
187        
188        /**
189         * reads the root node from the database
190         * @throws IndexException
191         */
192        private void readRootNodeId() throws IndexException {
193            
194            Connection con = null;
195            DBConnectionPool pool = null;
196            try {
197                pool = DBConnectionPool.getInstance();
198                con = pool.acquireConnection( jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), 
199                                                         jdbc.getPassword() );
200                
201                StringBuffer sb = new StringBuffer( 200 );
202                sb.append( "Select FK_ROOT, DEPTH from TAB_QUADTREE where ID = ");
203                sb.append( id );
204    
205                Statement stmt = con.createStatement();
206                ResultSet rs = stmt.executeQuery( sb.toString() );
207                if ( rs.next() ) {
208                    fk_root = rs.getString( "FK_ROOT" );       
209                    depth = rs.getInt( "DEPTH" );
210                } else {
211                    throw new IndexException( "could not read FK_ROOT and DEPTH for " +
212                                              "Quadtree with ID" + id );
213                }
214                rs.close();
215                stmt.close();
216            } catch (Exception e) {
217                throw new IndexException( "could not load quadtree definition from database", e );
218            } finally {
219                try {
220                    pool.releaseConnection( con, jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), 
221                                            jdbc.getPassword() );
222                } catch (Exception e1) {
223                    e1.printStackTrace();
224                }
225            }
226    
227        }
228        
229        /* (non-Javadoc)
230         * @see org.deegree.io.quadtree.Quadtree#getRootBoundingBox()
231         */
232        public Envelope getRootBoundingBox() throws IndexException {
233            DBNode node = new DBNode( fk_root, null, this, indexName, jdbc, 1 );
234            return node.getEnvelope();
235        }
236    
237    }
238    /* ********************************************************************
239    Changes to this class. What the people have been up to:
240    $Log$
241    Revision 1.2  2006/10/30 09:02:38  poth
242    implementation changed for optimized memory management for MemPointQuadtree
243    
244    Revision 1.1  2006/10/20 07:56:00  poth
245    core methods extracted to interfaces
246    
247    Revision 1.7  2006/05/18 14:08:54  poth
248    file comments completed
249    
250    Revision 1.6  2006/05/18 14:07:32  poth
251    *** empty log message ***
252    
253    Revision 1.5  2006/05/18 14:07:14  poth
254    not required typecast removed/ file comment footer added
255    
256    
257    ********************************************************************** */