Quantum GIS API Documentation  1.7.4
src/core/spatialindex/qgsspatialindex.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsspatialindex.cpp  - wrapper class for spatial index library
00003     ----------------------
00004     begin                : December 2006
00005     copyright            : (C) 2006 by Martin Dobias
00006     email                : wonder.sk at gmail dot com
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 /* $Id$ */
00016 
00017 #include "qgsspatialindex.h"
00018 
00019 #include "qgsgeometry.h"
00020 #include "qgsfeature.h"
00021 #include "qgsrectangle.h"
00022 #include "qgslogger.h"
00023 
00024 #include "SpatialIndex.h"
00025 
00026 using namespace SpatialIndex;
00027 
00028 
00029 // custom visitor that adds found features to list
00030 class QgisVisitor : public SpatialIndex::IVisitor
00031 {
00032   public:
00033     QgisVisitor( QList<int> & list )
00034         : mList( list ) {}
00035 
00036     void visitNode( const INode& n ) {}
00037 
00038     void visitData( const IData& d )
00039     {
00040       mList.append( d.getIdentifier() );
00041     }
00042 
00043     void visitData( std::vector<const IData*>& v ) {}
00044 
00045   private:
00046     QList<int>& mList;
00047 };
00048 
00049 
00050 QgsSpatialIndex::QgsSpatialIndex()
00051 {
00052   // for now only memory manager
00053   mStorageManager = StorageManager::createNewMemoryStorageManager();
00054 
00055   // create buffer
00056 
00057   unsigned int capacity = 10;
00058   bool writeThrough = false;
00059   mStorage = StorageManager::createNewRandomEvictionsBuffer( *mStorageManager, capacity, writeThrough );
00060 
00061   // R-Tree parameters
00062   double fillFactor = 0.7;
00063   unsigned long indexCapacity = 10;
00064   unsigned long leafCapacity = 10;
00065   unsigned long dimension = 2;
00066   RTree::RTreeVariant variant = RTree::RV_RSTAR;
00067 
00068   // create R-tree
00069   long indexId;
00070   mRTree = RTree::createNewRTree( *mStorage, fillFactor, indexCapacity,
00071                                   leafCapacity, dimension, variant, indexId );
00072 }
00073 
00074 QgsSpatialIndex:: ~QgsSpatialIndex()
00075 {
00076   delete mRTree;
00077   delete mStorage;
00078   delete mStorageManager;
00079 }
00080 
00081 Tools::Geometry::Region QgsSpatialIndex::rectToRegion( QgsRectangle rect )
00082 {
00083   double pt1[2], pt2[2];
00084   pt1[0] = rect.xMinimum();
00085   pt1[1] = rect.yMinimum();
00086   pt2[0] = rect.xMaximum();
00087   pt2[1] = rect.yMaximum();
00088   return Tools::Geometry::Region( pt1, pt2, 2 );
00089 }
00090 
00091 bool QgsSpatialIndex::featureInfo( QgsFeature& f, Tools::Geometry::Region& r, long& id )
00092 {
00093   QgsGeometry *g = f.geometry();
00094   if ( !g )
00095     return false;
00096 
00097   id = f.id();
00098   r = rectToRegion( g->boundingBox() );
00099   return true;
00100 }
00101 
00102 bool QgsSpatialIndex::insertFeature( QgsFeature& f )
00103 {
00104   Tools::Geometry::Region r;
00105   long id;
00106   if ( !featureInfo( f, r, id ) )
00107     return false;
00108 
00109   // TODO: handle possible exceptions correctly
00110   try
00111   {
00112     mRTree->insertData( 0, 0, r, id );
00113   }
00114   catch ( Tools::Exception &e )
00115   {
00116     Q_UNUSED( e );
00117     QgsDebugMsg( QString( "Tools::Exception caught: " ).arg( e.what().c_str() ) );
00118   }
00119   catch ( const std::exception &e )
00120   {
00121     Q_UNUSED( e );
00122     QgsDebugMsg( QString( "std::exception caught: " ).arg( e.what() ) );
00123   }
00124   catch ( ... )
00125   {
00126     QgsDebugMsg( "unknown spatial index exception caught" );
00127   }
00128 
00129   return true;
00130 }
00131 
00132 bool QgsSpatialIndex::deleteFeature( QgsFeature& f )
00133 {
00134   Tools::Geometry::Region r;
00135   long id;
00136   if ( !featureInfo( f, r, id ) )
00137     return false;
00138 
00139   // TODO: handle exceptions
00140   return mRTree->deleteData( r, id );
00141 }
00142 
00143 QList<int> QgsSpatialIndex::intersects( QgsRectangle rect )
00144 {
00145   QList<int> list;
00146   QgisVisitor visitor( list );
00147 
00148   Tools::Geometry::Region r = rectToRegion( rect );
00149 
00150   mRTree->intersectsWithQuery( r, visitor );
00151 
00152   return list;
00153 }
00154 
00155 QList<int> QgsSpatialIndex::nearestNeighbor( QgsPoint point, int neighbors )
00156 {
00157   QList<int> list;
00158   QgisVisitor visitor( list );
00159 
00160   double pt[2];
00161   pt[0] = point.x();
00162   pt[1] = point.y();
00163   Tools::Geometry::Point p( pt, 2 );
00164 
00165   mRTree->nearestNeighborQuery( neighbors, p, visitor );
00166 
00167   return list;
00168 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines