libspatialindex.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include <stdio.h>
  2. #include <cstdlib>
  3. #include <random>
  4. #include <chrono>
  5. #include <vector>
  6. #include <spatialindex/capi/sidx_api.h>
  7. #include <spatialindex/capi/sidx_impl.h>
  8. #include <spatialindex/capi/sidx_config.h>
  9. using namespace std;
  10. using namespace SpatialIndex;
  11. struct MyPoint{
  12. double x;
  13. double y;
  14. double z;
  15. void init(double newX, double newY, double newZ) {
  16. x = newX;
  17. y = newY;
  18. z = newZ;
  19. }
  20. double distance(){
  21. return x * x + y * y + z * z ;
  22. }
  23. };
  24. const long long pointNum = 1000000; //节点数;
  25. const int knn = 100; //k近邻;
  26. long long queryNum = 1;
  27. vector<MyPoint> pointVector;
  28. double* generateRandomPoint() {
  29. std::random_device rd;
  30. std::mt19937_64 gen(rd());
  31. //范围
  32. std::uniform_real_distribution<double> dis(0, 10);
  33. double* coords = new double[3];
  34. coords[0] = dis(gen);
  35. coords[1] = dis(gen);
  36. coords[2] = dis(gen);
  37. //可注释
  38. MyPoint myPoint ;
  39. myPoint.init(coords[0], coords[1], coords[2]);
  40. pointVector.push_back(myPoint);
  41. //Print
  42. //for(int i = 0; i < 3; i++) cout<<coords[i]<<" "; printf("\n");
  43. return coords;
  44. }
  45. Index* createIndex()
  46. {
  47. // create a property set with default values.
  48. // see utility.cc for all defaults http://libspatialindex.github.io/doxygen/Utility_8cc_source.html#l00031
  49. Tools::PropertySet* ps = GetDefaults();
  50. Tools::Variant var;
  51. // set index type to R*-Tree
  52. var.m_varType = Tools::VT_ULONG;
  53. var.m_val.ulVal = RT_RTree;
  54. ps->setProperty("IndexType", var);
  55. // Set index to store in memory (default is disk)
  56. var.m_varType = Tools::VT_ULONG;
  57. var.m_val.ulVal = RT_Memory;
  58. ps->setProperty("IndexStorageType", var);
  59. var.m_varType = Tools::VT_ULONG;
  60. var.m_val.ulVal = 3;
  61. ps->setProperty("Dimension", var);
  62. // initialize index
  63. Index* idx = new Index(*ps);
  64. delete ps;
  65. // check index is ok
  66. if (!idx->index().isIndexValid())
  67. throw "Failed to create a valid index";
  68. else
  69. cout << "created index" << endl;
  70. return idx;
  71. }
  72. void addPoint(Index* idx, double x, double y, double z, int64_t id)
  73. {
  74. // create array with x, y, z coordinates
  75. //double coords[] = {x, y, z};
  76. double* coords = generateRandomPoint();
  77. // shapes can also have an object associated with them but we'll leave that for the moment.
  78. uint8_t* pData = 0;
  79. uint32_t nDataLength = 0;
  80. // create shape - three-dimensional
  81. SpatialIndex::IShape* shape = 0;
  82. shape = new SpatialIndex::Point(coords, 3);
  83. // insert into the index along with an object and an ID
  84. idx->index().insertData(nDataLength, pData, *shape, id);
  85. //Print
  86. //cout << "Point " << id << " inserted into the index.";
  87. delete shape;
  88. delete[] coords;
  89. }
  90. std::vector<SpatialIndex::IData*>* getNearest(Index* idx, double x, double y, double z, long long k)
  91. {
  92. double coords[] = {x, y, z};
  93. // get a visitor object and a point from which to search
  94. ObjVisitor* visitor = new ObjVisitor;
  95. // make the point from x, y, z coordinates
  96. SpatialIndex::Point* r = new SpatialIndex::Point(coords, 3);
  97. // get nearest maxResults shapes from the index
  98. idx->index().nearestNeighborQuery(k, *r, *visitor);
  99. // get the count of results
  100. int64_t nResultCount;
  101. nResultCount = visitor->GetResultCount();
  102. // get the actual results
  103. std::vector<SpatialIndex::IData*>& results = visitor->GetResults();
  104. // an empty vector that we will copy the results to
  105. vector<SpatialIndex::IData*>* resultsCopy = new vector<SpatialIndex::IData*>();
  106. // copy the items into the newly allocated vector array
  107. // we need to make sure to clone the actual item instead
  108. // of just the pointers, as the visitor will nuke them
  109. // upon destroy
  110. for (int64_t i = 0; i < nResultCount; ++i)
  111. {
  112. resultsCopy->push_back(dynamic_cast<SpatialIndex::IData*>(results[i]->clone()));
  113. }
  114. delete r;
  115. delete visitor;
  116. //Print
  117. //cout << "found " << nResultCount << " results." << endl;
  118. return resultsCopy;
  119. }
  120. int main(int argc, char* argv[])
  121. {
  122. cout<<"knn = "<< knn<<endl;
  123. try {
  124. // initialize the Index pointer
  125. Index* idx = createIndex();
  126. // add some points
  127. auto insertStart = std::chrono::high_resolution_clock::now();
  128. for(int i = 0; i < pointNum; i++) {
  129. addPoint(idx, 0,0,0, i);
  130. //Print
  131. //cout<<"distance:"<<pointVector[i].distance()<<endl;
  132. }
  133. auto insertEnd = std::chrono::high_resolution_clock::now();
  134. std::chrono::duration<double> duration = insertEnd - insertStart;
  135. double insertTime = duration.count();
  136. cout<< "插入数据花费的时间为"<< insertTime << "秒"<<"("<<pointNum<<")"<<endl;
  137. // get the nearest two locations to the royal albert hall
  138. auto queryStart = std::chrono::high_resolution_clock::now();
  139. for(int i = 0 ; i<queryNum; i++){
  140. double* coords = generateRandomPoint();
  141. std::vector<SpatialIndex::IData*>* results = getNearest(idx, coords[0], coords[1], coords[2], knn);
  142. delete[] coords;
  143. }
  144. auto queryEnd = std::chrono::high_resolution_clock::now();
  145. std::chrono::duration<double> duration2 = queryEnd - queryStart;
  146. double queryTime = duration2.count();
  147. cout<< "查询数据花费的时间为"<< queryTime << "秒"<<"("<<queryNum<<")"<<endl;
  148. /*//Print
  149. if(knn <= pointNum){
  150. for(SpatialIndex::IData* point : *results){
  151. int id = point->getIdentifier();
  152. cout<<"最近的n个点:"<<id;
  153. cout<<"("<<pointVector[id].x<<", "<<pointVector[id].y<<", "<<pointVector[id].z<<")"<<endl;
  154. }//endfor
  155. }//endif
  156. */
  157. }//end try
  158. catch (const char* ex) {
  159. cout << "Exception: " << ex << endl;
  160. }
  161. return 0;
  162. }
  163. //g++ xxx.cpp -o xxx -I/home/marioh/usr/include -L/home/marioh/usr/lib -lspatialindex