Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qgsspatialindex.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsspatialindex.cpp - wrapper class for spatial index library
3  ----------------------
4  begin : December 2006
5  copyright : (C) 2006 by Martin Dobias
6  email : wonder.sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 /* $Id$ */
16 
17 #include "qgsspatialindex.h"
18 
19 #include "qgsgeometry.h"
20 #include "qgsfeature.h"
21 #include "qgsrectangle.h"
22 #include "qgslogger.h"
23 
24 #include "SpatialIndex.h"
25 
26 using namespace SpatialIndex;
27 
28 
29 // custom visitor that adds found features to list
30 class QgisVisitor : public SpatialIndex::IVisitor
31 {
32  public:
33  QgisVisitor( QList<int> & list )
34  : mList( list ) {}
35 
36  void visitNode( const INode& n ) {}
37 
38  void visitData( const IData& d )
39  {
40  mList.append( d.getIdentifier() );
41  }
42 
43  void visitData( std::vector<const IData*>& v ) {}
44 
45  private:
46  QList<int>& mList;
47 };
48 
49 
51 {
52  // for now only memory manager
53  mStorageManager = StorageManager::createNewMemoryStorageManager();
54 
55  // create buffer
56 
57  unsigned int capacity = 10;
58  bool writeThrough = false;
59  mStorage = StorageManager::createNewRandomEvictionsBuffer( *mStorageManager, capacity, writeThrough );
60 
61  // R-Tree parameters
62  double fillFactor = 0.7;
63  unsigned long indexCapacity = 10;
64  unsigned long leafCapacity = 10;
65  unsigned long dimension = 2;
66  RTree::RTreeVariant variant = RTree::RV_RSTAR;
67 
68  // create R-tree
69  long indexId;
70  mRTree = RTree::createNewRTree( *mStorage, fillFactor, indexCapacity,
71  leafCapacity, dimension, variant, indexId );
72 }
73 
75 {
76  delete mRTree;
77  delete mStorage;
78  delete mStorageManager;
79 }
80 
81 Tools::Geometry::Region QgsSpatialIndex::rectToRegion( QgsRectangle rect )
82 {
83  double pt1[2], pt2[2];
84  pt1[0] = rect.xMinimum();
85  pt1[1] = rect.yMinimum();
86  pt2[0] = rect.xMaximum();
87  pt2[1] = rect.yMaximum();
88  return Tools::Geometry::Region( pt1, pt2, 2 );
89 }
90 
91 bool QgsSpatialIndex::featureInfo( QgsFeature& f, Tools::Geometry::Region& r, long& id )
92 {
93  QgsGeometry *g = f.geometry();
94  if ( !g )
95  return false;
96 
97  id = f.id();
98  r = rectToRegion( g->boundingBox() );
99  return true;
100 }
101 
103 {
104  Tools::Geometry::Region r;
105  long id;
106  if ( !featureInfo( f, r, id ) )
107  return false;
108 
109  // TODO: handle possible exceptions correctly
110  try
111  {
112  mRTree->insertData( 0, 0, r, id );
113  }
114  catch ( Tools::Exception &e )
115  {
116  Q_UNUSED( e );
117  QgsDebugMsg( QString( "Tools::Exception caught: " ).arg( e.what().c_str() ) );
118  }
119  catch ( const std::exception &e )
120  {
121  Q_UNUSED( e );
122  QgsDebugMsg( QString( "std::exception caught: " ).arg( e.what() ) );
123  }
124  catch ( ... )
125  {
126  QgsDebugMsg( "unknown spatial index exception caught" );
127  }
128 
129  return true;
130 }
131 
133 {
134  Tools::Geometry::Region r;
135  long id;
136  if ( !featureInfo( f, r, id ) )
137  return false;
138 
139  // TODO: handle exceptions
140  return mRTree->deleteData( r, id );
141 }
142 
144 {
145  QList<int> list;
146  QgisVisitor visitor( list );
147 
148  Tools::Geometry::Region r = rectToRegion( rect );
149 
150  mRTree->intersectsWithQuery( r, visitor );
151 
152  return list;
153 }
154 
155 QList<int> QgsSpatialIndex::nearestNeighbor( QgsPoint point, int neighbors )
156 {
157  QList<int> list;
158  QgisVisitor visitor( list );
159 
160  double pt[2];
161  pt[0] = point.x();
162  pt[1] = point.y();
163  Tools::Geometry::Point p( pt, 2 );
164 
165  mRTree->nearestNeighborQuery( neighbors, p, visitor );
166 
167  return list;
168 }